in modules/binding-corba-runtime/src/main/java/org/apache/tuscany/sca/binding/corba/provider/util/OperationMapper.java [80:284]
private static Map iiopMap(Class<?> intfClass, boolean operationToMethod) {
Method[] methods = getAllMethods(intfClass);
// find every valid getter
Map<Method, String> getterByMethod = new HashMap<Method, String>(methods.length);
Map<String, Method> getterByName = new HashMap<String, Method>(methods.length);
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
String methodName = method.getName();
// no arguments allowed
if (method.getParameterTypes().length != 0) {
continue;
}
// must start with get or is
String verb;
if (methodName.startsWith("get") && methodName.length() > 3 && method.getReturnType() != void.class) {
verb = "get";
} else if (methodName.startsWith("is") && methodName.length() > 2 && method.getReturnType() == boolean.class) {
verb = "is";
} else {
continue;
}
// must only throw Remote or Runtime Exceptions
boolean exceptionsValid = true;
Class[] exceptionTypes = method.getExceptionTypes();
for (int j = 0; j < exceptionTypes.length; j++) {
Class<?> exceptionType = exceptionTypes[j];
if (!RemoteException.class.isAssignableFrom(exceptionType) &&
!RuntimeException.class.isAssignableFrom(exceptionType) &&
!Error.class.isAssignableFrom(exceptionType)) {
exceptionsValid = false;
break;
}
}
if (!exceptionsValid) {
continue;
}
String propertyName;
if (methodName.length() > verb.length() + 1 && Character.isUpperCase(methodName.charAt(verb.length() + 1))) {
propertyName = methodName.substring(verb.length());
} else {
propertyName = Character.toLowerCase(methodName.charAt(verb.length())) + methodName.substring(verb.length() + 1);
}
getterByMethod.put(method, propertyName);
getterByName.put(propertyName, method);
}
Map<Method, String> setterByMethod = new HashMap<Method, String>(methods.length);
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
String methodName = method.getName();
// must have exactally one arg
if (method.getParameterTypes().length != 1) {
continue;
}
// must return non void
if (method.getReturnType() != void.class) {
continue;
}
// must start with set
if (!methodName.startsWith("set") || methodName.length() <= 3) {
continue;
}
// must only throw Remote or Runtime Exceptions
boolean exceptionsValid = true;
Class<?>[] exceptionTypes = method.getExceptionTypes();
for (int j = 0; j < exceptionTypes.length; j++) {
Class<?> exceptionType = exceptionTypes[j];
if (!RemoteException.class.isAssignableFrom(exceptionType) &&
!RuntimeException.class.isAssignableFrom(exceptionType) &&
!Error.class.isAssignableFrom(exceptionType)) {
exceptionsValid = false;
break;
}
}
if (!exceptionsValid) {
continue;
}
String propertyName;
if (methodName.length() > 4 && Character.isUpperCase(methodName.charAt(4))) {
propertyName = methodName.substring(3);
} else {
propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
}
// must have a matching getter
Method getter = (Method) getterByName.get(propertyName);
if (getter == null) {
continue;
}
// setter property must match getter return value
if (!method.getParameterTypes()[0].equals(getter.getReturnType())) {
continue;
}
setterByMethod.put(method, propertyName);
}
// index the methods by name... used to determine which methods are overloaded
HashMap<String, List<Method>> overloadedMethods = new HashMap<String, List<Method>>(methods.length);
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
if (getterByMethod.containsKey(method) || setterByMethod.containsKey(method)) {
continue;
}
String methodName = method.getName();
List<Method> methodList = overloadedMethods.get(methodName);
if (methodList == null) {
methodList = new LinkedList<Method>();
overloadedMethods.put(methodName, methodList);
}
methodList.add(method);
}
// index the methods by lower case name... used to determine which methods differ only by case
Map<String, Set<String>> caseCollisionMethods = new HashMap<String, Set<String>>(methods.length);
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
if (getterByMethod.containsKey(method) || setterByMethod.containsKey(method)) {
continue;
}
String lowerCaseMethodName = method.getName().toLowerCase();
Set<String> methodSet = caseCollisionMethods.get(lowerCaseMethodName);
if (methodSet == null) {
methodSet = new HashSet<String>();
caseCollisionMethods.put(lowerCaseMethodName, methodSet);
}
methodSet.add(method.getName());
}
String className = getClassName(intfClass);
Map iiopMap = new HashMap(methods.length);
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
String iiopName = (String) getterByMethod.get(method);
if (iiopName != null) {
// if we have a leading underscore prepend with J
if (iiopName.charAt(0) == '_') {
iiopName = "J_get_" + iiopName.substring(1);
} else {
iiopName = "_get_" + iiopName;
}
} else {
iiopName = (String) setterByMethod.get(method);
if (iiopName != null) {
// if we have a leading underscore prepend with J
if (iiopName.charAt(0) == '_') {
iiopName = "J_set_" + iiopName.substring(1);
} else {
iiopName = "_set_" + iiopName;
}
} else {
iiopName = method.getName();
// if we have a leading underscore prepend with J
if (iiopName.charAt(0) == '_') {
iiopName = "J" + iiopName;
}
}
}
// if this name only differs by case add the case index to the end
Set<String> caseCollisions = caseCollisionMethods.get(method.getName().toLowerCase());
if (caseCollisions != null && caseCollisions.size() > 1) {
iiopName += upperCaseIndexString(iiopName);
}
// if this is an overloaded method append the parameter string
List<Method> overloads = overloadedMethods.get(method.getName());
if (overloads != null && overloads.size() > 1) {
iiopName += buildOverloadParameterString(method.getParameterTypes());
}
// if we have a leading underscore prepend with J
iiopName = replace(iiopName, '$', "U0024");
// if we have matched a keyword prepend with an underscore
if (keywords.contains(iiopName.toLowerCase())) {
iiopName = "_" + iiopName;
}
// if the name is the same as the class name, append an underscore
if (iiopName.equalsIgnoreCase(className)) {
iiopName += "_";
}
if (operationToMethod) {
iiopMap.put(iiopName, method);
} else {
iiopMap.put(method, iiopName);
}
}
return iiopMap;
}