FELIX-4631 : [DS][R6/RFC212] Implement field injection. WiP
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1637753 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 c5e0a86..be1ece5 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
@@ -24,81 +24,61 @@
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.Map;
import org.apache.felix.scr.impl.manager.ComponentContextImpl;
import org.apache.felix.scr.impl.manager.RefPair;
-import org.apache.felix.scr.impl.metadata.ReferenceMetadata.ReferenceScope;
import org.osgi.framework.BundleContext;
import org.osgi.service.log.LogService;
-
/**
- * Component method to be invoked on service (un)binding.
+ * Handler for field references
*/
public class FieldHandler
{
-
- // class references to simplify parameter checking
- protected static final Class<?> MAP_CLASS = Map.class;
-
+ /** The name of the field. */
private final String fieldName;
+
+ /** The component class. */
private final Class<?> componentClass;
+ /** The field used for the injection. */
private volatile Field field;
+ /** State handling. */
private volatile State state;
+ /**
+ * Create a new field handler
+ * @param fieldName name of the field
+ * @param componentClass component class
+ * @param referenceClassName service class name
+ */
public FieldHandler( final String fieldName, final Class<?> componentClass,
- final String referenceClassName, final ReferenceScope referenceScope)
+ final String referenceClassName)
{
this.fieldName = fieldName;
this.componentClass = componentClass;
this.state = NotResolved.INSTANCE;
}
- protected final String getFieldName()
- {
- return this.fieldName;
- }
-
- final Field getField()
- {
- return this.field;
- }
-
- protected final Class<?> getComponentClass()
- {
- return this.componentClass;
- }
-
-
- void setField( final Field f, final SimpleLogger 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 );
+ 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[]
- { getFieldName() }, null);
+ new Object[] { this.fieldName }, null);
}
}
-
- State getState()
- {
- return state;
- }
-
-
/**
* Finds the field named in the {@link #fieldName} field in the given
* <code>targetClass</code>. If the target class has no acceptable method
@@ -113,7 +93,7 @@
*/
private Field findField( final SimpleLogger logger ) throws InvocationTargetException
{
- final Class<?> targetClass = getComponentClass();
+ final Class<?> targetClass = this.componentClass;
final ClassLoader targetClasslLoader = targetClass.getClassLoader();
final String targetPackage = getPackageName( targetClass );
Class<?> theClass = targetClass;
@@ -125,12 +105,12 @@
if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
{
logger.log( LogService.LOG_DEBUG,
- "Locating field " + getFieldName() + " in class " + theClass.getName(), null );
+ "Locating field " + this.fieldName + " in class " + theClass.getName(), null );
}
try
{
- final Field field = doFindField( theClass, acceptPrivate, acceptPackage, logger );
+ final Field field = getField( theClass, acceptPrivate, acceptPackage, logger );
if ( field != null )
{
return field;
@@ -141,7 +121,7 @@
// 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[]
- { getFieldName(), theClass.getName(), targetClass.getName() }, null );
+ { this.fieldName, theClass.getName(), targetClass.getName() }, null );
break;
}
@@ -166,40 +146,32 @@
return null;
}
-
/**
- * Finds the method named in the {@link #m_methodName} field in the given
- * <code>targetClass</code>. If the target class has no acceptable method
- * the class hierarchy is traversed until a method is found or the root
- * of the class hierarchy is reached without finding a method.
+ * 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 methods should be
+ * @param acceptPrivate <code>true</code> if private fields should be
* considered.
- * @param acceptPackage <code>true</code> if package private methods should
+ * @param acceptPackage <code>true</code> if package private fields should
* be considered.
* @param logger
- * @return The requested method or <code>null</code> if no acceptable method
+ * @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 method.
+ * trying to find the requested field.
*/
- private Field doFindField( Class<?> targetClass, boolean acceptPrivate, boolean acceptPackage, SimpleLogger logger )
- throws SuitableMethodNotAccessibleException, InvocationTargetException
- {
- // TODO - check field type(!)
- return getField( targetClass, this.getFieldName(), acceptPrivate, acceptPackage, logger);
- }
-
- private Field getField( final Class<?> clazz, final String name, final boolean acceptPrivate,
+ 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( name );
+ final Field field = clazz.getDeclaredField( this.fieldName );
// accept public and protected fields only and ensure accessibility
if ( accept( field, acceptPrivate, acceptPackage ) )
@@ -217,7 +189,7 @@
if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
{
logger.log( LogService.LOG_DEBUG, "Declared Field {0}.{1} not found", new Object[]
- { clazz.getName(), name }, null );
+ { clazz.getName(), this.fieldName }, null );
}
}
catch ( NoClassDefFoundError cdfe )
@@ -228,7 +200,7 @@
if ( logger.isLogEnabled( LogService.LOG_WARNING ) )
{
StringBuffer buf = new StringBuffer();
- buf.append( "Failure loooking up field " ).append( name );
+ buf.append( "Failure loooking up field " ).append( this.fieldName );
buf.append( " in class class " ).append( clazz.getName() ).append( ". Assuming no such field." );
logger.log( LogService.LOG_WARNING, buf.toString(), cdfe );
}
@@ -241,45 +213,13 @@
{
// 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 " + name );
+ throw new InvocationTargetException( throwable, "Unexpected problem trying to get field " + this.fieldName );
}
// caught and ignored exception, assume no field and continue search
return null;
}
-/*
- @Override
- protected Object[] getParameters( Method method, BindParameters bp )
- {
- ComponentContextImpl key = bp.getComponentContext();
- Object[] result = new Object[ m_paramTypes.size()];
- RefPair<?, ?> refPair = bp.getRefPair();
- int i = 0;
- for ( ParamType pt: m_paramTypes ) {
- switch (pt) {
- case serviceReference:
- result[i++] = refPair.getRef();
- break;
- case serviceObjects:
- result[i++] = refPair.getServiceObjects();
- break;
-
- case map:
- result[i++] = new ReadOnlyDictionary<String, Object>( refPair.getRef() );
- break;
-
- case serviceType:
- result[i++] = refPair.getServiceObject(key);
- break;
-
- default: throw new IllegalStateException("unexpected ParamType: " + pt);
-
- }
- }
- return result;
- }
-*/
private enum METHOD_TYPE {
BIND,
UNBIND,
@@ -414,7 +354,7 @@
private synchronized void resolve( final FieldHandler baseMethod, SimpleLogger logger )
{
logger.log( LogService.LOG_DEBUG, "getting field: {0}", new Object[]
- {baseMethod.getFieldName()}, null );
+ {baseMethod.fieldName}, null );
// resolve the field
Field field = null;
@@ -425,7 +365,7 @@
catch ( InvocationTargetException ex )
{
logger.log( LogService.LOG_WARNING, "{0} cannot be found", new Object[]
- {baseMethod.getFieldName()}, ex.getTargetException() );
+ {baseMethod.fieldName}, ex.getTargetException() );
}
baseMethod.setField( field, logger );
@@ -440,7 +380,7 @@
throws InvocationTargetException
{
resolve( baseMethod, logger );
- return baseMethod.getState().invoke( baseMethod, mType, componentInstance, rawParameter, logger );
+ return baseMethod.state.invoke( baseMethod, mType, componentInstance, rawParameter, logger );
}
}
@@ -456,7 +396,7 @@
final SimpleLogger logger )
{
logger.log( LogService.LOG_ERROR, "Field [{1}] not found", new Object[]
- { baseMethod.getFieldName() }, null );
+ { baseMethod.fieldName }, null );
return null;
}
}
@@ -490,7 +430,7 @@
catch ( InvocationTargetException ite )
{
logger.log( LogService.LOG_ERROR, "The {0} field has thrown an exception", new Object[]
- { getFieldName() }, ite.getCause() );
+ { fieldName }, ite.getCause() );
}
return methodCallFailureResult;
@@ -522,7 +462,7 @@
catch ( InvocationTargetException ite )
{
logger.log( LogService.LOG_ERROR, "The {0} field has thrown an exception", new Object[]
- { getFieldName() }, ite.getCause() );
+ { fieldName }, ite.getCause() );
}
return methodCallFailureResult;
@@ -550,7 +490,7 @@
catch ( InvocationTargetException ite )
{
logger.log( LogService.LOG_ERROR, "The {0} field has thrown an exception", new Object[]
- { getFieldName() }, ite.getCause() );
+ { fieldName }, ite.getCause() );
}
return methodCallFailureResult;
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldMethods.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldMethods.java
index f4d693e..30c57ea 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldMethods.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/FieldMethods.java
@@ -39,8 +39,7 @@
handler = new FieldHandler(
m_dependencyMetadata.getField(),
instanceClass,
- m_dependencyMetadata.getInterface(),
- m_dependencyMetadata.getScope()
+ m_dependencyMetadata.getInterface()
);
}