001 /*
002 * Copyright 2005,2009 Ivan SZKIBA
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.ini4j.tutorial;
017
018 import org.ini4j.Ini;
019
020 import org.ini4j.sample.Dwarf;
021 import org.ini4j.sample.Dwarfs;
022
023 import org.ini4j.test.DwarfsData;
024 import org.ini4j.test.Helper;
025
026 import static org.junit.Assert.assertEquals;
027 import static org.junit.Assert.assertNotNull;
028
029 import java.io.File;
030 import java.io.FileReader;
031 import java.io.IOException;
032
033 import java.util.Map;
034 import java.util.Set;
035
036 //<editor-fold defaultstate="collapsed" desc="apt documentation">
037 //|
038 //| -------------
039 //| Ini Tutorial
040 //|
041 //|Ini Tutorial - How to use \[ini4j\] api
042 //|
043 //| This tutorial familiarize the reader with the usage of
044 //| the [ini4j] library's natural interface.
045 //|
046 //| Code sniplets in this tutorial tested with the following .ini file:
047 //| {{{../sample/dwarfs.ini.html}dwarfs.ini}}
048 //|
049 //</editor-fold>
050 public class IniTutorial extends AbstractTutorial
051 {
052 public static void main(String[] args) throws Exception
053 {
054 new IniTutorial().run(filearg(args));
055 }
056
057 @Override protected void run(File arg) throws Exception
058 {
059 Ini ini = new Ini(arg.toURI().toURL());
060
061 sample01(ini);
062 sample02(arg);
063 sample03(ini);
064 sample04(ini);
065 }
066
067 //|* Data model
068 //|
069 //| Data model for .ini files is represented by org.ini4j.Ini class. This class
070 //| implements Map\<String,Section\>. It mean you can access sections using
071 //| java.util.Map collection API interface. The Section is also a map, which is
072 //| implements Map\<String,String\>.
073 //{
074 void sample01(Ini ini)
075 {
076 Ini.Section section = ini.get("happy");
077
078 //
079 // read some values
080 //
081 String age = section.get("age");
082 String weight = section.get("weight");
083 String homeDir = section.get("homeDir");
084
085 //
086 // .. or just use java.util.Map interface...
087 //
088 Map<String, String> map = ini.get("happy");
089
090 age = map.get("age");
091 weight = map.get("weight");
092 homeDir = map.get("homeDir");
093
094 // get all section names
095 Set<String> sectionNames = ini.keySet();
096
097 //}
098 Helper.assertEquals(DwarfsData.happy, section.as(Dwarf.class));
099 }
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 }