View Javadoc

1   /**
2    Licensed to the Apache Software Foundation (ASF) under one or more
3    contributor license agreements.  See the NOTICE file distributed with
4    this work for additional information regarding copyright ownership.
5    The ASF licenses this file to You under the Apache License, Version 2.0
6    (the "License"); you may not use this file except in compliance with
7    the License.  You may obtain a copy of the License at
8   
9         http://www.apache.org/licenses/LICENSE-2.0
10  
11   Unless required by applicable law or agreed to in writing, software
12   distributed under the License is distributed on an "AS IS" BASIS,
13   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   See the License for the specific language governing permissions and
15   limitations under the License.
16  */
17  package org.apache.commons.inject.api;
18  
19  import java.lang.annotation.Annotation;
20  import java.lang.reflect.Field;
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import org.apache.commons.inject.api.bind.IBinder;
25  import org.apache.commons.inject.api.bind.IModule;
26  import org.apache.commons.inject.api.bind.IBinder.IInjectionParticipator;
27  import org.apache.commons.inject.util.Exceptions;
28  
29  /**
30   * Abstract implementation of a module, which injects loggers into fields.
31   * The field must be annotated like this:
32   * <pre>
33   *   @InjLogger private Logger log;
34   * </pre>
35   * or
36   * <pre>
37   *   @InjLogger(id="LoggerId") private Logger log;
38   * </pre>
39   * The second example would create a logger with the id "LoggerId". The first
40   * example would use the class name as a default value. (The class being that
41   * class, which declares the field.
42   */
43  public abstract class AbstractLoggerInjectingModule<Log> implements IModule {
44  
45  	@Override
46  	public void configure(IBinder pBinder) {
47  		pBinder.add(new IInjectionParticipator() {
48  			@Override
49  			public List<IPoint<Object>> getPoints(IKey<?> pKey, Class<?> pType) {
50  				final List<IPoint<Object>> points = new ArrayList<IPoint<Object>>();
51  				final Field[] fields = pType.getDeclaredFields();
52  				final Class<? extends Annotation> annotationClass = getAnnotationClass();
53  				for (final Field f : fields) {
54  					if (f.isAnnotationPresent(annotationClass)) {
55  						final Annotation annotation = f.getAnnotation(annotationClass);
56  						String id = getId(annotation, f.getDeclaringClass());
57  						if (id == null  ||  id.length() == 0) {
58  							id = f.getDeclaringClass().getName();
59  						}
60  						final Log logger = newLogger(id);
61  						points.add(new IPoint<Object>(){
62  							@Override
63  							public void injectTo(Object pInstance,
64  									IInjector pInjector) {
65  								try {
66  									if (!f.isAccessible()) {
67  										f.setAccessible(true);
68  									}
69  									f.set(pInstance, logger);
70  								} catch (Throwable t) {
71  									throw Exceptions.show(t);
72  								}
73  							}
74  						});
75  					}
76  				}
77  				return points;
78  			}
79  		});
80  	}
81  
82  	/**
83  	 * Creates a new logger with the given Id. Subclasses <em>must</em>
84  	 * overwrite this to return a suitable logger implementation.
85  	 */
86  	protected abstract Log newLogger(String pId);
87  
88  	/**
89  	 * Returns the annotation class, which denotes suitable target fields.
90  	 * By default, the class {@link InjLogger} is used.
91  	 */
92  	protected Class<? extends Annotation> getAnnotationClass() {
93  		return InjLogger.class;
94  	}
95  
96  	/**
97  	 * Called to calculate the Id, which is used to invoke {@link #newLogger(String)}.
98  	 * By default, {@link InjLogger#name()} is returned.
99  	 */
100 	protected String getId(Annotation pAnnotation, Class<?> pClass) {
101 		final InjLogger injLogger = (InjLogger) pAnnotation;
102 		final String id = injLogger.id();
103 		if (id == null  ||  id.length() == 0) {
104 			return pClass.getName();
105 		} else {
106 			return id;
107 		}
108 	}
109 }