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.tutorial.onestringproperty;
17  
18  import static org.hamcrest.MatcherAssert.assertThat;
19  import static org.hamcrest.Matchers.equalTo;
20  import static org.hamcrest.Matchers.is;
21  
22  import org.junit.Test;
23  
24  import de.smartics.projectdoc.annotations.DocCategory;
25  import de.smartics.projectdoc.annotations.Document;
26  import de.smartics.projectdoc.annotations.topic.DocChapter;
27  import de.smartics.projectdoc.annotations.topic.DocSection;
28  import de.smartics.properties.api.config.domain.ConfigurationProperties;
29  import de.smartics.properties.impl.config.classpath.ClasspathConfigurationProperties;
30  import de.smartics.properties.impl.config.classpath.ClasspathConfigurationPropertiesFactory;
31  
32  /**
33   * This tutorial shows how to declare a simple property of type {@link String},
34   * provide a definition for it and then access it from a client application.
35   */
36  @Document(title = "One-String-Property Tutorial!", sortKey = "basics0010")
37  @DocCategory({ "basics" })
38  // @DocTopic(path="basics", step="10")
39  public class OneStringPropertyTutorial
40  {
41    /**
42     * <p>
43     * Let's start with declaring a property set with one property!
44     * </p>
45     * <p>
46     * The declaration is a Java interface that is annotated with
47     * {@link de.smartics.properties.api.core.annotations.PropertySet}.
48     * </p>
49     * {@insertCode source="ApplicationProperties"}
50     */
51    @DocChapter
52    void propertySetDeclaration()
53    {
54    }
55  
56    /**
57     * <p>
58     * To provide a value for the {@link ApplicationProperties#host() host}
59     * property we place a standard properties file in the class path.
60     * </p>
61     * {@insertCode file="ApplicationProperties.properties"}
62     * <p>
63     * This file is in the same package as the interface file and is named
64     * </p>
65     *
66     * <pre>
67     * ApplicationProperties.properties
68     * </pre>
69     * <div class="note">
70     * <p>
71     * Placing a properties file in the class path is only one method for defining
72     * properties. Please refer to PENDING for examples of other sources of
73     * properties definitions.
74     * </p>
75     * </div>
76     */
77    @DocChapter
78    void propertyDefinition()
79    {
80    }
81  
82    /**
83     * <p>
84     * Finally we want to access this property from a client application.
85     * </p>
86     */
87    @Test
88    @DocChapter(suppressCode = true)
89    public void accessingProperties()
90    {
91      final ConfigurationProperties config = createConfiguration();
92      accessProperty(config);
93    }
94  
95    /**
96     * <p>
97     * The following code shows how to create a configuration.
98     * </p>
99     * {@insertCode}
100    * <p>
101    * In {@$1} we create a factory in order to create an empty configuration.
102    * This configuration may contain any number of property sets, although in
103    * this example our configuration contains only one.
104    * </p>
105    * <div class="note">
106    * <p>
107    * In this example we use a factory that creates a configuration that is
108    * capable of searching for property definitions on the class path, hence the
109    * factory is called {@link ClasspathConfigurationPropertiesFactory} and the
110    * configuration it creates is of type
111    * {@link ClasspathConfigurationProperties}.
112    * </p>
113    * <p>
114    * The <code>ClasspathConfigurationProperties</code> allow to add property
115    * sets via
116    * {@link ClasspathConfigurationProperties#addClassPathProperties(Class)}. By
117    * passing the type of the property set ({@link ApplicationProperties} in this
118    * case) the configuration reads a properties file with the same name
119    * (including the package) but with the file name extension
120    * <code>properties</code>. We have provided this file in
121    * <a href="#propertyDefinition">a previous step</a>.
122    * </p>
123    * </div>
124    * <p>
125    * In {@$2} the configuration instance is created. This instance is the
126    * container for all property sets (and up to now it is still empty).
127    * </p>
128    * <div class="note"> There are other implementations for the factory and
129    * configuration interface that collect the properties definitions by
130    * themselves. Please refer to {@PENDING ref to collecting impl tutorial}
131    * for details. </div>
132    * <p>
133    * In {@$3} we manually add the properties (declarations and definitions)
134    * to the configuration. This is a feature of
135    * {@link ClasspathConfigurationProperties}. Therefore we declared the
136    * variable <code>config</code> to be of this type. After initialization we
137    * only need the API provided by the {@link ConfigurationProperties}
138    * interface.
139    * </p>
140    */
141   @DocSection
142   private ConfigurationProperties createConfiguration()
143   {
144     final ClasspathConfigurationPropertiesFactory factory =
145         new ClasspathConfigurationPropertiesFactory(); // {1}
146     final ClasspathConfigurationProperties config = factory.create(); // {2}
147     config.addClassPathProperties(ApplicationProperties.class); // {3}
148     return config; // {x} - i.e. do not show this line
149   }
150 
151   /**
152    * <p>
153    * Accessing the property is quite simple.
154    * </p>
155    * {@insertCode}
156    * <p>
157    * First access the property set {@link ApplicationProperties} of the
158    * configuration ({@$1}), then we fetch the value for the
159    * <code>host</code> property ({@$2}).
160    * </p>
161    * <p>
162    * The value of the property <code>host</code> is <code>localhost</code> as
163    * expected.
164    * </p>
165    */
166   @DocSection
167   private void accessProperty(final ConfigurationProperties config)
168   {
169     final ApplicationProperties properties =
170         config.getProperties(ApplicationProperties.class); // {1}
171     final String host = properties.host(); // {2}
172 
173     assertThat(host, is(equalTo("localhost")));
174   }
175 }