Modified: felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java?rev=631196&r1=631195&r2=631196&view=diff ============================================================================== --- felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java (original) +++ felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java Tue Feb 26 04:20:30 2008 @@ -34,6 +34,7 @@ import org.apache.felix.ipojo.parser.MethodMetadata; import org.apache.felix.ipojo.parser.PojoMetadata; import org.apache.felix.ipojo.util.AbstractServiceDependency; +import org.apache.felix.ipojo.util.DependencyLifecycleListener; import org.osgi.framework.BundleContext; import org.osgi.framework.Filter; import org.osgi.framework.InvalidSyntaxException; @@ -43,7 +44,7 @@ * The dependency handler manages a list of service dependencies. * @author <a href="mailto:[EMAIL PROTECTED]">Felix Project Team</a> */ -public class DependencyHandler extends PrimitiveHandler { +public class DependencyHandler extends PrimitiveHandler implements DependencyLifecycleListener { /** * List of dependencies of the component. @@ -82,6 +83,24 @@ } /** + * Validate method. This method is invoked by an AbstractServiceDependency when this dependency becomes RESOLVED. + * @param dep : the dependency becoming RESOLVED. + * @see org.apache.felix.ipojo.util.DependencyLifecycleListener#validate(org.apache.felix.ipojo.util.AbstractServiceDependency) + */ + public void validate(AbstractServiceDependency dep) { + checkContext(); + } + + /** + * Invalidate method. This method is invoked by an AbstractServiceDependency when this dependency becomes UNRESOLVED or BROKEN. + * @param dep : the dependency becoming UNRESOLVED or BROKEN. + * @see org.apache.felix.ipojo.util.DependencyLifecycleListener#invalidate(org.apache.felix.ipojo.util.AbstractServiceDependency) + */ + public void invalidate(AbstractServiceDependency dep) { + setValidity(false); + } + + /** * Check the validity of the dependencies. */ protected void checkContext() { @@ -209,7 +228,10 @@ // TODO Auto-generated catch block e.printStackTrace(); } - } else if (!dep.getSpecification().getName().equals(type)) { throw new ConfigurationException("A required service is not correct : the field type [" + type + "] and the needed service interface [" + dep.getSpecification().getName() + "] are not the same"); } + } else if (!dep.getSpecification().getName().equals(type)) { + throw new ConfigurationException("A required service is not correct : the field type [" + type + "] and the needed service interface [" + dep.getSpecification().getName() + + "] are not the same"); + } } // Check that all required info are set @@ -267,7 +289,7 @@ } Filter fil = null; - if (filter != null) { + if (filter != null) { try { fil = getInstanceManager().getContext().createFilter(filter); } catch (InvalidSyntaxException e) { @@ -279,8 +301,8 @@ if (serviceSpecification != null) { spec = AbstractServiceDependency.loadSpecification(serviceSpecification, getInstanceManager().getContext()); } - - int policy = AbstractServiceDependency.getPolicy(deps[i]); + + int policy = AbstractServiceDependency.getPolicy(deps[i]); Comparator cmp = AbstractServiceDependency.getComparator(deps[i], getInstanceManager().getGlobalContext()); Dependency dep = new Dependency(this, field, spec, fil, optional, aggregate, id, bc, policy, cmp, di); @@ -377,12 +399,7 @@ * @see org.apache.felix.ipojo.Handler#onExit(Object, Method, java.lang.Object) */ public void onError(Object pojo, Method method, Object returnedObj) { - for (int i = 0; i < m_dependencies.length; i++) { - Dependency dep = m_dependencies[i]; - if (dep.getField() != null) { - dep.exit(); - } - } + onExit(pojo, method, returnedObj); } /**
Modified: felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java?rev=631196&r1=631195&r2=631196&view=diff ============================================================================== --- felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java (original) +++ felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java Tue Feb 26 04:20:30 2008 @@ -94,7 +94,7 @@ Element dep = new Element("Requires", ""); dep.addAttribute(new Attribute("Specification", m_dependencies[i].getInterface())); - if (!"".equals(m_dependencies[i].getFilter())) { + if (m_dependencies[i].getFilter() != null) { dep.addAttribute(new Attribute("Filter", m_dependencies[i].getFilter())); } @@ -112,16 +112,18 @@ dep.addAttribute(new Attribute("State", state)); List set = m_dependencies[i].getUsedServices(); - Iterator it = set.iterator(); - while (it.hasNext()) { - Element use = new Element("Uses", ""); - ServiceReference ref = (ServiceReference) it.next(); - use.addAttribute(new Attribute("service.id", ref.getProperty(Constants.SERVICE_ID).toString())); - String in = (String) ref.getProperty("instance.name"); - if (in != null) { - use.addAttribute(new Attribute("instance.name", in)); + if (set != null) { + Iterator it = set.iterator(); + while (it.hasNext()) { + Element use = new Element("Uses", ""); + ServiceReference ref = (ServiceReference) it.next(); + use.addAttribute(new Attribute("service.id", ref.getProperty(Constants.SERVICE_ID).toString())); + String in = (String) ref.getProperty("instance.name"); + if (in != null) { + use.addAttribute(new Attribute("instance.name", in)); + } + dep.addElement(use); } - dep.addElement(use); } deps.addElement(dep); Modified: felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java?rev=631196&r1=631195&r2=631196&view=diff ============================================================================== --- felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java (original) +++ felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java Tue Feb 26 04:20:30 2008 @@ -167,7 +167,7 @@ error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not accessible", e); throw new IllegalStateException(e.getMessage()); } catch (InvocationTargetException e) { - error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " has throws an exception : " + e.getTargetException().getMessage()); + error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " has throws an exception : " + e.getTargetException().getMessage(), e.getTargetException()); getInstanceManager().setState(ComponentInstance.INVALID); } } Modified: felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java?rev=631196&r1=631195&r2=631196&view=diff ============================================================================== --- felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java (original) +++ felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/Property.java Tue Feb 26 04:20:30 2008 @@ -306,8 +306,8 @@ // Else it is a neither a primitive type neither a String -> create the // object by calling a constructor with a string in argument. try { - Class c = m_providedService.getInstanceManager().getContext().getBundle().loadClass(internalType); - Constructor cst = c.getConstructor(new Class[] { String.class }); + final Class c = m_providedService.getInstanceManager().getContext().getBundle().loadClass(internalType); + final Constructor cst = c.getConstructor(new Class[] { String.class }); Object[] ob = (Object[]) Array.newInstance(c, values.length); for (int i = 0; i < values.length; i++) { ob[i] = cst.newInstance(new Object[] { values[i] }); Modified: felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java?rev=631196&r1=631195&r2=631196&view=diff ============================================================================== --- felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java (original) +++ felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java Tue Feb 26 04:20:30 2008 @@ -28,7 +28,7 @@ import java.util.Set; import org.apache.felix.ipojo.ConfigurationException; -import org.apache.felix.ipojo.IPojoConfiguration; +import org.apache.felix.ipojo.HandlerFactory; import org.apache.felix.ipojo.InstanceManager; import org.apache.felix.ipojo.PrimitiveHandler; import org.apache.felix.ipojo.architecture.ComponentTypeDescription; @@ -284,7 +284,7 @@ * @return the Dependency object, null if not found or if the DependencyHandler is not plugged to the instance */ private Dependency getAttachedDependency(Element element) { - DependencyHandler dh = (DependencyHandler) getHandler(IPojoConfiguration.IPOJO_NAMESPACE + ":requires"); + DependencyHandler dh = (DependencyHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":requires"); if (dh == null) { return null; } String id = element.getAttribute("id"); @@ -580,8 +580,15 @@ type = fm.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; + } - cd.addProperty(new PropertyDescription(name, type, value)); + cd.addProperty(new PropertyDescription(name, type, value, immutable)); } } } Modified: felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java?rev=631196&r1=631195&r2=631196&view=diff ============================================================================== --- felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java (original) +++ felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java Tue Feb 26 04:20:30 2008 @@ -18,7 +18,7 @@ */ package org.apache.felix.ipojo.parser; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.StringTokenizer; @@ -61,24 +61,7 @@ * @return the resulting string array */ public static List parseArraysAsList(String str) { - List result = new ArrayList(); - // Remove { and } - if (str.startsWith("{") && str.endsWith("}")) { - String m = str.substring(1, str.length() - 1); - // Check empty array - m = m.trim(); - if (m.length() == 0) { - return result; - } - String[] values = split(m, ","); - for (int i = 0; i < values.length; i++) { - result.add(values[i].trim()); - } - return result; - } else { - result.add(str); - return result; - } + return Arrays.asList(parseArrays(str)); } /** Modified: felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/AbstractServiceDependency.java URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/AbstractServiceDependency.java?rev=631196&r1=631195&r2=631196&view=diff ============================================================================== --- felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/AbstractServiceDependency.java (original) +++ felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/AbstractServiceDependency.java Tue Feb 26 04:20:30 2008 @@ -94,6 +94,11 @@ * Bundle context used by the dependency. (could be a service context). */ private BundleContext m_context; + + /** + * Listener object on which invoking the validate and invalidate methods. + */ + private DependencyLifecycleListener m_listener; /** * Actual state of the dependency. @@ -124,8 +129,9 @@ * @param comparator : comparator object to sort references * @param policy : binding policy * @param context : bundle context (or service context) + * @param listener : dependency lifecycle listener to notify from dependency state changes. */ - public AbstractServiceDependency(Class specification, boolean aggregate, boolean optional, Filter filter, Comparator comparator, int policy, BundleContext context) { + public AbstractServiceDependency(Class specification, boolean aggregate, boolean optional, Filter filter, Comparator comparator, int policy, BundleContext context, DependencyLifecycleListener listener) { m_specification = specification; m_aggregate = aggregate; m_optional = optional; @@ -138,6 +144,7 @@ m_comparator = new ServiceReferenceRankingComparator(); } m_state = UNRESOLVED; + m_listener = listener; } /** @@ -153,8 +160,10 @@ * Close the tracking. */ public void stop() { - m_tracker.close(); - m_tracker = null; + if (m_tracker != null) { + m_tracker.close(); + m_tracker = null; + } m_state = UNRESOLVED; } @@ -330,8 +339,9 @@ if (!(m_filter == null || m_filter.match(ref)) && match(ref)) { // The service does not match anymore. Call removedService. manageDeparture(ref, arg1); + } else { + onServiceModification(ref); } - // If the service match, nothing to do. } else { // The service was not used. Check if it matches. if ((m_filter == null || m_filter.match(ref)) && match(ref)) { @@ -391,6 +401,15 @@ * @param ref : the leaving service reference. */ public abstract void onServiceDeparture(ServiceReference ref); + + /** + * This method can be override by the concrete dependency to be notified of service modification. + * This modification is not an arrival or a departure. + * @param ref : modified service reference. + */ + public void onServiceModification(ServiceReference ref) { + // Do nothing by default. + } /** * Concrete dependency callback. This method is called when the dependency is reconfigured and when this reconfiguration implies changes on the matching service set ( and by the way on the injected service). @@ -400,14 +419,18 @@ public abstract void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals); /** - * Concrete dependency callback. This method is called when the dependency becomes unresolved or broken. + * Call the listener callback to notify the new state of the current dependency. */ - public abstract void invalidate(); + private void invalidate() { + m_listener.invalidate(this); + } /** - * Concrete dependency callback. This method is called when the dependency becomes resolved. + * Call the listener callback to notify the new state of the current dependency. */ - public abstract void validate(); + private void validate() { + m_listener.validate(this); + } /** * Get the actual state of the dependency. @@ -470,7 +493,7 @@ ServiceReference ref = (ServiceReference) m_matchingReferences.get(j); // Check if the reference is inside the matching list: if (!matching.contains(ref)) { - // The reference should be removed. + // The reference should be removed toRemove.add(ref); } } @@ -518,10 +541,12 @@ } else { // Create a local copy to avoid un-sync reference list access. int size; - ServiceReference newRef; + ServiceReference newRef = null; synchronized (m_matchingReferences) { size = m_matchingReferences.size(); - newRef = (ServiceReference) m_matchingReferences.get(0); + if (size > 0) { + newRef = (ServiceReference) m_matchingReferences.get(0); + } } // Non aggregate case. // If the used reference was not null Added: felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyLifecycleListener.java URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyLifecycleListener.java?rev=631196&view=auto ============================================================================== --- felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyLifecycleListener.java (added) +++ felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyLifecycleListener.java Tue Feb 26 04:20:30 2008 @@ -0,0 +1,39 @@ +/* + * 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.util; + + +/** + * This interface allows a class to be notified of dependency state changes. + * @author <a href="mailto:[EMAIL PROTECTED]">Felix Project Team</a> + */ +public interface DependencyLifecycleListener { + + /** + * The given dependency becomes valid. + * @param dependency : dependency becoming valid. + */ + void validate(AbstractServiceDependency dependency); + + /** + * The given dependency becomes invalid. + * @param dependency : dependency becoming invalid. + */ + void invalidate(AbstractServiceDependency dependency); +} Modified: felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Logger.java URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Logger.java?rev=631196&r1=631195&r2=631196&view=diff ============================================================================== --- felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Logger.java (original) +++ felix/sandbox/clement/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Logger.java Tue Feb 26 04:20:30 2008 @@ -28,6 +28,11 @@ * @author <a href="mailto:[EMAIL PROTECTED]">Felix Project Team</a> */ public class Logger { + + /** + * Ipojo default log level property. + */ + public static final String IPOJO_LOG_LEVEL = "ipojo.log.level"; /** * Log Level ERROR. @@ -76,6 +81,16 @@ m_level = level; m_context = bc; } + + /** + * Constructor. + * + * @param bc : bundle context + * @param name : name of the logger + */ + public Logger(BundleContext bc, String name) { + this(bc, name, getDefaultLevel(bc)); + } /** * Log a message. @@ -85,7 +100,7 @@ */ public void log(int level, String msg) { if (m_level >= level) { - dispatch(level, msg, null); + dispatch(level, msg); } } @@ -101,19 +116,14 @@ dispatch(level, msg, ex); } } - + /** * Internal log method. * * @param level : level of the message. * @param msg : message to log - * @param ex : exception attached to the message */ - private void dispatch(int level, String msg, Throwable ex) { - String s = msg; - if (ex != null) { - s += " (" + ex.getMessage() + ")"; - } + private void dispatch(int level, String msg) { ServiceReference ref = m_context.getServiceReference(LogService.class.getName()); LogService log = null; @@ -124,40 +134,134 @@ String message = null; switch (level) { case DEBUG: - message = "[" + m_name + "] DEBUG: " + s; + message = "[" + m_name + "] DEBUG: " + msg; if (log != null) { log.log(LogService.LOG_DEBUG, message); } System.err.println(message); break; case ERROR: - message = "[" + m_name + "] ERROR: " + s; + message = "[" + m_name + "] ERROR: " + msg; if (log != null) { log.log(LogService.LOG_ERROR, message); } System.err.println(message); break; case INFO: - message = "[" + m_name + "] INFO: " + s; + message = "[" + m_name + "] INFO: " + msg; if (log != null) { log.log(LogService.LOG_INFO, message); } System.err.println(message); break; case WARNING: - message = "[" + m_name + "] WARNING: " + s; + message = "[" + m_name + "] WARNING: " + msg; if (log != null) { log.log(LogService.LOG_WARNING, message); } System.err.println(message); break; default: - System.err.println("[" + m_name + "] UNKNOWN[" + level + "]: " + s); + System.err.println("[" + m_name + "] UNKNOWN[" + level + "]: " + msg); break; } if (log != null) { m_context.ungetService(ref); } + } + + /** + * Internal log method. + * + * @param level : level of the message. + * @param msg : message to log + * @param ex : exception attached to the message + */ + private void dispatch(int level, String msg, Throwable ex) { + + ServiceReference ref = m_context.getServiceReference(LogService.class.getName()); + LogService log = null; + if (ref != null) { + log = (LogService) m_context.getService(ref); + } + + String message = null; + switch (level) { + case DEBUG: + message = "[" + m_name + "] DEBUG: " + msg; + if (log != null) { + log.log(LogService.LOG_DEBUG, message, ex); + } + System.err.println(message); + ex.printStackTrace(); + break; + case ERROR: + message = "[" + m_name + "] ERROR: " + msg; + if (log != null) { + log.log(LogService.LOG_ERROR, message, ex); + } + System.err.println(message); + ex.printStackTrace(System.err); + break; + case INFO: + message = "[" + m_name + "] INFO: " + msg; + if (log != null) { + log.log(LogService.LOG_INFO, message, ex); + } + System.err.println(message); + ex.printStackTrace(System.err); + break; + case WARNING: + message = "[" + m_name + "] WARNING: " + msg; + if (log != null) { + log.log(LogService.LOG_WARNING, message, ex); + } + System.err.println(message); + ex.printStackTrace(System.err); + break; + default: + System.err.println("[" + m_name + "] UNKNOWN[" + level + "]: " + msg); + ex.printStackTrace(); + break; + } + + if (log != null) { + m_context.ungetService(ref); + } + } + + /** + * Get the default logger level. + * The property is searched inside the framework properties, the system properties, + * and in the manifest from the given bundle context. By default, set the level to WARNING. + * @param bc : bundle context. + * @return the default log level. + */ + private static int getDefaultLevel(BundleContext bc) { + // First check in the framework and in the system properties + String l = bc.getProperty(IPOJO_LOG_LEVEL); + + // If null, look in bundle manifest + if (l == null) { + l = (String) bc.getBundle().getHeaders().get(IPOJO_LOG_LEVEL); + } + + if (l != null) { + if (l.equalsIgnoreCase("info")) { + return INFO; + } else if (l.equalsIgnoreCase("debug")) { + return DEBUG; + } else if (l.equalsIgnoreCase("warning")) { + return WARNING; + } else if (l.equalsIgnoreCase("error")) { + return ERROR; + } + } + + // Either l is null, either the specified log level was unknown + // Set the default to WARNING + return WARNING; + } }
