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 }