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.Config; 019import org.ini4j.Ini; 020import org.ini4j.Options; 021 022import org.ini4j.sample.Dwarf; 023import org.ini4j.sample.DwarfBean; 024import org.ini4j.sample.Dwarfs; 025 026import org.ini4j.test.DwarfsData; 027 028import static org.junit.Assert.*; 029 030import java.io.File; 031import java.io.IOException; 032 033import java.net.URI; 034import java.net.URL; 035 036//<editor-fold defaultstate="collapsed" desc="apt documentation"> 037//| 038//| ------------- 039//| Bean Tutorial 040//| 041//|Bean Tutorial - Using your own API ! 042//| 043//| Yes, it can be done! To access the contents of sections you can use any of 044//| your self-defined Java Beans compatible API. 045//| In order to do this you only have to create a Java Beans-style interface or class. 046//| 047//| Source code for beans: {{{../sample/Dwarf.java.html}Dwarf}}, 048//| {{{../sample/DwarfBean.java.html}DwarfBean}} 049//| 050//| Code sniplets in this tutorial tested with the following .ini file: 051//| {{{../sample/dwarfs.ini.html}dwarfs.ini}} 052//| 053//</editor-fold> 054public class BeanTutorial extends AbstractTutorial 055{ 056 public static void main(String[] args) throws Exception 057 { 058 new BeanTutorial().run(filearg(args)); 059 } 060 061 @Override protected void run(File arg) throws Exception 062 { 063 Ini ini = new Ini(arg.toURI().toURL()); 064 065 sample01(ini); 066 sample02(ini); 067 sample03(ini); 068 sample04(arg.toURI().toURL()); 069 Options opts = new Options(); 070 071 opts.putAll(ini.get(Dwarfs.PROP_BASHFUL)); 072 sample05(opts); 073 074 // 075 File optFile = new File(arg.getParentFile(), OptTutorial.FILENAME); 076 077 sample06(optFile.toURI().toURL()); 078 } 079 080//| 081//|* Accessing sections as beans 082//| 083//| While writing a program we usually know the type of the section's values, 084//| so we can define one or more java interfaces to access them. An advantage of 085//| this solution is that the programmer doesn't have to convert the values 086//| because they are converted automatically to the type defined in the 087//| interface. 088//| 089//| Ofcourse you may use setters as well, not just getters. In this way you can 090//| change values type safe way. 091//{ 092 void sample01(Ini ini) 093 { 094 Ini.Section sec = ini.get("happy"); 095 Dwarf happy = sec.as(Dwarf.class); 096 int age = happy.getAge(); 097 URI homePage = happy.getHomePage(); 098 099 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}