/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.ipojo.api; import org.apache.felix.ipojo.ComponentInstance; import org.apache.felix.ipojo.PrimitiveInstanceDescription; import org.apache.felix.ipojo.handlers.dependency.DependencyDescription; import org.apache.felix.ipojo.metadata.Attribute; import org.apache.felix.ipojo.metadata.Element; /** * Allows configuring a service dependencies. * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a> */ public class Dependency implements HandlerConfiguration { /** * The dynamic binding policy. */ public static final int DYNAMIC = org.apache.felix.ipojo.handlers.dependency.Dependency.DYNAMIC_BINDING_POLICY; /** * The static binding policy. */ public static final int STATIC = org.apache.felix.ipojo.handlers.dependency.Dependency.STATIC_BINDING_POLICY; /** * The dynamic-priority binding policy. */ public static final int DYNAMIC_PRIORITY = org.apache.felix.ipojo.handlers.dependency.Dependency.DYNAMIC_PRIORITY_BINDING_POLICY; /** * The required specification. */ private String m_specification; /** * The LDAP filter of the dependency. */ private String m_filter; /** * The field of the implementation class attached to * this dependency. */ private String m_field; /** * The constructor parameter index. */ private int m_parameterIndex = -1; /** * Is the dependency optional? */ private boolean m_optional; /** * Is the dependency aggregate? */ private boolean m_aggregate; /** * Bind method attached to the dependency. */ private String m_bind; /** * Unbind method attached to the dependency. */ private String m_unbind; /** * Modified method attached to the dependency. */ private String m_modified; /** * The dependency binding policy. */ private int m_policy; /** * The dependency comparator. * (used to compare service providers) */ private String m_comparator; /** * The dependency default-implementation. */ private String m_di; /** * The dependency specific provider. */ private String m_from; /** * The dependency id. */ private String m_id; /** * Does the dependency supports nullable? */ private boolean m_nullable = true; /** * Does the dependency enables proxy. */ private boolean m_proxy = true; /** * Gets the dependency metadata. * @return the 'requires' element describing * the current dependency. */ public Element getElement() { ensureValidity(); Element dep = new Element("requires", ""); if (m_specification != null) { dep.addAttribute(new Attribute("specification", m_specification)); } if (m_filter != null) { dep.addAttribute(new Attribute("filter", m_filter)); } if (m_field != null) { dep.addAttribute(new Attribute("field", m_field)); } if (m_parameterIndex != -1) { dep.addAttribute(new Attribute("constructor-parameter", Integer.toString(m_parameterIndex))); } if (m_bind != null) { Element cb = new Element("callback", ""); cb.addAttribute(new Attribute("type", "bind")); cb.addAttribute(new Attribute("method", m_bind)); dep.addElement(cb); } if (m_unbind != null) { Element cb = new Element("callback", ""); cb.addAttribute(new Attribute("type", "unbind")); cb.addAttribute(new Attribute("method", m_unbind)); dep.addElement(cb); } if (m_modified != null) { Element cb = new Element("callback", ""); cb.addAttribute(new Attribute("type", "modified")); cb.addAttribute(new Attribute("method", m_modified)); dep.addElement(cb); } if (m_comparator != null) { dep.addAttribute(new Attribute("comparator", m_comparator)); } if (m_di != null) { dep.addAttribute(new Attribute("default-implementation", m_di)); } if (m_from != null) { dep.addAttribute(new Attribute("from", m_from)); } if (m_id != null) { dep.addAttribute(new Attribute("id", m_id)); } if (! m_nullable) { dep.addAttribute(new Attribute("nullable", "false")); } if (m_optional) { dep.addAttribute(new Attribute("optional", "true")); } if (m_aggregate) { dep.addAttribute(new Attribute("aggregate", "true")); } if (! m_proxy) { dep.addAttribute(new Attribute("proxy", "false")); } if (m_policy != -1) { if (m_policy == DYNAMIC) { dep.addAttribute(new Attribute("policy", "dynamic")); } else if (m_policy == STATIC) { dep.addAttribute(new Attribute("policy", "static")); } else if (m_policy == DYNAMIC_PRIORITY) { dep.addAttribute(new Attribute("policy", "dynamic-priority")); } // No other possibilities. } return dep; } /** * Sets the required service specification. * @param spec the specification * @return the current dependency object. */ public Dependency setSpecification(String spec) { m_specification = spec; return this; } /** * Sets the dependency filter. * @param filter the LDAP filter * @return the current dependency object */ public Dependency setFilter(String filter) { m_filter = filter; return this; } /** * Sets the field attached to the dependency. * @param field the implementation class field name. * @return the current dependency object */ public Dependency setField(String field) { m_field = field; return this; } /** * Sets the constructor parameter index of the dependency. * @param index the parameter index * @return the current dependency object */ public Dependency setConstructorParameter(int index) { m_parameterIndex = index; return this; } /** * Sets the dependency optionality. * @param opt <code>true</code> to set the * dependency to optional. * @return the current dependency object. */ public Dependency setOptional(boolean opt) { m_optional = opt; return this; } /** * Sets the dependency cardinality. * @param agg <code>true</code> to set the * dependency to aggregate. * @return the current dependency object. */ public Dependency setAggregate(boolean agg) { m_aggregate = agg; return this; } /** * Sets if the dependency supports nullable objects. * @param nullable <code>false</code> if the dependency does not * support the nullable object injection * @return the current dependency object. */ public Dependency setNullable(boolean nullable) { m_nullable = nullable; return this; } /** * Sets if the dependency injects proxies. * @param proxy <code>false</code> if the dependency does not * inject proxies but uses direct references. * @return the current dependency object. */ public Dependency setProxy(boolean proxy) { m_proxy = proxy; return this; } /** * Sets the dependency bind method. * @param bind the bind method name * @return the current dependency object. */ public Dependency setBindMethod(String bind) { m_bind = bind; return this; } /** * Sets the dependency unbind method. * @param unbind the unbind method * @return the current dependency object. */ public Dependency setUnbindMethod(String unbind) { m_unbind = unbind; return this; } /** * Sets the dependency modified method. * @param modified the modified method * @return the current dependency object. */ public Dependency setModifiedMethod(String modified) { m_modified = modified; return this; } /** * Sets the dependency binding policy. * @param policy the binding policy * @return the current dependency object */ public Dependency setBindingPolicy(int policy) { m_policy = policy; return this; } /** * Sets the dependency comparator. * @param cmp the comparator class name * @return the current dependency object */ public Dependency setComparator(String cmp) { m_comparator = cmp; return this; } /** * Sets the dependency default-implementation. * @param di the default-implementation class name * @return the current dependency object */ public Dependency setDefaultImplementation(String di) { m_di = di; return this; } /** * Sets the dependency 'from' attribute. * @param from the name of the service provider. * @return the current dependency object */ public Dependency setFrom(String from) { m_from = from; return this; } /** * Sets the dependency id. * @param id the dependency id. * @return the current dependency object. */ public Dependency setId(String id) { m_id = id; return this; } /** * Checks dependency configuration validity. */ private void ensureValidity() { // At least a field or methods. if (m_field == null && m_bind == null && m_unbind == null && m_parameterIndex == -1) { throw new IllegalStateException("A dependency must have a field or bind/unbind methods " + "or a parameter index"); } // Check binding policy. if (m_policy != -1) { if (!(m_policy == DYNAMIC || m_policy == STATIC || m_policy == DYNAMIC_PRIORITY)) { throw new IllegalStateException("Unknow binding policy : " + m_policy); } } } /** * Gets the dependency description object attached to * this dependency. * @param instance the instance on which searching the dependency * @return the dependency description attached to this dependency or * <code>null</code> if the dependency cannot be found. */ public DependencyDescription getDependencyDescription(ComponentInstance instance) { PrimitiveInstanceDescription desc = (PrimitiveInstanceDescription) instance.getInstanceDescription(); if (m_id != null) { return desc.getDependency(m_id); } if (m_specification != null) { return desc.getDependency(m_specification); } DependencyDescription[] deps = desc.getDependencies(); if (deps.length == 1) { return deps[0]; } // Cannot determine the dependency. return null; } }