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.Ini;
19
20 import org.ini4j.sample.Dwarf;
21 import org.ini4j.sample.Dwarfs;
22
23 import org.ini4j.test.DwarfsData;
24 import org.ini4j.test.Helper;
25
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertNotNull;
28
29 import java.io.File;
30 import java.io.FileReader;
31 import java.io.IOException;
32
33 import java.util.Map;
34 import java.util.Set;
35
36 //<editor-fold defaultstate="collapsed" desc="apt documentation">
37 //|
38 //| -------------
39 //| Ini Tutorial
40 //|
41 //|Ini Tutorial - How to use \[ini4j\] api
42 //|
43 //| This tutorial familiarize the reader with the usage of
44 //| the [ini4j] library's natural interface.
45 //|
46 //| Code sniplets in this tutorial tested with the following .ini file:
47 //| {{{../sample/dwarfs.ini.html}dwarfs.ini}}
48 //|
49 //</editor-fold>
50 public class IniTutorial extends AbstractTutorial
51 {
52 public static void main(String[] args) throws Exception
53 {
54 new IniTutorial().run(filearg(args));
55 }
56
57 @Override protected void run(File arg) throws Exception
58 {
59 Ini ini = new Ini(arg.toURI().toURL());
60
61 sample01(ini);
62 sample02(arg);
63 sample03(ini);
64 sample04(ini);
65 }
66
67 //|* Data model
68 //|
69 //| Data model for .ini files is represented by org.ini4j.Ini class. This class
70 //| implements Map\<String,Section\>. It mean you can access sections using
71 //| java.util.Map collection API interface. The Section is also a map, which is
72 //| implements Map\<String,String\>.
73 //{
74 void sample01(Ini ini)
75 {
76 Ini.Section section = ini.get("happy");
77
78 //
79 // read some values
80 //
81 String age = section.get("age");
82 String weight = section.get("weight");
83 String homeDir = section.get("homeDir");
84
85 //
86 // .. or just use java.util.Map interface...
87 //
88 Map<String, String> map = ini.get("happy");
89
90 age = map.get("age");
91 weight = map.get("weight");
92 homeDir = map.get("homeDir");
93
94 // get all section names
95 Set<String> sectionNames = ini.keySet();
96
97 //}
98 Helper.assertEquals(DwarfsData.happy, section.as(Dwarf.class));
99 }
100
101 //|
102 //|* Loading and storing data
103 //|
104 //| There is several way to load data into Ini object. It can be done by using
105 //| <<<load>>> methods or overloaded constructors. Data can be load from
106 //| InputStream, Reader, URL or File.
107 //|
108 //| You can store data using <<<store>>> methods. Data can store to OutputStream,
109 //| Writer, or File.
110 //{
111 void sample02(File file) throws IOException
112 {
113 Ini ini = new Ini();
114
115 ini.load(new FileReader(file));
116
117 //
118 // or instantiate and load data:
119 //
120 ini = new Ini(new FileReader(file));
121 File copy = File.createTempFile("sample", ".ini");
122
123 ini.store(copy);
124 //}
125 ini = new Ini(copy);
126 Helper.assertEquals(DwarfsData.dwarfs, ini.as(Dwarfs.class));
127 copy.delete();
128 }
129
130 //|
131 //|* Macro/variable substitution
132 //|
133 //| To get a value, besides <<<get()>>> you can also
134 //| use <<<fetch()>>> which resolves any occurrent $\{section/option\} format
135 //| variable references in the needed value.
136 //|
137 //{
138 void sample03(Ini ini)
139 {
140 Ini.Section dopey = ini.get("dopey");
141
142 // get method doesn't resolve variable references
143 String weightRaw = dopey.get("weight"); // = ${bashful/weight}
144 String heightRaw = dopey.get("height"); // = ${doc/height}
145
146 // to resolve references, you should use fetch method
147 String weight = dopey.fetch("weight"); // = 45.7
148 String height = dopey.fetch("height"); // = 87.7
149
150 //}
151 //| Assuming we have an .ini file with the following sections:
152 //|
153 //|+--------------+
154 //| [dopey]
155 //| weight = ${bashful/weight}
156 //| height = ${doc/height}
157 //|
158 //|[bashful]
159 //| weight = 45.7
160 //| height = 98.8
161 //|
162 //| [doc]
163 //| weight = 49.5
164 //| height = 87.7
165 //|+--------------+
166 //|
167 assertEquals(DwarfsData.INI_DOPEY_WEIGHT, weightRaw);
168 assertEquals(DwarfsData.INI_DOPEY_HEIGHT, heightRaw);
169 assertEquals(String.valueOf(DwarfsData.dopey.weight), weight);
170 assertEquals(String.valueOf(DwarfsData.dopey.height), height);
171 }
172
173 //|
174 //|* Multi values
175 //|
176 //| \[ini4j\] library introduces MultiMap interface, which is extends normal
177 //| Map, but allows multiply values per keys. You can simply index values for
178 //| a given key, similar to indexed properties in JavaBeans api.
179 //|
180 //{
181 void sample04(Ini ini)
182 {
183 Ini.Section sneezy = ini.get("sneezy");
184 String n1 = sneezy.get("fortuneNumber", 0); // = 11
185 String n2 = sneezy.get("fortuneNumber", 1); // = 22
186 String n3 = sneezy.get("fortuneNumber", 2); // = 33
187 String n4 = sneezy.get("fortuneNumber", 3); // = 44
188
189 // ok, lets do in it easier...
190 int[] n = sneezy.getAll("fortuneNumber", int[].class);
191 //}
192 // #2817399
193
194 assertEquals("11", n1);
195 assertEquals("22", n2);
196 assertEquals("33", n3);
197 assertEquals("44", n4);
198 assertEquals(4, n.length);
199 assertEquals(11, n[0]);
200 assertEquals(22, n[1]);
201 assertEquals(33, n[2]);
202 assertEquals(44, n[3]);
203 }
204
205 //|
206 //|* Tree model
207 //|
208 //| Beyond two level map model, Ini class provides tree model. You can access
209 //| Sections as tree. It means that section names becomes path names, with a
210 //| path separator character ('/' and '\' on Wini and Reg).
211 //|
212 //{
213 void sample05()
214 {
215 Ini ini = new Ini();
216
217 // lets add a section, it will create needed intermediate sections as well
218 ini.add("root/child/sub");
219
220 //
221 Ini.Section root;
222 Ini.Section sec;
223
224 root = ini.get("root");
225 sec = root.getChild("child").getChild("sub");
226
227 // or...
228 sec = root.lookup("child", "sub");
229
230 // or...
231 sec = root.lookup("child/sub");
232
233 // or even...
234 sec = ini.get("root/child/sub");
235
236 //}
237 //| If you are using Wini instead of Ini class, the path separator become '\'.
238 //|
239 assertNotNull(root.lookup("child", "sub"));
240 assertNotNull(ini.get("root/child"));
241 }
242 }