You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2015/07/09 00:10:16 UTC

svn commit: r1689973 [14/25] - in /felix/sandbox/pderop/dependencymanager.ds: cnf/ext/ cnf/localrepo/ cnf/localrepo/org.apache.felix.framework/ cnf/releaserepo/ org.apache.felix.dependencymanager.ds.itest/ org.apache.felix.dependencymanager.ds.itest/.s...

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ComponentServiceObjectsHelper.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,152 @@
+/*
+ * 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.scr.impl.helper;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceObjects;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.ComponentServiceObjects;
+
+
+/**
+ * Utility class for handling references using a ComponentServiceObjects
+ * to get services.
+ */
+public class ComponentServiceObjectsHelper
+{
+    private final BundleContext bundleContext;
+
+    private final Map<ServiceReference, ServiceObjects> serviceObjectsMap = new HashMap<ServiceReference, ServiceObjects>();
+
+    private final Map<ServiceObjects, List<Object>> services = new HashMap<ServiceObjects, List<Object>>();
+
+    private final ConcurrentMap<ServiceReference, Object> prototypeInstances = new ConcurrentHashMap<ServiceReference, Object>();
+
+    public ComponentServiceObjectsHelper(final BundleContext bundleContext)
+    {
+        this.bundleContext = bundleContext;
+    }
+
+    public void cleanup()
+    {
+        synchronized ( this )
+        {
+            for(final Map.Entry<ServiceObjects, List<Object>> entry : services.entrySet())
+            {
+                for(final Object service : entry.getValue())
+                {
+                    entry.getKey().ungetService(service);
+                }
+            }
+            services.clear();
+            serviceObjectsMap.clear();
+        }
+        prototypeInstances.clear();
+    }
+
+    public ComponentServiceObjects getServiceObjects(final ServiceReference<?> ref)
+    {
+        synchronized ( this )
+        {
+            ServiceObjects<?> so = this.serviceObjectsMap.get(ref);
+            if ( so == null )
+            {
+                so = this.bundleContext.getServiceObjects(ref);
+                if ( so != null )
+                {
+                    this.serviceObjectsMap.put(ref, so);
+                }
+            }
+
+            if ( so != null )
+            {
+                List<Object> services = this.services.get(so);
+                if ( services == null )
+                {
+                    services = new ArrayList<Object>();
+                    this.services.put(so, services);
+                }
+                final ServiceObjects serviceObjects = so;
+                final List<Object> serviceList = services;
+
+                return new ComponentServiceObjects() 
+                {
+
+                    public Object getService() 
+                    {
+                        final Object service = serviceObjects.getService();
+                        if ( service != null )
+                        {
+                            synchronized ( serviceList )
+                            {
+                                serviceList.add(service);
+                            }
+                        }
+                        return service;
+                    }
+
+                    public void ungetService(final Object service) 
+                    {
+                        boolean remove;
+                        synchronized ( serviceList )
+                        {
+                            remove = serviceList.remove(service);
+                        }
+                        if ( remove ) {
+                            serviceObjects.ungetService(service);
+                        }
+                    }
+
+                    public ServiceReference<?> getServiceReference() 
+                    {
+                        return ref;
+                    }
+                };
+            }
+        }
+        return null;
+    }
+
+    
+    public <T> T getPrototypeRefInstance(final ServiceReference<T> ref, ServiceObjects<T> serviceObjects) 
+    {
+    	T service = (T) prototypeInstances.get(ref);
+    	if ( service == null )
+    	{
+    		service = serviceObjects.getService();
+    		T oldService = (T)prototypeInstances.putIfAbsent(ref, service);
+    		if ( oldService != null )
+    		{
+    			// another thread created the instance already
+    			serviceObjects.ungetService(service);
+    			service = oldService;
+    		}
+    	}
+    	return service;
+    }
+   
+ }

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/DeactivateMethod.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/DeactivateMethod.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/DeactivateMethod.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/DeactivateMethod.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,44 @@
+/*
+ * 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.scr.impl.helper;
+
+import org.apache.felix.scr.impl.metadata.DSVersion;
+
+
+public class DeactivateMethod extends ActivateMethod
+{
+
+    @Override
+    boolean isDeactivate()
+    {
+        return true;
+    }
+
+    public DeactivateMethod( final String methodName,
+            final boolean methodRequired, final Class<?> componentClass, final DSVersion dsVersion, final boolean configurableServiceProperties, boolean supportsInterfaces )
+    {
+        super( methodName, methodRequired, componentClass, dsVersion, configurableServiceProperties, supportsInterfaces );
+    }
+
+    protected String getMethodNamePrefix()
+    {
+        return "deactivate";
+    }
+
+}

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/DuplexReferenceMethods.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/DuplexReferenceMethods.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/DuplexReferenceMethods.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/DuplexReferenceMethods.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,120 @@
+/*
+ * 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.scr.impl.helper;
+
+import org.apache.felix.scr.impl.manager.ComponentContextImpl;
+import org.apache.felix.scr.impl.manager.RefPair;
+import org.osgi.framework.BundleContext;
+
+public class DuplexReferenceMethods implements ReferenceMethods
+{
+    /** First is field methods. */
+    private final ReferenceMethods first;
+
+    /** Second is method methods. */
+    private final ReferenceMethods second;
+
+    public DuplexReferenceMethods(final ReferenceMethods first, final ReferenceMethods second)
+    {
+        this.first = first;
+        this.second = second;
+    }
+
+    public ReferenceMethod getBind()
+    {
+        return new DuplexReferenceMethod(first.getBind(), second.getBind());
+    }
+
+    public ReferenceMethod getUnbind()
+    {
+        return new DuplexReferenceMethod(first.getUnbind(), second.getUnbind());
+    }
+
+    public ReferenceMethod getUpdated()
+    {
+        return new DuplexReferenceMethod(first.getUpdated(), second.getUpdated());
+    }
+
+    public InitReferenceMethod getInit()
+    {
+        return new InitReferenceMethod()
+        {
+
+            public boolean init(Object componentInstance, SimpleLogger logger)
+            {
+                final InitReferenceMethod i1 = first.getInit();
+                if ( i1 != null )
+                {
+                    if ( !i1.init(componentInstance, logger))
+                    {
+                        return false;
+                    }
+                }
+                final InitReferenceMethod i2 = second.getInit();
+                if ( i2 != null )
+                {
+                    if ( !i2.init(componentInstance, logger))
+                    {
+                        return false;
+                    }
+                }
+                return true;
+            }
+        };
+    }
+
+    private static final class DuplexReferenceMethod implements ReferenceMethod
+    {
+
+        private final ReferenceMethod first;
+
+        private final ReferenceMethod second;
+
+        public DuplexReferenceMethod(final ReferenceMethod first, final ReferenceMethod second)
+        {
+            this.first = first;
+            this.second = second;
+        }
+
+        public MethodResult invoke(Object componentInstance,
+                BindParameters rawParameter,
+                MethodResult methodCallFailureResult, SimpleLogger logger)
+        {
+            if ( first.invoke(componentInstance, rawParameter, methodCallFailureResult, logger) != null )
+            {
+                return second.invoke(componentInstance, rawParameter, methodCallFailureResult, logger);
+            }
+            return null;
+        }
+
+        public <S, T> boolean getServiceObject(ComponentContextImpl<S> key,
+                RefPair<S, T> refPair, BundleContext context,
+                SimpleLogger logger)
+        {
+            // only if both return true, we return true
+            boolean result = first.getServiceObject(key, refPair, context, logger);
+            if ( result )
+            {
+                result = second.getServiceObject(key, refPair, context, logger);
+            }
+            return result;
+        }
+
+    }
+}

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldHandler.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldHandler.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldHandler.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldHandler.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,958 @@
+/*
+ * 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.scr.impl.helper;
+
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import org.apache.felix.scr.impl.manager.ComponentContextImpl;
+import org.apache.felix.scr.impl.manager.RefPair;
+import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+
+/**
+ * Handler for field references
+ */
+public class FieldHandler
+{
+    private enum ParamType {
+        serviceReference,
+        serviceObjects,
+        serviceType,
+        map,
+        tuple
+    }
+
+    /** The reference metadata. */
+    private final ReferenceMetadata metadata;
+
+    /** The component class. */
+    private final Class<?> componentClass;
+
+    /** The field used for the injection. */
+    private volatile Field field;
+
+    /** Value type. */
+    private volatile ParamType valueType;
+
+    /** State handling. */
+    private volatile State state;
+
+    /** Mapping of ref pairs to value bound */
+    private final Map<RefPair<?, ?>, Object> boundValues = new TreeMap<RefPair<?,?>, Object>(
+        new Comparator<RefPair<?, ?>>()
+        {
+
+            public int compare(final RefPair<?, ?> o1, final RefPair<?, ?> o2)
+            {
+                return o1.getRef().compareTo(o2.getRef());
+            }
+        });
+
+    /**
+     * Create a new field handler
+     * @param fieldName name of the field
+     * @param componentClass component class
+     * @param referenceClassName service class name
+     */
+    public FieldHandler( final ReferenceMetadata metadata,
+            final Class<?> componentClass)
+    {
+        this.metadata = metadata;
+        this.componentClass = componentClass;
+        this.state = NotResolved.INSTANCE;
+    }
+
+    /**
+     * Set the field.
+     * If the field is found, the state transitions to resolved, if the field is
+     * {@code null} the state transitions to not found.
+     * @param f The field or {@code null}.
+     * @param logger The logger
+     */
+    private void setField( final Field f, final SimpleLogger logger )
+    {
+        this.field = f;
+
+        if ( f != null )
+        {
+            state = Resolved.INSTANCE;
+            logger.log( LogService.LOG_DEBUG, "Found field: {0}",
+                    new Object[] { field }, null );
+        }
+        else
+        {
+            state = NotFound.INSTANCE;
+            logger.log(LogService.LOG_ERROR, "Field [{0}] not found; Component will fail",
+                new Object[] { this.metadata.getField() }, null);
+        }
+    }
+
+    /**
+     * Finds the field named in the {@link #fieldName} field in the given
+     * <code>targetClass</code>. If the target class has no acceptable method
+     * the class hierarchy is traversed until a field is found or the root
+     * of the class hierarchy is reached without finding a field.
+     *
+     * @return The requested field or <code>null</code> if no acceptable field
+     *      can be found in the target class or any super class.
+     * @throws InvocationTargetException If an unexpected Throwable is caught
+     *      trying to find the requested field.
+     * @param logger
+     */
+    private Field findField( final SimpleLogger logger )
+    throws InvocationTargetException
+    {
+        final Class<?> targetClass = this.componentClass;
+        final ClassLoader targetClasslLoader = targetClass.getClassLoader();
+        final String targetPackage = getPackageName( targetClass );
+        Class<?> theClass = targetClass;
+        boolean acceptPrivate = true;
+        boolean acceptPackage = true;
+        while (true)
+        {
+
+            if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
+            {
+                logger.log( LogService.LOG_DEBUG,
+                    "Locating field " + this.metadata.getField() + " in class " + theClass.getName(), null );
+            }
+
+            try
+            {
+                final Field field = getField( theClass, acceptPrivate, acceptPackage, logger );
+                if ( field != null )
+                {
+                    return field;
+                }
+            }
+            catch ( SuitableMethodNotAccessibleException ex )
+            {
+                // log and return null
+                logger.log( LogService.LOG_ERROR,
+                    "findField: Suitable but non-accessible field {0} found in class {1}, subclass of {2}", new Object[]
+                        { this.metadata.getField(), theClass.getName(), targetClass.getName() }, null );
+                break;
+            }
+
+            // if we get here, we have no field, so check the super class
+            theClass = theClass.getSuperclass();
+            if ( theClass == null )
+            {
+                break;
+            }
+
+            // super class field check ignores private fields and accepts
+            // package fields only if in the same package and package
+            // fields are (still) allowed
+            acceptPackage &= targetClasslLoader == theClass.getClassLoader()
+                && targetPackage.equals( getPackageName( theClass ) );
+
+            // private fields will not be accepted any more in super classes
+            acceptPrivate = false;
+        }
+
+        // nothing found after all these years ...
+        return null;
+    }
+
+    /**
+     * Finds the field named in the {@link #fieldName} field in the given
+     * <code>targetClass</code>. If the target class has no acceptable field
+     * the class hierarchy is traversed until a field is found or the root
+     * of the class hierarchy is reached without finding a field.
+     *
+     *
+     * @param targetClass The class in which to look for the method
+     * @param acceptPrivate <code>true</code> if private fields should be
+     *      considered.
+     * @param acceptPackage <code>true</code> if package private fields should
+     *      be considered.
+     * @param logger
+     * @return The requested field or <code>null</code> if no acceptable field
+     *      can be found in the target class or any super class.
+     * @throws InvocationTargetException If an unexpected Throwable is caught
+     *      trying to find the requested field.
+     */
+    private Field getField( final Class<?> clazz,
+            final boolean acceptPrivate,
+            final boolean acceptPackage,
+            final SimpleLogger logger )
+    throws SuitableMethodNotAccessibleException, InvocationTargetException
+    {
+        try
+        {
+            // find the declared field in this class
+            final Field field = clazz.getDeclaredField( this.metadata.getField() );
+
+            // accept public and protected fields only and ensure accessibility
+            if ( accept( field, acceptPrivate, acceptPackage ) )
+            {
+                return field;
+            }
+
+            // the method would fit the requirements but is not acceptable
+            throw new SuitableMethodNotAccessibleException();
+        }
+        catch ( NoSuchFieldException nsfe )
+        {
+            // thrown if no field is declared with the given name and
+            // parameters
+            if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
+            {
+                logger.log( LogService.LOG_DEBUG, "Declared Field {0}.{1} not found", new Object[]
+                    { clazz.getName(), this.metadata.getField() }, null );
+            }
+        }
+        catch ( NoClassDefFoundError cdfe )
+        {
+            // may be thrown if a method would be found but the signature
+            // contains throws declaration for an exception which cannot
+            // be loaded
+            if ( logger.isLogEnabled( LogService.LOG_WARNING ) )
+            {
+                StringBuffer buf = new StringBuffer();
+                buf.append( "Failure loooking up field " ).append( this.metadata.getField() );
+                buf.append( " in class class " ).append( clazz.getName() ).append( ". Assuming no such field." );
+                logger.log( LogService.LOG_WARNING, buf.toString(), cdfe );
+            }
+        }
+        catch ( SuitableMethodNotAccessibleException e)
+        {
+            throw e;
+        }
+        catch ( Throwable throwable )
+        {
+            // unexpected problem accessing the field, don't let everything
+            // blow up in this situation, just throw a declared exception
+            throw new InvocationTargetException( throwable, "Unexpected problem trying to get field " + this.metadata.getField() );
+        }
+
+        // caught and ignored exception, assume no field and continue search
+        return null;
+    }
+
+    /**
+     * Validate the field, type etc.
+     * @param f The field
+     * @param logger The logger
+     * @return The field if it's valid, {@code null} otherwise.
+     */
+    private Field validateField( final Field f, final SimpleLogger logger )
+    {
+        final Class<?> fieldType = f.getType();
+        final Class<?> referenceType = ClassUtils.getClassFromComponentClassLoader(
+                this.componentClass, metadata.getInterface(), logger);
+
+        // unary reference
+        if ( !metadata.isMultiple() )
+        {
+            if ( fieldType.isAssignableFrom(referenceType) )
+            {
+                valueType = ParamType.serviceType;
+            }
+            else if ( fieldType == ClassUtils.SERVICE_REFERENCE_CLASS )
+            {
+                valueType = ParamType.serviceReference;
+            }
+            else if ( fieldType == ClassUtils.COMPONENTS_SERVICE_OBJECTS_CLASS )
+            {
+                valueType = ParamType.serviceObjects;
+            }
+            else if ( fieldType == ClassUtils.MAP_CLASS )
+            {
+                valueType = ParamType.map;
+            }
+            else if ( fieldType == ClassUtils.MAP_ENTRY_CLASS )
+            {
+                valueType = ParamType.tuple;
+            }
+            else
+            {
+                logger.log( LogService.LOG_ERROR, "Field {0} in component {1} has unsupported type {2}", new Object[]
+                        {metadata.getField(), this.componentClass, fieldType.getName()}, null );
+                return null;
+            }
+
+            // if the field is dynamic and optional it has to be volatile
+            if ( !metadata.isStatic() && metadata.isOptional() )
+            {
+                if ( !Modifier.isVolatile(f.getModifiers()) )
+                {
+                    logger.log( LogService.LOG_ERROR, "Field {0} in component {1} must be declared volatile to handle a dynamic reference", new Object[]
+                            {metadata.getField(), this.componentClass}, null );
+                    return null;
+                }
+            }
+
+            // the field must not be final
+            if ( Modifier.isFinal(f.getModifiers()) )
+            {
+                logger.log( LogService.LOG_ERROR, "Field {0} in component {1} must not be declared as final", new Object[]
+                        {metadata.getField(), this.componentClass}, null );
+                return null;
+            }
+        }
+        else
+        {
+            // multiple cardinality, field type must be collection or subtype
+            if ( !ClassUtils.COLLECTION_CLASS.isAssignableFrom(fieldType) )
+            {
+                logger.log( LogService.LOG_ERROR, "Field {0} in component {1} has unsupported type {2}", new Object[]
+                        {metadata.getField(), this.componentClass, fieldType.getName()}, null );
+                return null;
+            }
+
+            // if the field is dynamic with the replace strategy it has to be volatile
+            if ( !metadata.isStatic() && metadata.isReplace() )
+            {
+                if ( !Modifier.isVolatile(f.getModifiers()) )
+                {
+                    logger.log( LogService.LOG_ERROR, "Field {0} in component {1} must be declared volatile to handle a dynamic reference", new Object[]
+                            {metadata.getField(), this.componentClass}, null );
+                    return null;
+                }
+            }
+
+            // replace strategy: field must not be final
+            //                   only collection and list allowed
+            if ( metadata.isReplace()  )
+            {
+                if ( Modifier.isFinal(f.getModifiers()) )
+                {
+                    logger.log( LogService.LOG_ERROR, "Field {0} in component {1} must not be declared as final", new Object[]
+                            {metadata.getField(), this.componentClass}, null );
+                    return null;
+                }
+                if ( fieldType != ClassUtils.LIST_CLASS && fieldType != ClassUtils.COLLECTION_CLASS )
+                {
+                    logger.log( LogService.LOG_ERROR, "Field {0} in component {1} has unsupported type {2}."+
+                    " It must be one of java.util.Collection or java.util.List.",
+                    new Object[] {metadata.getField(), this.componentClass, fieldType.getName()}, null );
+                    return null;
+
+                }
+            }
+
+            if ( ReferenceMetadata.FIELD_VALUE_TYPE_SERVICE.equals(metadata.getFieldCollectionType()) )
+            {
+                valueType = ParamType.serviceType;
+            }
+            else if ( ReferenceMetadata.FIELD_VALUE_TYPE_REFERENCE.equals(metadata.getFieldCollectionType()) )
+            {
+                valueType = ParamType.serviceReference;
+            }
+            else if ( ReferenceMetadata.FIELD_VALUE_TYPE_SERVICEOBJECTS.equals(metadata.getFieldCollectionType()) )
+            {
+                valueType = ParamType.serviceObjects;
+            }
+            else if ( ReferenceMetadata.FIELD_VALUE_TYPE_PROPERTIES.equals(metadata.getFieldCollectionType()) )
+            {
+                valueType = ParamType.map;
+            }
+            else if ( ReferenceMetadata.FIELD_VALUE_TYPE_TUPLE.equals(metadata.getFieldCollectionType()) )
+            {
+                valueType = ParamType.tuple;
+            }
+        }
+        return f;
+    }
+
+    private enum METHOD_TYPE
+    {
+        BIND,
+        UNBIND,
+        UPDATED
+    };
+
+    @SuppressWarnings("rawtypes")
+    private final class MapEntryImpl implements Map.Entry, Comparable<Map.Entry<?, ?>>
+    {
+
+        private final Object key;
+        private final Object value;
+        private final ServiceReference<?> ref;
+
+        public MapEntryImpl(final Object key,
+                final Object value,
+                final ServiceReference<?> ref)
+        {
+            this.key = key;
+            this.value = value;
+            this.ref = ref;
+        }
+
+        public Object getKey()
+        {
+            return this.key;
+        }
+
+        public Object getValue()
+        {
+            return this.value;
+        }
+
+        public Object setValue(final Object value)
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        public int compareTo(final Map.Entry<?, ?> o)
+        {
+            if ( o == null )
+            {
+                return 1;
+            }
+            if ( o instanceof MapEntryImpl )
+            {
+                final MapEntryImpl other = (MapEntryImpl)o;
+                return ref.compareTo(other.ref);
+
+            }
+            return new Integer(this.hashCode()).compareTo(o.hashCode());
+        }
+
+    }
+
+    private Object getValue(final ComponentContextImpl key,
+            final RefPair<?, ?> refPair)
+    {
+        final Object obj;
+        switch ( this.valueType )
+        {
+            case serviceType : obj = refPair.getServiceObject(key); break;
+            case serviceReference : obj = refPair.getRef(); break;
+            case serviceObjects : obj = ((ComponentServiceObjectsHelper)key.getComponentServiceObjectsHelper()).getServiceObjects(refPair.getRef()); break;
+            case map : obj = new ReadOnlyDictionary<String, Object>( refPair.getRef() ); break;
+            case tuple : final Object tupleKey = new ReadOnlyDictionary<String, Object>( refPair.getRef() );
+                         final Object tupleValue = refPair.getServiceObject(key);
+                         obj = new MapEntryImpl(tupleKey, tupleValue, refPair.getRef());
+                         break;
+            default: obj = null;
+        }
+        return obj;
+    }
+
+    private boolean initField(final Object componentInstance,
+            final SimpleLogger logger )
+    {
+        try
+        {
+            if ( metadata.isMultiple()
+                 && !metadata.isStatic() )
+            {
+                if ( metadata.isReplace()  )
+                {
+                    this.setFieldValue(componentInstance, Collections.emptyList());
+                }
+                else
+                {
+                    final Class<?> fieldType = this.field.getType();
+
+                    // update strategy: if DS implementation provides collection implementation
+                    //                  only list and collection are allowed, field must not be final
+                    final Object providedImpl = this.getFieldValue(componentInstance);
+                    if ( providedImpl == null)
+                    {
+                        if ( Modifier.isFinal(this.field.getModifiers()) )
+                        {
+                            logger.log( LogService.LOG_ERROR, "Field {0} in component {1} must not be declared as final", new Object[]
+                                    {metadata.getField(), this.componentClass}, null );
+                            return false;
+                        }
+                        if ( fieldType != ClassUtils.LIST_CLASS && fieldType != ClassUtils.COLLECTION_CLASS )
+                        {
+                            logger.log( LogService.LOG_ERROR, "Field {0} in component {1} has unsupported type {2}."+
+                            " It must be one of java.util.Collection or java.util.List.",
+                                new Object[] {metadata.getField(), this.componentClass, fieldType.getName()}, null );
+                            return false;
+                        }
+                        this.setFieldValue(componentInstance, new CopyOnWriteArraySet<Object>());
+                    }
+                }
+            }
+        }
+        catch ( final InvocationTargetException ite)
+        {
+            logger.log( LogService.LOG_ERROR, "Field {0} in component {1} can't be initialized.",
+                    new Object[] {metadata.getField(), this.componentClass}, ite );
+            return false;
+
+        }
+        return true;
+    }
+
+    private Collection<Object> getReplaceCollection()
+    {
+        final List<Object> objects = new ArrayList<Object>();
+        for(final Object val : this.boundValues.values())
+        {
+            objects.add(val);
+        }
+        return objects;
+    }
+
+    private MethodResult updateField( final METHOD_TYPE mType,
+            final Object componentInstance,
+            final BindParameters bp,
+            final SimpleLogger logger )
+        throws InvocationTargetException
+    {
+        final ComponentContextImpl key = bp.getComponentContext();
+        final RefPair<?, ?> refPair = bp.getRefPair();
+
+        if ( !this.metadata.isMultiple() )
+        {
+            // unary references
+            // unbind needs only be done, if reference is dynamic and optional
+            if ( mType == METHOD_TYPE.UNBIND )
+            {
+                if ( this.metadata.isOptional() && !this.metadata.isStatic() )
+                {
+                    // we only reset if it was previously set with this value
+                    if ( this.boundValues.size() == 1 )
+                    {
+                        this.setFieldValue(componentInstance, null);
+                    }
+                }
+                this.boundValues.remove(refPair);
+            }
+            // updated needs only be done, if reference is dynamic and optional
+            // and the value type is map or tuple
+            else if ( mType == METHOD_TYPE.UPDATED )
+            {
+                if ( this.metadata.isOptional() && !this.metadata.isStatic() )
+                {
+                    if ( this.valueType == ParamType.map || this.valueType == ParamType.tuple )
+                    {
+                        final Object obj = getValue(key, refPair);
+                        this.setFieldValue(componentInstance, obj);
+                        this.boundValues.put(refPair, obj);
+                    }
+                }
+            }
+            // bind needs always be done
+            else
+            {
+                final Object obj = getValue(key, refPair);
+                this.setFieldValue(componentInstance, obj);
+                this.boundValues.put(refPair, obj);
+            }
+        }
+        else
+        {
+            // multiple references
+
+            // bind: replace or update the field
+            if ( mType == METHOD_TYPE.BIND )
+            {
+                final Object obj = getValue(key, refPair);
+                this.boundValues.put(refPair, obj);
+                if ( metadata.isReplace() )
+                {
+                    this.setFieldValue(componentInstance, getReplaceCollection());
+                }
+                else
+                {
+                    @SuppressWarnings("unchecked")
+                    final Collection<Object> col = (Collection<Object>)this.getFieldValue(componentInstance);
+                    col.add(obj);
+                }
+            }
+            // unbind needs only be done, if reference is dynamic
+            else if ( mType == METHOD_TYPE.UNBIND)
+            {
+                if ( !metadata.isStatic() )
+                {
+                    final Object obj = this.boundValues.remove(refPair);
+                    if ( metadata.isReplace() )
+                    {
+                        this.setFieldValue(componentInstance, getReplaceCollection());
+                    }
+                    else
+                    {
+                        @SuppressWarnings("unchecked")
+                        final Collection<Object> col = (Collection<Object>)this.getFieldValue(componentInstance);
+                        col.remove(obj);
+                    }
+                }
+            }
+            // updated needs only be done, if reference is dynamic
+            // and the value type is map or tuple
+            else if ( mType == METHOD_TYPE.UPDATED)
+            {
+                if ( !this.metadata.isStatic()
+                     && (this.valueType == ParamType.map || this.valueType == ParamType.tuple ) )
+                {
+                    final Object obj = getValue(key, refPair);
+                    final Object oldObj = this.boundValues.put(refPair, obj);
+
+                    if ( metadata.isReplace() )
+                    {
+                        this.setFieldValue(componentInstance, getReplaceCollection());
+                    }
+                    else
+                    {
+                        @SuppressWarnings("unchecked")
+                        final Collection<Object> col = (Collection<Object>)this.getFieldValue(componentInstance);
+                        col.add(obj);
+                        col.remove(oldObj);
+                    }
+                }
+            }
+        }
+
+        return MethodResult.VOID;
+    }
+
+    private void setFieldValue(final Object componentInstance, final Object value)
+    throws InvocationTargetException
+    {
+        try
+        {
+            field.set(componentInstance, value);
+        }
+        catch ( final IllegalArgumentException iae )
+        {
+            throw new InvocationTargetException(iae);
+        }
+        catch ( final IllegalAccessException iae )
+        {
+            throw new InvocationTargetException(iae);
+        }
+    }
+
+    private Object getFieldValue(final Object componentInstance)
+    throws InvocationTargetException
+    {
+        try
+        {
+            return field.get(componentInstance);
+        }
+        catch ( final IllegalArgumentException iae )
+        {
+            throw new InvocationTargetException(iae);
+        }
+        catch ( final IllegalAccessException iae )
+        {
+            throw new InvocationTargetException(iae);
+        }
+    }
+
+    /**
+     * Returns <code>true</code> if the field is acceptable to be returned from the
+     * {@link #getField(Class, String, boolean, boolean, SimpleLogger)} and also
+     * makes the field accessible.
+     * <p>
+     * This method returns <code>true</code> if the field:
+     * <ul>
+     * <li>Is not static</li>
+     * <li>Is public or protected</li>
+     * <li>Is private and <code>acceptPrivate</code> is <code>true</code></li>
+     * <li>Is package private and <code>acceptPackage</code> is <code>true</code></li>
+     * </ul>
+     * <p>
+     *
+     * @param field The field to check
+     * @param acceptPrivate Whether a private field is acceptable
+     * @param acceptPackage Whether a package private field is acceptable
+     * @return whether the field is acceptable
+     */
+    private static boolean accept( final Field field,
+            final boolean acceptPrivate,
+            final boolean acceptPackage )
+    {
+        // check modifiers now
+        final int mod = field.getModifiers();
+
+        // no static fields
+        if ( Modifier.isStatic( mod ) )
+        {
+            return false;
+        }
+
+        // accept public and protected fields
+        if ( Modifier.isPublic( mod ) || Modifier.isProtected( mod ) )
+        {
+            setAccessible( field );
+            return true;
+        }
+
+        // accept private if accepted
+        if ( Modifier.isPrivate( mod ) )
+        {
+            if ( acceptPrivate )
+            {
+                setAccessible( field );
+                return true;
+            }
+
+            return false;
+        }
+
+        // accept default (package)
+        if ( acceptPackage )
+        {
+            setAccessible( field );
+            return true;
+        }
+
+        // else don't accept
+        return false;
+    }
+
+    private static void setAccessible(final Field field)
+    {
+        AccessController.doPrivileged( new PrivilegedAction<Object>()
+        {
+            public Object run()
+            {
+                field.setAccessible( true );
+                return null;
+            }
+        } );
+    }
+
+
+    /**
+     * Returns the name of the package to which the class belongs or an
+     * empty string if the class is in the default package.
+     */
+    public static String getPackageName( Class<?> clazz )
+    {
+        String name = clazz.getName();
+        int dot = name.lastIndexOf( '.' );
+        return ( dot > 0 ) ? name.substring( 0, dot ) : "";
+    }
+
+    /**
+     * Internal state interface.
+     */
+    private static interface State
+    {
+
+        MethodResult invoke( final FieldHandler handler,
+                final METHOD_TYPE mType,
+                final Object componentInstance,
+                final BindParameters rawParameter,
+                final SimpleLogger logger )
+        throws InvocationTargetException;
+
+        boolean fieldExists( final FieldHandler handler, final SimpleLogger logger);
+    }
+
+    /**
+     * Initial state.
+     */
+    private static class NotResolved implements State
+    {
+        private static final State INSTANCE = new NotResolved();
+
+        private synchronized void resolve( final FieldHandler handler, final SimpleLogger logger )
+        {
+            logger.log( LogService.LOG_DEBUG, "getting field: {0}", new Object[]
+                    {handler.metadata.getField()}, null );
+
+            // resolve the field
+            Field field = null;
+            try
+            {
+                field = handler.findField( logger );
+                field = handler.validateField( field, logger );
+            }
+            catch ( final InvocationTargetException ex )
+            {
+                logger.log( LogService.LOG_WARNING, "{0} cannot be found", new Object[]
+                        {handler.metadata.getField()}, ex.getTargetException() );
+                field = null;
+            }
+
+            handler.setField( field, logger );
+        }
+
+        public MethodResult invoke( final FieldHandler handler,
+                final METHOD_TYPE mType,
+                final Object componentInstance,
+                final BindParameters rawParameter,
+                SimpleLogger logger )
+        throws InvocationTargetException
+        {
+            resolve( handler, logger );
+            return handler.state.invoke( handler, mType, componentInstance, rawParameter, logger );
+        }
+
+        public boolean fieldExists( final FieldHandler handler, final SimpleLogger logger)
+        {
+            resolve( handler, logger );
+            return handler.state.fieldExists( handler, logger );
+        }
+    }
+
+    /**
+     * Final state of field couldn't be found or errors occured.
+     */
+    private static class NotFound implements State
+    {
+        private static final State INSTANCE = new NotFound();
+
+        public MethodResult invoke( final FieldHandler handler,
+                final METHOD_TYPE mType,
+                final Object componentInstance,
+                final BindParameters rawParameter,
+                final SimpleLogger logger )
+        {
+            logger.log( LogService.LOG_ERROR, "Field [{0}] not found", new Object[]
+                { handler.metadata.getField() }, null );
+            return null;
+        }
+
+        public boolean fieldExists( final FieldHandler handler, final SimpleLogger logger)
+        {
+            return false;
+        }
+    }
+
+    /**
+     * Final state of field could be found and is valid.
+     */
+    private static class Resolved implements State
+    {
+        private static final State INSTANCE = new Resolved();
+
+        public MethodResult invoke( final FieldHandler handler,
+                final METHOD_TYPE mType,
+                final Object componentInstance,
+                final BindParameters rawParameter,
+                final SimpleLogger logger )
+            throws InvocationTargetException
+        {
+            return handler.updateField( mType, componentInstance, rawParameter, logger );
+        }
+
+        public boolean fieldExists( final FieldHandler handler, final SimpleLogger logger)
+        {
+            return true;
+        }
+    }
+
+    public boolean fieldExists( SimpleLogger logger )
+    {
+        return this.state.fieldExists( this, logger );
+    }
+
+    public static final class ReferenceMethodImpl
+        implements ReferenceMethod
+    {
+
+        private final METHOD_TYPE methodType;
+
+        private final FieldHandler handler;
+
+        public ReferenceMethodImpl(final METHOD_TYPE mt, final FieldHandler handler)
+        {
+            this.methodType = mt;
+            this.handler = handler;
+        }
+
+        public MethodResult invoke(final Object componentInstance,
+                final BindParameters rawParameter,
+                final MethodResult methodCallFailureResult,
+                final SimpleLogger logger)
+        {
+            try
+            {
+                return handler.state.invoke( handler,
+                        methodType,
+                        componentInstance,
+                        rawParameter,
+                        logger );
+            }
+            catch ( final InvocationTargetException ite )
+            {
+                logger.log( LogService.LOG_ERROR, "The {0} field has thrown an exception", new Object[]
+                    { handler.metadata.getField() }, ite.getCause() );
+            }
+
+            return methodCallFailureResult;
+        }
+
+        public <S, T> boolean getServiceObject(final ComponentContextImpl<S> key,
+                final RefPair<S, T> refPair,
+                final BundleContext context,
+                final SimpleLogger logger)
+        {
+            if ( methodType != METHOD_TYPE.UNBIND )
+            {
+                //??? this resolves which we need.... better way?
+                if ( refPair.getServiceObject(key) == null
+                  && handler.fieldExists( logger )
+                  && (handler.valueType == ParamType.serviceType || handler.valueType == ParamType.tuple ) )
+                {
+                    return refPair.getServiceObject(key, context, logger);
+                }
+            }
+            return true;
+        }
+
+    }
+    public ReferenceMethod getBind()
+    {
+        return new ReferenceMethodImpl(METHOD_TYPE.BIND, this);
+    }
+
+    public ReferenceMethod getUnbind()
+    {
+        return new ReferenceMethodImpl(METHOD_TYPE.UNBIND, this);
+    }
+
+    public ReferenceMethod getUpdated()
+    {
+        return new ReferenceMethodImpl(METHOD_TYPE.UPDATED, this);
+    }
+
+    public InitReferenceMethod getInit()
+    {
+        return new InitReferenceMethod()
+        {
+
+            public boolean init(final Object componentInstance, final SimpleLogger logger)
+            {
+                if ( fieldExists( logger) )
+                {
+                    return initField(componentInstance, logger);
+                }
+                return false;
+            }
+        };
+    }
+}

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldMethods.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldMethods.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldMethods.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/FieldMethods.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,71 @@
+/*
+ * 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.scr.impl.helper;
+
+
+import org.apache.felix.scr.impl.metadata.DSVersion;
+import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
+
+/**
+ * @version $Rev: 1637793 $ $Date: 2014-11-10 06:51:04 +0100 (Mon, 10 Nov 2014) $
+ */
+public class FieldMethods implements ReferenceMethods
+{
+    private final ReferenceMethod bind;
+    private final ReferenceMethod updated;
+    private final ReferenceMethod unbind;
+    private final InitReferenceMethod init;
+
+    public FieldMethods( final ReferenceMetadata m_dependencyMetadata,
+            final Class<?> instanceClass,
+            final DSVersion dsVersion,
+            final boolean configurableServiceProperties )
+    {
+        final FieldHandler handler = new FieldHandler(
+                m_dependencyMetadata,
+                instanceClass
+        );
+        bind = handler.getBind();
+        unbind = handler.getUnbind();
+        updated = handler.getUpdated();
+        init = handler.getInit();
+    }
+
+    public ReferenceMethod getBind()
+    {
+        return bind;
+    }
+
+    public ReferenceMethod getUnbind()
+    {
+        return unbind;
+    }
+
+    public ReferenceMethod getUpdated()
+    {
+        return updated;
+    }
+
+    public InitReferenceMethod getInit()
+    {
+        return init;
+    }
+}

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/InitReferenceMethod.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/InitReferenceMethod.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/InitReferenceMethod.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/InitReferenceMethod.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,29 @@
+/*
+ * 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.scr.impl.helper;
+
+
+
+/**
+ * Callback for initializing the reference
+ */
+public interface InitReferenceMethod
+{
+    boolean init( final Object componentInstance, final SimpleLogger logger );
+}

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/Logger.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/Logger.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/Logger.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/Logger.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,70 @@
+/*
+ * 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.scr.impl.helper;
+
+
+import org.apache.felix.scr.impl.metadata.ComponentMetadata;
+
+
+/**
+ * The <code>Logger</code> interface defines a simple API to enable some logging
+ * in the XML Parser and ComponentMetadata handling classes and at the same
+ * time not be too intrusive for the unit tests.
+ */
+public interface Logger
+{
+
+    /**
+     * Returns <code>true</code> if logging for the given level is enabled.
+     */
+    boolean isLogEnabled( int level );
+
+
+    /**
+     * Method to actually emit the log message. If the LogService is available,
+     * the message will be logged through the LogService. Otherwise the message
+     * is logged to stdout (or stderr in case of LOG_ERROR level messages),
+     *
+     * @param level The log level to log the message at
+     * @param pattern The <code>java.text.MessageFormat</code> message format
+     *      string for preparing the message
+     * @param arguments The format arguments for the <code>pattern</code>
+ *      string.
+     * @param metadata  component metadata if known
+     * @param componentId  component ID if known
+     * @param ex An optional <code>Throwable</code> whose stack trace is written,
+     */
+    void log( int level, String pattern, Object[] arguments, ComponentMetadata metadata, Long componentId, Throwable ex );
+
+
+    /**
+     * Writes a messages for the given <code>ComponentMetadata</code>.
+     *
+     * @param level The log level of the messages. This corresponds to the log
+     *          levels defined by the OSGi LogService.
+     * @param message The message to print
+     * @param metadata The {@link org.apache.felix.scr.impl.metadata.ComponentMetadata} whose processing caused
+ *          the message. This may be <code>null</code> if the component
+ *          metadata is not known or applicable.
+     * @param componentId
+     * @param ex The <code>Throwable</code> causing the message to be logged.
+     */
+    void log( int level, String message, ComponentMetadata metadata, Long componentId, Throwable ex );
+
+}

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/MethodResult.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/MethodResult.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/MethodResult.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/MethodResult.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,63 @@
+/*
+ * 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.scr.impl.helper;
+
+import java.util.Map;
+
+/**
+ * The <code>MethodResult</code> conveys the return value of one of the
+ * activate, modify, and deactivate methods.
+ * <p>
+ * Note that the method returning <code>null</code> or being defined as
+ * <code>void</code> is not the same thing. If the method returns
+ * <code>null</code> an instance of this class is returned whose
+ * {@link #getResult()} method returns <code>null</code>. If the method is
+ * defined as <code>void</code> the special instance {@link #VOID} is returned.
+ */
+public class MethodResult
+{
+
+    /**
+     * Predefined instance indicating a successfull call to a void method.
+     */
+    public static final MethodResult VOID = new MethodResult(false, null);
+
+    /**
+     * The actual result from the method, which may be <code>null</code>.
+     */
+    private final Map<String, Object> result;
+
+    private final boolean hasResult;
+
+    MethodResult(final boolean hasResult, final Map<String, Object> result)
+    {
+        this.hasResult = hasResult;
+        this.result = result;
+    }
+
+    public boolean hasResult()
+    {
+        return hasResult;
+    }
+
+    public Map<String, Object> getResult()
+    {
+        return result;
+    }
+}

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ModifiedMethod.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ModifiedMethod.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ModifiedMethod.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ModifiedMethod.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,44 @@
+/*
+ * 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.scr.impl.helper;
+
+import org.apache.felix.scr.impl.metadata.DSVersion;
+
+
+public class ModifiedMethod extends ActivateMethod
+{
+
+    public ModifiedMethod( final String methodName,
+            final Class<?> componentClass, final DSVersion dsVersion, final boolean configurableServiceProperties, boolean supportsInterfaces )
+    {
+        super( methodName, methodName != null, componentClass, dsVersion, configurableServiceProperties, supportsInterfaces );
+    }
+
+
+    protected boolean acceptEmpty()
+    {
+        return true;
+    }
+
+
+    protected String getMethodNamePrefix()
+    {
+        return "modified";
+    }
+}

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ReadOnlyDictionary.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ReadOnlyDictionary.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ReadOnlyDictionary.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ReadOnlyDictionary.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,215 @@
+/*
+ * 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.scr.impl.helper;
+
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.framework.ServiceReference;
+
+
+/**
+ * The <code>ReadOnlyDictionary</code> is both a <code>Dictionary</code> and
+ * a <code>Map</code> whose modification methods (like {@link #put(Object, Object)},
+ * {@link #remove(Object)}, etc.) throw an {@link UnsupportedOperationException}.
+ */
+public class ReadOnlyDictionary<S, T> extends Dictionary<S, T>
+    implements Map<S, T>, Comparable<ReadOnlyDictionary<S, T>>
+{
+
+    private final Hashtable<S, T> m_delegate;
+
+    private final ServiceReference<?> m_serviceReference;
+
+    /**
+     * Creates a wrapper for the given delegate dictionary providing read
+     * only access to the data.
+     */
+    public ReadOnlyDictionary( final Map<S, T> delegate )
+    {
+        if ( delegate instanceof Hashtable )
+        {
+            this.m_delegate = ( Hashtable<S, T> ) delegate;
+        }
+        else
+        {
+            this.m_delegate = new Hashtable<S, T>();
+            for ( Map.Entry<S, T> entry: delegate.entrySet() )
+            {
+                this.m_delegate.put( entry.getKey(), entry.getValue() );
+            }
+        }
+        m_serviceReference = null;
+    }
+
+
+    /**
+     * Creates a wrapper for the given service reference providing read only
+     * access to the reference properties.
+     */
+    public ReadOnlyDictionary( final ServiceReference<?> serviceReference )
+    {
+        Hashtable properties = new Hashtable();
+        final String[] keys = serviceReference.getPropertyKeys();
+        if ( keys != null )
+        {
+            for ( int j = 0; j < keys.length; j++ )
+            {
+                final String key = keys[j];
+                properties.put( key, serviceReference.getProperty( key ) );
+            }
+        }
+        m_delegate = properties;
+        m_serviceReference = serviceReference;
+    }
+
+
+    //---------- Dictionary API
+
+    @Override
+    public Enumeration<T> elements()
+    {
+        return m_delegate.elements();
+    }
+
+    @Override
+    public T get( final Object key )
+    {
+        return m_delegate.get( key );
+    }
+
+
+    @Override
+    public boolean isEmpty()
+    {
+        return m_delegate.isEmpty();
+    }
+
+
+    @Override
+    public Enumeration<S> keys()
+    {
+        return m_delegate.keys();
+    }
+
+
+    /**
+     * This method has no effect and always returns <code>null</code> as this
+     * instance is read-only and cannot modify and properties.
+     */
+    @Override
+    public T put( final S key, final T value )
+    {
+        throw new UnsupportedOperationException();
+    }
+
+
+    /**
+     * This method has no effect and always returns <code>null</code> as this
+     * instance is read-only and cannot modify and properties.
+     */
+    @Override
+    public T remove( final Object key )
+    {
+        throw new UnsupportedOperationException();
+    }
+
+
+    @Override
+    public int size()
+    {
+        return m_delegate.size();
+    }
+
+
+    @Override
+    public String toString()
+    {
+        return m_delegate.toString();
+    }
+
+
+    //---------- Map API
+
+    public void clear()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+
+    public boolean containsKey( Object key )
+    {
+        return m_delegate.containsKey( key );
+    }
+
+
+    public boolean containsValue( Object value )
+    {
+        return m_delegate.containsValue( value );
+    }
+
+
+    public Set<Entry<S, T>> entrySet()
+    {
+        return Collections.unmodifiableSet( m_delegate.entrySet() );
+    }
+
+
+    public Set<S> keySet()
+    {
+        return Collections.unmodifiableSet( m_delegate.keySet() );
+    }
+
+
+    public void putAll( Map<? extends S, ? extends T> m )
+    {
+        throw new UnsupportedOperationException();
+    }
+
+
+    public Collection<T> values()
+    {
+        return Collections.unmodifiableCollection( m_delegate.values() );
+    }
+
+
+    public int compareTo(final ReadOnlyDictionary<S, T> o)
+    {
+        if ( m_serviceReference == null )
+        {
+            if ( o.m_serviceReference == null )
+            {
+                return 0;
+            }
+            return 1;
+        }
+        else if ( o.m_serviceReference == null )
+        {
+            return -1;
+        }
+        return m_serviceReference.compareTo(o.m_serviceReference);
+    }
+
+}

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ReferenceMethod.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ReferenceMethod.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ReferenceMethod.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ReferenceMethod.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,37 @@
+/*
+ * 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.scr.impl.helper;
+
+import org.apache.felix.scr.impl.manager.ComponentContextImpl;
+import org.apache.felix.scr.impl.manager.RefPair;
+import org.osgi.framework.BundleContext;
+
+
+
+
+/**
+ * Component method to be invoked on service (un)binding.
+ */
+public interface ReferenceMethod
+{
+    MethodResult invoke( final Object componentInstance, final BindParameters rawParameter,
+            final MethodResult methodCallFailureResult, SimpleLogger logger );
+
+    <S, T> boolean getServiceObject( ComponentContextImpl<S> key, RefPair<S, T> refPair, BundleContext context, SimpleLogger logger );
+}

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ReferenceMethods.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ReferenceMethods.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ReferenceMethods.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/ReferenceMethods.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,36 @@
+/*
+ * 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.scr.impl.helper;
+
+
+/**
+ * @version $Rev: 1637793 $ $Date: 2014-11-10 06:51:04 +0100 (Mon, 10 Nov 2014) $
+ */
+public interface ReferenceMethods
+{
+
+    ReferenceMethod getBind();
+
+    ReferenceMethod getUnbind();
+
+    ReferenceMethod getUpdated();
+
+    /** Optional. */
+    InitReferenceMethod getInit();
+}

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/SimpleLogger.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/SimpleLogger.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/SimpleLogger.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/SimpleLogger.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,33 @@
+/*
+ * 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.scr.impl.helper;
+
+/**
+ * @version $Rev: 1382234 $ $Date: 2012-09-08 05:55:26 +0200 (Sat, 08 Sep 2012) $
+ */
+public interface SimpleLogger
+{
+    void log( int level, String message, Throwable ex );
+
+    void log( int level, String message, Object[] arguments, Throwable ex );
+
+    boolean isLogEnabled( int level );
+}

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/SuitableMethodNotAccessibleException.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/SuitableMethodNotAccessibleException.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/SuitableMethodNotAccessibleException.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/SuitableMethodNotAccessibleException.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,24 @@
+/*
+ * 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.scr.impl.helper;
+
+
+public class SuitableMethodNotAccessibleException extends Exception
+{
+}
\ No newline at end of file

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UnbindMethod.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UnbindMethod.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UnbindMethod.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UnbindMethod.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,45 @@
+/*
+ * 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.scr.impl.helper;
+
+import org.apache.felix.scr.impl.metadata.DSVersion;
+import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
+
+
+/**
+ * Component method to be invoked on service unbinding.
+ */
+public class UnbindMethod extends BindMethod
+implements org.apache.felix.scr.impl.helper.ReferenceMethod
+{
+
+    public UnbindMethod( final String methodName,
+            final Class<?> componentClass, final String referenceClassName, final DSVersion dsVersion, final boolean configurableServiceProperties, ReferenceMetadata.ReferenceScope referenceScope )
+    {
+        super( methodName, componentClass, referenceClassName, dsVersion, configurableServiceProperties, referenceScope );
+    }
+
+
+    @Override
+    protected String getMethodNamePrefix()
+    {
+        return "unbind";
+    }
+
+}
\ No newline at end of file

Added: felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UpdatedMethod.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UpdatedMethod.java?rev=1689973&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UpdatedMethod.java (added)
+++ felix/sandbox/pderop/dependencymanager.ds/org.apache.felix.dependencymanager.ds/src/org/apache/felix/scr/impl/helper/UpdatedMethod.java Wed Jul  8 22:10:14 2015
@@ -0,0 +1,45 @@
+/*
+ * 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.scr.impl.helper;
+
+import org.apache.felix.scr.impl.metadata.DSVersion;
+import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
+
+
+/**
+ * Component method to be invoked on service property update of a bound service.
+ */
+public class UpdatedMethod extends BindMethod
+implements org.apache.felix.scr.impl.helper.ReferenceMethod
+{
+
+    public UpdatedMethod( final String methodName,
+            final Class<?> componentClass, final String referenceClassName, final DSVersion dsVersion, final boolean configurableServiceProperties, ReferenceMetadata.ReferenceScope referenceScope )
+    {
+        super( methodName, componentClass, referenceClassName, dsVersion, configurableServiceProperties, referenceScope );
+    }
+
+
+    @Override
+    protected String getMethodNamePrefix()
+    {
+        return "update";
+    }
+
+}
\ No newline at end of file