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.impl.config.jndi;
17  
18  import java.util.List;
19  
20  import javax.annotation.concurrent.ThreadSafe;
21  import javax.naming.Context;
22  import javax.naming.InitialContext;
23  import javax.naming.NamingException;
24  
25  import de.smartics.properties.api.config.domain.ConfigurationException;
26  import de.smartics.properties.api.config.domain.ConfigurationPropertiesManagement;
27  import de.smartics.properties.api.config.domain.PropertyProvider;
28  import de.smartics.properties.api.config.domain.key.ConfigurationKey;
29  import de.smartics.properties.api.config.domain.key.ConfigurationKeyFactory;
30  import de.smartics.properties.api.core.app.JndiContext;
31  import de.smartics.properties.impl.config.cache.CacheConfigurationPropertiesManagement;
32  import de.smartics.properties.spi.config.domain.key.ConfigurationKeyContextManager;
33  import de.smartics.properties.spi.config.support.AbstractConfigurationPropertiesFactory;
34  
35  /**
36   * Factory to create instances of {@link JndiConfigurationProperties}.
37   */
38  @ThreadSafe
39  public final class JndiConfigurationPropertiesFactory extends
40      AbstractConfigurationPropertiesFactory<ConfigurationPropertiesManagement>
41  {
42    // ********************************* Fields *********************************
43  
44    // --- constants ------------------------------------------------------------
45  
46    /**
47     * The class version identifier.
48     */
49    private static final long serialVersionUID = 1L;
50  
51    // --- members --------------------------------------------------------------
52  
53    // ****************************** Initializer *******************************
54  
55    // ****************************** Constructors ******************************
56  
57    /**
58     * Default constructor.
59     *
60     * @throws IllegalStateException if the JNDI context cannot be accessed.
61     */
62    public JndiConfigurationPropertiesFactory() throws IllegalStateException
63    {
64      getFactoryConfiguration().setSkipClassPathPropertyLoading(true);
65      init();
66    }
67  
68    // ****************************** Inner Classes *****************************
69  
70    // ********************************* Methods ********************************
71  
72    // --- init -----------------------------------------------------------------
73  
74    private void init() throws IllegalStateException
75    {
76      try
77      {
78        final Context jndi = new InitialContext();
79        final List<String> keys = JndiContext.configKeys(jndi);
80        for (final String key : keys)
81        {
82          final JndiContext context = JndiContext.config(jndi, key);
83          final ConfigurationKey<?> configurationKey = parseKey(context, key);
84          final PropertyProvider provider =
85              new JndiConfigurationPropertyProvider(configurationKey, context);
86          addPropertyProviders(provider);
87        }
88      }
89      catch (final NamingException e)
90      {
91        // FIXME: smartics-exception
92        throw new IllegalStateException("Cannot access JNDI context.");
93      }
94    }
95  
96    private ConfigurationKey<?> parseKey(final JndiContext context,
97        final String key)
98    {
99      final ConfigurationKeyFactory<?> factory =
100         ConfigurationKeyContextManager.INSTANCE.context()
101             .configurationKeyFactory();
102     try
103     {
104       final ConfigurationKey<?> configurationKey =
105           factory.createKeyFromString(key);
106       return configurationKey;
107     }
108     catch (final IllegalArgumentException e)
109     {
110       final JndiContextMessageBean message =
111           JndiContextMessageBean.invalidKey(e, context.getSourceId(), key);
112       throw new JndiPropertyStoreException(message);
113     }
114   }
115 
116   // --- get&set --------------------------------------------------------------
117 
118   // --- business -------------------------------------------------------------
119 
120   /**
121    * Creates an empty instance of the configuration properties instance. Where
122    * the public create methods may consult a cache, this method is required to
123    * create a new instance.
124    *
125    * @param key the key to the instance.
126    * @return the instance. Never <code>null</code>.
127    * @throws NullPointerException if {@code key} is <code>null</code>.
128    * @throws ConfigurationException if the configuration cannot be created.
129    * @throws IllegalStateException if the JNDI context cannot be accessed to
130    *           create a new configuration.
131    */
132   protected ConfigurationPropertiesManagement createNewConfiguration(
133       final ConfigurationKey<?> key) throws NullPointerException,
134     ConfigurationException, IllegalStateException
135   {
136     try
137     {
138       final ConfigurationPropertiesManagement config = createCache(key);
139       return config;
140     }
141     catch (final NamingException e)
142     {
143       throw new IllegalStateException("Cannot fetch configuration for key '"
144                                       + key + "' from JNDI.", e); // TODO
145                                                                   // smartics-exception
146     }
147   }
148 
149   private ConfigurationPropertiesManagement createCache(
150       final ConfigurationKey<?> key) throws NamingException
151   {
152     final JndiConfigurationProperties uncached =
153         new JndiConfigurationProperties(key, getRegistry(),
154             getFactoryConfiguration().getDecrypter());
155     if (getFactoryConfiguration().isUseCache())
156     {
157       return new CacheConfigurationPropertiesManagement(uncached);
158     }
159     else
160     {
161       return uncached;
162     }
163   }
164 
165   // --- object basics --------------------------------------------------------
166 
167 }