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.spi.config.proxy;
17  
18  import de.smartics.properties.api.config.domain.SerializableConfigurationProperties;
19  import de.smartics.properties.api.core.annotations.PropertySet;
20  
21  /**
22   * This factory creates a implementation object via a java dynamic proxy for a
23   * given properties interface. Using this object it is possible to access the
24   * properties and when defined in the given interface the keys and property
25   * descriptions can be accessed.
26   */
27  public final class PropertyConfigurationObjectBuilder
28  {
29    // ********************************* Fields *********************************
30  
31    // --- constants ------------------------------------------------------------
32  
33    // --- members --------------------------------------------------------------
34  
35    // ****************************** Initializer *******************************
36  
37    // ****************************** Constructors ******************************
38  
39    /**
40     * The default message suffix.
41     */
42    private static final String MESSAGE =
43        "Only classes that represent an"
44            + " interface and that interface must have a 'PropertySet'"
45            + " annotation are allowed.";
46  
47    /**
48     * Default constructor.
49     */
50    public PropertyConfigurationObjectBuilder()
51    {
52    }
53  
54    // ****************************** Inner Classes *****************************
55  
56    // ********************************* Methods ********************************
57  
58    // --- init -----------------------------------------------------------------
59  
60    // --- get&set --------------------------------------------------------------
61  
62    // --- business -------------------------------------------------------------
63  
64    /**
65     * Build the object that contains the properties information for the given
66     * properties interface. The interface must be provided through its class
67     * object and has to have a {@link PropertySet} annotation.
68     *
69     * @param propertiesInterface the properties interface as class object with an
70     *          {@link PropertySet} annotation.
71     * @param configurationProperties the configuration properties that shall be
72     *          used to access the properties.
73     * @param <T> to provide a type safe access to the properties the returned
74     *          object implements the given properties interface.
75     * @return the object that contains the properties information for the given
76     *         properties interface.
77     * @throws NotAPropertySetAnnotatedInterfaceException when the given class
78     *           does not represent an interface and this interface is not
79     *           annotated with {@link PropertySet} or when null.
80     */
81    public <T> T build(final Class<T> propertiesInterface,
82        final SerializableConfigurationProperties configurationProperties)
83      throws NotAPropertySetAnnotatedInterfaceException
84    {
85      checkForValidPropertiesInterface(propertiesInterface);
86      final T propertiesObject =
87          buildObject(propertiesInterface, configurationProperties);
88      return propertiesObject;
89    }
90  
91    @SuppressWarnings("unchecked")
92    private <T> T buildObject(final Class<T> propertiesInterface,
93        final SerializableConfigurationProperties configurationProperties)
94    {
95      final T propertiesObject =
96          (T) java.lang.reflect.Proxy.newProxyInstance(
97              propertiesInterface.getClassLoader(),
98              new Class[] { propertiesInterface },
99              new PropertiesProxyInvocationHandler(configurationProperties));
100     return propertiesObject;
101   }
102 
103   private <T> void checkForValidPropertiesInterface(
104       final Class<T> propertiesInterface)
105   {
106     checkNull(propertiesInterface);
107     checkIfInterface(propertiesInterface);
108     checkIfCorrectAnnotated(propertiesInterface);
109   }
110 
111   private <T> void checkNull(final Class<T> propertiesInterface)
112   {
113     if (propertiesInterface == null)
114     {
115       throw new NotAPropertySetAnnotatedInterfaceException(
116           "Null is not allowed." + MESSAGE);
117     }
118   }
119 
120   private <T> void checkIfInterface(final Class<T> propertiesInterface)
121   {
122     if (!propertiesInterface.isInterface())
123     {
124       throw new NotAPropertySetAnnotatedInterfaceException("Not an interface."
125                                                            + MESSAGE);
126     }
127   }
128 
129   private <T> void checkIfCorrectAnnotated(final Class<T> propertiesInterface)
130   {
131     final PropertySet propertySetAnnotation =
132         propertiesInterface.getAnnotation(PropertySet.class);
133     if (propertySetAnnotation == null)
134     {
135       throw new NotAPropertySetAnnotatedInterfaceException(
136           "Not a valid annotated interface." + MESSAGE);
137     }
138   }
139 
140   // --- object basics --------------------------------------------------------
141 
142 }