View Javadoc

1   /*
2    * Copyright 2005,2009 Ivan SZKIBA
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 org.ini4j.tutorial;
17  
18  import org.ini4j.Config;
19  import org.ini4j.Ini;
20  import org.ini4j.Options;
21  
22  import org.ini4j.sample.Dwarf;
23  import org.ini4j.sample.DwarfBean;
24  import org.ini4j.sample.Dwarfs;
25  
26  import org.ini4j.test.DwarfsData;
27  
28  import static org.junit.Assert.*;
29  
30  import java.io.File;
31  import java.io.IOException;
32  
33  import java.net.URI;
34  import java.net.URL;
35  
36  //<editor-fold defaultstate="collapsed" desc="apt documentation">
37  //|
38  //|                -------------
39  //|                Bean Tutorial
40  //|
41  //|Bean Tutorial - Using your own API !
42  //|
43  //| Yes, it can be done! To access the contents of sections you can use any of
44  //| your self-defined Java Beans compatible API.
45  //| In order to do this you only have to create a Java Beans-style interface or class.
46  //|
47  //| Source code for beans: {{{../sample/Dwarf.java.html}Dwarf}},
48  //| {{{../sample/DwarfBean.java.html}DwarfBean}}
49  //|
50  //| Code sniplets in this tutorial tested with the following .ini file:
51  //| {{{../sample/dwarfs.ini.html}dwarfs.ini}}
52  //|
53  //</editor-fold>
54  public class BeanTutorial extends AbstractTutorial
55  {
56      public static void main(String[] args) throws Exception
57      {
58          new BeanTutorial().run(filearg(args));
59      }
60  
61      @Override protected void run(File arg) throws Exception
62      {
63          Ini ini = new Ini(arg.toURI().toURL());
64  
65          sample01(ini);
66          sample02(ini);
67          sample03(ini);
68          sample04(arg.toURI().toURL());
69          Options opts = new Options();
70  
71          opts.putAll(ini.get(Dwarfs.PROP_BASHFUL));
72          sample05(opts);
73  
74          //
75          File optFile = new File(arg.getParentFile(), OptTutorial.FILENAME);
76  
77          sample06(optFile.toURI().toURL());
78      }
79  
80  //|
81  //|* Accessing sections as beans
82  //|
83  //| While writing a program we usually know the type of the section's values,
84  //| so we can define one or more java interfaces to access them. An advantage of
85  //| this solution is that the programmer doesn't have to convert the values
86  //| because they are converted automatically to the type defined in the
87  //| interface.
88  //|
89  //| Ofcourse you may use setters as well, not just getters. In this way you can
90  //| change values type safe way.
91  //{
92      void sample01(Ini ini)
93      {
94          Ini.Section sec = ini.get("happy");
95          Dwarf happy = sec.as(Dwarf.class);
96          int age = happy.getAge();
97          URI homePage = happy.getHomePage();
98  
99          happy.setWeight(45.55);
100 
101 //}
102 //|
103 //| The <<<happy instanceof Dwarf>>> relation is of course fulfilled in the
104 //| example above.
105 //|
106         assertEquals(DwarfsData.happy.homePage.toString(), homePage.toString());
107         assertEquals(DwarfsData.happy.age, age);
108         assertEquals(45.55, happy.getWeight(), 0.01);
109     }
110 
111 //|
112 //|* Marshalling beans
113 //|
114 //| Sometimes we want to store existing java beans in text file. This operation
115 //| usually called marshalling.
116 //|
117 //| With [ini4j] it is easy to store bean properties in a section. You simply
118 //| create a section, and call the sections's <<<from()>>> method. Thats it.
119 //{
120     void sample02(Ini ini)
121     {
122         DwarfBean sleepy = new DwarfBean();
123 
124         sleepy.setAge(87);
125         sleepy.setWeight(44.3);
126         Ini.Section sec = ini.add("sleepy");
127 
128         sec.from(sleepy);
129 
130 //}
131 //|
132         assertTrue(sec.containsKey(Dwarf.PROP_AGE));
133         assertTrue(sec.containsKey(Dwarf.PROP_WEIGHT));
134     }
135 
136 //|
137 //|* Unmarshalling beans
138 //|
139 //| If you have a marshalled bean in text file then you may want to read it
140 //| into bean. This operation usually called unmarshalling.
141 //|
142 //| With [ini4j] it is easy to load bean properties from a section. You simply
143 //| instantiate a bean, and call the sections's <<<to()>>> method. Thats it.
144 //{
145     void sample03(Ini ini)
146     {
147         DwarfBean grumpy = new DwarfBean();
148 
149         ini.get("grumpy").to(grumpy);
150 
151 //}
152 //|
153         assertEquals(DwarfsData.grumpy.age, grumpy.getAge());
154         assertEquals(DwarfsData.grumpy.homeDir, grumpy.getHomeDir());
155     }
156 
157 //|
158 //|* Indexed properties
159 //|
160 //| For handling indexed properties, you should allow mulpti option value
161 //| handling in configuration. After enabling this feature, option may contains
162 //| multiply values (multi line in file). These values can mapped to indexed
163 //| bean property.
164 //{
165     void sample04(URL location) throws IOException
166     {
167         Config cfg = new Config();
168 
169         cfg.setMultiOption(true);
170         Ini ini = new Ini();
171 
172         ini.setConfig(cfg);
173         ini.load(location);
174         Ini.Section sec = ini.get("sneezy");
175         Dwarf sneezy = sec.as(Dwarf.class);
176         int[] numbers = sneezy.getFortuneNumber();
177 
178         //
179         // same as above but with unmarshalling...
180         //
181         DwarfBean sneezyBean = new DwarfBean();
182 
183         sec.to(sneezyBean);
184         numbers = sneezyBean.getFortuneNumber();
185 
186 //}
187         assertArrayEquals(DwarfsData.sneezy.fortuneNumber, numbers);
188         assertEquals(DwarfsData.sneezy.fortuneNumber.length, sec.length("fortuneNumber"));
189         assertArrayEquals(DwarfsData.sneezy.fortuneNumber, sneezy.getFortuneNumber());
190         assertArrayEquals(DwarfsData.sneezy.fortuneNumber, sneezyBean.getFortuneNumber());
191     }
192 
193 //|
194 //|* Options
195 //|
196 //| Not only Ini and Ini.Section has bean interface. There is a bean interface
197 //| for OptionMap class and each derived class for example for Options.
198 //| Options is an improved java.util.Properties replacement.
199 //{
200     void sample05(Options opts)
201     {
202         Dwarf dwarf = opts.as(Dwarf.class);
203         int age = dwarf.getAge();
204 
205         //
206         // same as above but with unmarshalling
207         //
208         DwarfBean dwarfBean = new DwarfBean();
209 
210         opts.to(dwarfBean);
211         age = dwarfBean.getAge();
212 
213 //}
214 //|
215 //| In sample above the top level properties (like "age") mapped to bean
216 //| properties.
217 //|
218         assertEquals(DwarfsData.bashful.age, dwarf.getAge());
219         assertEquals(DwarfsData.bashful.age, dwarfBean.getAge());
220     }
221 
222 //|
223 //|* Prefixed mapping
224 //|
225 //| Both Ini.Section and Options has possibility to add a prefix to property
226 //| names while mapping from bean property name to Ini.Section or Options
227 //| key.
228 //{
229     void sample06(URL optPath) throws IOException
230     {
231         Options opt = new Options(optPath);
232         Dwarf dwarf = opt.as(Dwarf.class, "happy.");
233         DwarfBean bean = new DwarfBean();
234 
235         opt.to(bean, "dopey.");
236 
237 //}
238 //|
239 //| In the above example, <<<dwarf>>> bean will contain properties starts with
240 //| <<<happy.>>> while <<<bean>>> will contain properties starts with
241 //| <<<dopey.>>>
242         assertEquals(DwarfsData.happy.age, dwarf.getAge());
243         assertEquals(DwarfsData.dopey.age, bean.getAge());
244     }
245 //}
246 }