You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2014/11/10 06:51:05 UTC
svn commit: r1637793 - in
/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl: helper/ manager/
metadata/ runtime/
Author: cziegeler
Date: Mon Nov 10 05:51:04 2014
New Revision: 1637793
URL: http://svn.apache.org/r1637793
Log:
FELIX-4631 : [DS][R6/RFC212] Implement field injection. WiP
Added:
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/InitReferenceMethod.java (with props)
Modified:
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethods.java
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ClassUtils.java
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldHandler.java
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldMethods.java
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ReferenceMethods.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/SingleComponentManager.java
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java
felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java
Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethods.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethods.java?rev=1637793&r1=1637792&r2=1637793&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethods.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethods.java Mon Nov 10 05:51:04 2014
@@ -71,4 +71,9 @@ public class BindMethods implements Refe
{
return m_updated;
}
+
+ public InitReferenceMethod getInit()
+ {
+ return null;
+ }
}
Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ClassUtils.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ClassUtils.java?rev=1637793&r1=1637792&r2=1637793&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ClassUtils.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ClassUtils.java Mon Nov 10 05:51:04 2014
@@ -20,6 +20,7 @@ package org.apache.felix.scr.impl.helper
import java.util.Collection;
+import java.util.List;
import java.util.Map;
import org.apache.felix.scr.impl.Activator;
@@ -45,6 +46,7 @@ public class ClassUtils
public static final Class<?> MAP_ENTRY_CLASS = Map.Entry.class;
public static final Class<?> COLLECTION_CLASS = Collection.class;
+ public static final Class<?> LIST_CLASS = List.class;
static {
Class<?> serviceObjectsClass = null;
Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldHandler.java?rev=1637793&r1=1637792&r2=1637793&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldHandler.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldHandler.java Mon Nov 10 05:51:04 2014
@@ -24,8 +24,13 @@ import java.lang.reflect.InvocationTarge
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.IdentityHashMap;
+import java.util.List;
import java.util.Map;
+import java.util.concurrent.CopyOnWriteArraySet;
import org.apache.felix.scr.impl.manager.ComponentContextImpl;
import org.apache.felix.scr.impl.manager.RefPair;
@@ -61,8 +66,8 @@ public class FieldHandler
/** State handling. */
private volatile State state;
- /** Last ref pair used to set. */
- private volatile RefPair<?, ?> lastRefPair;
+ /** Mapping of ref pairs to value bound */
+ private final Map<RefPair<?, ?>, Object> boundValues = new IdentityHashMap<RefPair<?,?>, Object>();
/**
* Create a new field handler
@@ -299,6 +304,14 @@ public class FieldHandler
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
{
@@ -310,6 +323,57 @@ public class FieldHandler
return null;
}
+ // if the field is dynamic with the replace strategy it has to be volatile
+ if ( !metadata.isStatic() && metadata.getFieldStrategy().equals(ReferenceMetadata.FIELD_STRATEGY_REPLACE) )
+ {
+ 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.getFieldStrategy().equals(ReferenceMetadata.FIELD_STRATEGY_REPLACE) )
+ {
+ 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.getFieldValueType()) )
+ {
+ valueType = ParamType.serviceType;
+ }
+ else if ( ReferenceMetadata.FIELD_VALUE_TYPE_REFERENCE.equals(metadata.getFieldValueType()) )
+ {
+ valueType = ParamType.serviceReference;
+ }
+ else if ( ReferenceMetadata.FIELD_VALUE_TYPE_SERVICEOBJECTS.equals(metadata.getFieldValueType()) )
+ {
+ valueType = ParamType.serviceObjects;
+ }
+ else if ( ReferenceMetadata.FIELD_VALUE_TYPE_PROPERTIES.equals(metadata.getFieldValueType()) )
+ {
+ valueType = ParamType.map;
+ }
+ else if ( ReferenceMetadata.FIELD_VALUE_TYPE_TUPLE.equals(metadata.getFieldValueType()) )
+ {
+ valueType = ParamType.tuple;
+ }
}
return f;
}
@@ -331,13 +395,72 @@ public class FieldHandler
case tuple : final Object tupleKey = new ReadOnlyDictionary<String, Object>( refPair.getRef() );
final Object tupleValue = refPair.getServiceObject(key);
final Map<?, ?> tupleMap = Collections.singletonMap(tupleKey, tupleValue);
- obj = tupleMap.entrySet().iterator().next();
+ obj = tupleMap.entrySet().iterator().next(); // TODO check/make entry comparable
break;
default: obj = null;
}
return obj;
}
+ private boolean initField(final Object componentInstance,
+ final SimpleLogger logger )
+ {
+ try
+ {
+ if ( metadata.isMultiple()
+ && !metadata.isStatic() )
+ {
+ if ( ReferenceMetadata.FIELD_STRATEGY_REPLACE.equals(metadata.getFieldStrategy()) )
+ {
+ 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() {
+ // TODO sort!
+ 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,
@@ -356,29 +479,25 @@ public class FieldHandler
if ( this.metadata.isOptional() && !this.metadata.isStatic() )
{
// we only reset if it was previously set with this value
- if ( refPair == lastRefPair )
+ if ( this.boundValues.size() == 1 )
{
this.setFieldValue(componentInstance, null);
- this.lastRefPair = null;
}
}
- else
- {
- this.lastRefPair = 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() )
{
- final Object obj = getValue(key, refPair);
- this.setFieldValue(componentInstance, obj);
- this.lastRefPair = refPair;
- }
- else
- {
- this.lastRefPair = null;
+ 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
@@ -386,7 +505,69 @@ public class FieldHandler
{
final Object obj = getValue(key, refPair);
this.setFieldValue(componentInstance, obj);
- this.lastRefPair = refPair;
+ 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 ( ReferenceMetadata.FIELD_STRATEGY_REPLACE.equals(metadata.getFieldStrategy()) )
+ {
+ 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 ( ReferenceMetadata.FIELD_STRATEGY_REPLACE.equals(metadata.getFieldStrategy()) )
+ {
+ 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 ( ReferenceMetadata.FIELD_STRATEGY_REPLACE.equals(metadata.getFieldStrategy()) )
+ {
+ this.setFieldValue(componentInstance, getReplaceCollection());
+ }
+ else
+ {
+ @SuppressWarnings("unchecked")
+ final Collection<Object> col = (Collection<Object>)this.getFieldValue(componentInstance);
+ col.add(obj);
+ col.remove(oldObj);
+ }
+ }
}
}
@@ -617,13 +798,16 @@ public class FieldHandler
return this.state.fieldExists( this, logger );
}
- public static final class ReferenceMethodImpl implements ReferenceMethod {
+ 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) {
+ public ReferenceMethodImpl(final METHOD_TYPE mt, final FieldHandler handler)
+ {
this.methodType = mt;
this.handler = handler;
}
@@ -631,7 +815,8 @@ public class FieldHandler
public MethodResult invoke(final Object componentInstance,
final BindParameters rawParameter,
final MethodResult methodCallFailureResult,
- final SimpleLogger logger) {
+ final SimpleLogger logger)
+ {
try
{
return handler.state.invoke( handler,
@@ -652,7 +837,8 @@ public class FieldHandler
public <S, T> boolean getServiceObject(final ComponentContextImpl<S> key,
final RefPair<S, T> refPair,
final BundleContext context,
- final SimpleLogger logger) {
+ final SimpleLogger logger)
+ {
if ( methodType != METHOD_TYPE.UNBIND )
{
//??? this resolves which we need.... better way?
@@ -667,15 +853,37 @@ public class FieldHandler
}
}
- public ReferenceMethod getBind() {
+ public ReferenceMethod getBind()
+ {
return new ReferenceMethodImpl(METHOD_TYPE.BIND, this);
}
- public ReferenceMethod getUnbind() {
+ public ReferenceMethod getUnbind()
+ {
return new ReferenceMethodImpl(METHOD_TYPE.UNBIND, this);
}
- public ReferenceMethod getUpdated() {
+ public ReferenceMethod getUpdated()
+ {
return new ReferenceMethodImpl(METHOD_TYPE.UPDATED, this);
}
+
+ public InitReferenceMethod getInit() {
+ if ( metadata.isMultiple() )
+ {
+ return new InitReferenceMethod()
+ {
+
+ public boolean init(final Object componentInstance, final SimpleLogger logger)
+ {
+ if ( fieldExists( logger) )
+ {
+ return initField(componentInstance, logger);
+ }
+ return false;
+ }
+ };
+ }
+ return null;
+ }
}
Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldMethods.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldMethods.java?rev=1637793&r1=1637792&r2=1637793&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldMethods.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldMethods.java Mon Nov 10 05:51:04 2014
@@ -29,31 +29,43 @@ import org.apache.felix.scr.impl.metadat
*/
public class FieldMethods implements ReferenceMethods
{
- private final FieldHandler handler;
+ 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 )
{
- handler = new FieldHandler(
+ final FieldHandler handler = new FieldHandler(
m_dependencyMetadata,
instanceClass
);
+ bind = handler.getBind();
+ unbind = handler.getUnbind();
+ updated = handler.getUpdated();
+ init = handler.getInit();
}
public ReferenceMethod getBind()
{
- return handler.getBind();
+ return bind;
}
public ReferenceMethod getUnbind()
{
- return handler.getUnbind();
+ return unbind;
}
public ReferenceMethod getUpdated()
{
- return handler.getUpdated();
+ return updated;
+ }
+
+ public InitReferenceMethod getInit()
+ {
+ return init;
}
}
Added: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/InitReferenceMethod.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/InitReferenceMethod.java?rev=1637793&view=auto
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/InitReferenceMethod.java (added)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/InitReferenceMethod.java Mon Nov 10 05:51:04 2014
@@ -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 );
+}
Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/InitReferenceMethod.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/InitReferenceMethod.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/InitReferenceMethod.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ReferenceMethods.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ReferenceMethods.java?rev=1637793&r1=1637792&r2=1637793&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ReferenceMethods.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/helper/ReferenceMethods.java Mon Nov 10 05:51:04 2014
@@ -30,4 +30,7 @@ public interface ReferenceMethods
ReferenceMethod getUnbind();
ReferenceMethod getUpdated();
+
+ /** Optional. */
+ InitReferenceMethod getInit();
}
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=1637793&r1=1637792&r2=1637793&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 Mon Nov 10 05:51:04 2014
@@ -1415,6 +1415,14 @@ public class DependencyManager<S, T> imp
*/
boolean open( ComponentContextImpl<S> componentContext, EdgeInfo edgeInfo )
{
+ if ( !invokeInitMethod(componentContext) )
+ {
+ m_componentManager.log( LogService.LOG_DEBUG,
+ "For dependency {0}, failed to initialize object",
+ new Object[] {getName()}, null );
+ return false;
+ }
+
int serviceCount = 0;
AtomicInteger trackingCount = new AtomicInteger( );
Collection<RefPair<S, T>> refs;
@@ -1518,6 +1526,24 @@ public class DependencyManager<S, T> imp
}
/**
+ * Calls the optional init reference method.
+ */
+ boolean invokeInitMethod( final ComponentContextImpl<S> componentContext )
+ {
+ // The bind method is only invoked if the implementation object is not
+ // null. This is valid for both immediate and delayed components
+ if ( m_bindMethods.getInit() != null )
+ {
+ final Object componentInstance = componentContext.getImplementationObject( false );
+ if ( componentInstance != null )
+ {
+ return m_bindMethods.getInit().init(componentInstance, m_componentManager);
+ }
+ }
+ return true;
+ }
+
+ /**
* Calls the bind method. In case there is an exception while calling the
* bind method, the service is not considered to be bound to the instance
* object
Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java?rev=1637793&r1=1637792&r2=1637793&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/SingleComponentManager.java Mon Nov 10 05:51:04 2014
@@ -25,7 +25,6 @@ import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.felix.scr.impl.BundleComponentActivator;
@@ -43,7 +42,6 @@ import org.osgi.service.component.Compon
import org.osgi.service.component.ComponentInstance;
import org.osgi.service.log.LogService;
import org.osgi.util.promise.Deferred;
-import org.osgi.util.promise.Promise;
/**
@@ -61,7 +59,7 @@ public class SingleComponentManager<S> e
// Merged properties from xml descriptor and all configurations
private Map<String, Object> m_configurationProperties;
-
+
// optional properties provided in the ComponentFactory.newInstance method
private Map<String, Object> m_factoryProperties;
@@ -73,7 +71,7 @@ public class SingleComponentManager<S> e
private Dictionary<String, Object> m_serviceProperties;
private final ThreadLocal<Boolean> m_circularReferences = new ThreadLocal<Boolean>();
-
+
/**
* The constructor receives both the activator and the metadata
* @param componentMethods
@@ -82,13 +80,14 @@ public class SingleComponentManager<S> e
{
this(container, componentMethods, false);
}
-
+
public SingleComponentManager( ComponentContainer<S> container, ComponentMethods componentMethods,
boolean factoryInstance )
{
super( container, componentMethods, factoryInstance );
}
+ @Override
void clear()
{
m_container.disposed( this );
@@ -145,6 +144,7 @@ public class SingleComponentManager<S> e
}
+ @Override
protected void deleteComponent( int reason )
{
if ( !isStateLocked() )
@@ -245,7 +245,7 @@ public class SingleComponentManager<S> e
log( LogService.LOG_ERROR, "Error during instantiation of the implementation object", t );
return null;
}
-
+
componentContext.setImplementationObject(implementationObject);
// 3. set the implementation object prematurely
@@ -353,11 +353,13 @@ public class SingleComponentManager<S> e
}
+ @Override
boolean hasInstance()
{
return m_componentContext != null;
}
+ @Override
<T> void invokeBindMethod( DependencyManager<S, T> dependencyManager, RefPair<S, T> refPair, int trackingCount )
{
ComponentContextImpl<S> componentContext = m_componentContext;
@@ -368,6 +370,7 @@ public class SingleComponentManager<S> e
}
}
+ @Override
<T> void invokeUpdatedMethod( DependencyManager<S, T> dependencyManager, RefPair<S, T> refPair, int trackingCount )
{
ComponentContextImpl<S> componentContext = m_componentContext;
@@ -378,6 +381,7 @@ public class SingleComponentManager<S> e
}
}
+ @Override
<T> void invokeUnbindMethod( DependencyManager<S, T> dependencyManager, RefPair<S, T> oldRefPair, int trackingCount )
{
ComponentContextImpl<S> componentContext = m_componentContext;
@@ -394,6 +398,7 @@ public class SingleComponentManager<S> e
}
+ @Override
void registerComponentId()
{
super.registerComponentId();
@@ -401,6 +406,7 @@ public class SingleComponentManager<S> e
}
+ @Override
void unregisterComponentId()
{
super.unregisterComponentId();
@@ -417,6 +423,7 @@ public class SingleComponentManager<S> e
*
* @return a private map of component properties
*/
+ @Override
public Map<String, Object> getProperties()
{
@@ -426,7 +433,7 @@ public class SingleComponentManager<S> e
// 1. Merge all the config properties
Map<String, Object> props = new HashMap<String, Object>();
- if ( m_configurationProperties != null )
+ if ( m_configurationProperties != null )
{
props.putAll(m_configurationProperties);
}
@@ -436,7 +443,7 @@ public class SingleComponentManager<S> e
if (getComponentMetadata().getDSVersion().isDS13() && m_factoryProperties.containsKey(Constants.SERVICE_PID))
{
List<String> servicePids = (List<String>) m_configurationProperties.get(Constants.SERVICE_PID);
- if (servicePids == null)
+ if (servicePids == null)
{
servicePids = new ArrayList<String>();
}
@@ -458,6 +465,7 @@ public class SingleComponentManager<S> e
return m_properties;
}
+ @Override
public void setServiceProperties( Dictionary<String, ?> serviceProperties )
{
if ( serviceProperties == null || serviceProperties.isEmpty() )
@@ -475,6 +483,7 @@ public class SingleComponentManager<S> e
updateServiceRegistration();
}
+ @Override
public Dictionary<String, Object> getServiceProperties()
{
if ( m_serviceProperties != null )
@@ -533,6 +542,7 @@ public class SingleComponentManager<S> e
* @param changeCount Change count for the configuration
* @param targetedPID TargetedPID for the configuration
*/
+ @Override
public void reconfigure( Map<String, Object> configuration, boolean configurationDeleted )
{
// store the properties
@@ -622,7 +632,7 @@ public class SingleComponentManager<S> e
if ( configurationDeleted && !getComponentMetadata().isDeleteCallsModify()){
return false;
}
-
+
// 1. no live update if there is no declared method
if ( getComponentMetadata().getModified() == null )
{
@@ -747,7 +757,7 @@ public class SingleComponentManager<S> e
}
}
-
+
@Override
boolean getServiceInternal()
{
@@ -755,7 +765,7 @@ public class SingleComponentManager<S> e
{
log( LogService.LOG_ERROR, "Circular reference detected, getService returning null", null );
dumpThreads();
- return false;
+ return false;
}
m_circularReferences.set( Boolean.TRUE );
try
Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java?rev=1637793&r1=1637792&r2=1637793&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/ReferenceMetadata.java Mon Nov 10 05:51:04 2014
@@ -725,6 +725,14 @@ public class ReferenceMetadata
}
}
+ // static references only allow replace strateg
+ if ( m_isStatic )
+ {
+ if ( ! m_field_strategy.equals(FIELD_STRATEGY_REPLACE) )
+ {
+ throw componentMetadata.validationFailure( "Field strategy update not allowed for static field references." );
+ }
+ }
}
Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java?rev=1637793&r1=1637792&r2=1637793&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/runtime/ServiceComponentRuntimeImpl.java Mon Nov 10 05:51:04 2014
@@ -18,7 +18,6 @@
*/
package org.apache.felix.scr.impl.runtime;
-import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -49,20 +48,20 @@ import org.osgi.util.promise.Promise;
public class ServiceComponentRuntimeImpl implements ServiceComponentRuntime
{
-
+
private static final String[] EMPTY = {};
-
+
private final BundleContext context;
private final ComponentRegistry componentRegistry;
- public ServiceComponentRuntimeImpl(BundleContext context,ComponentRegistry componentRegistry)
+ public ServiceComponentRuntimeImpl(BundleContext context,ComponentRegistry componentRegistry)
{
this.context = context;
this.componentRegistry = componentRegistry;
}
- public Collection<ComponentDescriptionDTO> getComponentDescriptionDTOs(Bundle... bundles)
+ public Collection<ComponentDescriptionDTO> getComponentDescriptionDTOs(Bundle... bundles)
{
List<ComponentHolder<?>> holders;
if (bundles == null || bundles.length == 0)
@@ -89,13 +88,13 @@ public class ServiceComponentRuntimeImpl
{
return holderToDescription(holder);
}
- else
+ else
{
return null;
}
}
- public Collection<ComponentConfigurationDTO> getComponentConfigurationDTOs(ComponentDescriptionDTO description)
+ public Collection<ComponentConfigurationDTO> getComponentConfigurationDTOs(ComponentDescriptionDTO description)
{
if ( description == null)
{
@@ -113,13 +112,13 @@ public class ServiceComponentRuntimeImpl
return result;
}
- public boolean isComponentEnabled(ComponentDescriptionDTO description)
+ public boolean isComponentEnabled(ComponentDescriptionDTO description)
{
ComponentHolder<?> holder = getHolderFromDescription( description);
return holder.isEnabled();
}
- public Promise<Void> enableComponent(ComponentDescriptionDTO description)
+ public Promise<Void> enableComponent(ComponentDescriptionDTO description)
{
ComponentHolder<?> holder = getHolderFromDescription( description);
return holder.enableComponents(true);
@@ -130,8 +129,8 @@ public class ServiceComponentRuntimeImpl
ComponentHolder<?> holder = getHolderFromDescription( description);
return holder.disableComponents(true); //synchronous
}
-
- private ComponentConfigurationDTO managerToConfiguration(ComponentManager<?> manager, ComponentDescriptionDTO description)
+
+ private ComponentConfigurationDTO managerToConfiguration(ComponentManager<?> manager, ComponentDescriptionDTO description)
{
ComponentConfigurationDTO dto = new ComponentConfigurationDTO();
dto.satisfiedReferences = satisfiedRefManagersToDTO(manager.getReferenceManagers());
@@ -167,7 +166,7 @@ public class ServiceComponentRuntimeImpl
return dtos.toArray( new SatisfiedReferenceDTO[dtos.size()] );
}
- private UnsatisfiedReferenceDTO[] unsatisfiedRefManagersToDTO(List<? extends ReferenceManager<?, ?>> referenceManagers)
+ private UnsatisfiedReferenceDTO[] unsatisfiedRefManagersToDTO(List<? extends ReferenceManager<?, ?>> referenceManagers)
{
List<UnsatisfiedReferenceDTO> dtos = new ArrayList<UnsatisfiedReferenceDTO>();
for (ReferenceManager<?, ?> ref: referenceManagers)
@@ -243,7 +242,7 @@ public class ServiceComponentRuntimeImpl
dto.serviceInterfaces = m.getServiceMetadata() == null? EMPTY: m.getServiceMetadata().getProvides();
return dto;
}
-
+
private Map<String, Object> deepCopy(Map<String, Object> source)
{
HashMap<String, Object> result = new HashMap<String, Object>(source.size());
@@ -291,17 +290,17 @@ public class ServiceComponentRuntimeImpl
}
return String.valueOf(source);
}
-
+
boolean checkType(Class<?> type)
{
if (type == String.class) return true;
if (type == Boolean.class) return true;
if (Number.class.isAssignableFrom(type)) return true;
if (DTO.class.isAssignableFrom(type)) return true;
- return false;
+ return false;
}
-
- private ReferenceDTO[] refsToDTO(List<ReferenceMetadata> dependencies)
+
+ private ReferenceDTO[] refsToDTO(List<ReferenceMetadata> dependencies)
{
ReferenceDTO[] dtos = new ReferenceDTO[dependencies.size()];
int i = 0;
@@ -310,11 +309,27 @@ public class ServiceComponentRuntimeImpl
ReferenceDTO dto = new ReferenceDTO();
dto.bind = r.getBind();
dto.cardinality = r.getCardinality();
+ dto.field = r.getField();
dto.interfaceName = r.getInterface();
dto.name = r.getName();
dto.policy = r.getPolicy();
dto.policyOption = r.getPolicyOption();
dto.scope = r.getScope().name();
+ if ( r.getField() != null )
+ {
+ if ( ReferenceMetadata.FIELD_STRATEGY_REPLACE.equals(r.getFieldStrategy()) )
+ {
+ dto.strategy = ReferenceDTO.STRATEGY_FIELD_REPLACE;
+ }
+ else
+ {
+ dto.strategy = ReferenceDTO.STRATEGY_FIELD_UPDATE;
+ }
+ }
+ else
+ {
+ dto.strategy = r.getBind() != null ? ReferenceDTO.STRATEGY_METHOD : ReferenceDTO.STRATEGY_LOOKUP;
+ }
dto.target = r.getTarget();
dto.unbind = r.getUnbind();
dto.updated = r.getUpdated();
@@ -323,7 +338,7 @@ public class ServiceComponentRuntimeImpl
return dtos;
}
- private BundleDTO bundleToDTO(BundleContext bundleContext)
+ private BundleDTO bundleToDTO(BundleContext bundleContext)
{
if (bundleContext == null)
{