001: /*****************************************************************************
002: * Copyright (C) PicoContainer Organization. All rights reserved. *
003: * ------------------------------------------------------------------------- *
004: * The software in this package is published under the terms of the BSD *
005: * style license a copy of which has been included with this distribution in *
006: * the LICENSE.txt file. *
007: * *
008: * Original code by *
009: *****************************************************************************/package org.picocontainer.injectors;
010:
011: import org.picocontainer.ComponentMonitor;
012: import org.picocontainer.LifecycleStrategy;
013: import org.picocontainer.Parameter;
014: import org.picocontainer.NameBinding;
015: import org.picocontainer.annotations.Bind;
016:
017: import java.lang.annotation.Annotation;
018: import java.lang.reflect.AccessibleObject;
019: import java.lang.reflect.Field;
020: import java.lang.reflect.InvocationTargetException;
021: import java.security.AccessController;
022: import java.security.PrivilegedAction;
023: import java.util.ArrayList;
024: import java.util.List;
025:
026: /**
027: * Injection happens after instantiation, and through fields marked as injection points via an Annotation.
028: * The default annotation of org.picocontainer.annotations.@Inject can be overridden.
029: */
030: public class AnnotatedFieldInjector extends IterativeInjector {
031:
032: /**
033: * Serialization UUID.
034: */
035: private static final long serialVersionUID = -1995850745951708186L;
036:
037: private final Class<? extends Annotation> injectionAnnotation;
038:
039: public AnnotatedFieldInjector(Object key, Class<?> impl,
040: Parameter[] parameters, ComponentMonitor componentMonitor,
041: LifecycleStrategy lifecycleStrategy,
042: Class<? extends Annotation> injectionAnnotation,
043: boolean useNames) {
044:
045: super (key, impl, parameters, componentMonitor,
046: lifecycleStrategy, useNames);
047: this .injectionAnnotation = injectionAnnotation;
048: }
049:
050: protected void initializeInjectionMembersAndTypeLists() {
051: injectionMembers = new ArrayList<AccessibleObject>();
052: List<Annotation> bindingIds = new ArrayList<Annotation>();
053: final List<Class> typeList = new ArrayList<Class>();
054: final Field[] fields = getFields();
055: for (final Field field : fields) {
056: if (isAnnotatedForInjection(field)) {
057: injectionMembers.add(field);
058: typeList.add(box(field.getType()));
059: bindingIds.add(getBinding(field));
060: }
061: }
062: injectionTypes = typeList.toArray(new Class[0]);
063: bindings = bindingIds.toArray(new Annotation[0]);
064: }
065:
066: private Annotation getBinding(Field field) {
067: Annotation[] annotations = field.getAnnotations();
068: for (Annotation annotation : annotations) {
069: if (annotation.annotationType().isAnnotationPresent(
070: Bind.class)) {
071: return annotation;
072: }
073: }
074: return null;
075: }
076:
077: protected boolean isAnnotatedForInjection(Field field) {
078: return field.getAnnotation(injectionAnnotation) != null;
079: }
080:
081: private Field[] getFields() {
082: return (Field[]) AccessController
083: .doPrivileged(new PrivilegedAction() {
084: public Object run() {
085: return getComponentImplementation()
086: .getDeclaredFields();
087: }
088: });
089: }
090:
091: protected void injectIntoMember(AccessibleObject member,
092: Object componentInstance, Object toInject)
093: throws IllegalAccessException, InvocationTargetException {
094: Field field = (Field) member;
095: field.setAccessible(true);
096: field.set(componentInstance, toInject);
097: }
098:
099: public String getDescriptor() {
100: return "FieldInjector-";
101: }
102:
103: protected NameBinding makeParameterNameImpl(
104: final AccessibleObject member) {
105: return new NameBinding() {
106: public String getName() {
107: return ((Field) member).getName();
108: }
109: };
110: }
111: }
|