Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
PropertiesContext |
|
|
1.6521739130434783;1,652 | ||||
PropertiesContext$1 |
|
|
1.6521739130434783;1,652 | ||||
PropertiesContext$Builder |
|
|
1.6521739130434783;1,652 |
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.api.core.domain; |
|
17 | ||
18 | import java.io.Serializable; |
|
19 | import java.net.URL; |
|
20 | import java.util.ArrayList; |
|
21 | import java.util.List; |
|
22 | import java.util.Locale; |
|
23 | ||
24 | import javax.annotation.CheckForNull; |
|
25 | import javax.annotation.concurrent.ThreadSafe; |
|
26 | ||
27 | import org.apache.commons.lang.LocaleUtils; |
|
28 | import org.apache.commons.lang.StringUtils; |
|
29 | import org.apache.commons.lang.builder.ToStringBuilder; |
|
30 | ||
31 | import de.smartics.properties.api.core.context.alias.AliasTraverser; |
|
32 | import de.smartics.properties.api.core.context.alias.DuplicateAliasException; |
|
33 | import de.smartics.properties.api.core.context.alias.PropertyAliasMapping; |
|
34 | import de.smartics.properties.api.core.context.alias.UnknownAliasException; |
|
35 | import de.smartics.util.lang.Arg; |
|
36 | import de.smartics.util.lang.BlankArgumentException; |
|
37 | ||
38 | /** |
|
39 | * Defines the configuration for smartics properties configuration. |
|
40 | * <p> |
|
41 | * A context provides information for all its properties. Not all properties of |
|
42 | * an application may refer to the same context. |
|
43 | * </p> |
|
44 | * |
|
45 | * @impl For testing purposes please refer to |
|
46 | * <code>help.de.smartics.properties.core.PropertiesContextBuilder</code>. |
|
47 | */ |
|
48 | @ThreadSafe |
|
49 | 75 | public final class PropertiesContext implements Serializable |
50 | { // NOPMD |
|
51 | // ********************************* Fields ********************************* |
|
52 | ||
53 | // --- constants ------------------------------------------------------------ |
|
54 | ||
55 | /** |
|
56 | * The class version identifier. |
|
57 | */ |
|
58 | private static final long serialVersionUID = 1L; |
|
59 | ||
60 | /** |
|
61 | * The path to the folder within <code>META-INF</code> where properties |
|
62 | * resources are located. |
|
63 | * <p> |
|
64 | * The value of this constant is {@value}. |
|
65 | * </p> |
|
66 | */ |
|
67 | public static final String META_INF_HOME = "META-INF/smartics-properties"; |
|
68 | ||
69 | /** |
|
70 | * The path to the folder within <code>{@value #META_INF_HOME}</code> where |
|
71 | * boot properties resources are located. |
|
72 | * <p> |
|
73 | * The value of this constant is {@value}. |
|
74 | * </p> |
|
75 | */ |
|
76 | public static final String BOOT_PROPERTIES_HOME = META_INF_HOME + "/boot"; |
|
77 | ||
78 | /** |
|
79 | * The name of the properties configuration file that provides information for |
|
80 | * declarations. This file provides information in archives that provide |
|
81 | * property meta data (descriptors). |
|
82 | * <p> |
|
83 | * The value of this constant is {@value}. |
|
84 | * </p> |
|
85 | */ |
|
86 | public static final String DECLARATION_FILE_NAME = "declaration.xml"; |
|
87 | ||
88 | /** |
|
89 | * The name of the properties configuration file that provides information for |
|
90 | * definitions. This file provides information in archives that provide |
|
91 | * property values. |
|
92 | * <p> |
|
93 | * The value of this constant is {@value}. |
|
94 | * </p> |
|
95 | */ |
|
96 | public static final String DEFINITION_FILE_NAME = "definition.xml"; |
|
97 | ||
98 | /** |
|
99 | * The default location of the properties declaration configuration file. |
|
100 | * <p> |
|
101 | * The value of this constant is {@value}. |
|
102 | * </p> |
|
103 | */ |
|
104 | public static final String DECLARATION_FILE = META_INF_HOME + '/' |
|
105 | + DECLARATION_FILE_NAME; |
|
106 | ||
107 | /** |
|
108 | * The default location of the properties definition configuration file. |
|
109 | * <p> |
|
110 | * The value of this constant is {@value}. |
|
111 | * </p> |
|
112 | */ |
|
113 | public static final String DEFINITION_FILE = META_INF_HOME + '/' |
|
114 | + DEFINITION_FILE_NAME; |
|
115 | ||
116 | /** |
|
117 | * The location of the property reports within the <code>META-INF</code> |
|
118 | * folder. |
|
119 | * <p> |
|
120 | * The value of this constant is {@value}. |
|
121 | * </p> |
|
122 | */ |
|
123 | private static final String META_INF_PROPERTY_REPORT = META_INF_HOME |
|
124 | + "/property-report/"; |
|
125 | ||
126 | /** |
|
127 | * The location of the property set reports within the <code>META-INF</code> |
|
128 | * folder. |
|
129 | * <p> |
|
130 | * The value of this constant is {@value}. |
|
131 | * </p> |
|
132 | */ |
|
133 | public static final String META_INF_PROPERTY_SET_REPORT = |
|
134 | META_INF_HOME + "/property-set-report/"; |
|
135 | ||
136 | /** |
|
137 | * Specifies the default report location on the home page. |
|
138 | * <p> |
|
139 | * The value of this constant is {@value}. |
|
140 | * </p> |
|
141 | */ |
|
142 | private static final String DEFAULT_REPORT_LOCATION = "/property"; |
|
143 | ||
144 | // --- members -------------------------------------------------------------- |
|
145 | ||
146 | /** |
|
147 | * The list of supported locales. The list contains locales the context |
|
148 | * provides localized information for. |
|
149 | * |
|
150 | * @serial |
|
151 | */ |
|
152 | private final List<Locale> locales; |
|
153 | ||
154 | /** |
|
155 | * The URL to the home page of the project. May be <code>null</code>. |
|
156 | * |
|
157 | * @serial |
|
158 | */ |
|
159 | private final String homePageUrl; |
|
160 | ||
161 | /** |
|
162 | * The URL to the root directory of smartics properties reports. May be |
|
163 | * <code>null</code>. |
|
164 | * |
|
165 | * @serial |
|
166 | */ |
|
167 | private final String propertiesReportUrl; |
|
168 | ||
169 | /** |
|
170 | * The mapping of alias names of property reports to their physical names. |
|
171 | * |
|
172 | * @impl Although {@link PropertyAliasMapping} is not thread-safe, this |
|
173 | * instance provides no write-access to it. |
|
174 | * @serial |
|
175 | */ |
|
176 | private final PropertyAliasMapping aliasMapping; |
|
177 | ||
178 | // ****************************** Initializer ******************************* |
|
179 | ||
180 | // ****************************** Constructors ****************************** |
|
181 | ||
182 | /** |
|
183 | * Default constructor. |
|
184 | */ |
|
185 | private PropertiesContext(final Builder builder) |
|
186 | 55 | { |
187 | 55 | this.locales = builder.locales; |
188 | 55 | this.homePageUrl = builder.homePageUrl; |
189 | 55 | this.propertiesReportUrl = builder.propertiesReportUrl; |
190 | 55 | this.aliasMapping = builder.aliasMapping; |
191 | 55 | } |
192 | ||
193 | // ****************************** Inner Classes ***************************** |
|
194 | ||
195 | /** |
|
196 | * The builder of {@link PropertiesContext}. |
|
197 | */ |
|
198 | 277 | public static final class Builder |
199 | { |
|
200 | // ******************************** Fields ******************************** |
|
201 | ||
202 | // --- constants ---------------------------------------------------------- |
|
203 | ||
204 | // --- members ------------------------------------------------------------ |
|
205 | ||
206 | /** |
|
207 | * The list of supported locales. The list contains locales the context |
|
208 | * provides localized information for. |
|
209 | */ |
|
210 | 57 | private List<Locale> locales = new ArrayList<Locale>(); |
211 | ||
212 | /** |
|
213 | * The URL to the home page of the project. |
|
214 | */ |
|
215 | private String homePageUrl; |
|
216 | ||
217 | /** |
|
218 | * The URL to the root directory of smartics properties reports. |
|
219 | */ |
|
220 | private String propertiesReportUrl; |
|
221 | ||
222 | /** |
|
223 | * The mapping of alias names of property reports to their physical names. |
|
224 | */ |
|
225 | 57 | private final PropertyAliasMapping aliasMapping = |
226 | new PropertyAliasMapping(); |
|
227 | ||
228 | // ***************************** Initializer ****************************** |
|
229 | ||
230 | // ***************************** Constructors ***************************** |
|
231 | ||
232 | // ***************************** Inner Classes **************************** |
|
233 | ||
234 | // ******************************** Methods ******************************* |
|
235 | ||
236 | // --- init --------------------------------------------------------------- |
|
237 | ||
238 | // --- get&set ------------------------------------------------------------ |
|
239 | ||
240 | /** |
|
241 | * Sets the list of supported locales. The list contains locales the context |
|
242 | * provides localized information for. |
|
243 | * |
|
244 | * @param locales the list of supported locales. |
|
245 | * @return a reference to the builder. |
|
246 | * @throws NullPointerException if {@code locales} is <code>null</code>. |
|
247 | */ |
|
248 | public Builder withLocales(final List<Locale> locales) |
|
249 | throws NullPointerException |
|
250 | { |
|
251 | 3 | this.locales = Arg.checkNotNull("locales", locales); |
252 | 3 | return this; |
253 | } |
|
254 | ||
255 | /** |
|
256 | * Sets the URL to the home page of the project. |
|
257 | * |
|
258 | * @param homePageUrl the URL to the home page of the project. |
|
259 | * @return a reference to the builder. |
|
260 | * @throws NullPointerException if {@code homePageUrl} is <code>null</code>. |
|
261 | * @throws IllegalArgumentException if {@code homePageUrl} is blank. |
|
262 | */ |
|
263 | public Builder withHomePageUrl(final String homePageUrl) |
|
264 | throws NullPointerException, IllegalArgumentException |
|
265 | { |
|
266 | 11 | this.homePageUrl = |
267 | normalizeUrl(Arg.checkNotBlank("homePageUrl", homePageUrl)); |
|
268 | 10 | return this; |
269 | } |
|
270 | ||
271 | /** |
|
272 | * Sets the URL to the root directory of smartics properties reports. |
|
273 | * |
|
274 | * @param propertiesReportUrl the URL to the root directory of smartics |
|
275 | * properties reports. |
|
276 | * @return a reference to the builder. |
|
277 | * @throws NullPointerException if {@code propertiesReportUrl} is |
|
278 | * <code>null</code>. |
|
279 | * @throws IllegalArgumentException if {@code propertiesReportUrl} is blank. |
|
280 | */ |
|
281 | public Builder withPropertiesReportUrl(final String propertiesReportUrl) |
|
282 | throws NullPointerException, IllegalArgumentException |
|
283 | { |
|
284 | 11 | Arg.checkNotBlank("propertiesReportUrl", propertiesReportUrl); |
285 | 10 | this.propertiesReportUrl = normalizeUrl(propertiesReportUrl); |
286 | 10 | return this; |
287 | } |
|
288 | ||
289 | /** |
|
290 | * Adds a new alias to the given physical resource. |
|
291 | * |
|
292 | * @param alias the new alias. |
|
293 | * @param physical the resource the alias refers to. |
|
294 | * @return a reference to the builder. |
|
295 | * @throws BlankArgumentException if either {@code alias} or |
|
296 | * {@code physical} is blank. |
|
297 | * @throws DuplicateAliasException if there is already an alias registered |
|
298 | * that points to a different physical resource. |
|
299 | */ |
|
300 | public Builder withAlias(final String alias, final String physical) |
|
301 | throws BlankArgumentException, DuplicateAliasException |
|
302 | { |
|
303 | 0 | aliasMapping.add(alias, physical); |
304 | 0 | return this; |
305 | } |
|
306 | ||
307 | // --- business ----------------------------------------------------------- |
|
308 | ||
309 | /** |
|
310 | * Creates the instance. |
|
311 | * |
|
312 | * @return the new instance. |
|
313 | */ |
|
314 | public PropertiesContext build() |
|
315 | { |
|
316 | 55 | return new PropertiesContext(this); |
317 | } |
|
318 | ||
319 | // --- object basics ------------------------------------------------------ |
|
320 | } |
|
321 | ||
322 | // ********************************* Methods ******************************** |
|
323 | ||
324 | // --- init ----------------------------------------------------------------- |
|
325 | ||
326 | // --- factory -------------------------------------------------------------- |
|
327 | ||
328 | /** |
|
329 | * Creates an empty context. |
|
330 | * |
|
331 | * @return an empty context. |
|
332 | */ |
|
333 | public static PropertiesContext createEmptyContext() |
|
334 | { |
|
335 | 0 | return new Builder().build(); |
336 | } |
|
337 | ||
338 | // --- get&set -------------------------------------------------------------- |
|
339 | ||
340 | /** |
|
341 | * Returns the URL to the home page of the project. |
|
342 | * |
|
343 | * @return the URL to the home page of the project. May be <code>null</code>. |
|
344 | */ |
|
345 | @CheckForNull |
|
346 | public String getHomePageUrl() |
|
347 | { |
|
348 | 4 | return homePageUrl; |
349 | } |
|
350 | ||
351 | /** |
|
352 | * Returns the URL to the root directory of smartics properties reports. |
|
353 | * |
|
354 | * @return the URL to the root directory of smartics properties reports. May |
|
355 | * be <code>null</code>. |
|
356 | */ |
|
357 | @CheckForNull |
|
358 | public String getPropertiesReportUrl() |
|
359 | { |
|
360 | 5 | if (propertiesReportUrl == null && homePageUrl != null) |
361 | { |
|
362 | 0 | return homePageUrl + DEFAULT_REPORT_LOCATION; |
363 | } |
|
364 | 5 | return propertiesReportUrl; |
365 | } |
|
366 | ||
367 | /** |
|
368 | * Returns the URL to the index document of smartics properties reports. |
|
369 | * |
|
370 | * @return the URL to the index document of smartics properties reports. May |
|
371 | * be <code>null</code>. |
|
372 | */ |
|
373 | @CheckForNull |
|
374 | public String getPropertiesReportIndexUrl() |
|
375 | { |
|
376 | 3 | return createReportUrl("smartics-properties-report"); |
377 | } |
|
378 | ||
379 | /** |
|
380 | * Returns the list of supported locales. The list contains locales the |
|
381 | * context provides localized information for. |
|
382 | * |
|
383 | * @return the list of supported locales. |
|
384 | */ |
|
385 | public List<Locale> getLocales() |
|
386 | { |
|
387 | 0 | return locales; |
388 | } |
|
389 | ||
390 | // --- business ------------------------------------------------------------- |
|
391 | ||
392 | private static String normalizeUrl(final String url) |
|
393 | { |
|
394 | 20 | return StringUtils.chomp(url, "/"); |
395 | } |
|
396 | ||
397 | /** |
|
398 | * Returns the URL to the relative target. |
|
399 | * |
|
400 | * @param target the relative URL. |
|
401 | * @return the absolute URL to the report or <code>null</code> if no root URL |
|
402 | * is provided by the context. |
|
403 | * @throws IllegalArgumentException of {@code target} is blank. |
|
404 | */ |
|
405 | public String createReportUrl(final String target) |
|
406 | throws IllegalArgumentException |
|
407 | { |
|
408 | 7 | Arg.checkNotBlank("target", target); |
409 | ||
410 | 6 | if (StringUtils.isEmpty(propertiesReportUrl)) |
411 | { |
|
412 | 3 | return null; |
413 | } |
|
414 | ||
415 | 3 | final String htmlFile = target + ".html"; |
416 | 3 | if (target.charAt(0) == '/') |
417 | { |
|
418 | 1 | return propertiesReportUrl + htmlFile; |
419 | } |
|
420 | else |
|
421 | { |
|
422 | 2 | return propertiesReportUrl + '/' + htmlFile; |
423 | } |
|
424 | } |
|
425 | ||
426 | /** |
|
427 | * Returns the URL to the report documentation for the given descriptor. |
|
428 | * |
|
429 | * @param descriptor the properties descriptor whose report documentation URL |
|
430 | * is requested. |
|
431 | * @return the absolute URL to the report. |
|
432 | */ |
|
433 | public String createReportUrl(final PropertyDescriptor descriptor) |
|
434 | { |
|
435 | 1 | final String target = resolve(descriptor); |
436 | 1 | final String url = createReportUrl(target); |
437 | 1 | return url; |
438 | } |
|
439 | ||
440 | private static String resolve(final PropertyDescriptor descriptor) |
|
441 | { |
|
442 | 8 | final DocumentName name = descriptor.getDocumentName(); |
443 | 8 | final String target = name.getName(); |
444 | // final String target = descriptor.getKey().toString(); |
|
445 | 8 | return target; |
446 | } |
|
447 | ||
448 | /** |
|
449 | * Returns the URL to the XML report in the META-INF directory of the given |
|
450 | * descriptor. |
|
451 | * |
|
452 | * @param descriptor the properties descriptor whose XML report URL is |
|
453 | * requested. |
|
454 | * @return the class loader root rooted path. |
|
455 | */ |
|
456 | public String createMetaInfPath(final PropertyDescriptor descriptor) |
|
457 | { |
|
458 | 1 | return createMetaInfPath(descriptor, null); |
459 | } |
|
460 | ||
461 | /** |
|
462 | * Returns the URL to the XML report in the META-INF directory of the given |
|
463 | * descriptor. |
|
464 | * |
|
465 | * @param descriptor the properties descriptor whose XML report URL is |
|
466 | * requested. |
|
467 | * @param locale the locale to determine the comments. |
|
468 | * @return the class loader root rooted path. |
|
469 | */ |
|
470 | @SuppressWarnings("unchecked") |
|
471 | public String createMetaInfPath(final PropertyDescriptor descriptor, |
|
472 | final Locale locale) |
|
473 | { |
|
474 | 7 | final String target = resolve(descriptor); |
475 | ||
476 | 7 | if (locale != null) |
477 | { |
|
478 | 6 | final List<Locale> locales = LocaleUtils.localeLookupList(locale); |
479 | 6 | for (final Locale currentLocale : locales) |
480 | { |
|
481 | 9 | final String path = |
482 | META_INF_PROPERTY_REPORT + target + '_' + currentLocale + ".xml"; |
|
483 | 9 | final ClassLoader loader = descriptor.getClass().getClassLoader(); // NOPMD |
484 | 9 | final URL resource = loader.getResource(path); |
485 | 9 | if (resource != null) |
486 | { |
|
487 | 5 | return path; |
488 | } |
|
489 | 4 | } |
490 | } |
|
491 | ||
492 | 2 | final String path = META_INF_PROPERTY_REPORT + target + ".xml"; |
493 | 2 | return path; |
494 | } |
|
495 | ||
496 | /** |
|
497 | * Returns the URL to the property set XML report in the META-INF directory of |
|
498 | * the given descriptor. |
|
499 | * |
|
500 | * @param descriptor the properties descriptor whose property set XML report |
|
501 | * URL is requested. |
|
502 | * @return the class loader root rooted path. |
|
503 | */ |
|
504 | public String createMetaInfPathPropertySet(final PropertyDescriptor descriptor) |
|
505 | { |
|
506 | 0 | return createMetaInfPathPropertySet(descriptor, null); |
507 | } |
|
508 | ||
509 | /** |
|
510 | * Returns the URL to the property set XML report in the META-INF directory of |
|
511 | * the given descriptor. |
|
512 | * |
|
513 | * @param descriptor the properties descriptor whose property set XML report |
|
514 | * URL is requested. |
|
515 | * @param locale the locale to determine the comments. |
|
516 | * @return the class loader root rooted path. |
|
517 | */ |
|
518 | @SuppressWarnings("unchecked") |
|
519 | public String createMetaInfPathPropertySet( |
|
520 | final PropertyDescriptor descriptor, final Locale locale) |
|
521 | { |
|
522 | 0 | final String target = descriptor.getKey().getPropertySet(); |
523 | ||
524 | 0 | if (locale != null) |
525 | { |
|
526 | 0 | final List<Locale> locales = LocaleUtils.localeLookupList(locale); |
527 | 0 | for (final Locale currentLocale : locales) |
528 | { |
|
529 | 0 | final String path = |
530 | META_INF_PROPERTY_SET_REPORT + target + '_' + currentLocale |
|
531 | + ".xml"; |
|
532 | 0 | final ClassLoader loader = descriptor.getClass().getClassLoader(); // NOPMD |
533 | 0 | final URL resource = loader.getResource(path); |
534 | 0 | if (resource != null) |
535 | { |
|
536 | 0 | return path; |
537 | } |
|
538 | 0 | } |
539 | } |
|
540 | ||
541 | 0 | final String path = META_INF_PROPERTY_SET_REPORT + target + ".xml"; |
542 | 0 | return path; |
543 | } |
|
544 | ||
545 | /** |
|
546 | * Resolves the alias to the target it points to. |
|
547 | * |
|
548 | * @param alias the alias whose physical resource is requested. |
|
549 | * @return the target the alias points to. |
|
550 | * @throws BlankArgumentException if {@code alias} is blank. |
|
551 | * @throws UnknownAliasException if the alias is not known. |
|
552 | */ |
|
553 | public String resolve(final String alias) throws BlankArgumentException, |
|
554 | UnknownAliasException |
|
555 | { |
|
556 | 0 | return aliasMapping.get(alias); |
557 | } |
|
558 | ||
559 | /** |
|
560 | * Traverses the registered aliases. |
|
561 | * |
|
562 | * @param traverser the traverser to use. |
|
563 | * @throws NullPointerException if {@code traverser} is <code>null</code>. |
|
564 | */ |
|
565 | public void traverseAliases(final AliasTraverser traverser) |
|
566 | throws NullPointerException |
|
567 | { |
|
568 | 0 | aliasMapping.traverse(traverser); |
569 | 0 | } |
570 | ||
571 | /** |
|
572 | * Checks whether any aliases are registered. |
|
573 | * |
|
574 | * @return <code>true</code> if at least one alias is registered, |
|
575 | * <code>false</code> otherwise. |
|
576 | */ |
|
577 | public boolean hasAliases() |
|
578 | { |
|
579 | 0 | return !aliasMapping.isEmpty(); |
580 | } |
|
581 | ||
582 | // --- object basics -------------------------------------------------------- |
|
583 | ||
584 | /** |
|
585 | * Returns the string representation of the object. |
|
586 | * |
|
587 | * @return the string representation of the object. |
|
588 | */ |
|
589 | @Override |
|
590 | public String toString() |
|
591 | { |
|
592 | 0 | return ToStringBuilder.reflectionToString(this); |
593 | } |
|
594 | } |