001/*
002 *  Copyright 2010, 2011 Chris Pheby
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.jadira.bindings.core.cdi;
017
018import java.lang.annotation.Annotation;
019import java.net.URL;
020
021import javax.enterprise.event.Observes;
022import javax.enterprise.inject.spi.Extension;
023import javax.enterprise.inject.spi.ProcessAnnotatedType;
024
025import org.jadira.bindings.core.api.Binding;
026import org.jadira.bindings.core.api.Converter;
027import org.jadira.bindings.core.api.FromUnmarshaller;
028import org.jadira.bindings.core.api.ToMarshaller;
029import org.jadira.bindings.core.binder.BasicBinder;
030import org.jadira.bindings.core.binder.Binder;
031import org.jadira.bindings.core.binder.ConverterKey;
032import org.jadira.bindings.core.binder.RegisterableBinder;
033
034/**
035 * A CDI Portable Extension that inspects beans being loaded by the container for bindings.
036 */
037public class BinderExtension implements Extension, Binder, RegisterableBinder {
038
039        /**
040         * Wrapped default binder
041         */
042    private static final BasicBinder BINDING = new BasicBinder(); 
043    
044    /**
045     * Create a new instance of BinderExtension
046     */
047    public BinderExtension() {}
048    
049    /**
050     * {@inheritDoc}
051     */
052    /* @Override */
053    public <T, E> void processAnnotatedType(@Observes ProcessAnnotatedType<T> pat) {
054
055        Class<?> candidateClass = pat.getAnnotatedType().getJavaClass();
056
057        if (!candidateClass.isInterface()) {
058
059            try {
060                if (Binding.class.isAssignableFrom(candidateClass)) {
061
062                    @SuppressWarnings("unchecked")
063                    Class<? extends Binding<T, E>> bindingClass = (Class<? extends Binding<T, E>>) candidateClass;
064                    Binding<T, E> myBinding = bindingClass.newInstance();
065                    BINDING.registerBinding(myBinding.getBoundClass(), myBinding.getTargetClass(), myBinding);
066                } else if (ToMarshaller.class.isAssignableFrom(candidateClass)
067                        || FromUnmarshaller.class.isAssignableFrom(candidateClass)) {
068                    if (ToMarshaller.class.isAssignableFrom(candidateClass)) {
069
070                        @SuppressWarnings("unchecked")
071                        Class<? extends ToMarshaller<T,E>> bindingClass = (Class<? extends ToMarshaller<T,E>>) candidateClass;
072                        ToMarshaller<T,E> myBinding = bindingClass.newInstance();
073                        BINDING.registerMarshaller(myBinding.getBoundClass(), myBinding.getTargetClass(), myBinding);
074                    }
075                    if (FromUnmarshaller.class.isAssignableFrom(candidateClass)) {
076
077                        @SuppressWarnings("unchecked")
078                        Class<? extends FromUnmarshaller<T,E>> bindingClass = (Class<? extends FromUnmarshaller<T,E>>) candidateClass;
079                        FromUnmarshaller<T,E> myBinding = bindingClass.newInstance();
080                        BINDING.registerUnmarshaller(myBinding.getBoundClass(), myBinding.getTargetClass(), myBinding);
081                    }
082                } else if (Converter.class.isAssignableFrom(candidateClass)) {
083
084                    @SuppressWarnings("unchecked")
085                    Class<? extends Converter<T, E>> bindingClass = (Class<? extends Converter<T, E>>) candidateClass;
086                    Converter<T,E> myConverter = bindingClass.newInstance();
087                    BINDING.registerConverter(myConverter.getInputClass(), myConverter.getOutputClass(), myConverter);
088                } else {
089                        BINDING.registerAnnotatedClasses(candidateClass);
090                }
091            } catch (InstantiationException e) {
092                throw new IllegalStateException("Cannot instantiate binding class: " + candidateClass);
093            } catch (IllegalAccessException e) {
094                throw new IllegalStateException("Cannot instantiate binding class: " + candidateClass);
095            }
096        }
097    }
098
099    /**
100     * {@inheritDoc}
101     */
102    /* @Override */
103        public <S, T> T convertTo(Class<T> output, Object object) {
104                return BINDING.convertTo(output, object);
105        }
106
107    /**
108     * {@inheritDoc}
109     */
110    /* @Override */
111        public <S, T> T convertTo(Class<T> output, Object object,
112                        Class<? extends Annotation> qualifier) {
113                return BINDING.convertTo(output, object, qualifier);
114        }
115    
116    /**
117     * {@inheritDoc}
118     */
119    /* @Override */
120        public <S, T> T convertTo(Class<S> sourceClass, Class<T> target, Object object) {
121                return BINDING.convertTo(sourceClass, target, object);
122        }
123
124    /**
125     * {@inheritDoc}
126     */
127    /* @Override */
128        public <S, T> T convertTo(Class<S> sourceClass, Class<T> target, Object object, Class<? extends Annotation> qualifier) {
129                return BINDING.convertTo(sourceClass, target, object, qualifier);
130        }
131
132    /**
133     * {@inheritDoc}
134     */
135    /* @Override */
136        public <S, T> T convertTo(ConverterKey<S,T> key, Object object) {
137                return BINDING.convertTo(key, object);
138        }
139        
140    /**
141     * {@inheritDoc}
142     */
143    /* @Override */
144        public <S, T> Binding<S, T> findBinding(Class<S> source, Class<T> target) {
145                return BINDING.findBinding(source, target);
146        }
147
148    /**
149     * {@inheritDoc}
150     */
151    /* @Override */
152        public <S, T> ToMarshaller<S, T> findMarshaller(Class<S> source, Class<T> target) {
153                return BINDING.findMarshaller(source, target);
154        }
155
156    /**
157     * {@inheritDoc}
158     */
159    /* @Override */
160        public <S, T> Converter<S, T> findConverter(Class<S> source, Class<T> target) {
161                return BINDING.findConverter(source, target);
162        }
163
164    /**
165     * {@inheritDoc}
166     */
167    /* @Override */
168        public <S, T> FromUnmarshaller<S, T> findUnmarshaller(Class<S> source, Class<T> target) {
169                return BINDING.findUnmarshaller(source, target);
170        }
171
172    /**
173     * {@inheritDoc}
174     */
175    /* @Override */
176        public <S, T> Binding<S, T> findBinding(Class<S> source, Class<T> target, Class<? extends Annotation> qualifier) {
177                return BINDING.findBinding(source, target, qualifier);
178        }
179        
180    /**
181     * {@inheritDoc}
182     */
183    /* @Override */
184        public <S, T> Binding<S,T> findBinding(ConverterKey<S,T> key) {
185                return BINDING.findBinding(key);
186        }
187
188    /**
189     * {@inheritDoc}
190     */
191    /* @Override */
192        public <S, T> ToMarshaller<S, T> findMarshaller(Class<S> source, Class<T> target, Class<? extends Annotation> qualifier) {
193                return BINDING.findMarshaller(source, target, qualifier);
194        }
195
196    /**
197     * {@inheritDoc}
198     */
199    /* @Override */
200        public <S, T> ToMarshaller<S,T> findMarshaller(ConverterKey<S,T> key) {
201                return BINDING.findMarshaller(key);
202        }
203        
204    /**
205     * {@inheritDoc}
206     */
207    /* @Override */
208        public <S, T> Converter<S, T> findConverter(Class<S> source, Class<T> target, Class<? extends Annotation> qualifier) {
209                return BINDING.findConverter(source, target, qualifier);
210        }
211
212    /**
213     * {@inheritDoc}
214     */
215    /* @Override */
216        public <S, T> Converter<S,T> findConverter(ConverterKey<S,T> key) {
217                return BINDING.findConverter(key);
218        }
219        
220    /**
221     * {@inheritDoc}
222     */
223    /* @Override */
224        public <S, T> FromUnmarshaller<S, T> findUnmarshaller(Class<S> source, Class<T> target, Class<? extends Annotation> qualifier) {
225                return BINDING.findUnmarshaller(source, target, qualifier);
226        }
227
228    /**
229     * {@inheritDoc}
230     */
231    /* @Override */
232        public <S, T> FromUnmarshaller<S,T> findUnmarshaller(ConverterKey<S,T> key) {
233                return BINDING.findUnmarshaller(key);
234        }
235        
236    /**
237     * {@inheritDoc}
238     */
239    /* @Override */
240    public void registerConfiguration(URL nextLocation) {
241        BINDING.registerConfiguration(nextLocation);
242    }
243        
244    /**
245     * {@inheritDoc}
246     */
247    /* @Override */
248        public <S, T> void registerBinding(Class<S> sourceClass, Class<T> targetClass, Binding<S, T> converter) {
249                BINDING.registerBinding(sourceClass, targetClass, converter);
250        }
251
252    /**
253     * {@inheritDoc}
254     */
255    /* @Override */
256        public <S, T> void registerUnmarshaller(Class<S> sourceClass, Class<T> targetClass, FromUnmarshaller<S, T> converter) {
257                BINDING.registerUnmarshaller(sourceClass, targetClass, converter);
258        }
259
260    /**
261     * {@inheritDoc}
262     */
263    /* @Override */
264        public <S, T> void registerMarshaller(Class<S> sourceClass, Class<T> targetClass, ToMarshaller<S, T> converter) {
265                BINDING.registerMarshaller(sourceClass, targetClass, converter);
266        }
267
268    /**
269     * {@inheritDoc}
270     */
271    /* @Override */
272        public <S, T> void registerConverter(Class<S> sourceClass, Class<T> targetClass, Converter<S, T> converter) {
273                BINDING.registerConverter(sourceClass, targetClass, converter);
274        }
275
276    /**
277     * {@inheritDoc}
278     */
279    /* @Override */
280        public <S, T> void registerBinding(Class<S> sourceClass, Class<T> targetClass, Binding<S, T> converter, Class<? extends Annotation> qualifier) {
281                BINDING.registerBinding(sourceClass, targetClass, converter, qualifier);
282        }
283        
284    /**
285     * {@inheritDoc}
286     */
287    /* @Override */
288        public <S, T> void registerBinding(ConverterKey<S,T> key, Binding<S, T> converter) {
289                BINDING.registerBinding(key, converter);
290        }
291
292    /**
293     * {@inheritDoc}
294     */
295    /* @Override */
296        public <S, T> void registerUnmarshaller(Class<S> sourceClass, Class<T> targetClass, FromUnmarshaller<S, T> converter, Class<? extends Annotation> qualifier) {
297                BINDING.registerUnmarshaller(sourceClass, targetClass, converter, qualifier);
298        }
299
300    /**
301     * {@inheritDoc}
302     */
303    /* @Override */
304        public <S, T> void registerUnmarshaller(ConverterKey<S,T> key, FromUnmarshaller<S, T> converter) {
305                BINDING.registerUnmarshaller(key, converter);
306        }
307        
308    /**
309     * {@inheritDoc}
310     */
311    /* @Override */
312        public <S, T> void registerMarshaller(Class<S> sourceClass, Class<T> targetClass, ToMarshaller<S, T> converter, Class<? extends Annotation> qualifier) {
313                BINDING.registerMarshaller(sourceClass, targetClass, converter, qualifier);     
314        }
315        
316    /**
317     * {@inheritDoc}
318     */
319    /* @Override */
320        public <S, T> void registerMarshaller(ConverterKey<S,T> key, ToMarshaller<S, T> converter) {
321                BINDING.registerMarshaller(key, converter);
322        }
323
324    /**
325     * {@inheritDoc}
326     */
327    /* @Override */
328        public <S, T> void registerConverter(Class<S> sourceClass, Class<T> targetClass, Converter<S, T> converter, Class<? extends Annotation> qualifier) {
329                BINDING.registerConverter(sourceClass, targetClass, converter, qualifier);
330        }
331        
332    /**
333     * {@inheritDoc}
334     */
335    /* @Override */
336        public <S, T> void registerConverter(ConverterKey<S,T> key, Converter<S, T> converter) {
337                BINDING.registerConverter(key, converter);
338        }
339
340    /**
341     * {@inheritDoc}
342     */
343    /* @Override */
344        public void registerAnnotatedClasses(Class<?>... classesToInspect) {
345                BINDING.registerAnnotatedClasses(classesToInspect);
346        }
347        
348    /**
349     * {@inheritDoc}
350     */
351    /* @Override */
352        public Iterable<ConverterKey<?,?>> getConverterEntries() {
353                return BINDING.getConverterEntries();
354        }
355
356    /**
357     * {@inheritDoc}
358     */
359    /* @Override */
360        public <T> T convertFromString(Class<T> output, String object) {
361                return BINDING.convertFromString(output, object);
362        }
363
364    /**
365     * {@inheritDoc}
366     */
367    /* @Override */
368        public <T> T convertFromString(Class<T> output, String object,
369                        Class<? extends Annotation> qualifier) {
370                return BINDING.convertFromString(output, object, qualifier);
371        }
372
373    /**
374     * {@inheritDoc}
375     */
376    /* @Override */
377        public String convertToString(Object object) {
378                return BINDING.convertToString(object);
379        }
380
381    /**
382     * {@inheritDoc}
383     */
384    /* @Override */
385        public String convertToString(Object object,
386                        Class<? extends Annotation> qualifier) {
387                return BINDING.convertToString(object, qualifier);
388        }
389
390    /**
391     * {@inheritDoc}
392     */
393    /* @Override */
394        public <S> String convertToString(Class<S> input, Object object) {
395                return BINDING.convertToString(input, object);
396        }
397
398    /**
399     * {@inheritDoc}
400     */
401    /* @Override */
402        public <S> String convertToString(Class<S> input, Object object,
403                        Class<? extends Annotation> qualifier) {
404                return BINDING.convertToString(input, object, qualifier);
405        }
406}