EMMA Coverage Report (generated Wed Oct 26 13:47:17 EDT 2011)
[all classes][org.jclouds.logging.config]

COVERAGE SUMMARY FOR SOURCE FILE [BindLoggersAnnotatedWithResource.java]

nameclass, %method, %block, %line, %
BindLoggersAnnotatedWithResource.java100% (3/3)100% (7/7)94%  (126/134)94%  (32/34)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class BindLoggersAnnotatedWithResource$AssignLoggerToField100% (1/1)100% (2/2)72%  (21/29)80%  (8/10)
afterInjection (Object): void 100% (1/1)60%  (12/20)67%  (4/6)
BindLoggersAnnotatedWithResource$AssignLoggerToField (Logger, Field): void 100% (1/1)100% (9/9)100% (4/4)
     
class BindLoggersAnnotatedWithResource100% (1/1)100% (3/3)100% (87/87)100% (21/21)
BindLoggersAnnotatedWithResource (Logger$LoggerFactory): void 100% (1/1)100% (6/6)100% (3/3)
getLoggerFieldsAnnotatedWithResource (Class): Set 100% (1/1)100% (24/24)100% (6/6)
hear (TypeLiteral, TypeEncounter): void 100% (1/1)100% (57/57)100% (12/12)
     
class BindLoggersAnnotatedWithResource$LoggerFieldsAnnotatedWithResource100% (1/1)100% (2/2)100% (18/18)100% (3/3)
BindLoggersAnnotatedWithResource$LoggerFieldsAnnotatedWithResource (): void 100% (1/1)100% (3/3)100% (1/1)
apply (Field): boolean 100% (1/1)100% (15/15)100% (2/2)

1/**
2 * Licensed to jclouds, Inc. (jclouds) under one or more
3 * contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  jclouds 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 */
19package org.jclouds.logging.config;
20 
21import static com.google.common.collect.Sets.filter;
22 
23import java.lang.annotation.Annotation;
24import java.lang.reflect.Field;
25import java.util.Arrays;
26import java.util.HashSet;
27import java.util.Set;
28 
29import javax.annotation.Resource;
30import javax.inject.Inject;
31import javax.inject.Named;
32 
33import org.jclouds.logging.Logger;
34import org.jclouds.logging.Logger.LoggerFactory;
35 
36import com.google.common.annotations.VisibleForTesting;
37import com.google.common.base.Predicate;
38import com.google.inject.ProvisionException;
39import com.google.inject.TypeLiteral;
40import com.google.inject.spi.InjectionListener;
41import com.google.inject.spi.TypeEncounter;
42import com.google.inject.spi.TypeListener;
43 
44/**
45 * TypeListener that will bind {@link org.jclouds.logging.Logger} to members annotated with
46 * {@link javax.annotation.Resource}
47 * <p/>
48 * This class is a TypeListener so that it can create a logger whose category is
49 * the same as the name of the injected instance's class.
50 * <p/>
51 * Note that this occurs post-object construction through
52 * {@link com.google.inject.Binder#bindListener}.
53 * <p/>
54 * Here's an example usage:
55 * <pre>
56 *     class A {
57 *         @Resource private Logger logger = Logger.NULL;
58 *     }
59 * <p/>
60 *     Injector i = Guice.createInjector(new AbstractModule() {
61 *         @Override protected void configure() {
62 *             bindListener(any(), new
63 *                 BindLoggersAnnotatedWithResource( new
64 *                     JDKLogger.JDKLoggerFactory()));
65 *         }
66 *     });
67 * <p/>
68 *     A = i.getInstance(A.class);
69 *     // A will now have a logger associated with it
70 * </pre>
71 *
72 * @author Adrian Cole
73 */
74public class BindLoggersAnnotatedWithResource implements TypeListener {
75 
76    static class AssignLoggerToField<I> implements InjectionListener<I> {
77        private final Logger logger;
78        private final Field field;
79 
80        AssignLoggerToField(Logger logger, Field field) {
81            this.logger = logger;
82            this.field = field;
83        }
84 
85        public void afterInjection(I injectee) {
86            try {
87                field.setAccessible(true);
88                field.set(injectee, logger);
89            } catch (IllegalAccessException e) {
90                throw new ProvisionException(e.getMessage(), e);
91            }
92        }
93    }
94 
95    static class LoggerFieldsAnnotatedWithResource implements
96            Predicate<Field> {
97        public boolean apply(Field from) {
98            Annotation inject = from.getAnnotation(Resource.class);
99            return (inject != null && from.getType().isAssignableFrom(Logger.class));
100        }
101    }
102 
103    private final LoggerFactory loggerFactory;
104 
105    @Inject
106    public BindLoggersAnnotatedWithResource(LoggerFactory loggerFactory) {
107        this.loggerFactory = loggerFactory;
108    }
109 
110    public <I> void hear(TypeLiteral<I> injectableType,
111                         TypeEncounter<I> encounter) {
112 
113        Class<? super I> type = injectableType.getRawType();
114        Set<Field> loggerFields = getLoggerFieldsAnnotatedWithResource(type);
115        if (loggerFields.size() == 0)
116            return;
117 
118        Logger logger = loggerFactory.getLogger(type.getName());
119 
120        for (Field field : loggerFields) {
121           if (field.isAnnotationPresent(Named.class)){
122              Named name = field.getAnnotation(Named.class);
123              encounter.register(new AssignLoggerToField<I>(loggerFactory.getLogger(name.value()), field));
124           } else {
125              encounter.register(new AssignLoggerToField<I>(logger, field));
126           }
127        }
128    }
129 
130    @VisibleForTesting
131    Set<Field> getLoggerFieldsAnnotatedWithResource(Class<?> declaredType) {
132        Set<Field> fields = new HashSet<Field>();
133        Class<?> type = declaredType;
134        while (type != null) {
135            fields.addAll(Arrays.asList(type.getDeclaredFields()));
136            type = type.getSuperclass();
137        }
138        return filter(fields, new LoggerFieldsAnnotatedWithResource());
139    }
140}

[all classes][org.jclouds.logging.config]
EMMA 2.0.5312 (C) Vladimir Roubtsov