Author: fmeschbe Date: Wed May 9 18:25:22 2012 New Revision: 1336331 URL: http://svn.apache.org/viewvc?rev=1336331&view=rev Log: FELIX-3377 Commit my latest patch (FELIX-3377-4-fmeschbe.patch) including input from David Jencks (thanks alot).
- Activate, Modified, Deactivate methods may return Map to set service properties - Namespace "http://felix.apache.org/xmlns/scr/v1.2.0-felix" is required for component declaration to support this feature - ExtComponentContext provides setServiceProperties method to explicitly set the service registration properties at any time Added: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/MethodResult.java Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/component/ExtComponentContext.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ActivateMethod.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/DeactivateMethod.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/XmlHandler.java felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/ActivateMethodTest.java felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/metadata/XmlHandlerTest.java felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentConfigurationTest.java felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/MutablePropertiesTest.java felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/MutatingServiceImpl.java felix/trunk/scr/src/test/resources/integration_test_mutable_properties.xml Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/component/ExtComponentContext.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/component/ExtComponentContext.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/component/ExtComponentContext.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/component/ExtComponentContext.java Wed May 9 18:25:22 2012 @@ -33,47 +33,23 @@ public interface ExtComponentContext ext { /** - * Updates the service registration properties of the component - * registered as a service. The effects are: - * <ol> - * <li>The properties read from the component descriptor are updated - * with the values from the given dictionary</li> - * <li>Configuration Admin properties are applied</li> - * <li>The ServiceRegistration service properties are updated with the - * result.</li> - * </ol> + * Sets the service registration properties of the component + * registered as a service. If the component is not registered as + * a service, this method has no effect. * <p> - * Calling this method is does not cause a component reconfiguration as - * would be caused by a Configuration update. Particularly the - * configured modified method (if any) is not called as a result of - * calling this method. - * <p> - * Please note: - * <ul> - * <li>The provided properties may overwrite or add properties to - * the properties read from the component descriptor. It is not - * possible to remove such descriptor properties</li> - * <li>The provided properties are only valid for the livecycle of the - * component instance. After reactivation of a component (and thus - * creation of a new component instance) the properties are removed. - * </li> - * <li>If the component can be dynamically updated with configuration - * these properties will influence such configuration.</li> - * <li>Configuration is not updated in the Configuration Admin Service - * when calling service</li> - * <li>Properties provided with this method may still be overwriiten - * with configuration provided by the Configuration Admin Service.</lI> - * </ul> - * <p> - * If the component to which this context belongs is not registered as - * a service, this method + * The <code>component.id</code> and <code>component.name</code> + * property are set by the Service Component Runtime and cannot be + * removed or replaced. * * @param properties properties to update the default component - * properties with. + * properties with. If this is <code>null</code> or empty the + * default set of properties as defined in Section 112.6, + * Component Properties, are used as the service registration + * properties. * * @throws IllegalStateException if this method is called for a * Component Factory component */ - void updateProperties( Dictionary properties ); + void setServiceProperties( Dictionary properties ); } Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ActivateMethod.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ActivateMethod.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ActivateMethod.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ActivateMethod.java Wed May 9 18:25:22 2012 @@ -21,7 +21,6 @@ package org.apache.felix.scr.impl.helper import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; - import org.apache.felix.scr.impl.manager.AbstractComponentManager; import org.osgi.service.component.ComponentContext; import org.osgi.service.log.LogService; @@ -70,7 +69,7 @@ public class ActivateMethod extends Base { if ( methods[i].getName().equals( getMethodName() ) && isSuitable( methods[i] ) ) { - if ( accept( methods[i], acceptPrivate, acceptPackage ) ) + if ( accept( methods[i], acceptPrivate, acceptPackage, returnValue() ) ) { // check modifiers etc. return methods[i]; @@ -143,12 +142,20 @@ public class ActivateMethod extends Base return "activate"; } - - public boolean invoke( Object componentInstance, Object rawParameter, final boolean methodCallFailureResult ) + protected boolean returnValue() { - return methodExists() && super.invoke( componentInstance, rawParameter, methodCallFailureResult ); + // allow returning Map if declared as DS 1.2-Felix or newer + return isDS12Felix(); } + public MethodResult invoke(Object componentInstance, Object rawParameter, final MethodResult methodCallFailureResult) + { + if (methodExists()) + { + return super.invoke(componentInstance, rawParameter, methodCallFailureResult); + } + return null; + } /** * Returns a method taking a single parameter of one of the @@ -250,7 +257,6 @@ public class ActivateMethod extends Base private final ComponentContext m_componentContext; private final int m_reason; - public ActivatorParameter( ComponentContext componentContext, int reason ) { this.m_componentContext = componentContext; Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java Wed May 9 18:25:22 2012 @@ -24,7 +24,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.Map; - import org.apache.felix.scr.impl.manager.AbstractComponentManager; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; @@ -56,7 +55,6 @@ abstract class BaseMethod private State m_state; - protected BaseMethod( final AbstractComponentManager componentManager, final String methodName, final Class componentClass ) { @@ -94,6 +92,12 @@ abstract class BaseMethod } + protected final boolean isDS12Felix() + { + return getComponentManager().getComponentMetadata().isDS12Felix(); + } + + protected final String getMethodName() { return m_methodName; @@ -145,11 +149,6 @@ abstract class BaseMethod * the class hierarchy is traversed until a method is found or the root * of the class hierarchy is reached without finding a method. * - * @param targetClass The class in which to look for the method - * @param acceptPrivate <code>true</code> if private methods should be - * considered. - * @param acceptPackage <code>true</code> if package private methods should - * be considered. * @return The requested method or <code>null</code> if no acceptable method * can be found in the target class or any super class. * @throws InvocationTargetException If an unexpected Throwable is caught @@ -185,7 +184,7 @@ abstract class BaseMethod { // log and return null getComponentManager().log( LogService.LOG_ERROR, - "DependencyManager : Suitable but non-accessible method found in class {0}", new Object[] + "findMethod: Suitable but non-accessible method found in class {0}", new Object[] { targetClass.getName() }, null ); break; } @@ -216,15 +215,16 @@ abstract class BaseMethod final boolean acceptPackage ) throws SuitableMethodNotAccessibleException, InvocationTargetException; - private boolean invokeMethod( final Object componentInstance, final Object rawParameter ) + private MethodResult invokeMethod( final Object componentInstance, final Object rawParameter ) throws InvocationTargetException { try { if ( componentInstance != null ) { - final Object[] params = getParameters( m_method, rawParameter ); - m_method.invoke( componentInstance, params ); + final Object[] params = getParameters(m_method, rawParameter); + Object result = m_method.invoke(componentInstance, params); + return new MethodResult((m_method.getReturnType() != Void.TYPE), (Map) result); } else { @@ -236,7 +236,7 @@ abstract class BaseMethod catch ( IllegalStateException ise ) { getComponentManager().log( LogService.LOG_DEBUG, ise.getMessage(), null ); - return false; + return null; } catch ( IllegalAccessException ex ) { @@ -256,9 +256,18 @@ abstract class BaseMethod } // assume success (also if the mehotd is not available or accessible) - return true; + return MethodResult.VOID; // TODO: or null ?? } + protected void processResult( Object configResults, Object result, Method method ) + { + //no op + } + + protected boolean returnValue() + { + return false; + } /** * Returns the parameter array created from the <code>rawParameter</code> @@ -311,7 +320,7 @@ abstract class BaseMethod Method method = clazz.getDeclaredMethod( name, parameterTypes ); // accept public and protected methods only and ensure accessibility - if ( accept( method, acceptPrivate, acceptPackage ) ) + if ( accept( method, acceptPrivate, acceptPackage, returnValue() ) ) { return method; } @@ -384,15 +393,16 @@ abstract class BaseMethod * This method is package private for unit testing purposes. It is not * meant to be called from client code. * + * * @param method The method to check * @param acceptPrivate Whether a private method is acceptable * @param acceptPackage Whether a package private method is acceptable - * @return + * @param allowReturnValue whether the method can return a value (to update service registration properties) + * @return whether the method is acceptable */ - protected static boolean accept( Method method, boolean acceptPrivate, boolean acceptPackage ) + static boolean accept( Method method, boolean acceptPrivate, boolean acceptPackage, boolean allowReturnValue ) { - // method must be void - if ( Void.TYPE != method.getReturnType() ) + if (!(Void.TYPE == method.getReturnType() || (MAP_CLASS == method.getReturnType() && allowReturnValue))) { return false; } @@ -455,6 +465,8 @@ abstract class BaseMethod * Calls the declared method on the given component with the provided * method call arguments. * + * + * * @param componentInstance The component instance on which to call the * method * @param rawParameter The parameter container providing the actual @@ -468,8 +480,8 @@ abstract class BaseMethod * <code>methodCallFailureResult</code> is returned if the method was * found and called, but the method threw an exception. */ - public boolean invoke( final Object componentInstance, final Object rawParameter, - final boolean methodCallFailureResult ) + public MethodResult invoke( final Object componentInstance, final Object rawParameter, + final MethodResult methodCallFailureResult ) { try { @@ -493,7 +505,7 @@ abstract class BaseMethod private static interface State { - boolean invoke( final BaseMethod baseMethod, final Object componentInstance, final Object rawParameter ) + MethodResult invoke( final BaseMethod baseMethod, final Object componentInstance, final Object rawParameter ) throws InvocationTargetException; @@ -506,9 +518,9 @@ abstract class BaseMethod private static final State INSTANCE = new NotApplicable(); - public boolean invoke( final BaseMethod baseMethod, final Object componentInstance, final Object rawParameter ) + public MethodResult invoke( final BaseMethod baseMethod, final Object componentInstance, final Object rawParameter ) { - return true; + return MethodResult.VOID; } @@ -545,7 +557,7 @@ abstract class BaseMethod } - public boolean invoke( final BaseMethod baseMethod, final Object componentInstance, final Object rawParameter ) + public MethodResult invoke( final BaseMethod baseMethod, final Object componentInstance, final Object rawParameter ) throws InvocationTargetException { resolve( baseMethod ); @@ -565,14 +577,14 @@ abstract class BaseMethod private static final State INSTANCE = new NotFound(); - public boolean invoke( final BaseMethod baseMethod, final Object componentInstance, final Object rawParameter ) + public MethodResult invoke( final BaseMethod baseMethod, final Object componentInstance, final Object rawParameter ) { // 112.3.1 If the method is not found , SCR must log an error // message with the log service, if present, and ignore the // method baseMethod.getComponentManager().log( LogService.LOG_ERROR, "{0} method [{1}] not found", new Object[] { baseMethod.getMethodNamePrefix(), baseMethod.getMethodName() }, null ); - return false; + return null; } @@ -587,7 +599,7 @@ abstract class BaseMethod private static final State INSTANCE = new Resolved(); - public boolean invoke( final BaseMethod baseMethod, final Object componentInstance, final Object rawParameter ) + public MethodResult invoke( final BaseMethod baseMethod, final Object componentInstance, final Object rawParameter ) throws InvocationTargetException { baseMethod.getComponentManager().log( LogService.LOG_DEBUG, "invoking {0}: {1}", new Object[] Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java Wed May 9 18:25:22 2012 @@ -195,7 +195,7 @@ public class BindMethod extends BaseMeth if ( suitableMethodNotAccessible ) { getComponentManager().log( LogService.LOG_ERROR, - "DependencyManager : Suitable but non-accessible method found in class {0}", new Object[] + "doFindMethod: Suitable but non-accessible method found in class {0}", new Object[] { targetClass.getName() }, null ); throw new SuitableMethodNotAccessibleException(); } @@ -428,7 +428,7 @@ public class BindMethod extends BaseMeth // reference's interface attribute if ( theParameter.isAssignableFrom( parameterClass ) ) { - if ( accept( method, acceptPrivate, acceptPackage ) ) + if ( accept( method, acceptPrivate, acceptPackage, false ) ) { return method; } @@ -521,7 +521,7 @@ public class BindMethod extends BaseMeth // parameters must be refclass,map if ( parameters[0].isAssignableFrom( parameterClass ) && parameters[1] == MAP_CLASS ) { - if ( accept( method, acceptPrivate, acceptPackage ) ) + if ( accept( method, acceptPrivate, acceptPackage, false ) ) { return method; } Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/DeactivateMethod.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/DeactivateMethod.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/DeactivateMethod.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/DeactivateMethod.java Wed May 9 18:25:22 2012 @@ -46,4 +46,5 @@ public class DeactivateMethod extends Ac { return "deactivate"; } + } Added: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/MethodResult.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/MethodResult.java?rev=1336331&view=auto ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/MethodResult.java (added) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/MethodResult.java Wed May 9 18:25:22 2012 @@ -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 result; + + private final boolean hasResult; + + MethodResult(final boolean hasResult, final Map result) + { + this.hasResult = hasResult; + this.result = result; + } + + public boolean hasResult() + { + return hasResult; + } + + public Map getResult() + { + return result; + } +} Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java Wed May 9 18:25:22 2012 @@ -797,7 +797,7 @@ public abstract class AbstractComponentM public abstract Dictionary getProperties(); - public abstract void resetComponentProperties( Dictionary properties ); + public abstract void setServiceProperties(Dictionary serviceProperties, boolean updateServiceRegistration); /** * Returns the subset of component properties to be used as service Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java Wed May 9 18:25:22 2012 @@ -27,7 +27,6 @@ import org.apache.felix.scr.impl.helper. import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; -import org.osgi.service.component.ComponentContext; import org.osgi.service.component.ComponentInstance; @@ -135,9 +134,9 @@ public class ComponentContextImpl implem //---------- Speculative MutableProperties interface ------------------------------ - public void updateProperties(Dictionary properties) + public void setServiceProperties(Dictionary properties) { - getComponentManager().resetComponentProperties(properties); + getComponentManager().setServiceProperties(properties, true); } } Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java Wed May 9 18:25:22 2012 @@ -209,7 +209,8 @@ public class ComponentFactoryImpl extend return props; } - public void resetComponentProperties(Dictionary properties) { + public void setServiceProperties(Dictionary serviceProperties, boolean updateServiceRegistration) + { throw new IllegalStateException( "ComponentFactory service properties are immutable" ); } Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java Wed May 9 18:25:22 2012 @@ -31,6 +31,7 @@ import org.apache.felix.scr.Component; import org.apache.felix.scr.Reference; import org.apache.felix.scr.impl.BundleComponentActivator; import org.apache.felix.scr.impl.helper.BindMethod; +import org.apache.felix.scr.impl.helper.MethodResult; import org.apache.felix.scr.impl.helper.UnbindMethod; import org.apache.felix.scr.impl.helper.UpdatedMethod; import org.apache.felix.scr.impl.metadata.ReferenceMetadata; @@ -1059,7 +1060,7 @@ public class DependencyManager implement { return getService( ref ); } - }, true ); + }, MethodResult.VOID ) != null; } // Concurrency Issue: The component instance still exists but @@ -1112,6 +1113,7 @@ public class DependencyManager implement { // The updated method is only invoked if the implementation object is not // null. This is valid for both immediate and delayed components + //TODO should updated methods be able to change config properties? if ( m_componentInstance != null ) { m_updated.invoke( m_componentInstance, new BindMethod.Service() @@ -1126,7 +1128,7 @@ public class DependencyManager implement { return getService( ref ); } - }, true ); + }, MethodResult.VOID ); } else { @@ -1167,7 +1169,7 @@ public class DependencyManager implement { return getService( ref ); } - }, true ); + }, MethodResult.VOID ); } else { Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java Wed May 9 18:25:22 2012 @@ -23,11 +23,14 @@ import java.util.Dictionary; import java.util.Hashtable; import java.util.Iterator; import java.util.List; +import java.util.Map; import org.apache.felix.scr.impl.BundleComponentActivator; import org.apache.felix.scr.impl.config.ComponentHolder; import org.apache.felix.scr.impl.helper.ActivateMethod; +import org.apache.felix.scr.impl.helper.ActivateMethod.ActivatorParameter; import org.apache.felix.scr.impl.helper.DeactivateMethod; +import org.apache.felix.scr.impl.helper.MethodResult; import org.apache.felix.scr.impl.helper.ModifiedMethod; import org.apache.felix.scr.impl.metadata.ComponentMetadata; import org.apache.felix.scr.impl.metadata.ReferenceMetadata; @@ -71,7 +74,7 @@ public class ImmediateComponentManager e // properties supplied ot ExtComponentContext.updateProperties // null if properties are not to be overwritten - private Dictionary m_propertiesOverwrite; + private Dictionary m_serviceProperties; // the component properties from the Configuration Admin Service // this is null, if none exist or none are provided @@ -140,7 +143,7 @@ public class ImmediateComponentManager e m_implementationObject = null; m_componentContext = null; m_properties = null; - m_propertiesOverwrite = null; + m_serviceProperties = null; } @@ -228,8 +231,9 @@ public class ImmediateComponentManager e } // 4. Call the activate method, if present - if ( !m_activateMethod.invoke( implementationObject, - new ActivateMethod.ActivatorParameter( componentContext, 1 ), false ) ) + final MethodResult result = m_activateMethod.invoke(implementationObject, new ActivatorParameter( + componentContext, 1), null); + if (result == null) { // 112.5.8 If the activate method throws an exception, SCR must log an error message // containing the exception with the Log Service and activation fails @@ -242,6 +246,10 @@ public class ImmediateComponentManager e return null; } + else if (result.hasResult()) + { + setServiceProperties(result.getResult(), true); + } return implementationObject; } @@ -262,8 +270,12 @@ public class ImmediateComponentManager e // don't care for the result, the error (acccording to 112.5.12 If the deactivate // method throws an exception, SCR must log an error message containing the // exception with the Log Service and continue) has already been logged - m_deactivateMethod.invoke( implementationObject, new ActivateMethod.ActivatorParameter( componentContext, - reason ), true ); + final MethodResult result = m_deactivateMethod.invoke( implementationObject, new ActivatorParameter( componentContext, + reason ), null ); + if (result != null && result.hasResult()) + { + setServiceProperties(result.getResult(), true); + } // 2. Unbind any bound services Iterator it = getReversedDependencyManagers(); @@ -348,16 +360,13 @@ public class ImmediateComponentManager e } } - // 3. overwrite as per ExtComponentContext.updateProperties - copyTo( props, m_propertiesOverwrite ); - - // 4. overlay with Configuration Admin properties + // 3. overlay with Configuration Admin properties copyTo( props, m_configurationProperties ); - // 5. copy any component factory properties, not supported yet + // 4. copy any component factory properties, not supported yet copyTo( props, m_factoryProperties ); - // 6. set component.name and component.id + // 5. set component.name and component.id props.put( ComponentConstants.COMPONENT_NAME, getComponentMetadata().getName() ); props.put( ComponentConstants.COMPONENT_ID, new Long( getId() ) ); @@ -368,17 +377,69 @@ public class ImmediateComponentManager e } - public void resetComponentProperties( Dictionary properties ) + public void setServiceProperties(Map serviceProperties, boolean updateServiceRegistration) { - m_propertiesOverwrite = copyTo( null, properties ); - m_properties = null; - Dictionary serviceProperties = getServiceProperties(); - if ( getServiceRegistration() != null ) + Dictionary serviceProps = (serviceProperties == null) ? null : new Hashtable(serviceProperties); + setServiceProperties(serviceProps, updateServiceRegistration); + } + + public void setServiceProperties(Dictionary serviceProperties, boolean updateServiceRegistration) + { + if ( serviceProperties == null || serviceProperties.isEmpty() ) + { + m_serviceProperties = null; + } + else + { + m_serviceProperties = copyTo(null, serviceProperties); + // set component.name and component.id + m_serviceProperties.put( ComponentConstants.COMPONENT_NAME, getComponentMetadata().getName() ); + m_serviceProperties.put( ComponentConstants.COMPONENT_ID, new Long( getId() ) ); + } + + if (updateServiceRegistration) { - getServiceRegistration().setProperties( serviceProperties ); + updateServiceRegistration(); } } + public Dictionary getServiceProperties() { + if ( m_serviceProperties != null ) + { + return m_serviceProperties; + } + return super.getServiceProperties(); + } + + private void updateServiceRegistration() + { + ServiceRegistration sr = getServiceRegistration(); + if (sr != null) + { + try + { + // Don't propagate if service properties did not change. + final Dictionary regProps = getServiceProperties(); + if (!servicePropertiesMatches(sr, regProps)) + { + sr.setProperties(regProps); + } + } + catch (IllegalStateException ise) + { + // service has been unregistered asynchronously, ignore + } + catch (IllegalArgumentException iae) + { + log(LogService.LOG_ERROR, + "Unexpected configuration property problem when updating service registration", iae); + } + catch (Throwable t) + { + log(LogService.LOG_ERROR, "Unexpected problem when updating service registration", t); + } + } + } /** * Called by the Configuration Admin Service to update the component with @@ -487,8 +548,9 @@ public class ImmediateComponentManager e // invariant: modify method existing and no static bound service changes // 4. call method (nothing to do when failed, since it has already been logged) - if ( !m_modifyMethod.invoke( getInstance(), new ActivateMethod.ActivatorParameter( m_componentContext, -1 ), - true ) ) + final MethodResult result = m_modifyMethod.invoke(getInstance(), + new ActivatorParameter(m_componentContext, -1), null); + if (result == null) { // log an error if the declared method cannot be found log( LogService.LOG_ERROR, "Declared modify method ''{0}'' cannot be found, configuring by reactivation", @@ -496,6 +558,10 @@ public class ImmediateComponentManager e { getComponentMetadata().getModified() }, null ); return false; } + else if (result.hasResult()) + { + setServiceProperties(result.getResult(), false); + } // 5. update the target filter on the services now, this may still // result in unsatisfied dependencies, in which case we abort @@ -510,34 +576,7 @@ public class ImmediateComponentManager e } // 6. update service registration properties - ServiceRegistration sr = getServiceRegistration(); - if ( sr != null ) - { - try - { - // Don't propagate if service properties did not change. - final Dictionary regProps = getServiceProperties(); - if ( !servicePropertiesMatches( sr, regProps ) ) - { - sr.setProperties( regProps ); - } - } - catch ( IllegalStateException ise ) - { - // service has been unregistered asynchronously, ignore - } - catch ( IllegalArgumentException iae ) - { - log( LogService.LOG_ERROR, - "Unexpected configuration property problem when updating service registration", - iae ); - } - catch ( Throwable t ) - { - log( LogService.LOG_ERROR, "Unexpected problem when updating service registration", - t ); - } - } + updateServiceRegistration(); // 7. everything set and done, the component has been udpated return true; Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java Wed May 9 18:25:22 2012 @@ -364,7 +364,7 @@ public class ComponentMetadata /** * Returns <code>true</code> if the metadata declaration has used the - * Declarative Services version 1.1-felixnamespace or a later namespace. + * Declarative Services version 1.1-felix namespace or a later namespace. * * @see <a href="https://issues.apache.org/jira/browse/FELIX-1893">FELIX-1893</a> */ @@ -375,6 +375,28 @@ public class ComponentMetadata /** + * Returns <code>true</code> if the metadata declaration has used the + * Declarative Services version 1.2 namespace or a later namespace. + */ + public boolean isDS12() + { + return getNamespaceCode() >= XmlHandler.DS_VERSION_1_2; + } + + + /** + * Returns <code>true</code> if the metadata declaration has used the + * Declarative Services version 1.2-felix namespace or a later namespace. + * + * @see <a href="https://issues.apache.org/jira/browse/FELIX-3377">FELIX-3377</a> + */ + public boolean isDS12Felix() + { + return getNamespaceCode() >= XmlHandler.DS_VERSION_1_2_FELIX; + } + + + /** * Returns the name of the component * * @return A string containing the name of the component Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/XmlHandler.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/XmlHandler.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/XmlHandler.java (original) +++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/XmlHandler.java Wed May 9 18:25:22 2012 @@ -54,6 +54,12 @@ public class XmlHandler implements KXml2 // Namespace URI of DS 1.1-felix (see FELIX-1893) public static final String NAMESPACE_URI_1_1_FELIX = "http://felix.apache.org/xmlns/scr/v1.1.0-felix"; + // Namespace URI of DS 1.2 + public static final String NAMESPACE_URI_1_2 = "http://www.osgi.org/xmlns/scr/v1.2.0"; + + // Namespace URI of DS 1.2-felix (see FELIX-3377) + public static final String NAMESPACE_URI_1_2_FELIX = "http://felix.apache.org/xmlns/scr/v1.2.0-felix"; + // namespace code for non-DS namespace public static final int DS_VERSION_NONE = -1; @@ -66,6 +72,12 @@ public class XmlHandler implements KXml2 // namespace code for the DS 1.1-felix specification public static final int DS_VERSION_1_1_FELIX = 2; + // namespace code for the DS 1.2 specification + public static final int DS_VERSION_1_2 = 3; + + // namespace code for the DS 1.1-felix specification + public static final int DS_VERSION_1_2_FELIX = 4; + // mapping of namespace URI to namespace code private static final Map NAMESPACE_CODE_MAP; @@ -103,6 +115,8 @@ public class XmlHandler implements KXml2 NAMESPACE_CODE_MAP.put( NAMESPACE_URI, new Integer( DS_VERSION_1_0 ) ); NAMESPACE_CODE_MAP.put( NAMESPACE_URI_1_1, new Integer( DS_VERSION_1_1 ) ); NAMESPACE_CODE_MAP.put( NAMESPACE_URI_1_1_FELIX, new Integer( DS_VERSION_1_1_FELIX ) ); + NAMESPACE_CODE_MAP.put( NAMESPACE_URI_1_2, new Integer( DS_VERSION_1_2 ) ); + NAMESPACE_CODE_MAP.put( NAMESPACE_URI_1_2_FELIX, new Integer( DS_VERSION_1_2_FELIX ) ); } Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/ActivateMethodTest.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/ActivateMethodTest.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/ActivateMethodTest.java (original) +++ felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/ActivateMethodTest.java Wed May 9 18:25:22 2012 @@ -55,7 +55,7 @@ public class ActivateMethodTest extends { super.setUp(); - m_ctx = (ComponentContext) EasyMock.createNiceMock( ComponentContext.class ); + m_ctx = (ComponentContext) EasyMock.createNiceMock(ComponentContext.class); EasyMock.expect( m_ctx.getProperties() ).andReturn( new Hashtable() ).anyTimes(); EasyMock.replay( new Object[] { m_ctx } ); @@ -272,7 +272,7 @@ public class ActivateMethodTest extends }; ImmediateComponentManager icm = new ImmediateComponentManager( null, null, metadata ); ActivateMethod am = new ActivateMethod( icm, methodName, methodName != null, obj.getClass() ); - am.invoke( obj, new ActivateMethod.ActivatorParameter( m_ctx, -1 ), false ); + am.invoke( obj, new ActivateMethod.ActivatorParameter( m_ctx, -1 ), null ); Method m = get(am, "m_method"); assertNotNull( m ); assertEquals( methodName, m.getName() ); @@ -300,7 +300,7 @@ public class ActivateMethodTest extends }; ImmediateComponentManager icm = new ImmediateComponentManager( null, null, metadata ); ActivateMethod am = new ActivateMethod( icm, methodName, methodName != null, obj.getClass() ); - am.invoke( obj, new ActivateMethod.ActivatorParameter( m_ctx, -1 ), false ); + am.invoke( obj, new ActivateMethod.ActivatorParameter( m_ctx, -1 ), null ); assertNull( get( am, "m_method" ) ); assertNull( obj.getCalledMethod() ); } @@ -310,7 +310,7 @@ public class ActivateMethodTest extends throws NoSuchMethodException { Method method = ACCEPT_METHOD_CLASS.getDeclaredMethod( methodName, null ); - boolean accepted = BaseMethod.accept( method, acceptPrivate, acceptPackage ); + boolean accepted = BaseMethod.accept( method, acceptPrivate, acceptPackage, false ); assertEquals( expected, accepted ); } Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java (original) +++ felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java Wed May 9 18:25:22 2012 @@ -441,7 +441,7 @@ public class BindMethodTest extends Test ImmediateComponentManager icm = new ImmediateComponentManager( null, null, metadata ); BindMethod bm = new BindMethod( icm, methodName, component.getClass(), "reference", FakeService.class.getName() ); - bm.invoke( component, m_service, true ); + bm.invoke( component, m_service, null ); assertEquals( expectCallPerformed, component.callPerformed ); } } Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/metadata/XmlHandlerTest.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/metadata/XmlHandlerTest.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/metadata/XmlHandlerTest.java (original) +++ felix/trunk/scr/src/test/java/org/apache/felix/scr/impl/metadata/XmlHandlerTest.java Wed May 9 18:25:22 2012 @@ -106,7 +106,7 @@ public class XmlHandlerTest extends Test final List metadataList = readMetadataFromString( "<scr:component xmlns:scr=\"http://www.osgi.org/xmlns/scr/v1.1.0\" name=\"n\" ><implementation class=\"n\"/></scr:component>" ); assertEquals( "1 Descriptor expected", 1, metadataList.size() ); final ComponentMetadata metadata = ( ComponentMetadata ) metadataList.get( 0 ); - assertEquals( "Expect NS 1.0.0", XmlHandler.DS_VERSION_1_1, metadata.getNamespaceCode() ); + assertEquals( "Expect NS 1.1.0", XmlHandler.DS_VERSION_1_1, metadata.getNamespaceCode() ); } @@ -115,7 +115,25 @@ public class XmlHandlerTest extends Test final List metadataList = readMetadataFromString( "<scr:component xmlns:scr=\"http://felix.apache.org/xmlns/scr/v1.1.0-felix\" name=\"n\" ><implementation class=\"n\"/></scr:component>" ); assertEquals( "1 Descriptor expected", 1, metadataList.size() ); final ComponentMetadata metadata = ( ComponentMetadata ) metadataList.get( 0 ); - assertEquals( "Expect NS 1.0.0", XmlHandler.DS_VERSION_1_1_FELIX, metadata.getNamespaceCode() ); + assertEquals( "Expect NS 1.1.0-felix", XmlHandler.DS_VERSION_1_1_FELIX, metadata.getNamespaceCode() ); + } + + + public void test_namespace_1_2_0() throws Exception + { + final List metadataList = readMetadataFromString( "<scr:component xmlns:scr=\"http://www.osgi.org/xmlns/scr/v1.2.0\" name=\"n\" ><implementation class=\"n\"/></scr:component>" ); + assertEquals( "1 Descriptor expected", 1, metadataList.size() ); + final ComponentMetadata metadata = ( ComponentMetadata ) metadataList.get( 0 ); + assertEquals( "Expect NS 1.2.0", XmlHandler.DS_VERSION_1_2, metadata.getNamespaceCode() ); + } + + + public void test_namespace_1_2_0_felix() throws Exception + { + final List metadataList = readMetadataFromString( "<scr:component xmlns:scr=\"http://felix.apache.org/xmlns/scr/v1.2.0-felix\" name=\"n\" ><implementation class=\"n\"/></scr:component>" ); + assertEquals( "1 Descriptor expected", 1, metadataList.size() ); + final ComponentMetadata metadata = ( ComponentMetadata ) metadataList.get( 0 ); + assertEquals( "Expect NS 1.2.0-felix", XmlHandler.DS_VERSION_1_2_FELIX, metadata.getNamespaceCode() ); } Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentConfigurationTest.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentConfigurationTest.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentConfigurationTest.java (original) +++ felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentConfigurationTest.java Wed May 9 18:25:22 2012 @@ -35,7 +35,7 @@ public class ComponentConfigurationTest static { // uncomment to enable debugging of this test class - // paxRunnerVmOption = DEBUG_VM_OPTION; + // paxRunnerVmOption = DEBUG_VM_OPTION; } Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/MutablePropertiesTest.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/MutablePropertiesTest.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/MutablePropertiesTest.java (original) +++ felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/MutablePropertiesTest.java Wed May 9 18:25:22 2012 @@ -30,6 +30,7 @@ import org.apache.felix.scr.integration. import org.junit.Test; import org.junit.runner.RunWith; import org.ops4j.pax.exam.junit.JUnit4TestRunner; +import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; @@ -40,20 +41,22 @@ public class MutablePropertiesTest exten static { // uncomment to enable debugging of this test class -// paxRunnerVmOption = DEBUG_VM_OPTION; + // paxRunnerVmOption = DEBUG_VM_OPTION; descriptorFile = "/integration_test_mutable_properties.xml"; } @Test - public void test_mutable_properties() + public void test_mutable_properties() throws InvalidSyntaxException { final Component component = findComponentByName( "components.mutable.properties" ); TestCase.assertNotNull( component ); TestCase.assertEquals( Component.STATE_REGISTERED, component.getState() ); - ServiceReference serviceReference = bundleContext.getServiceReference( MutatingService.class.getName() ); + ServiceReference[] serviceReferences = bundleContext.getServiceReferences( MutatingService.class.getName(), "(service.pid=components.mutable.properties)" ); + TestCase.assertEquals( 1, serviceReferences.length ); + ServiceReference serviceReference = serviceReferences[0]; checkProperties( serviceReference, 8, "otherValue", "p1", "p2" ); //update theValue @@ -62,20 +65,52 @@ public class MutablePropertiesTest exten TestCase.assertEquals( Component.STATE_ACTIVE, component.getState() ); Dictionary d = new Hashtable(Collections.singletonMap( PROP_NAME, "anotherValue" )); s.updateProperties(d); - checkProperties(serviceReference, 8, "anotherValue", "p1", "p2"); + checkProperties(serviceReference, 5, "anotherValue", "p1", "p2"); //configure with configAdmin configure( "components.mutable.properties" ); delay(); - checkProperties(serviceReference, 8, PROP_NAME, "p1", "p2"); + //no change + checkProperties(serviceReference, 5, "anotherValue", "p1", "p2"); - //check that a property from config admin can't be changed + //check that removing config switches back to defaults modified by config admin + s.updateProperties(null); + checkProperties( serviceReference, 8, "theValue", "p1", "p2" ); + + bundleContext.ungetService(serviceReference); + } + + @Test + public void test_mutable_properties_returned() throws InvalidSyntaxException + { + final Component component = findComponentByName( "components.mutable.properties2" ); + TestCase.assertNotNull( component ); + TestCase.assertEquals( Component.STATE_REGISTERED, component.getState() ); + + ServiceReference[] serviceReferences = bundleContext.getServiceReferences( MutatingService.class.getName(), "(service.pid=components.mutable.properties2)" ); + TestCase.assertEquals( 1, serviceReferences.length ); + ServiceReference serviceReference = serviceReferences[0]; + checkProperties( serviceReference, 8, "otherValue", "p1", "p2" ); + + //update theValue + MutatingService s = ( MutatingService ) bundleContext.getService( serviceReference ); + Assert.assertNotNull(s); + checkProperties( serviceReference, 8, "anotherValue1", "p1", "p2" ); + TestCase.assertEquals( Component.STATE_ACTIVE, component.getState() ); + Dictionary d = new Hashtable(Collections.singletonMap( PROP_NAME, "anotherValue" )); s.updateProperties(d); - checkProperties(serviceReference, 8, PROP_NAME, "p1", "p2"); + checkProperties(serviceReference, 5, "anotherValue", "p1", "p2"); + + //configure with configAdmin + configure( "components.mutable.properties2" ); + delay(); + delay(); + //no change + checkProperties(serviceReference, 8, "anotherValue2", "p1", "p2"); - //check that another one can - s.updateProperties(new Hashtable(Collections.singletonMap( "p1", "changed" ))); - checkProperties(serviceReference, 8, PROP_NAME, "changed", "p2"); + //check that removing config switches back to defaults modified by config admin + s.updateProperties(null); + checkProperties( serviceReference, 8, "theValue", "p1", "p2" ); bundleContext.ungetService(serviceReference); } @@ -83,8 +118,10 @@ public class MutablePropertiesTest exten private void checkProperties(ServiceReference serviceReference, int count, String otherValue, String p1, String p2) { Assert.assertEquals("wrong property count", count, serviceReference.getPropertyKeys().length); Assert.assertEquals(otherValue, serviceReference.getProperty(PROP_NAME)); - Assert.assertEquals(p1, serviceReference.getProperty("p1")); - Assert.assertEquals(p2, serviceReference.getProperty("p2")); + if ( count > 5 ) { + Assert.assertEquals(p1, serviceReference.getProperty("p1")); + Assert.assertEquals(p2, serviceReference.getProperty("p2")); + } } Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/MutatingServiceImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/MutatingServiceImpl.java?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/MutatingServiceImpl.java (original) +++ felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/MutatingServiceImpl.java Wed May 9 18:25:22 2012 @@ -20,6 +20,8 @@ package org.apache.felix.scr.integration import java.util.Dictionary; +import java.util.Hashtable; +import java.util.Map; import org.apache.felix.scr.component.ExtComponentContext; import org.osgi.service.component.ComponentContext; @@ -39,8 +41,30 @@ public class MutatingServiceImpl impleme } + private Map activateMutate( ComponentContext activateContext ) + { + this.activateContext = activateContext; + Map result = new Hashtable( (Map )activateContext.getProperties() ); + result.put( "theValue", "anotherValue1"); + return result; + } + + private Map modifiedMutate( ComponentContext activateContext ) + { + Map result = new Hashtable( (Map )activateContext.getProperties() ); + result.put( "theValue", "anotherValue2"); + return result; + } + + private Map deactivateMutate( ComponentContext activateContext ) + { + Map result = new Hashtable( (Map )activateContext.getProperties() ); + result.put( "theValue", "anotherValue3"); + return result; + } + public void updateProperties(Dictionary changes) { - ((ExtComponentContext)activateContext).updateProperties(changes); + ((ExtComponentContext)activateContext).setServiceProperties(changes); } } Modified: felix/trunk/scr/src/test/resources/integration_test_mutable_properties.xml URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/resources/integration_test_mutable_properties.xml?rev=1336331&r1=1336330&r2=1336331&view=diff ============================================================================== --- felix/trunk/scr/src/test/resources/integration_test_mutable_properties.xml (original) +++ felix/trunk/scr/src/test/resources/integration_test_mutable_properties.xml Wed May 9 18:25:22 2012 @@ -19,7 +19,7 @@ --> <components> <scr:component name="components.mutable.properties" - xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" + xmlns:scr="http://felix.apache.org/xmlns/scr/v1.2.0-felix" enabled="true" configuration-policy="optional" activate="activate" @@ -33,4 +33,20 @@ <property name="p1" value="p1" /> <property name="p2" value="p2" /> </scr:component> + <scr:component name="components.mutable.properties2" + xmlns:scr="http://felix.apache.org/xmlns/scr/v1.2.0-felix" + enabled="true" + configuration-policy="optional" + activate="activateMutate" + modified="modifiedMutate" + deactivate="deactivateMutate"> + <implementation class="org.apache.felix.scr.integration.components.MutatingServiceImpl" /> + <service> + <provide interface="org.apache.felix.scr.integration.components.MutatingService" /> + </service> + <property name="service.pid" value="components.mutable.properties2" /> + <property name="theValue" value="otherValue" /> + <property name="p1" value="p1" /> + <property name="p2" value="p2" /> + </scr:component> </components>
