use of org.apache.felix.ipojo.parser.FieldMetadata in project felix by apache.
the class ProvidedServiceHandler method configure.
/**
* Configure the handler.
* @param componentMetadata : the component type metadata
* @param configuration : the instance configuration
* @throws ConfigurationException : the metadata are 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 {
m_providedServices.clear();
// Create the dependency according to the component metadata
Element[] providedServices = componentMetadata.getElements("Provides");
for (Element providedService : providedServices) {
// Set by the initialize component factory.
String[] serviceSpecifications = ParseUtils.parseArrays(providedService.getAttribute("specifications"));
// Get the factory policy
int factory = ProvidedService.SINGLETON_STRATEGY;
Class custom = null;
String strategy = providedService.getAttribute("strategy");
if (strategy == null) {
strategy = providedService.getAttribute("factory");
}
if (strategy != null) {
if ("singleton".equalsIgnoreCase(strategy)) {
factory = ProvidedService.SINGLETON_STRATEGY;
} else if ("service".equalsIgnoreCase(strategy)) {
factory = ProvidedService.SERVICE_STRATEGY;
} else if ("method".equalsIgnoreCase(strategy)) {
factory = ProvidedService.STATIC_STRATEGY;
} else if ("instance".equalsIgnoreCase(strategy)) {
factory = ProvidedService.INSTANCE_STRATEGY;
} else {
// Customized policy
try {
custom = getInstanceManager().getContext().getBundle().loadClass(strategy);
if (!CreationStrategy.class.isAssignableFrom(custom)) {
throw new ConfigurationException("The custom creation policy class " + custom.getName() + " does not implement " + CreationStrategy.class.getName());
}
} catch (ClassNotFoundException e) {
throw new ConfigurationException("The custom creation policy class " + strategy + " cannot be loaded ", e);
}
}
}
// Then create the provided service
ProvidedService svc = new ProvidedService(this, serviceSpecifications, factory, custom, configuration);
// Post-Registration callback
String post = providedService.getAttribute("post-registration");
if (post != null) {
Callback cb = new Callback(post, new Class[] { ServiceReference.class }, false, getInstanceManager());
svc.setPostRegistrationCallback(cb);
}
post = providedService.getAttribute("post-unregistration");
if (post != null) {
// TODO Can we really send the service reference here ?
Callback cb = new Callback(post, new Class[] { ServiceReference.class }, false, getInstanceManager());
svc.setPostUnregistrationCallback(cb);
}
Element[] props = providedService.getElements("Property");
if (props != null) {
// Property[] properties = new Property[props.length];
Property[] properties = new Property[props.length];
for (int j = 0; 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");
Property prop = new Property(name, field, null, value, type, getInstanceManager(), this);
properties[j] = prop;
// Check if the instance configuration has a value for this property
Object object = configuration.get(prop.getName());
if (object != null) {
prop.setValue(object);
}
if (field != null) {
getInstanceManager().register(new FieldMetadata(field, type), this);
// Cannot register the property as the interception is necessary
// to deal with registration update.
}
}
// Attach to properties to the provided service
svc.setProperties(properties);
}
Element[] controllers = providedService.getElements("Controller");
if (controllers != null) {
for (Element controller : controllers) {
String field = controller.getAttribute("field");
if (field == null) {
throw new ConfigurationException("The field attribute of a controller is mandatory");
}
String v = controller.getAttribute("value");
boolean value = !(v != null && v.equalsIgnoreCase("false"));
String s = controller.getAttribute("specification");
if (s == null) {
s = "ALL";
}
svc.setController(field, value, s);
getInstanceManager().register(new FieldMetadata(field, "boolean"), this);
}
}
if (checkProvidedService(svc)) {
m_providedServices.add(svc);
} else {
StringBuilder itfs = new StringBuilder();
for (String serviceSpecification : serviceSpecifications) {
itfs.append(' ');
itfs.append(serviceSpecification);
}
throw new ConfigurationException("The provided service" + itfs + " is not valid");
}
// Initialize the description.
m_description = new ProvidedServiceHandlerDescription(this, getProvidedServices());
}
}
use of org.apache.felix.ipojo.parser.FieldMetadata in project felix by apache.
the class TemporalHandler method configure.
/**
* Configure method. Creates managed dependencies.
*
* @param meta the component type metadata.
* @param dictionary the instance configuration.
* @throws ConfigurationException if the dependency is not configured correctly
* @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
*/
public void configure(Element meta, Dictionary dictionary) throws ConfigurationException {
PojoMetadata manipulation = getFactory().getPojoMetadata();
Element[] deps = meta.getElements("requires", NAMESPACE);
// Also check with temporal is no requires.
if (deps == null || deps.length == 0) {
deps = meta.getElements("temporal", NAMESPACE);
}
// Get instance filters.
Dictionary filtersConfiguration = getRequiresFilters(dictionary.get("temporal.filters"));
if (filtersConfiguration == null || filtersConfiguration.isEmpty()) {
// Fall back on the Requires handler configuration, if any
filtersConfiguration = getRequiresFilters(dictionary.get("requires.filters"));
}
// Get from filters if any.
Dictionary fromConfiguration = getRequiresFilters(dictionary.get("temporal.from"));
if (fromConfiguration == null || fromConfiguration.isEmpty()) {
// Fall back on the Requires handler configuration, if any
fromConfiguration = getRequiresFilters(dictionary.get("requires.from"));
}
for (int i = 0; i < deps.length; i++) {
if (!deps[i].containsAttribute("field") || m_dependencies.contains(deps[i].getAttribute("field"))) {
error("One temporal dependency must be attached to a field or the field is already used");
return;
}
String field = deps[i].getAttribute("field");
String id = field;
if (deps[i].containsAttribute("id")) {
id = deps[i].getAttribute("id");
}
FieldMetadata fieldmeta = manipulation.getField(field);
if (fieldmeta == null) {
error("The field " + field + " does not exist in the class " + getInstanceManager().getClassName());
return;
}
boolean agg = false;
boolean collection = false;
String spec = fieldmeta.getFieldType();
if (spec.endsWith("[]")) {
agg = true;
spec = spec.substring(0, spec.length() - 2);
} else if (Collection.class.getName().equals(spec)) {
agg = true;
collection = true;
// Collection detected. Check for the specification attribute
spec = deps[i].getAttribute("specification");
if (spec == null) {
error("A dependency injected inside a Collection must contain the 'specification' attribute");
}
}
// Determine the filter
String fil = deps[i].getAttribute("filter");
// Override the filter if filter configuration if available in the instance configuration
if (filtersConfiguration != null && id != null && filtersConfiguration.get(id) != null) {
fil = (String) filtersConfiguration.get(id);
}
// Check the from attribute
String from = deps[i].getAttribute("from");
if (fromConfiguration != null && id != null && fromConfiguration.get(id) != null) {
from = (String) fromConfiguration.get(id);
}
if (from != null) {
String fromFilter = "(|(instance.name=" + from + ")(service.pid=" + from + "))";
if (agg) {
warn("The 'from' attribute is incompatible with aggregate requirements: only one provider will " + "match : " + fromFilter);
}
if (fil != null) {
// Append the two filters
fil = "(&" + fromFilter + fil + ")";
} else {
fil = fromFilter;
}
}
Filter filter = null;
if (fil != null) {
try {
filter = getInstanceManager().getContext().createFilter(fil);
} catch (InvalidSyntaxException e) {
throw new ConfigurationException("A requirement filter is invalid : " + filter, e);
}
}
String prox = deps[i].getAttribute("proxy");
// Use proxy by default except for array:
boolean proxy = prox == null || prox.equals("true");
if (prox == null && proxy) {
// Proxy set because of the default.
if (agg && !collection) {
// Aggregate and array
proxy = false;
}
}
if (proxy && agg) {
if (!collection) {
error("Proxied aggregate temporal dependencies cannot be an array. Only collections are supported");
}
}
long timeout = DEFAULT_TIMEOUT;
if (deps[i].containsAttribute("timeout")) {
String to = deps[i].getAttribute("timeout");
if (to.equalsIgnoreCase("infinite") || to.equalsIgnoreCase("-1")) {
// Infinite wait time ...
timeout = Long.MAX_VALUE;
} else {
timeout = new Long(deps[i].getAttribute("timeout")).longValue();
}
}
int policy = NO_POLICY;
String di = null;
String onTimeout = deps[i].getAttribute("onTimeout");
if (onTimeout != null) {
if (onTimeout.equalsIgnoreCase("nullable")) {
policy = NULLABLE;
} else if (onTimeout.equalsIgnoreCase("empty-array") || onTimeout.equalsIgnoreCase("empty")) {
policy = EMPTY;
if (!agg) {
// The empty array policy can only be used on aggregate dependencies
error("Cannot use the empty array policy for " + field + " : non aggregate dependency.");
}
} else if (onTimeout.equalsIgnoreCase("null")) {
policy = NULL;
} else if (onTimeout.length() > 0) {
di = onTimeout;
policy = DEFAULT_IMPLEMENTATION;
}
}
Class specification = DependencyMetadataHelper.loadSpecification(spec, getInstanceManager().getContext());
TemporalDependency dep = new TemporalDependency(specification, agg, collection, proxy, filter, getInstanceManager().getContext(), timeout, policy, di, this);
m_dependencies.add(dep);
if (!proxy) {
// Register method interceptor only if are not a proxy
MethodMetadata[] methods = manipulation.getMethods();
for (int k = 0; k < methods.length; k++) {
getInstanceManager().register(methods[k], dep);
}
}
getInstanceManager().register(fieldmeta, dep);
}
}
use of org.apache.felix.ipojo.parser.FieldMetadata in project felix by apache.
the class TransactionHandler method configure.
public void configure(Element arg0, Dictionary arg1) throws ConfigurationException {
Element[] elements = arg0.getElements(NAME, NAMESPACE);
if (elements.length > 1) {
throw new ConfigurationException("The handler " + NAMESPACE + ":" + NAME + " cannot be declared several times");
}
String field = elements[0].getAttribute(FIELD_ATTRIBUTE);
if (field != null) {
FieldMetadata meta = getPojoMetadata().getField(field);
if (meta == null) {
throw new ConfigurationException("The transaction field does not exist in the pojo class : " + field);
}
if (!meta.getFieldType().equals(Transaction.class.getName())) {
throw new ConfigurationException("The transaction field type must be " + Transaction.class.getName());
}
// Register the interceptor
getInstanceManager().register(meta, this);
}
String oncommit = elements[0].getAttribute(ONCOMMIT_ATTRIBUTE);
if (oncommit != null) {
m_onCommit = new Callback(oncommit, new String[] { Transaction.class.getName() }, false, getInstanceManager());
}
String onrollback = elements[0].getAttribute(ONROLLBACK_ATTRIBUTE);
if (onrollback != null) {
m_onRollback = new Callback(onrollback, new String[] { Transaction.class.getName() }, false, getInstanceManager());
}
Element[] sub = elements[0].getElements(TRANSACTIONAL_ELEMENT);
if (sub == null || sub.length == 0) {
throw new ConfigurationException("The handler " + NAMESPACE + ":" + NAME + " must have " + TRANSACTIONAL_ELEMENT + " subelement");
}
for (int i = 0; i < sub.length; i++) {
String method = sub[i].getAttribute(METHOD_ATTRIBUTE);
String to = sub[i].getAttribute(TIMEOUT_ATTRIBUTE);
String propa = sub[i].getAttribute(PROPAGATION_ATTRIBUTE);
String nrbf = sub[i].getAttribute(NOROLLBACKFOR_ATTRIBUTE);
String eorb = sub[i].getAttribute(EXCEPTIONONROLLBACK_ATTRIBUTE);
if (method == null) {
throw new ConfigurationException("A transactional element must specified the method attribute");
}
MethodMetadata meta = this.getPojoMetadata().getMethod(method);
if (meta == null) {
throw new ConfigurationException("A transactional method is not in the pojo class : " + method);
}
int timeout = 0;
if (to != null) {
timeout = new Integer(to).intValue();
}
int propagation = DEFAULT_PROPAGATION;
if (propa != null) {
propagation = parsePropagation(propa);
}
List<String> exceptions = new ArrayList<String>();
if (nrbf != null) {
exceptions = (List<String>) ParseUtils.parseArraysAsList(nrbf);
}
boolean exceptionOnRollback = false;
if (eorb != null) {
exceptionOnRollback = new Boolean(eorb).booleanValue();
}
TransactionalMethod tm = new TransactionalMethod(method, propagation, timeout, exceptions, exceptionOnRollback, this);
m_methods.add(tm);
this.getInstanceManager().register(meta, tm);
}
}
use of org.apache.felix.ipojo.parser.FieldMetadata in project felix by apache.
the class ConfigurationHandler method configure.
/**
* Configures the handler.
* Access to field does not require synchronization as this method is executed
* before any thread access to this object.
*
* @param metadata the metadata of the component
* @param configuration the instance configuration
* @throws ConfigurationException one property metadata is 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 {
// Build the map
Element[] confs = metadata.getElements("Properties", "");
Element[] configurables = confs[0].getElements("Property");
// Check if the component is dynamically configurable
// Propagation enabled by default.
m_mustPropagate = true;
// We must create a copy as the Config Admin dictionary has some limitations
m_toPropagate = new Hashtable<String, Object>();
if (configuration != null) {
Enumeration keys = configuration.keys();
while (keys.hasMoreElements()) {
String key = (String) keys.nextElement();
// we don't propagate properties starting with .
if (!excluded(key)) {
m_toPropagate.put(key, configuration.get(key));
}
}
}
String propa = confs[0].getAttribute("propagation");
if (propa != null && propa.equalsIgnoreCase("false")) {
m_mustPropagate = false;
m_toPropagate = null;
}
// Check if the component support ConfigurationADmin reconfiguration
// Look inside the component type description
m_managedServicePID = confs[0].getAttribute("pid");
// Look inside the instance configuration.
String instanceMSPID = (String) configuration.get(MANAGED_SERVICE_PID);
if (instanceMSPID != null) {
m_managedServicePID = instanceMSPID;
}
// updated method
String upd = confs[0].getAttribute("updated");
if (upd != null) {
MethodMetadata method = getPojoMetadata().getMethod(upd);
if (method == null) {
throw new ConfigurationException("The updated method is not found in the class " + getInstanceManager().getClassName());
} else if (method.getMethodArguments().length == 0) {
m_updated = new Callback(upd, new Class[0], false, getInstanceManager());
} else if (method.getMethodArguments().length == 1 && method.getMethodArguments()[0].equals(Dictionary.class.getName())) {
m_updated = new Callback(upd, new Class[] { Dictionary.class }, false, getInstanceManager());
} else {
throw new ConfigurationException("The updated method is found in the class " + getInstanceManager().getClassName() + " must have either no argument or a Dictionary");
}
}
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");
int index = -1;
// The initialize method has fixed the property name.
String name = configurables[i].getAttribute("name");
String value = configurables[i].getAttribute("value");
// The initialize method has fixed the property name.
String type = configurables[i].getAttribute("type");
Property prop;
if (paramIndex == null) {
prop = new Property(name, fieldName, methodName, value, type, getInstanceManager(), this);
} else {
index = Integer.parseInt(paramIndex);
prop = new Property(name, fieldName, methodName, index, value, type, getInstanceManager(), this);
}
addProperty(prop);
// Check if the instance configuration contains value for the current property :
if (configuration.get(name) == null) {
if (fieldName != null && configuration.get(fieldName) != null) {
prop.setValue(configuration.get(fieldName));
}
} else {
prop.setValue(configuration.get(name));
}
if (fieldName != null) {
FieldMetadata field = new FieldMetadata(fieldName, type);
getInstanceManager().register(field, prop);
}
if (index != -1) {
getInstanceManager().register(index, prop);
}
}
m_description = new ConfigurationHandlerDescription(this, m_configurableProperties, m_managedServicePID);
}
use of org.apache.felix.ipojo.parser.FieldMetadata 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);
}
}
Aggregations