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.domain.key.envapp;
17  
18  import java.util.Collections;
19  import java.util.HashSet;
20  import java.util.Set;
21  
22  import javax.annotation.CheckForNull;
23  import javax.annotation.concurrent.ThreadSafe;
24  
25  import de.smartics.properties.api.config.domain.key.ConfigurationKey;
26  import de.smartics.properties.spi.config.definition.PropertiesDefinitionContext;
27  import de.smartics.properties.spi.config.domain.key.PropertyResourceMatchers;
28  
29  /**
30   * Contains information from the <code>definition.xml</code> that is contained
31   * in archives providing property information, based on environment and
32   * application.
33   */
34  @ThreadSafe
35  public abstract class AbstractPropertiesDefinitionContext implements
36      PropertiesDefinitionContext
37  {
38    // ********************************* Fields *********************************
39  
40    // --- constants ------------------------------------------------------------
41  
42    /**
43     * The class version identifier.
44     */
45    private static final long serialVersionUID = 1L;
46  
47    /**
48     * The default top level domains to identify groups.
49     * <ol>
50     * <li><code>biz</code></li>
51     * <li><code>com</code></li>
52     * <li><code>edu</code></li>
53     * <li><code>gov</code></li>
54     * <li><code>info</code></li>
55     * <li><code>net</code></li>
56     * <li><code>org</code></li>
57     * </ol>
58     */
59    public static final Set<String> DEFAULT_TLDS;
60  
61    // --- members --------------------------------------------------------------
62  
63    /**
64     * The collection of top-level-domains (tlds). Country codes (two letters) are
65     * not necessarily mentioned here since they are dealt with generically.
66     *
67     * @serial
68     */
69    private final Set<String> tlds;
70  
71    /**
72     * The collection of registered environment names.
73     *
74     * @serial
75     */
76    private final Set<String> environments;
77  
78    /**
79     * The collection of registered node names.
80     *
81     * @serial
82     */
83    private final Set<String> nodes;
84  
85    /**
86     * The collection of registered group names.
87     *
88     * @serial
89     */
90    private final Set<String> groups;
91  
92    /**
93     * The matcher of properties file path names to a associated configuration
94     * key.
95     *
96     * @serial
97     */
98    private final PropertyResourceMatchers matchers;
99  
100   // ****************************** Initializer *******************************
101 
102   static
103   {
104     final Set<String> defaults = new HashSet<String>();
105     defaults.add("biz");
106     defaults.add("com");
107     defaults.add("edu");
108     defaults.add("gov");
109     defaults.add("info");
110     defaults.add("net");
111     defaults.add("org");
112     DEFAULT_TLDS = Collections.unmodifiableSet(defaults);
113   }
114 
115   // ****************************** Constructors ******************************
116 
117   /**
118    * Convenience constructor using the default TLDs and not registering any
119    * environments, nodes or groups.
120    */
121   public AbstractPropertiesDefinitionContext()
122   {
123     this(DEFAULT_TLDS, null, null, null, null);
124   }
125 
126   /**
127    * Convenience constructor using the default TLDs and no explicit files.
128    *
129    * @param environments the collection of registered environment names.
130    * @param nodes the collection of registered node names.
131    * @param groups the collection of registered group names.
132    */
133   public AbstractPropertiesDefinitionContext(final Set<String> environments,
134       final Set<String> nodes, final Set<String> groups)
135   {
136     this(DEFAULT_TLDS, environments, nodes, groups);
137   }
138 
139   /**
140    * Convenience constructor without an explicit path to configuration key
141    * mapping.
142    *
143    * @param tlds the collection of top-level-domains (tlds).
144    * @param environments the collection of registered environment names.
145    * @param nodes the collection of registered node names.
146    * @param groups the collection of registered group names.
147    */
148   public AbstractPropertiesDefinitionContext(final Set<String> tlds,
149       final Set<String> environments, final Set<String> nodes,
150       final Set<String> groups)
151   {
152     this(tlds, environments, nodes, groups, null);
153   }
154 
155   /**
156    * Convenience constructor using the default TLDs.
157    *
158    * @param environments the collection of registered environment names.
159    * @param nodes the collection of registered node names.
160    * @param groups the collection of registered group names.
161    * @param matchers the matcher of properties file path names to a associated
162    *          configuration key.
163    */
164   public AbstractPropertiesDefinitionContext(final Set<String> environments,
165       final Set<String> nodes, final Set<String> groups,
166       final PropertyResourceMatchers matchers)
167   {
168     this(DEFAULT_TLDS, environments, nodes, groups, matchers);
169   }
170 
171   /**
172    * Default constructor.
173    *
174    * @param tlds the collection of top-level-domains (tlds).
175    * @param environments the collection of registered environment names.
176    * @param nodes the collection of registered node names.
177    * @param groups the collection of registered group names.
178    * @param matchers the matcher of properties file path names to a associated
179    *          configuration key.
180    */
181   public AbstractPropertiesDefinitionContext(final Set<String> tlds,
182       final Set<String> environments, final Set<String> nodes,
183       final Set<String> groups, final PropertyResourceMatchers matchers)
184   {
185     this.tlds = create(tlds);
186     this.environments = create(environments);
187     this.nodes = create(nodes);
188     this.groups = create(groups);
189     this.matchers =
190         (matchers != null ? matchers : new PropertyResourceMatchers());
191   }
192 
193   // ****************************** Inner Classes *****************************
194 
195   // ********************************* Methods ********************************
196 
197   // --- init -----------------------------------------------------------------
198 
199   private static Set<String> create(final Set<String> set)
200   {
201     return set != null ? new HashSet<String>(set) : new HashSet<String>();
202   }
203 
204   // --- get&set --------------------------------------------------------------
205 
206   // --- business -------------------------------------------------------------
207 
208   /**
209    * Checks if the given string is a registered top level domain (tld) or
210    * contains only two letters.
211    *
212    * @param token the token to check.
213    * @return <code>true</code> if the {@code token} is not <code>null</code>, is
214    *         registered or contains exactly two letters, <code>false</code>
215    *         otherwise.
216    */
217   public final boolean isRegisteredGroupTld(final String token)
218   {
219     return token != null && (tlds.contains(token) || isCountryTld(token));
220   }
221 
222   private static boolean isCountryTld(final String tld)
223   {
224     return tld.length() == 2 && Character.isLetter(tld.charAt(0))
225            && Character.isLetter(tld.charAt(1));
226   }
227 
228   /**
229    * Checks if the given token is a registered environment.
230    *
231    * @param token the token to check.
232    * @return <code>true</code> if the token is a registered environment,
233    *         <code>false</code> otherwise.
234    */
235   public final boolean isRegisteredEnvironment(final String token)
236   {
237     return environments.contains(token);
238   }
239 
240   /**
241    * Checks if the given token is a registered node.
242    *
243    * @param token the token to check.
244    * @return <code>true</code> if the token is a registered node,
245    *         <code>false</code> otherwise.
246    */
247   public final boolean isRegisteredNode(final String token)
248   {
249     return nodes.contains(token);
250   }
251 
252   /**
253    * Checks if the given token is a registered group.
254    *
255    * @param token the token to check.
256    * @return <code>true</code> if the token is a registered group,
257    *         <code>false</code> otherwise.
258    */
259   public final boolean isRegisteredGroup(final String token)
260   {
261     return groups.contains(token);
262   }
263 
264   /**
265    * Returns the configuration key associated with the given {@code path}.
266    *
267    * @param path the path to fetch its configuration key. Note that a
268    *          <code>null</code> value is allowed.
269    * @return the configuration key for the given {@code path} or
270    *         <code>null</code> if no key is associated with it.
271    */
272   @CheckForNull
273   public final ConfigurationKey<?> getKey(final String path)
274   {
275     return matchers.getKey(path);
276   }
277 
278   /**
279    * Checks if the given token is a group. It is a group if it is either
280    * registered explicitly or the token starts with a registered TLD or it
281    * starts with two letters and a dot.
282    *
283    * @param token the token to check.
284    * @return <code>true</code> if the token is a group, <code>false</code>
285    *         otherwise.
286    */
287   public final boolean isGroup(final String token)
288   {
289     if (!isRegisteredGroup(token))
290     {
291       final String tld = determineTld(token);
292       if (isRegisteredGroupTld(tld))
293       {
294         return true;
295       }
296 
297       return false;
298     }
299 
300     return true;
301   }
302 
303   private String determineTld(final String token)
304   {
305     final int index = token.indexOf('.');
306     if (index != -1)
307     {
308       return token.substring(0, index);
309     }
310     return null;
311   }
312 
313   // --- object basics --------------------------------------------------------
314 
315   @Override
316   public String toString()
317   {
318     final StringBuilder buffer = new StringBuilder(128);
319 
320     buffer.append("TLDs          :");
321     for (final String tld : tlds)
322     {
323       buffer.append(' ').append(tld);
324     }
325 
326     buffer.append("\nEnvironments  :");
327     for (final String environment : environments)
328     {
329       buffer.append(' ').append(environment);
330     }
331 
332     buffer.append("\nNodes         :");
333     for (final String node : nodes)
334     {
335       buffer.append(' ').append(node);
336     }
337 
338     buffer.append("\nGroups        :");
339     for (final String group : groups)
340     {
341       buffer.append(' ').append(group);
342     }
343 
344     buffer.append("\nPaths: ").append(matchers);
345 
346     return buffer.toString();
347   }
348 }