List<String> reverseTargetScopes = Configuration.getConfiguration().getReverseInjectableScopes();
InstanceWireTarget target = new InstanceWireTarget();
Class<?> cls = instance.getClass();
ContextData cd;
// at first, retrieve methods information
// TODO we should use class name to confirm contextdata annotation
// because they are possibly from different class loader. The problem is
// whether it is a problem?
Method[] mtds = cls.getMethods();
for (Method method : mtds) {
cd = ConvertableAnnotationRetriever.retrieveAnnotation(ContextData.class, method.getAnnotations());
if (cd != null) {
// cd = method.getAnnotation(ContextData.class);
MethodInfo mi = new MethodInfo();
mi.method = method;
boolean isGet = false;
boolean isSet = false;
String declaredName = cd.name();
if (StringUtils.isEmpty(declaredName)) {
String name = method.getName();
if (name.startsWith("set")) {
name = name.substring(3);
isSet = true;
} else if (name.startsWith("get")) {
name = name.substring(3);
isGet = true;
} else if (name.startsWith("is")) {
name = name.substring(2);
isSet = true;
} else {
switch (method.getParameterTypes().length) {
case 0:
isGet = true;
break;
case 1:
isSet = true;
break;
default:
String msg = String.format("Method [%s]:[%s] can not be treated as a getter or setter method.", cls.getName(),
method.toGenericString());
throw new DataOperationException(msg);
}
}
char[] cs = name.toCharArray();
cs[0] = Character.toLowerCase(cs[0]);
mi.name = new String(cs);
} else {
mi.name = declaredName;
int typeLength = method.getParameterTypes().length;
if (typeLength == 0) {
isGet = true;
} else if (typeLength == 1) {
isSet = true;
} else {
String msg = String.format(
"Only one parameter is allowed on a method declared with ContextData annoataion.(%s:%s)", cls.getName(),
mi.name);
throw new DataOperationException(msg);
}
}
mi.scope = cd.scope();
mi.typeUnMatch = cd.typeUnMatch();
if (isGet) {
// only if the reverse value is explicitly set to true and
// the scope is contained in the allowing reverse injection
// list
if (cd.reverse()) {
if (reverseTargetScopes.contains(mi.scope)) {
mi.type = method.getReturnType();
mi.fixForPrimitiveType();
target.getMethodList.add(mi);
} else {
String msg = String.format(
"Only scope in [%s] can be marked as reverse injectable but found scope as %s (%s:%s).",
reverseTargetScopes.toString(), mi.scope, cls.getName(), mi.name);
Asta4DWarningException awe = new Asta4DWarningException(msg);
logger.warn(msg, awe);
}
}
}
if (isSet) {
mi.type = method.getParameterTypes()[0];
mi.isContextDataHolder = ContextDataHolder.class.isAssignableFrom(mi.type);
mi.fixForPrimitiveType();
ContextDataSet cdSet = ConvertableAnnotationRetriever
.retrieveAnnotation(ContextDataSet.class, mi.type.getAnnotations());
if (cdSet == null) {
mi.contextDataSetFactory = null;
} else {
mi.contextDataSetFactory = cdSet.factory().newInstance();
mi.isContextDataSetSingletonInContext = cdSet.singletonInContext();
}
target.setMethodList.add(mi);
}
}
}
// then retrieve fields information
String objCls = Object.class.getName();
Field[] flds;
FieldInfo fi;
while (!cls.getName().equals(objCls)) {
flds = cls.getDeclaredFields();
for (Field field : flds) {
cd = ConvertableAnnotationRetriever.retrieveAnnotation(ContextData.class, field.getAnnotations());
if (cd != null) {
fi = new FieldInfo();
fi.field = field;
fi.type = field.getType();
fi.isContextDataHolder = ContextDataHolder.class.isAssignableFrom(fi.type);
String delcaredName = cd == null ? "" : cd.name();
if (StringUtils.isEmpty(delcaredName)) {
fi.name = field.getName();
} else {
fi.name = cd.name();
}
fi.scope = cd == null ? "" : cd.scope();
fi.typeUnMatch = cd.typeUnMatch();
fi.fixForPrimitiveType();
ContextDataSet cdSet = ConvertableAnnotationRetriever
.retrieveAnnotation(ContextDataSet.class, fi.type.getAnnotations());
if (cdSet == null) {
fi.contextDataSetFactory = null;
} else {
fi.contextDataSetFactory = cdSet.factory().newInstance();
fi.isContextDataSetSingletonInContext = cdSet.singletonInContext();
}
target.setFieldList.add(fi);
if (cd.reverse()) {//
if (reverseTargetScopes.contains(fi.scope)) {
target.getFieldList.add(fi);
} else {
String msg = String.format(
"Only scope in [%s] can be marked as reverse injectable but found scope as %s (%s:%s).",