FELIX-4631 : [DS][R6/RFC212] Implement field injection.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1638284 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldHandler.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldHandler.java
index 0592088..c8e07a2 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldHandler.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldHandler.java
@@ -27,15 +27,17 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.IdentityHashMap;
+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;
/**
@@ -67,7 +69,15 @@
private volatile State state;
/** Mapping of ref pairs to value bound */
- private final Map<RefPair<?, ?>, Object> boundValues = new IdentityHashMap<RefPair<?,?>, Object>();
+ 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
@@ -378,24 +388,75 @@
return f;
}
- private enum METHOD_TYPE {
+ 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 RefPair<?, ?> refPair)
+ {
final Object obj;
- switch ( this.valueType ) {
+ switch ( this.valueType )
+ {
case serviceType : obj = refPair.getServiceObject(key); break;
case serviceReference : obj = refPair.getRef(); break;
case serviceObjects : obj = refPair.getServiceObjects(); 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);
- final Map<?, ?> tupleMap = Collections.singletonMap(tupleKey, tupleValue);
- obj = tupleMap.entrySet().iterator().next(); // TODO check/make entry comparable
+ obj = new MapEntryImpl(tupleKey, tupleValue, refPair.getRef());
break;
default: obj = null;
}
@@ -451,8 +512,8 @@
return true;
}
- private Collection<Object> getReplaceCollection() {
- // TODO sort!
+ private Collection<Object> getReplaceCollection()
+ {
final List<Object> objects = new ArrayList<Object>();
for(final Object val : this.boundValues.values())
{
@@ -577,11 +638,16 @@
private void setFieldValue(final Object componentInstance, final Object value)
throws InvocationTargetException
{
- try {
+ try
+ {
field.set(componentInstance, value);
- } catch ( final IllegalArgumentException iae ) {
+ }
+ catch ( final IllegalArgumentException iae )
+ {
throw new InvocationTargetException(iae);
- } catch ( final IllegalAccessException iae ) {
+ }
+ catch ( final IllegalAccessException iae )
+ {
throw new InvocationTargetException(iae);
}
}
@@ -589,11 +655,16 @@
private Object getFieldValue(final Object componentInstance)
throws InvocationTargetException
{
- try {
+ try
+ {
return field.get(componentInstance);
- } catch ( final IllegalArgumentException iae ) {
+ }
+ catch ( final IllegalArgumentException iae )
+ {
throw new InvocationTargetException(iae);
- } catch ( final IllegalAccessException iae ) {
+ }
+ catch ( final IllegalAccessException iae )
+ {
throw new InvocationTargetException(iae);
}
}
@@ -868,7 +939,8 @@
return new ReferenceMethodImpl(METHOD_TYPE.UPDATED, this);
}
- public InitReferenceMethod getInit() {
+ public InitReferenceMethod getInit()
+ {
if ( metadata.isMultiple() )
{
return new InitReferenceMethod()