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 */ 016package org.ini4j.tutorial; 017 018import org.ini4j.Ini; 019 020import org.ini4j.sample.Dwarf; 021import org.ini4j.sample.Dwarfs; 022 023import org.ini4j.test.DwarfsData; 024import org.ini4j.test.Helper; 025 026import static org.junit.Assert.assertEquals; 027import static org.junit.Assert.assertNotNull; 028 029import java.io.File; 030import java.io.FileReader; 031import java.io.IOException; 032 033import java.util.Map; 034import 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> 050public 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}