use of org.apache.felix.ipojo.parser.PojoMetadata in project felix by apache.
the class ProvidedServiceHandlerTest method testServiceDetectionSuperClass.
public void testServiceDetectionSuperClass() throws ConfigurationException {
String classname = "org.apache.felix.ipojo.handlers.providedservice.ComponentTestWithSuperClass";
Element metadata = new Element("component", "");
Element manipulation = new Element("manipulation", "");
metadata.addAttribute(new Attribute("classname", classname));
Element provides = new Element("provides", "");
provides.addAttribute(new Attribute("specifications", "java.beans.SimpleBeanInfo"));
metadata.addElement(provides);
metadata.addElement(manipulation);
manipulation.addAttribute(new Attribute("classname", classname));
manipulation.addAttribute(new Attribute("super", "java.beans.SimpleBeanInfo"));
Mockito.when(factory.getPojoMetadata()).thenReturn(new PojoMetadata(metadata));
Mockito.when(factory.getClassName()).thenReturn(classname);
handler.initializeComponentFactory(desc, metadata);
System.out.println(metadata);
}
use of org.apache.felix.ipojo.parser.PojoMetadata in project felix by apache.
the class ConfigurationHandler method initializeComponentFactory.
/**
* Initialize the component type.
*
* @param desc : component type description to populate.
* @param metadata : component type metadata.
* @throws ConfigurationException : metadata are incorrect.
* @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
*/
public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {
Element[] confs = metadata.getElements("Properties", "");
if (confs == null) {
return;
}
Element[] configurables = confs[0].getElements("Property");
for (int i = 0; configurables != null && i < configurables.length; i++) {
String fieldName = configurables[i].getAttribute("field");
String methodName = configurables[i].getAttribute("method");
String paramIndex = configurables[i].getAttribute("constructor-parameter");
if (fieldName == null && methodName == null && paramIndex == null) {
throw new ConfigurationException("Malformed property : The property needs to contain" + " at least a field, a method or a constructor-parameter");
}
String name = configurables[i].getAttribute("name");
if (name == null) {
if (fieldName == null && methodName != null) {
name = methodName;
} else if (fieldName == null && paramIndex != null) {
// Extract the name from the arguments.
MethodMetadata[] constructors = getFactory().getPojoMetadata().getConstructors();
if (constructors.length != 1) {
throw new ConfigurationException("Cannot infer the property name injected in the constructor " + "parameter #" + paramIndex + " - add the `name` attribute");
} else {
int idx = Integer.valueOf(paramIndex);
if (constructors[0].getMethodArgumentNames().length > idx) {
name = constructors[0].getMethodArgumentNames()[idx];
} else {
throw new ConfigurationException("Cannot infer the property name injected in the constructor " + "parameter #" + paramIndex + " - not enough argument in the constructor :" + constructors[0].getArguments());
}
}
} else {
name = fieldName;
}
// Add the type to avoid configure checking
configurables[i].addAttribute(new Attribute("name", name));
}
String value = configurables[i].getAttribute("value");
// Detect the type of the property
PojoMetadata manipulation = getFactory().getPojoMetadata();
String type = null;
if (methodName != null) {
MethodMetadata[] method = manipulation.getMethods(methodName);
if (method.length == 0) {
type = configurables[i].getAttribute("type");
if (type == null) {
throw new ConfigurationException("Malformed property : The type of the property cannot be discovered, add a 'type' attribute");
}
} else {
if (method[0].getMethodArguments().length != 1) {
throw new ConfigurationException("Malformed property : The method " + methodName + " does not have one argument");
}
type = method[0].getMethodArguments()[0];
// Add the type to avoid configure checking
configurables[i].addAttribute(new Attribute("type", type));
}
} else if (fieldName != null) {
FieldMetadata field = manipulation.getField(fieldName);
if (field == null) {
throw new ConfigurationException("Malformed property : The field " + fieldName + " does not exist in the implementation class");
}
type = field.getFieldType();
// Add the type to avoid configure checking
configurables[i].addAttribute(new Attribute("type", type));
} else if (paramIndex != null) {
int index = Integer.parseInt(paramIndex);
type = configurables[i].getAttribute("type");
MethodMetadata[] cts = manipulation.getConstructors();
// we the index 'index'.
if (type == null && cts.length > 0 && cts[0].getMethodArguments().length > index) {
type = cts[0].getMethodArguments()[index];
} else if (type == null) {
// Applied only if type was not determined.
throw new ConfigurationException("Cannot determine the type of the property " + index + ", please use the type attribute");
}
configurables[i].addAttribute(new Attribute("type", type));
}
// Is the property set to immutable
boolean immutable = false;
String imm = configurables[i].getAttribute("immutable");
immutable = imm != null && imm.equalsIgnoreCase("true");
boolean mandatory = false;
String man = configurables[i].getAttribute("mandatory");
mandatory = man != null && man.equalsIgnoreCase("true");
PropertyDescription pd;
if (value == null) {
// Cannot be immutable if we have no value.
pd = new PropertyDescription(name, type, null, false);
} else {
pd = new PropertyDescription(name, type, value, immutable);
}
if (mandatory) {
pd.setMandatory();
}
desc.addProperty(pd);
}
}
use of org.apache.felix.ipojo.parser.PojoMetadata in project felix by apache.
the class DependencyHandler method configure.
/**
* Configure the handler.
*
* @param componentMetadata : the component type metadata
* @param configuration : the instance configuration
* @throws ConfigurationException : one dependency metadata is not correct.
* @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
*/
public void configure(Element componentMetadata, Dictionary configuration) throws ConfigurationException {
PojoMetadata manipulation = getFactory().getPojoMetadata();
boolean atLeastOneField = false;
// Create the dependency according to the component metadata
Element[] deps = componentMetadata.getElements("Requires");
// Get instance filters.
Dictionary filtersConfiguration = getRequiresFilters(configuration.get("requires.filters"));
Dictionary fromConfiguration = (Dictionary) configuration.get("requires.from");
for (int i = 0; deps != null && i < deps.length; i++) {
// Create the dependency metadata
final Element dependencyElement = deps[i];
String field = dependencyElement.getAttribute("field");
String serviceSpecification = getServiceSpecificationAttribute(dependencyElement);
String opt = dependencyElement.getAttribute("optional");
boolean optional = opt != null && opt.equalsIgnoreCase("true");
String defaultImpl = dependencyElement.getAttribute("default-implementation");
String exception = dependencyElement.getAttribute("exception");
String to = dependencyElement.getAttribute("timeout");
int timeout = 0;
if (to != null) {
timeout = Integer.parseInt(to);
}
String agg = dependencyElement.getAttribute("aggregate");
boolean aggregate = agg != null && agg.equalsIgnoreCase("true");
String identity = dependencyElement.getAttribute("id");
String nul = dependencyElement.getAttribute("nullable");
boolean nullable = nul == null || nul.equalsIgnoreCase("true");
boolean isProxy = isProxy(dependencyElement);
BundleContext context = getFacetedBundleContext(dependencyElement);
String filter = computeFilter(dependencyElement, filtersConfiguration, fromConfiguration, aggregate, identity);
Filter fil = createAndCheckFilter(filter);
Class spec = null;
if (serviceSpecification != null) {
spec = DependencyMetadataHelper.loadSpecification(serviceSpecification, getInstanceManager().getContext());
}
int policy = DependencyMetadataHelper.getPolicy(dependencyElement);
Comparator cmp = DependencyMetadataHelper.getComparator(dependencyElement, getInstanceManager().getGlobalContext());
Dependency dep = new Dependency(this, field, spec, fil, optional, aggregate, nullable, isProxy, identity, context, policy, cmp, defaultImpl, exception);
dep.setTimeout(timeout);
// Look for dependency callback :
addCallbacksToDependency(dependencyElement, dep);
// Add the constructor parameter if needed
String paramIndex = dependencyElement.getAttribute("constructor-parameter");
if (paramIndex != null) {
int index = Integer.parseInt(paramIndex);
dep.addConstructorInjection(index);
}
// Check the dependency, throws an exception on error.
DependencyConfigurationChecker.ensure(dep, dependencyElement, manipulation);
m_dependencies.add(dep);
if (dep.getField() != null) {
getInstanceManager().register(manipulation.getField(dep.getField()), dep);
atLeastOneField = true;
}
}
if (atLeastOneField) {
// Does register only if we have fields
MethodMetadata[] methods = manipulation.getMethods();
for (MethodMetadata method : methods) {
for (Dependency dep : m_dependencies) {
getInstanceManager().register(method, dep);
}
}
// Also track the inner class methods
for (String inner : manipulation.getInnerClasses()) {
MethodMetadata[] meths = manipulation.getMethodsFromInnerClass(inner);
if (meths != null) {
for (MethodMetadata method : meths) {
for (Dependency dep : m_dependencies) {
getInstanceManager().register(method, inner, dep);
}
}
}
}
}
// Initialize the description.
m_description = new DependencyHandlerDescription(this, getDependencies());
manageContextSources(configuration);
}
use of org.apache.felix.ipojo.parser.PojoMetadata in project felix by apache.
the class LifecycleCallbackHandler method configure.
/**
* Configure the handler.
* @param metadata : the component type metadata
* @param configuration : the instance configuration
* @throws ConfigurationException : one callback metadata is not correct (either the transition or the method are not correct).
* @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
*/
public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
m_callbacks = new LifecycleCallback[0];
String imm = metadata.getAttribute("immediate");
m_immediate = imm != null && imm.equalsIgnoreCase("true");
PojoMetadata meta = getFactory().getPojoMetadata();
Element[] hooksMetadata = metadata.getElements("callback");
for (int i = 0; hooksMetadata != null && i < hooksMetadata.length; i++) {
String method = hooksMetadata[i].getAttribute("method");
if (method == null) {
throw new ConfigurationException("Lifecycle callback : A callback needs to contain a method attribute");
}
MethodMetadata met = meta.getMethod(method, new String[0]);
int transition = -1;
String trans = hooksMetadata[i].getAttribute("transition");
if (trans == null) {
throw new ConfigurationException("Lifecycle callback : the transition attribute is missing");
} else {
if (trans.equalsIgnoreCase("validate")) {
transition = LifecycleCallback.VALIDATE;
} else if (trans.equalsIgnoreCase("invalidate")) {
transition = LifecycleCallback.INVALIDATE;
} else {
throw new ConfigurationException("Lifecycle callback : Unknown or malformed transition : " + trans);
}
}
LifecycleCallback callback = null;
if (met == null) {
callback = new LifecycleCallback(this, transition, method);
} else {
callback = new LifecycleCallback(this, transition, met);
}
addCallback(callback);
}
}
use of org.apache.felix.ipojo.parser.PojoMetadata in project felix by apache.
the class ProvidedServiceHandler method initializeComponentFactory.
/**
* Initialize the component type.
* @param desc : component type description to populate.
* @param metadata : component type metadata.
* @throws ConfigurationException : occurs when the POJO does not implement any interfaces.
* @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
*/
public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {
// Change ComponentInfo
Element[] provides = metadata.getElements("provides");
PojoMetadata manipulation = getFactory().getPojoMetadata();
for (Element provide : provides) {
// First : create the serviceSpecification list
String[] serviceSpecification = manipulation.getInterfaces();
String parent = manipulation.getSuperClass();
Set<String> interfaces = new HashSet<String>();
Set<String> parentClasses = new HashSet<String>();
try {
computeInterfacesAndSuperClasses(serviceSpecification, parent, desc.getBundleContext().getBundle(), interfaces, parentClasses);
getLogger().log(Logger.INFO, "Collected interfaces from " + metadata.getAttribute("classname") + " : " + interfaces);
getLogger().log(Logger.INFO, "Collected super classes from " + metadata.getAttribute("classname") + " : " + parentClasses);
} catch (ClassNotFoundException e) {
throw new ConfigurationException("An interface or parent class cannot be loaded", e);
}
String serviceSpecificationStr = provide.getAttribute("specifications");
if (serviceSpecificationStr == null) {
serviceSpecificationStr = provide.getAttribute("interface");
if (serviceSpecificationStr != null) {
warn("The 'interface' attribute is deprecated, use the 'specifications' attribute instead of 'interface'");
}
}
if (serviceSpecificationStr != null) {
List<String> itfs = ParseUtils.parseArraysAsList(serviceSpecificationStr);
for (String itf : itfs) if (!interfaces.contains(itf) && !parentClasses.contains(itf) && !desc.getFactory().getClassName().equals(itf)) {
desc.getFactory().getLogger().log(Logger.ERROR, "The specification " + itf + " is not implemented by " + metadata.getAttribute("classname"));
}
interfaces.clear();
interfaces.addAll(itfs);
}
if (interfaces.isEmpty()) {
warn("No service interface found in the class hierarchy, use the implementation class");
interfaces.add(desc.getFactory().getClassName());
}
StringBuffer specs = null;
Set<String> set = new HashSet<String>(interfaces);
// Remove POJO.
set.remove(Pojo.class.getName());
for (String spec : set) {
desc.addProvidedServiceSpecification(spec);
if (specs == null) {
specs = new StringBuffer("{");
specs.append(spec);
} else {
specs.append(',');
specs.append(spec);
}
}
specs.append('}');
// Add interface attribute to avoid checking in the configure method
provide.addAttribute(new Attribute("specifications", specs.toString()));
Element[] props = provide.getElements("property");
for (int j = 0; props != null && j < props.length; j++) {
String name = props[j].getAttribute("name");
String value = props[j].getAttribute("value");
String type = props[j].getAttribute("type");
String field = props[j].getAttribute("field");
// Get property name :
if (field != null && name == null) {
name = field;
}
// Check type if not already set
if (type == null) {
if (field == null) {
throw new ConfigurationException("The property " + name + " has neither type nor field.");
}
FieldMetadata fieldMeta = manipulation.getField(field);
if (fieldMeta == null) {
throw new ConfigurationException("A declared property was not found in the implementation class : " + field);
}
type = fieldMeta.getFieldType();
props[j].addAttribute(new Attribute("type", type));
}
// Is the property set to immutable
boolean immutable = false;
String imm = props[j].getAttribute("immutable");
if (imm != null && imm.equalsIgnoreCase("true")) {
immutable = true;
}
PropertyDescription pd = new PropertyDescription(name, type, value, immutable);
desc.addProperty(pd);
String man = props[j].getAttribute("mandatory");
if (man != null && man.equalsIgnoreCase("true")) {
pd.setMandatory();
}
}
}
}
Aggregations