
jadex.requiredservice.impl.MicroRequiredServiceLoader Maven / Gradle / Ivy
package jadex.requiredservice.impl;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;
import jadex.common.ClassInfo;
import jadex.common.FieldInfo;
import jadex.common.MethodInfo;
import jadex.common.SReflect;
import jadex.common.UnparsedExpression;
import jadex.micro.MicroClassReader;
import jadex.providedservice.ServiceScope;
import jadex.providedservice.annotation.Service;
import jadex.requiredservice.RequiredServiceBinding;
import jadex.requiredservice.RequiredServiceInfo;
import jadex.requiredservice.annotation.OnService;
import jadex.requiredservice.annotation.RequiredService;
import jadex.requiredservice.annotation.RequiredServices;
public class MicroRequiredServiceLoader
{
public static Object readFeatureModel(final Class> clazz, ClassLoader cl)
{
Class> cma = clazz;
//Map rservices = new HashMap<>();
RequiredServiceModel rsm = new RequiredServiceModel();
boolean reqsdone = false;
while(cma!=null && !cma.equals(Object.class))
{
// Take all but new overrides old
if(!reqsdone)
{
if(MicroClassReader.isAnnotationPresent(cma, RequiredServices.class, cl))
{
RequiredServices val = (RequiredServices)MicroClassReader.getAnnotation(cma, RequiredServices.class, cl);
RequiredService[] vals = val.value();
reqsdone = val.replace();
for(int i=0; i0? rs.name(): fields[i].getName();
// multi field
if(SReflect.isIterableClass(fields[i].getType()))
{
Class> type = SReflect.getIterableComponentType(fields[i].getGenericType());
if(Object.class.equals(rsis.getType().getType(cl)))
rsis.setType(new ClassInfo(type));
if(ser.name().length()>0)
checkAndAddRequiredServiceInfo(rsis, rsm.getRequiredServices(), cl);
ServiceInjectionInfo sii = new ServiceInjectionInfo().setFieldInfo(new FieldInfo(fields[i])).setRequiredServiceInfo(rsis);
if(ser.query().toBoolean()!=null)
sii.setQuery(ser.query().toBoolean());
else
sii.setQuery(true); // default on collection fields is true
sii.setRequired(ser.required().toBoolean()); // continue with init if service is not required
sii.setLazy(ser.required().toBoolean());
sii.setActive(ser.active()); // time the query should be active
rsm.addServiceInjection(name, sii);
}
else // normal field
{
if(Object.class.equals(rsis.getType().getType(cl)))
rsis.setType(new ClassInfo(fields[i].getType()));
if(ser.name().length()>0)
checkAndAddRequiredServiceInfo(rsis, rsm.getRequiredServices(), cl);
ServiceInjectionInfo sii = new ServiceInjectionInfo().setFieldInfo(new FieldInfo(fields[i])).setRequiredServiceInfo(rsis);
if(ser.query().toBoolean()!=null)
sii.setQuery(ser.query().toBoolean());
else
sii.setQuery(false); // default on fields is false
sii.setRequired(ser.required().toBoolean());
sii.setLazy(ser.required().toBoolean());
sii.setActive(ser.active());
rsm.addServiceInjection(name, sii);
}
}
}
// Find method injection targets by reflection (services)
Method[] methods = cma.getDeclaredMethods();
for(int i=0; i0? ser.requiredservice().name(): guessName(methods[i].getName());
String name = ser.name();
if(name.length()==0)
name = rs.name();
if(name.length()==0)
MicroClassReader.guessName(methods[i].getName());
RequiredServiceInfo rsis = (RequiredServiceInfo)rsm.getRequiredServices().get(name);
if(rsis==null)
{
rsis = createRequiredServiceInfo(rs, cl);
if(new ClassInfo(Object.class).equals(rsis.getType()))
{
Class> iftype = Object.class.equals(ser.requiredservice().type())? guessParameterType(methods[i].getParameterTypes(), cl): ser.requiredservice().type();
rsis.setType(new ClassInfo(iftype));
}
checkAndAddRequiredServiceInfo(rsis, rsm.getRequiredServices(), cl);
}
ServiceInjectionInfo sii = new ServiceInjectionInfo().setMethodInfo(new MethodInfo(methods[i])).setRequiredServiceInfo(rsis);
//if(ser.requiredservice().name().length()>0)
// checkAndAddRequiredServiceInfo(rsis, rsers, cl);
if(ser.query().toBoolean()!=null)
sii.setQuery(ser.query().toBoolean());
else
sii.setQuery(true); // default on methods is true
sii.setRequired(ser.required().toBoolean());
sii.setLazy(ser.required().toBoolean());
sii.setActive(ser.active());
rsm.addServiceInjection(name, sii);
}
}
}
cma = cma.getSuperclass();
}
return rsm;//.values().toArray(new Object[rservices.size()]);
}
/**
* Create a required service info from annotation.
*/
protected static RequiredServiceInfo createRequiredServiceInfo(RequiredService rs, ClassLoader cl)
{
RequiredServiceBinding binding = createBinding(rs);
//List nfprops = null;//createNFRProperties(rs.nfprops());
/*for(NFRProperty prop: rs.nfprops())
{
nfprops.add(new NFRPropertyInfo(prop.name(), new ClassInfo(prop.value().getName()),
new MethodInfo(prop.methodname(), prop.methodparametertypes())));
}*/
RequiredServiceInfo rsis = new RequiredServiceInfo(rs.name(), rs.type(),
rs.min(), rs.max(), binding,
//nfprops,
Arrays.asList(rs.tags())); // rs.multiple()
return rsis;
}
/**
* Create a service binding.
*/
public static RequiredServiceBinding createBinding(RequiredService rq)
{
UnparsedExpression scopeexpression = rq.scopeexpression()!=null && rq.scopeexpression().length()>0
? new UnparsedExpression("scopeexpression", ServiceScope.class, rq.scopeexpression(), null) : null;
return new RequiredServiceBinding(null, null, null,
rq.scope(), MicroClassReader.createUnparsedExpressions(rq.interceptors()),
rq.proxytype()
)
.setScopeExpression(scopeexpression);
}
/**
*
*/
public static void checkAndAddRequiredServiceInfo(RequiredServiceInfo rsis, Map rsers, ClassLoader cl)
{
// Do not add definitions without name!
if(rsis.getName()==null || rsis.getName().length()==0)
return;
if(rsers.containsKey(rsis.getName()))
{
RequiredServiceInfo old = (RequiredServiceInfo)rsers.get(rsis.getName());
//if(old.isMultiple()!=rsis.isMultiple()
if(old.getMin()!=rsis.getMin() || old.getMax()!=rsis.getMax() || !old.getType().getType(cl).equals(rsis.getType().getType(cl)))
throw new RuntimeException("Extension hierarchy contains incompatible required service more than once: "+rsis.getName());
}
else
{
rsers.put(rsis.getName(), rsis);
}
}
/**
*
*/
public static Class> guessParameterType(Class>[] ptypes, ClassLoader cl)
{
Class> iftype = null;
for(Class> ptype: ptypes)
{
if(MicroClassReader.isAnnotationPresent(ptype, Service.class, cl))
{
iftype = ptype;
break;
}
}
if(iftype==null || Object.class.equals(iftype))
throw new RuntimeException("No service interface found for service query");
return iftype;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy