props.remove(exclude);
}
int wiredCount = 0;
for (String prop : props) {
PropertyAdaptor type = getPropertyAdaptor(obj, prop);
Class propertyType = type.getPropertyType();
if (propertyType.isPrimitive() || propertyType.isAnnotation() || propertyType.isArray() || propertyType.isEnum()) {
// and primitive types of course can't be injected!
alwaysExcludedCollection.add(prop);
continue;
}
if ( propertyType.getPackage().getName().startsWith("java")) {
// if it is a standard java class then lets exclude it.
alwaysExcludedCollection.add(prop);
continue;
}
// if it is not readable then, then we can't verify that
// we are not overwriting non-null property.
if ( !type.isReadable() || !type.isWritable()) {
alwaysExcludedCollection.add(prop);
continue;
}
if ( propertyType.getAnnotation(NotService.class) != null) {
alwaysExcludedCollection.add(prop);
continue;
}
// check to see if we have a service to offer before bothering
// to checking if the property can be set. This avoids triggering
// actions caused by calling the get/setters.
Object srv = null;
if ( type.getPropertyType() == Log.class) {
// log is special.
srv = LogFactory.getLog(obj.getClass());
} else {
ConcurrentMap<String, String> classServiceMap = serviceMap.get(obj.getClass());
if (classServiceMap == null) {
serviceMap.putIfAbsent(obj.getClass(), new ConcurrentHashMap<String, String>());
classServiceMap = serviceMap.get(obj.getClass());
}
String serviceName = classServiceMap.get(prop);
if ( serviceName == null) {
InjectService service;
try {
service = findInjectService(obj, type);
} catch(DontInjectException e) {
// do nothing
alwaysExcludedCollection.add(prop);
continue;
}
if ( service != null ) {
serviceName = service.value();
if ( StringUtils.isNotBlank(serviceName)) {
for (String attempt: new String[] {
serviceName,
serviceName +'.' +type.getPropertyName(),
serviceName +'.' +StringUtils.capitalize(type.getPropertyName())
}) {
try {
srv = module.getService(attempt, propertyType);
if ( srv != null ) {
serviceName = attempt;
break;
}
}catch(Exception e) {
// oh well... not around.
}
}
}
}
if ( srv != null ) {
classServiceMap.putIfAbsent(prop, serviceName);
} else {
// we looked but did not find... no need to look again.
classServiceMap.putIfAbsent(prop, "");
}
} else if ( !serviceName.isEmpty()){
// we already found the service.
srv = module.getService(serviceName, propertyType);
}
if ( srv == null) {
try {
srv = module.getService(propertyType);
} catch (Exception e) {
}
}
}
if (srv == null) {
alwaysExcludedCollection.add(prop);
} else if ( type.read(obj) == null) {
// Doing the read check last avoids
// triggering problems caused by lazy initialization and read-only properties.
if ( type.getPropertyType().isAssignableFrom(srv.getClass())) {
type.write(obj, srv);
wiredCount++;
} else {
// this is probably an error so we do not just add to the exclude list.
throw new ApplicationRuntimeException("Trying to set property "+obj.getClass()+"."+prop+" however, the property type="+type.getPropertyType()+
" is not a superclass or same class as "+srv.getClass()+". srv="+srv);
}
}
}
if ( getLog().isDebugEnabled()) {