1 package org.apache.onami.autobind.annotations.features;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 import static java.lang.String.format;
21 import static java.util.Collections.addAll;
22 import static java.util.logging.Logger.getLogger;
23 import static org.apache.onami.autobind.annotations.To.Type.IMPLEMENTATION;
24 import static org.apache.onami.autobind.install.BindingStage.BINDING;
25 import static org.apache.onami.autobind.install.BindingStage.IGNORE;
26 import static org.apache.onami.autobind.jsr330.Names.named;
27
28 import java.lang.annotation.Annotation;
29 import java.util.ArrayList;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Map.Entry;
34 import java.util.logging.Level;
35 import java.util.logging.Logger;
36
37 import javax.inject.Named;
38 import javax.inject.Qualifier;
39 import javax.inject.Singleton;
40
41 import org.apache.onami.autobind.annotations.Bind;
42 import org.apache.onami.autobind.annotations.GuiceAnnotation;
43 import org.apache.onami.autobind.install.BindingStage;
44 import org.apache.onami.autobind.scanner.features.BindingScannerFeature;
45
46 import com.google.inject.BindingAnnotation;
47 import org.apache.onami.autobind.utils.ClassLoadingUtils;
48
49 @Singleton
50 public class AutoBindingFeature
51 extends BindingScannerFeature
52 {
53
54 protected final Logger _logger = getLogger( getClass().getName() );
55
56 @Override
57 public BindingStage accept( Class<Object> annotatedClass, Map<String, Annotation> annotations )
58 {
59 if ( annotations.containsKey( Bind.class.getName() ) )
60 {
61 Bind annotation = (Bind) annotations.get( Bind.class.getName() );
62 if ( !annotation.multiple() && !( IMPLEMENTATION == annotation.to().value() ) )
63 {
64 return BINDING;
65 }
66 }
67 return IGNORE;
68 }
69
70 @SuppressWarnings( "unchecked" )
71 @Override
72 public void process( final Class<Object> annotatedClass, final Map<String, Annotation> annotations )
73 {
74 Bind annotation = (Bind) annotations.get( Bind.class.getName() );
75 Map<String, Annotation> filtered = filter( annotations );
76
77 final boolean asSingleton =
78 ( annotations.containsKey( com.google.inject.Singleton.class.getName() ) || annotations.containsKey( javax.inject.Singleton.class.getName() ) );
79
80 if ( annotation.value().value().length() > 0 )
81 {
82 filtered.put( Named.class.getName(), named( resolver.resolve( annotation.value().value() ) ) );
83 }
84
85 Class<Object>[] interfaces;
86
87 switch ( annotation.to().value() )
88 {
89 case CUSTOM:
90 interfaces = (Class<Object>[]) annotation.to().customs();
91 break;
92
93 case SUPER:
94 Class<? super Object> superclass = annotatedClass.getSuperclass();
95 if ( Object.class.equals( superclass ) )
96 {
97 interfaces = new Class[] { annotatedClass };
98 }
99 else
100 {
101 interfaces = new Class[] { superclass };
102 }
103
104 break;
105
106 case INTERFACES:
107 default:
108 interfaces = (Class<Object>[]) annotatedClass.getInterfaces();
109 if ( interfaces.length == 0 )
110 {
111 List<Class<?>> interfaceCollection = new ArrayList<Class<?>>();
112 Class<? super Object> parent = annotatedClass.getSuperclass();
113 while ( parent != null && !parent.equals( Object.class ) )
114 {
115 addAll( interfaceCollection, parent.getInterfaces() );
116 parent = parent.getSuperclass();
117 }
118 interfaces = interfaceCollection.toArray( new Class[interfaceCollection.size()] );
119 if ( interfaces.length == 0 )
120 {
121 interfaces = new Class[] { annotatedClass };
122
123 }
124 }
125 }
126
127 for ( Class<Object> interf : interfaces )
128 {
129 if ( _logger.isLoggable( Level.FINE ) )
130 {
131 _logger.fine( format( "Binding Class %s to Interface %s. Singleton? %s ",
132 annotatedClass, interf, asSingleton ) );
133 }
134
135 if ( filtered.size() > 0 )
136 {
137 for ( Annotation anno : filtered.values() )
138 {
139 bind( annotatedClass, interf, anno, ( asSingleton ? Singleton.class : null ) );
140 }
141 }
142 else
143 {
144 bind( annotatedClass, interf, null, ( asSingleton ? Singleton.class : null ) );
145 }
146 }
147 }
148
149 @SuppressWarnings( "unchecked" )
150 protected Map<String, Annotation> filter( final Map<String, Annotation> annotations )
151 {
152 Map<String, Annotation> filtered = new HashMap<String, Annotation>( annotations );
153
154 for ( Entry<String, Annotation> entry : annotations.entrySet() )
155 {
156 String key = entry.getKey();
157 if ( qualifiers.contains( key ) )
158 {
159 continue;
160 }
161 if ( others.contains( key ) )
162 {
163 filtered.remove( key );
164 continue;
165 }
166 Class<? extends Annotation> annotation;
167 try
168 {
169 annotation = (Class<? extends Annotation>) ClassLoadingUtils.loadClass(key);
170 if ( annotation.isAnnotationPresent( GuiceAnnotation.class ) )
171 {
172 filtered.remove( key );
173 others.add( key );
174 continue;
175 }
176 if ( annotation.isAnnotationPresent( Qualifier.class ) )
177 {
178 qualifiers.add( key );
179 continue;
180 }
181 if ( annotation.isAnnotationPresent( BindingAnnotation.class ) )
182 {
183 qualifiers.add( key );
184 continue;
185 }
186 filtered.remove( key );
187 others.add( key );
188 }
189 catch ( ClassNotFoundException e )
190 {
191
192 }
193 }
194
195 return filtered;
196 }
197
198 }