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.cache;
17  
18  import static de.smartics.properties.api.config.cache.CacheConfiguration.CACHE_ID;
19  import static de.smartics.properties.api.config.cache.CacheConfiguration.CACHE_NAME;
20  import static de.smartics.properties.api.config.cache.CacheConfiguration.JNDI_NAME;
21  
22  import java.io.BufferedInputStream;
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.io.Serializable;
26  import java.net.URL;
27  import java.util.Collections;
28  import java.util.Enumeration;
29  import java.util.List;
30  import java.util.Properties;
31  
32  import org.apache.commons.io.IOUtils;
33  import org.apache.commons.lang.StringUtils;
34  
35  import de.smartics.properties.api.config.cache.CacheConfiguration;
36  import de.smartics.properties.api.core.domain.PropertiesContext;
37  
38  /**
39   * Responsible to read configuration properties to connect to a cache stored via
40   * JNDI.
41   */
42  public class CacheConfigurationPropertiesLoader implements Serializable
43  {
44    // ********************************* Fields *********************************
45  
46    // --- constants ------------------------------------------------------------
47  
48    /**
49     * The class version identifier.
50     * <p>
51     * The value of this constant is {@value}.
52     * </p>
53     */
54    private static final long serialVersionUID = 1L;
55  
56    /**
57     * The location within the classpath to find the configuration file to load.
58     */
59    public static final String CLASSPATH_LOCATION =
60        PropertiesContext.BOOT_PROPERTIES_HOME + "/cache.properties";
61  
62    // --- members --------------------------------------------------------------
63  
64    // ****************************** Initializer *******************************
65  
66    // ****************************** Constructors ******************************
67  
68    /**
69     * Default constructor.
70     */
71    public CacheConfigurationPropertiesLoader()
72    {
73    }
74  
75    // ****************************** Inner Classes *****************************
76  
77    // ********************************* Methods ********************************
78  
79    // --- init -----------------------------------------------------------------
80  
81    // --- get&set --------------------------------------------------------------
82  
83    // --- business -------------------------------------------------------------
84  
85    /**
86     * Loads the cache configuration from the classpath.
87     *
88     * @return the cache configuration.
89     * @throws CacheException on any problem loading the cache.
90     * @throws IllegalStateException if the configuration files cannot be found on
91     *           the classpath.
92     */
93    public CacheConfiguration load() throws CacheException, IllegalStateException
94    {
95      try
96      {
97        final Properties properties = loadProperties();
98        check(properties);
99        final CacheConfiguration config = new CacheConfiguration(properties);
100       return config;
101     }
102     catch (final IOException e)
103     {
104       throw new CacheException(CacheMessageBean.configFailure(e,
105           CLASSPATH_LOCATION));
106     }
107   }
108 
109   private void check(final Properties properties) throws CacheException
110   {
111     checkProperty(properties, JNDI_NAME);
112     checkProperty(properties, CACHE_NAME);
113   }
114 
115   private void checkProperty(final Properties properties, final String key)
116   {
117     final String cacheName = properties.getProperty(key);
118     if (StringUtils.isBlank(cacheName))
119     {
120       throw new CacheException(CacheMessageBean.missingProperty(
121           CLASSPATH_LOCATION, key));
122     }
123   }
124 
125   private Properties loadProperties() throws IOException, IllegalStateException
126   {
127     final Enumeration<URL> urlsEnum =
128         Thread.currentThread().getContextClassLoader()
129             .getResources(CLASSPATH_LOCATION);
130     final List<URL> urls = Collections.list(urlsEnum);
131     final int count = urls.size();
132     if (count == 1)
133     {
134       final URL url = urls.get(0);
135 
136       final Properties properties = new Properties();
137       final InputStream in = new BufferedInputStream(url.openStream());
138       try
139       {
140         properties.load(in);
141       }
142       finally
143       {
144         IOUtils.closeQuietly(in);
145       }
146       properties.setProperty(CACHE_ID, url.toString());
147 
148       return properties;
149     }
150     else if (count == 0)
151     {
152       throw new IllegalStateException(String.format(
153           "Cannot find '%s' to configure the access to a cache.",
154           CLASSPATH_LOCATION));
155     }
156     else
157     {
158       throw new IllegalStateException(String.format(
159           "Found more than one configuration for '%s' to access a cache: %s",
160           CLASSPATH_LOCATION, urls));
161     }
162   }
163 
164   // --- object basics --------------------------------------------------------
165 
166 }