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     *****************************************************************************/
010    package org.picocontainer.injectors;
011    
012    import org.picocontainer.ComponentMonitor;
013    import org.picocontainer.LifecycleStrategy;
014    import org.picocontainer.Parameter;
015    
016    import java.lang.reflect.Field;
017    import java.lang.reflect.InvocationTargetException;
018    import java.lang.reflect.Member;
019    import java.security.AccessController;
020    import java.security.PrivilegedAction;
021    import java.util.ArrayList;
022    import java.util.List;
023    
024    public class AnnotatedFieldInjector extends IterativeInjector {
025    
026        private final Class injectionAnnotation;
027    
028        public AnnotatedFieldInjector(Object key,
029                                      Class impl,
030                                      Parameter[] parameters,
031                                      ComponentMonitor componentMonitor,
032                                      LifecycleStrategy lifecycleStrategy, Class injectionAnnotation) {
033    
034            super(key, impl, parameters, componentMonitor, lifecycleStrategy);
035            this.injectionAnnotation = injectionAnnotation;
036        }
037    
038        protected void initializeInjectionMembersAndTypeLists() {
039            injectionMembers = new ArrayList<Member>();
040            final List<Class> typeList = new ArrayList<Class>();
041            final Field[] fields = getFields();
042            for (final Field field : fields) {
043                if (isAnnotatedForInjection(field)) {
044                    injectionMembers.add(field);
045                    typeList.add(field.getType());
046                }
047            }
048            injectionTypes = typeList.toArray(new Class[0]);
049        }
050    
051        protected boolean isAnnotatedForInjection(Field field) {
052            return field.getAnnotation(injectionAnnotation) != null;
053        }
054    
055        private Field[] getFields() {
056            return (Field[]) AccessController.doPrivileged(new PrivilegedAction() {
057                public Object run() {
058                    return getComponentImplementation().getDeclaredFields();
059                }
060            });
061        }
062    
063    
064        protected void injectIntoMember(Member member, Object componentInstance, Object toInject)
065            throws IllegalAccessException, InvocationTargetException {
066            Field field = (Field) member;
067            field.setAccessible(true);
068            field.set(componentInstance, toInject);
069        }
070    
071        public String toString() {
072            return "FieldInjector-" + super.toString();
073        }
074    
075    }