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 }