View Javadoc

1   /*
2    * Copyright 2012-2013 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.properties.integration.cdi.extension;
17  
18  import static de.smartics.properties.integration.cdi.extension.ConfigurationMessageBean.noClassAnnotated;
19  import static de.smartics.properties.integration.cdi.extension.ConfigurationMessageBean.tooManyClassesAnnotated;
20  
21  import java.lang.annotation.Annotation;
22  import java.util.Iterator;
23  import java.util.LinkedList;
24  import java.util.List;
25  import java.util.Set;
26  
27  import javax.enterprise.context.Dependent;
28  import javax.enterprise.inject.Any;
29  import javax.enterprise.inject.Produces;
30  import javax.enterprise.inject.spi.Bean;
31  import javax.enterprise.inject.spi.BeanManager;
32  import javax.enterprise.util.AnnotationLiteral;
33  
34  import de.smartics.properties.api.config.domain.key.ConfigurationKey;
35  import de.smartics.properties.api.config.domain.key.ConfigurationKeyHelper;
36  import de.smartics.properties.integration.cdi.Application;
37  import de.smartics.properties.spi.config.domain.key.ConfigurationKeyContext;
38  import de.smartics.properties.spi.config.domain.key.ConfigurationKeyContextManager;
39  
40  /**
41   * Factory with cdi producer to create the current valid configuration key.
42   */
43  public class ConfigurationKeyFactory
44  {
45  
46    /**
47     * Factory method that produces the actual (runtime dependent) configuration
48     * key.
49     *
50     * @param manager the {@link BeanManager}.
51     * @return the current valid configuration key.
52     */
53    @Produces
54    @Dependent
55    @SuppressWarnings("rawtypes")
56    // CDI does not accept generics here.
57    public ConfigurationKey createConfigurationKey(final BeanManager manager)
58    {
59      final ConfigurationKey<?> key = identifyConfigurationKey(manager);
60      return key;
61    }
62  
63    private ConfigurationKey<?> identifyConfigurationKey(
64        final BeanManager beanManager)
65    {
66      final ConfigurationKeyContext context =
67          ConfigurationKeyContextManager.INSTANCE.context();
68  
69      final ConfigurationKeyHelper kh = context.configurationKeyHelper(true);
70      final Class<?> clazz = fetchTypeWithAnnotation(beanManager);
71      final ConfigurationKey<?> key = kh.load(clazz);
72      return key;
73    }
74  
75    private Class<?> fetchTypeWithAnnotation(final BeanManager beanManager)
76    {
77      final Annotation anyAnnotation = new AnnotationLiteral<Any>()
78      {
79        private static final long serialVersionUID = 1L;
80      };
81      final Set<Bean<?>> beans =
82          beanManager.getBeans(Object.class, anyAnnotation);
83  
84      final Bean<?> annotatedBean = fetchBeanWithAnnotation(beans);
85  
86      return annotatedBean.getBeanClass();
87    }
88  
89    private Bean<?> fetchBeanWithAnnotation(final Set<Bean<?>> beans)
90    {
91      final List<Bean<?>> annotatedBeans = new LinkedList<Bean<?>>();
92      for (final Iterator<Bean<?>> iterator = beans.iterator(); iterator
93          .hasNext();)
94      {
95        final Bean<?> bean = (Bean<?>) iterator.next();
96        if (isAnnotated(bean))
97        {
98          annotatedBeans.add(bean);
99        }
100     }
101     final int size = annotatedBeans.size();
102     if (size == 0)
103     {
104       throw new ConfigurationException(noClassAnnotated());
105     }
106     else if (size == 1)
107     {
108       return annotatedBeans.get(0);
109     }
110     else
111     {
112       throw new ConfigurationException(tooManyClassesAnnotated(annotatedBeans));
113     }
114   }
115 
116   private boolean isAnnotated(final Bean<?> bean)
117   {
118     boolean isAnnotated = false;
119     final Set<Annotation> qualifiers = bean.getQualifiers();
120     for (final Iterator<Annotation> iterator2 = qualifiers.iterator(); iterator2
121         .hasNext();)
122     {
123       final Annotation annotation = (Annotation) iterator2.next();
124       isAnnotated |= annotation.annotationType().equals(Application.class);
125     }
126     return isAnnotated;
127   }
128 
129 }