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.support;
17  
18  import java.util.List;
19  import java.util.Map;
20  import java.util.Map.Entry;
21  
22  import javax.annotation.CheckForNull;
23  import javax.annotation.concurrent.ThreadSafe;
24  
25  import de.smartics.properties.api.config.domain.ConfigurationPropertiesManagement;
26  import de.smartics.properties.api.config.domain.ConfigurationRepositoryManagement;
27  import de.smartics.properties.api.config.domain.MissingConfigurationException;
28  import de.smartics.properties.api.config.domain.key.ConfigurationKey;
29  import de.smartics.properties.api.core.domain.ConfigException;
30  import de.smartics.properties.api.core.domain.PropertiesContext;
31  import de.smartics.properties.api.core.domain.PropertyDescriptor;
32  import de.smartics.properties.api.core.domain.PropertyDescriptorRegistry;
33  import de.smartics.util.lang.Arg;
34  
35  /**
36   * Creates and caches configurations.
37   * <p>
38   * Required by the {@link ClassPathLoader} to store all encountered
39   * configuration properties.
40   * </p>
41   *
42   * @param <T> the type of {@link ConfigurationPropertiesManagement} created and
43   *          stored by this factory cache.
44   */
45  @ThreadSafe
46  public final class FactoryCache<T extends ConfigurationPropertiesManagement>
47  {
48    // ********************************* Fields *********************************
49  
50    // --- constants ------------------------------------------------------------
51  
52    // --- members --------------------------------------------------------------
53  
54    /**
55     * The cache of currently loaded configurations.
56     *
57     * @impl the implementation of the cache is required to be thread-safe.
58     */
59    private final ConfigurationRepositoryManagement cache;
60  
61    /**
62     * The factory to create instances of
63     * {@link ConfigurationPropertiesManagement}.
64     */
65    private final AbstractConfigurationPropertiesFactory<?> factory;
66  
67    /**
68     * The shared registry of property descriptors.
69     */
70    private final PropertyDescriptorRegistry registry;
71  
72    // ****************************** Initializer *******************************
73  
74    // ****************************** Constructors ******************************
75  
76    /**
77     * Default constructor.
78     *
79     * @param cache the cache of currently loaded configurations.
80     * @param factory the factory to create instances of
81     *          {@link ConfigurationPropertiesManagement}.
82     */
83    public FactoryCache(final ConfigurationRepositoryManagement cache,
84        final AbstractConfigurationPropertiesFactory<?> factory)
85    {
86      this.cache = cache;
87      this.factory = factory;
88      this.registry = factory.getRegistry();
89    }
90  
91    // ****************************** Inner Classes *****************************
92  
93    // ********************************* Methods ********************************
94  
95    // --- init -----------------------------------------------------------------
96  
97    // --- get&set --------------------------------------------------------------
98  
99    /**
100    * Returns the cache of currently loaded configurations.
101    *
102    * @return the cache of currently loaded configurations.
103    */
104   public ConfigurationRepositoryManagement getCache()
105   {
106     return cache;
107   }
108 
109   // --- business -------------------------------------------------------------
110 
111   /**
112    * Returns the context for the given type.
113    *
114    * @param declaringType the type of a property descriptor.
115    * @return the context for the declared properties. May return
116    *         <code>null</code> if the {@code declaringType} is unknown.
117    * @throws ConfigException if the context for the descriptor cannot be found.
118    * @throws NullPointerException if {@code declaringType} is <code>null</code>.
119    */
120   @CheckForNull
121   public PropertiesContext getContext(final Class<?> declaringType)
122     throws NullPointerException, ConfigException
123   {
124     return registry.getContext(declaringType);
125   }
126 
127   /**
128    * Registers the list of descriptors to the given declaring types.
129    *
130    * @param descriptorMap a map of declaring types to their associated
131    *          descriptors.
132    * @throws NullPointerException if {@code descriptorMap} or if any key of
133    *           value of that map is <code>null</code>.
134    */
135   public void registerDescriptors(
136       final Map<Class<?>, List<PropertyDescriptor>> descriptorMap)
137     throws NullPointerException
138   {
139     Arg.checkNotNull("descriptorMap", descriptorMap);
140 
141     for (final Entry<Class<?>, List<PropertyDescriptor>> entry : descriptorMap
142         .entrySet())
143     {
144       final Class<?> declaringType = entry.getKey();
145       final List<PropertyDescriptor> descriptors = entry.getValue();
146       registry.addDescriptors(declaringType, descriptors);
147     }
148   }
149 
150   /**
151    * Creates an instance of {@link ConfigurationPropertiesManagement}.
152    *
153    * @param key the key to the configuration to be created.
154    * @return the created configuration.
155    */
156   public ConfigurationPropertiesManagement ensureManagement(
157       final ConfigurationKey<?> key)
158   {
159     try
160     {
161       return cache.getPropertiesManagement(key);
162     }
163     catch (final MissingConfigurationException e)
164     {
165       return createPropertiesManagement(key);
166     }
167   }
168 
169   /**
170    * Creates an instance of {@link ConfigurationPropertiesManagement}.
171    *
172    * @param key the key to the configuration to be created.
173    * @return the created configuration.
174    */
175   public ConfigurationPropertiesManagement createPropertiesManagement(
176       final ConfigurationKey<?> key)
177   {
178     final ConfigurationPropertiesManagement configuration =
179         factory.createNewConfiguration(key);
180     cache.registerProperties(key, configuration);
181     return configuration;
182   }
183 
184   // --- object basics --------------------------------------------------------
185 
186   /**
187    * Returns the string representation of the object.
188    *
189    * @return the string representation of the object.
190    */
191   @Override
192   public String toString()
193   {
194     final StringBuilder buffer = new StringBuilder();
195 
196     buffer.append("== Descriptor Registry:\n").append(registry);
197     buffer.append("\n== Configuration Cache:\n").append(cache);
198     buffer.append("\n== Factory Type       : ").append(
199         factory.getClass().getName());
200 
201     return buffer.toString();
202   }
203 }