Extract package-name routing heuristics for single-machine fallback.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -139,77 +139,9 @@ public class HeuristicBeanResolutionEngine implements BeanResolutionEngine {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String targetVar = hasExplicitBeanTarget ? explicitTarget : chain.getContextMachineId();
|
Boolean packageMatch = PackageNameRoutingHeuristics.matches(chain, currentMachineName, explicitTarget);
|
||||||
if (targetVar == null && chain.getTriggerPoint() != null) {
|
if (packageMatch != null) {
|
||||||
targetVar = chain.getTriggerPoint().getStateMachineId();
|
return packageMatch;
|
||||||
}
|
|
||||||
|
|
||||||
String simplifiedMachineName = currentMachineName != null ? currentMachineName.substring(currentMachineName.lastIndexOf('.') + 1).toLowerCase() : "";
|
|
||||||
|
|
||||||
if (targetVar != null && !targetVar.isEmpty()) {
|
|
||||||
targetVar = targetVar.toLowerCase();
|
|
||||||
if (targetVar.endsWith("statemachine")) {
|
|
||||||
String prefix = targetVar.substring(0, targetVar.length() - "statemachine".length());
|
|
||||||
if (!prefix.isEmpty()) {
|
|
||||||
if (simplifiedMachineName.contains(prefix)) {
|
|
||||||
return true; // Explicit positive match
|
|
||||||
} else {
|
|
||||||
return false; // Explicit negative match
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (simplifiedMachineName.contains(targetVar)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chain.getMethodChain() != null && !chain.getMethodChain().isEmpty() && currentMachineName != null) {
|
|
||||||
String smPackage = getPackageName(currentMachineName);
|
|
||||||
String smSimple = getSimpleClassName(currentMachineName);
|
|
||||||
String smPrefix = getFirstCamelCaseWord(smSimple);
|
|
||||||
|
|
||||||
boolean hasPositiveMatch = false;
|
|
||||||
boolean hasStrongMismatch = false;
|
|
||||||
|
|
||||||
if (chain.getTriggerPoint() != null && chain.getTriggerPoint().getClassName() != null) {
|
|
||||||
String chainClass = chain.getTriggerPoint().getClassName();
|
|
||||||
String chainPackage = getPackageName(chainClass);
|
|
||||||
String chainSimple = getSimpleClassName(chainClass);
|
|
||||||
String chainPrefix = getFirstCamelCaseWord(chainSimple);
|
|
||||||
|
|
||||||
if (smPrefix != null && chainPrefix != null && smPrefix.equals(chainPrefix)) {
|
|
||||||
hasPositiveMatch = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDomainMatch(smPackage, chainPackage, smPrefix, chainPrefix)) {
|
|
||||||
hasPositiveMatch = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String method : chain.getMethodChain()) {
|
|
||||||
String chainClass = getClassNameOnly(method);
|
|
||||||
String chainPackage = getPackageName(chainClass);
|
|
||||||
String chainSimple = getSimpleClassName(chainClass);
|
|
||||||
String chainPrefix = getFirstCamelCaseWord(chainSimple);
|
|
||||||
|
|
||||||
if (smPrefix != null && chainPrefix != null && smPrefix.equals(chainPrefix)) {
|
|
||||||
hasPositiveMatch = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDomainMatch(smPackage, chainPackage, smPrefix, chainPrefix)) {
|
|
||||||
hasPositiveMatch = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDomainMismatch(smPackage, chainPackage, smPrefix, chainPrefix, smSimple, chainSimple)) {
|
|
||||||
hasStrongMismatch = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasPositiveMatch) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (hasStrongMismatch) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return context == null || isSingleStateMachine(context);
|
return context == null || isSingleStateMachine(context);
|
||||||
}
|
}
|
||||||
@@ -344,160 +276,6 @@ public class HeuristicBeanResolutionEngine implements BeanResolutionEngine {
|
|||||||
java.util.Set.of("StateMachine", "StateMachineFactory", "StateMachineModelFactory")).size();
|
java.util.Set.of("StateMachine", "StateMachineFactory", "StateMachineModelFactory")).size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDomainMatch(String smPackage, String chainPackage, String smPrefix, String chainPrefix) {
|
|
||||||
if (smPackage == null || chainPackage == null || smPackage.isEmpty() || chainPackage.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (smPackage.equals(chainPackage)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!chainPackage.startsWith(smPackage + ".") && !smPackage.startsWith(chainPackage + ".")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find deepest common package root
|
|
||||||
String[] p1 = smPackage.split("\\.");
|
|
||||||
String[] p2 = chainPackage.split("\\.");
|
|
||||||
int matchIdx = -1;
|
|
||||||
for (int i = 0; i < Math.min(p1.length, p2.length); i++) {
|
|
||||||
if (p1[i].equals(p2[i])) {
|
|
||||||
matchIdx = i;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the state machine's prefix is part of the shared common package,
|
|
||||||
// then the state machine represents the parent domain of the caller.
|
|
||||||
if (smPrefix != null && matchIdx >= 0) {
|
|
||||||
String lowerPrefix = smPrefix.toLowerCase();
|
|
||||||
for (int i = 0; i <= matchIdx; i++) {
|
|
||||||
if (p1[i].toLowerCase().contains(lowerPrefix) || lowerPrefix.contains(p1[i].toLowerCase())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isDomainMismatch(String smPackage, String chainPackage, String smPrefix, String chainPrefix, String smSimple, String chainSimple) {
|
|
||||||
if (smPackage == null || chainPackage == null || smPackage.isEmpty() || chainPackage.isEmpty()) return false;
|
|
||||||
if (smPrefix == null || chainPrefix == null) return false;
|
|
||||||
|
|
||||||
String smLower = smPrefix.toLowerCase();
|
|
||||||
String chainLower = chainPrefix.toLowerCase();
|
|
||||||
|
|
||||||
// Ignore generic/technical class prefixes
|
|
||||||
if (smLower.equals("state") || smLower.equals("statemachine") || smLower.equals("config") || smLower.equals("configuration") || smLower.equals("adapter") ||
|
|
||||||
smLower.equals("enterprise") || smLower.equals("app") || smLower.equals("global") || smLower.equals("core") || smLower.equals("project") || smLower.equals("main") || smLower.equals("base") || smLower.equals("common") || smLower.equals("shared") ||
|
|
||||||
chainLower.equals("state") || chainLower.equals("statemachine") || chainLower.equals("config") || chainLower.equals("configuration") || chainLower.equals("adapter") ||
|
|
||||||
chainLower.equals("enterprise") || chainLower.equals("app") || chainLower.equals("global") || chainLower.equals("core") || chainLower.equals("project") || chainLower.equals("main") || chainLower.equals("base") || chainLower.equals("common") || chainLower.equals("shared")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If class prefixes diverge, check if they are from different domains
|
|
||||||
if (!smLower.equals(chainLower)) {
|
|
||||||
// If one prefix is present as a domain/feature segment in the other package, they are related
|
|
||||||
if (chainPackage.toLowerCase().contains(smLower) || smPackage.toLowerCase().contains(chainLower)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, if they diverge under a shared project package root, it is a mismatch
|
|
||||||
String[] p1 = smPackage.split("\\.");
|
|
||||||
String[] p2 = chainPackage.split("\\.");
|
|
||||||
int matchIdx = -1;
|
|
||||||
for (int i = 0; i < Math.min(p1.length, p2.length); i++) {
|
|
||||||
if (p1[i].equals(p2[i])) {
|
|
||||||
matchIdx = i;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (matchIdx >= 1) {
|
|
||||||
// If they diverge under a shared root, check if the divergence is only on generic package layers
|
|
||||||
boolean onlyGenericDivergence = true;
|
|
||||||
Set<String> genericLayers = Set.of(
|
|
||||||
"config", "configuration", "service", "services", "impl", "api", "web",
|
|
||||||
"controller", "controllers", "messaging", "listener", "listeners",
|
|
||||||
"repository", "repositories", "db", "model", "models", "domain",
|
|
||||||
"constants", "utils", "helper", "helpers", "event", "events",
|
|
||||||
"state", "states", "transition", "transitions"
|
|
||||||
);
|
|
||||||
for (int i = matchIdx + 1; i < p1.length; i++) {
|
|
||||||
if (!genericLayers.contains(p1[i].toLowerCase())) {
|
|
||||||
onlyGenericDivergence = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (onlyGenericDivergence) {
|
|
||||||
for (int i = matchIdx + 1; i < p2.length; i++) {
|
|
||||||
if (!genericLayers.contains(p2[i].toLowerCase())) {
|
|
||||||
onlyGenericDivergence = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!onlyGenericDivergence) {
|
|
||||||
return true; // Mismatch under a shared root
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<String> extractDomainTerms(String pkg, String prefix) {
|
|
||||||
Set<String> terms = new HashSet<>();
|
|
||||||
if (pkg != null && !pkg.isEmpty()) {
|
|
||||||
String[] segments = pkg.split("\\.");
|
|
||||||
// Take segments from index 2 onwards if length > 2
|
|
||||||
int start = segments.length > 2 ? 2 : 0;
|
|
||||||
for (int i = start; i < segments.length; i++) {
|
|
||||||
terms.add(segments[i].toLowerCase());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (prefix != null && !prefix.isEmpty()) {
|
|
||||||
terms.add(prefix.toLowerCase());
|
|
||||||
}
|
|
||||||
return terms;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getPackageName(String fqn) {
|
|
||||||
if (fqn == null || !fqn.contains(".")) return "";
|
|
||||||
return fqn.substring(0, fqn.lastIndexOf('.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getSimpleClassName(String fqn) {
|
|
||||||
if (fqn == null) return "";
|
|
||||||
if (!fqn.contains(".")) return fqn;
|
|
||||||
return fqn.substring(fqn.lastIndexOf('.') + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getClassNameOnly(String methodFqn) {
|
|
||||||
if (methodFqn == null) return "";
|
|
||||||
String clean = methodFqn;
|
|
||||||
if (clean.contains("(")) {
|
|
||||||
clean = clean.substring(0, clean.indexOf('('));
|
|
||||||
}
|
|
||||||
if (clean.contains(".")) {
|
|
||||||
clean = clean.substring(0, clean.lastIndexOf('.'));
|
|
||||||
}
|
|
||||||
return clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getFirstCamelCaseWord(String simpleName) {
|
|
||||||
if (simpleName == null || simpleName.isEmpty()) return null;
|
|
||||||
String[] words = simpleName.split("(?<!^)(?=[A-Z])");
|
|
||||||
if (words.length > 0) {
|
|
||||||
return words[0];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String eraseGenerics(String type) {
|
private String eraseGenerics(String type) {
|
||||||
if (type == null) return null;
|
if (type == null) return null;
|
||||||
int idx = type.indexOf('<');
|
int idx = type.indexOf('<');
|
||||||
|
|||||||
@@ -0,0 +1,256 @@
|
|||||||
|
package click.kamil.springstatemachineexporter.analysis.enricher.routing;
|
||||||
|
|
||||||
|
import click.kamil.springstatemachineexporter.analysis.model.CallChain;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Legacy package-prefix and domain-name matching for single-machine / null-context fallback routing.
|
||||||
|
*/
|
||||||
|
final class PackageNameRoutingHeuristics {
|
||||||
|
|
||||||
|
private PackageNameRoutingHeuristics() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true/false if package heuristics decide, null if inconclusive
|
||||||
|
*/
|
||||||
|
static Boolean matches(CallChain chain, String currentMachineName, String explicitBeanTarget) {
|
||||||
|
if (chain == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasExplicitBeanTarget = explicitBeanTarget != null && !explicitBeanTarget.isEmpty();
|
||||||
|
String targetVar = hasExplicitBeanTarget ? explicitBeanTarget : chain.getContextMachineId();
|
||||||
|
if (targetVar == null && chain.getTriggerPoint() != null) {
|
||||||
|
targetVar = chain.getTriggerPoint().getStateMachineId();
|
||||||
|
}
|
||||||
|
|
||||||
|
String simplifiedMachineName = currentMachineName != null
|
||||||
|
? currentMachineName.substring(currentMachineName.lastIndexOf('.') + 1).toLowerCase()
|
||||||
|
: "";
|
||||||
|
|
||||||
|
if (targetVar != null && !targetVar.isEmpty()) {
|
||||||
|
targetVar = targetVar.toLowerCase();
|
||||||
|
if (targetVar.endsWith("statemachine")) {
|
||||||
|
String prefix = targetVar.substring(0, targetVar.length() - "statemachine".length());
|
||||||
|
if (!prefix.isEmpty()) {
|
||||||
|
if (simplifiedMachineName.contains(prefix)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (simplifiedMachineName.contains(targetVar)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chain.getMethodChain() != null && !chain.getMethodChain().isEmpty() && currentMachineName != null) {
|
||||||
|
String smPackage = getPackageName(currentMachineName);
|
||||||
|
String smSimple = getSimpleClassName(currentMachineName);
|
||||||
|
String smPrefix = getFirstCamelCaseWord(smSimple);
|
||||||
|
|
||||||
|
boolean hasPositiveMatch = false;
|
||||||
|
boolean hasStrongMismatch = false;
|
||||||
|
|
||||||
|
if (chain.getTriggerPoint() != null && chain.getTriggerPoint().getClassName() != null) {
|
||||||
|
String chainClass = chain.getTriggerPoint().getClassName();
|
||||||
|
String chainPackage = getPackageName(chainClass);
|
||||||
|
String chainSimple = getSimpleClassName(chainClass);
|
||||||
|
String chainPrefix = getFirstCamelCaseWord(chainSimple);
|
||||||
|
|
||||||
|
if (smPrefix != null && chainPrefix != null && smPrefix.equals(chainPrefix)) {
|
||||||
|
hasPositiveMatch = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDomainMatch(smPackage, chainPackage, smPrefix, chainPrefix)) {
|
||||||
|
hasPositiveMatch = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String method : chain.getMethodChain()) {
|
||||||
|
String chainClass = getClassNameOnly(method);
|
||||||
|
String chainPackage = getPackageName(chainClass);
|
||||||
|
String chainSimple = getSimpleClassName(chainClass);
|
||||||
|
String chainPrefix = getFirstCamelCaseWord(chainSimple);
|
||||||
|
|
||||||
|
if (smPrefix != null && chainPrefix != null && smPrefix.equals(chainPrefix)) {
|
||||||
|
hasPositiveMatch = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDomainMatch(smPackage, chainPackage, smPrefix, chainPrefix)) {
|
||||||
|
hasPositiveMatch = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDomainMismatch(smPackage, chainPackage, smPrefix, chainPrefix, smSimple, chainSimple)) {
|
||||||
|
hasStrongMismatch = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasPositiveMatch) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (hasStrongMismatch) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isDomainMatch(String smPackage, String chainPackage, String smPrefix, String chainPrefix) {
|
||||||
|
if (smPackage == null || chainPackage == null || smPackage.isEmpty() || chainPackage.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (smPackage.equals(chainPackage)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chainPackage.startsWith(smPackage + ".") && !smPackage.startsWith(chainPackage + ".")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] p1 = smPackage.split("\\.");
|
||||||
|
String[] p2 = chainPackage.split("\\.");
|
||||||
|
int matchIdx = -1;
|
||||||
|
for (int i = 0; i < Math.min(p1.length, p2.length); i++) {
|
||||||
|
if (p1[i].equals(p2[i])) {
|
||||||
|
matchIdx = i;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (smPrefix != null && matchIdx >= 0) {
|
||||||
|
String lowerPrefix = smPrefix.toLowerCase();
|
||||||
|
for (int i = 0; i <= matchIdx; i++) {
|
||||||
|
if (p1[i].toLowerCase().contains(lowerPrefix) || lowerPrefix.contains(p1[i].toLowerCase())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isDomainMismatch(
|
||||||
|
String smPackage,
|
||||||
|
String chainPackage,
|
||||||
|
String smPrefix,
|
||||||
|
String chainPrefix,
|
||||||
|
String smSimple,
|
||||||
|
String chainSimple) {
|
||||||
|
if (smPackage == null || chainPackage == null || smPackage.isEmpty() || chainPackage.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (smPrefix == null || chainPrefix == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String smLower = smPrefix.toLowerCase();
|
||||||
|
String chainLower = chainPrefix.toLowerCase();
|
||||||
|
|
||||||
|
if (smLower.equals("state") || smLower.equals("statemachine") || smLower.equals("config")
|
||||||
|
|| smLower.equals("configuration") || smLower.equals("adapter")
|
||||||
|
|| smLower.equals("enterprise") || smLower.equals("app") || smLower.equals("global")
|
||||||
|
|| smLower.equals("core") || smLower.equals("project") || smLower.equals("main")
|
||||||
|
|| smLower.equals("base") || smLower.equals("common") || smLower.equals("shared")
|
||||||
|
|| chainLower.equals("state") || chainLower.equals("statemachine") || chainLower.equals("config")
|
||||||
|
|| chainLower.equals("configuration") || chainLower.equals("adapter")
|
||||||
|
|| chainLower.equals("enterprise") || chainLower.equals("app") || chainLower.equals("global")
|
||||||
|
|| chainLower.equals("core") || chainLower.equals("project") || chainLower.equals("main")
|
||||||
|
|| chainLower.equals("base") || chainLower.equals("common") || chainLower.equals("shared")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!smLower.equals(chainLower)) {
|
||||||
|
if (chainPackage.toLowerCase().contains(smLower) || smPackage.toLowerCase().contains(chainLower)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] p1 = smPackage.split("\\.");
|
||||||
|
String[] p2 = chainPackage.split("\\.");
|
||||||
|
int matchIdx = -1;
|
||||||
|
for (int i = 0; i < Math.min(p1.length, p2.length); i++) {
|
||||||
|
if (p1[i].equals(p2[i])) {
|
||||||
|
matchIdx = i;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (matchIdx >= 1) {
|
||||||
|
boolean onlyGenericDivergence = true;
|
||||||
|
Set<String> genericLayers = Set.of(
|
||||||
|
"config", "configuration", "service", "services", "impl", "api", "web",
|
||||||
|
"controller", "controllers", "messaging", "listener", "listeners",
|
||||||
|
"repository", "repositories", "db", "model", "models", "domain",
|
||||||
|
"constants", "utils", "helper", "helpers", "event", "events",
|
||||||
|
"state", "states", "transition", "transitions"
|
||||||
|
);
|
||||||
|
for (int i = matchIdx + 1; i < p1.length; i++) {
|
||||||
|
if (!genericLayers.contains(p1[i].toLowerCase())) {
|
||||||
|
onlyGenericDivergence = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (onlyGenericDivergence) {
|
||||||
|
for (int i = matchIdx + 1; i < p2.length; i++) {
|
||||||
|
if (!genericLayers.contains(p2[i].toLowerCase())) {
|
||||||
|
onlyGenericDivergence = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!onlyGenericDivergence) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getPackageName(String fqn) {
|
||||||
|
if (fqn == null || !fqn.contains(".")) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return fqn.substring(0, fqn.lastIndexOf('.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getSimpleClassName(String fqn) {
|
||||||
|
if (fqn == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (!fqn.contains(".")) {
|
||||||
|
return fqn;
|
||||||
|
}
|
||||||
|
return fqn.substring(fqn.lastIndexOf('.') + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getClassNameOnly(String methodFqn) {
|
||||||
|
if (methodFqn == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String clean = methodFqn;
|
||||||
|
if (clean.contains("(")) {
|
||||||
|
clean = clean.substring(0, clean.indexOf('('));
|
||||||
|
}
|
||||||
|
if (clean.contains(".")) {
|
||||||
|
clean = clean.substring(0, clean.lastIndexOf('.'));
|
||||||
|
}
|
||||||
|
return clean;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getFirstCamelCaseWord(String simpleName) {
|
||||||
|
if (simpleName == null || simpleName.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String[] words = simpleName.split("(?<!^)(?=[A-Z])");
|
||||||
|
if (words.length > 0) {
|
||||||
|
return words[0];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user