View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.onami.factoryannotation;
20  
21  import java.lang.annotation.Annotation;
22  import java.lang.reflect.Field;
23  
24  import org.apache.onami.factoryannotation.AccessibleHelper.AccessibleHelperCallback;
25  
26  import com.google.inject.MembersInjector;
27  import com.google.inject.ProvisionException;
28  
29  class FactoryAnnotationSingleFieldMemberInjector<T, A extends Annotation>
30      implements MembersInjector<T>
31  {
32  
33      private final FactoryAnnotationProvider<T, A> factoryAnnotationProvider;
34  
35      private final Field field;
36  
37      private final A annotation;
38  
39      private final FactoryAnnotationProvision<T, A> factoryAnnotationProvision;
40  
41      private final FactoryAnnotationProvisionListener<T, A> provisionListener;
42  
43      FactoryAnnotationSingleFieldMemberInjector( final FactoryAnnotationProvider<T, A> factoryAnnotationProvider, final Field field,
44                                         final FactoryAnnotationProvisionListener<T, A> provisionListener, final A annotation,
45                                         final FactoryAnnotationProvision<T, A> factoryAnnotationProvision )
46      {
47  
48          this.factoryAnnotationProvider = factoryAnnotationProvider;
49          this.field = field;
50          this.annotation = annotation;
51          this.factoryAnnotationProvision = factoryAnnotationProvision;
52          this.provisionListener = provisionListener;
53      }
54  
55      public void injectMembers( final T instance )
56      {
57          AccessibleHelper.executePrivileged( field, new AccessibleHelperCallback<Field>()
58          {
59  
60              public void execute( final Field accessibleObject )
61              {
62                  try
63                  {
64                      // If annotated with both @Inject and a binding
65                      // annotation it is possible that there would be two
66                      // injection request, so just prevent injecting a
67                      // value a second time
68                      if ( accessibleObject.get( instance ) == null )
69                      {
70                          final FactoryAnnotationProvision<T, A> ip = FactoryAnnotationProvisionImpl.modify( factoryAnnotationProvision, instance );
71  
72                          final T value = factoryAnnotationProvider.buildValue( annotation );
73  
74                          // Notify listener before we inject the value
75                          if ( provisionListener != null )
76                          {
77                              provisionListener.beforeInjection( ip, annotation );
78                          }
79  
80                          accessibleObject.set( instance, value );
81  
82                          // Notify listener after injection is done
83                          if ( provisionListener != null )
84                          {
85                              provisionListener.afterInjection( ip, annotation, value );
86                          }
87                      }
88  
89                  }
90                  catch ( final IllegalAccessException e )
91                  {
92                      throw new ProvisionException( "Provision failed", e );
93                  }
94              }
95  
96          } );
97      }
98  
99      @SuppressWarnings( "unchecked" )
100     static final <A extends Annotation, I, T> MembersInjector<I> buildMemberInjector( final FactoryAnnotationProvider<T, A> factoryAnnotationProvider,
101                                                                                       final Field field,
102                                                                                       final FactoryAnnotationProvisionListener<T, A> provisionListener,
103                                                                                       final A annotation,
104                                                                                       final FactoryAnnotationProvision<T, A> factoryAnnotationProvision )
105     {
106 
107         return (MembersInjector<I>) new FactoryAnnotationSingleFieldMemberInjector<T, A>( factoryAnnotationProvider, field,
108                                                                                  provisionListener, annotation,
109                                                                                  factoryAnnotationProvision );
110 
111     }
112 
113 }