Clover coverage report - [ini4j]
Coverage timestamp: Sze nov. 30 2005 08:31:05 CET
file stats: LOC: 401   Methods: 33
NCLOC: 317   Classes: 5
 
 Source file Conditionals Statements Methods TOTAL
Ini.java 90% 98,4% 100% 96,9%
coverage coverage
 1    /*
 2    * Copyright 2005 [ini4j] Development Team
 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;
 17   
 18    import java.io.*;
 19    import java.net.URL;
 20    import java.util.*;
 21    import java.lang.reflect.*;
 22   
 23    import org.xml.sax.*;
 24    import org.xml.sax.helpers.*;
 25    import javax.xml.parsers.*;
 26   
 27    public class Ini extends LinkedHashMap<String,Ini.Section>
 28    {
 29    private static final String OPERATOR = " " + IniParser.OPERATOR + " ";
 30    private static final char SUBST_CHAR = '$';
 31    private static final String SUBST_BEGIN = SUBST_CHAR + "{";
 32    private static final int SUBST_BEGIN_LEN = SUBST_BEGIN.length();
 33    private static final String SUBST_END = "}";
 34    private static final int SUBST_END_LEN = SUBST_END.length();
 35    private static final char SUBST_ESCAPE = '\\';
 36    private static final char SUBST_SEPARATOR = '/';
 37    private static final String SUBST_PROPERTY = "@prop";
 38    private static final String SUBST_ENVIRONMENT = "@env";
 39   
 40    private Map<Class,Object> _beans;
 41   
 42    public class Section extends LinkedHashMap<String,String>
 43    {
 44    private String _name;
 45    private Map<Class,Object> _beans;
 46   
 47    class BeanInvocationHandler extends AbstractBeanInvocationHandler
 48    {
 49  401 protected Object getPropertySpi(String property, Class<?> clazz)
 50    {
 51  401 return fetch(property);
 52    }
 53   
 54  1 protected void setPropertySpi(String property, Object value, Class<?> clazz)
 55    {
 56  1 put(property, value.toString());
 57    }
 58   
 59  336 protected boolean hasPropertySpi(String property)
 60    {
 61  336 return containsKey(property);
 62    }
 63    }
 64   
 65  165 public Section(String name)
 66    {
 67  165 super();
 68  165 _name = name;
 69    }
 70   
 71  47 public String getName()
 72    {
 73  47 return _name;
 74    }
 75   
 76  85 public synchronized <T> T to(Class<T> clazz)
 77    {
 78  85 Object bean;
 79   
 80  85 if ( _beans == null )
 81    {
 82  80 _beans = new HashMap<Class,Object>();
 83  80 bean = null;
 84    }
 85    else
 86    {
 87  5 bean = _beans.get(clazz);
 88    }
 89   
 90  85 if ( bean == null )
 91    {
 92  81 bean = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] {clazz}, new BeanInvocationHandler());
 93  81 _beans.put(clazz, bean);
 94    }
 95   
 96  85 return clazz.cast(bean);
 97    }
 98   
 99  538 public String fetch(Object key)
 100    {
 101  538 String value = get(key);
 102   
 103  538 if ( (value != null) && (value.indexOf(SUBST_CHAR) >= 0) )
 104    {
 105  84 StringBuilder buffer = new StringBuilder(value);
 106  84 resolve(buffer, this);
 107  84 value = buffer.toString();
 108    }
 109  538 return value;
 110    }
 111    }
 112   
 113    class BeanInvocationHandler extends AbstractBeanInvocationHandler
 114    {
 115    private Map<String,Object> _sectionBeans = new HashMap<String, Object>();
 116   
 117  136 protected Object getPropertySpi(String property, Class<?> clazz)
 118    {
 119  136 Object o = _sectionBeans.get(property);
 120   
 121  136 if ( o == null )
 122    {
 123  80 Section section = get(property);
 124   
 125  80 if ( section != null )
 126    {
 127  79 o = section.to(clazz);
 128  79 _sectionBeans.put(property, o);
 129    }
 130    }
 131   
 132  136 return o;
 133    }
 134   
 135  1 protected void setPropertySpi(String property, Object value, Class<?> clazz)
 136    {
 137  1 throw new UnsupportedOperationException("read only bean");
 138    }
 139   
 140  1 protected boolean hasPropertySpi(String property)
 141    {
 142  1 return false;
 143    }
 144    }
 145   
 146    class Builder implements IniHandler
 147    {
 148    private Section currentSection;
 149   
 150  25 public void startIni()
 151    {
 152    ;
 153    }
 154   
 155  24 public void endIni()
 156    {
 157    ;
 158    }
 159   
 160  182 public void startSection(String sectionName)
 161    {
 162  182 Section s = get(sectionName);
 163  182 currentSection = (s != null) ? s : add(sectionName);
 164    }
 165   
 166  182 public void endSection()
 167    {
 168  182 currentSection = null;
 169    }
 170   
 171  671 public void handleOption(String name, String value)
 172    {
 173  671 currentSection.put(name, value);
 174    }
 175    }
 176   
 177  34 public Ini()
 178    {
 179    ;
 180    }
 181   
 182  2 public Ini(Reader input) throws IOException, InvalidIniFormatException
 183    {
 184  2 this();
 185  2 load(input);
 186    }
 187   
 188  12 public Ini(InputStream input) throws IOException, InvalidIniFormatException
 189    {
 190  12 this();
 191  12 load(input);
 192    }
 193   
 194  4 public Ini(URL input) throws IOException, InvalidIniFormatException
 195    {
 196  4 this();
 197  4 load(input);
 198    }
 199   
 200  165 public Section add(String name)
 201    {
 202  165 Section s = new Section(name);
 203  165 put(name, s);
 204  165 return s;
 205    }
 206   
 207  3 public Section remove(Section section)
 208    {
 209  3 return remove((Object)section.getName() );
 210    }
 211   
 212  1 public void store(OutputStream output) throws IOException
 213    {
 214  1 store(new OutputStreamWriter(output));
 215    }
 216   
 217  3 public void store(Writer output) throws IOException
 218    {
 219  3 PrintWriter pr = new PrintWriter(output);
 220   
 221  3 for(Ini.Section s : values())
 222    {
 223  15 pr.print(IniParser.SECTION_BEGIN);
 224  15 pr.print(Convert.escape(s.getName()));
 225  15 pr.println(IniParser.SECTION_END);
 226   
 227  15 for(Map.Entry<String,String> e : s.entrySet())
 228    {
 229  57 pr.print(Convert.escape(e.getKey()));
 230  57 pr.print(OPERATOR);
 231  57 pr.println(Convert.escape(e.getValue()));
 232    }
 233   
 234  15 pr.println();
 235    }
 236  3 pr.flush();
 237    }
 238   
 239  14 public void load(InputStream input) throws IOException, InvalidIniFormatException
 240    {
 241  14 load(new InputStreamReader(input));
 242    }
 243   
 244  17 public void load(Reader input) throws IOException, InvalidIniFormatException
 245    {
 246  17 Builder builder = new Builder();
 247  17 IniParser.newInstance().parse(input, builder);
 248    }
 249   
 250  9 public void load(URL input) throws IOException, InvalidIniFormatException
 251    {
 252  9 Builder builder = new Builder();
 253  9 IniParser.newInstance().parse(input, builder);
 254    }
 255   
 256  1 public void storeToXML(OutputStream output) throws IOException
 257    {
 258  1 storeToXML(new OutputStreamWriter(output));
 259    }
 260   
 261  2 public void storeToXML(Writer output) throws IOException
 262    {
 263  2 PrintWriter pr = new PrintWriter(output);
 264   
 265  2 pr.println("<ini version='1.0'>");
 266   
 267  2 for(Ini.Section s : values())
 268    {
 269  14 pr.print(" <section key='");
 270  14 pr.print(s.getName());
 271  14 pr.println("'>");
 272   
 273  14 for(Map.Entry<String,String> e : s.entrySet())
 274    {
 275  56 pr.print(" <option key='");
 276  56 pr.print(e.getKey());
 277  56 pr.print("' value='");
 278  56 pr.print(e.getValue());
 279  56 pr.println("'/>");
 280    }
 281   
 282  14 pr.println(" </section>");
 283    }
 284   
 285  2 pr.println("</ini>");
 286  2 pr.flush();
 287    }
 288   
 289  2 public void loadFromXML(InputStream input) throws IOException, InvalidIniFormatException
 290    {
 291  2 loadFromXML(new InputStreamReader(input));
 292    }
 293   
 294  3 public void loadFromXML(Reader input) throws IOException, InvalidIniFormatException
 295    {
 296  3 Builder builder = new Builder();
 297  3 IniParser.newInstance().parseXML(input, builder);
 298    }
 299   
 300  1 public void loadFromXML(URL input) throws IOException, InvalidIniFormatException
 301    {
 302  1 Builder builder = new Builder();
 303  1 IniParser.newInstance().parseXML(input, builder);
 304    }
 305   
 306  16 public <T> T to(Class<T> clazz)
 307    {
 308  16 Object bean;
 309   
 310  16 if ( _beans == null )
 311    {
 312  13 _beans = new HashMap<Class,Object>();
 313  13 bean = null;
 314    }
 315    else
 316    {
 317  3 bean = _beans.get(clazz);
 318    }
 319   
 320  16 if ( bean == null )
 321    {
 322  14 bean = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] {clazz}, new BeanInvocationHandler());
 323  14 _beans.put(clazz, bean);
 324    }
 325   
 326  16 return clazz.cast(bean);
 327    }
 328   
 329  95 protected void resolve(StringBuilder buffer, Section owner)
 330    {
 331  95 int begin = -1;
 332  95 int end = -1;
 333   
 334  95 for(int i = buffer.indexOf(SUBST_BEGIN); (i>=0); i = buffer.indexOf(SUBST_BEGIN, i+1) )
 335    {
 336  95 if ( (i+2) > buffer.length() )
 337    {
 338  0 break;
 339    }
 340   
 341  95 if ( (i != 0) && (buffer.charAt(i-1) == SUBST_ESCAPE) )
 342    {
 343  0 continue;
 344    }
 345   
 346  95 begin = i;
 347   
 348  95 end = buffer.indexOf(SUBST_END, i);
 349   
 350  95 if ( end < 0 )
 351    {
 352  2 break;
 353    }
 354   
 355  93 if ( (begin >= 0) && (end > 0) )
 356    {
 357  93 String var = buffer.substring(begin+SUBST_BEGIN_LEN,end);
 358  93 String group = null;
 359  93 int sep = var.indexOf(SUBST_SEPARATOR);
 360  93 String value = null;
 361   
 362  93 if ( sep > 0 )
 363    {
 364  90 group = var.substring(0,sep);
 365  90 var = var.substring(sep+1);
 366    }
 367   
 368  93 if ( var != null )
 369    {
 370  93 if ( group == null )
 371    {
 372  3 value = owner.fetch(var);
 373    }
 374  90 else if ( SUBST_ENVIRONMENT.equals(group))
 375    {
 376  1 value = System.getenv(var);
 377    }
 378  89 else if ( SUBST_PROPERTY.equals(group) )
 379    {
 380  1 value = System.getProperty(var);
 381    }
 382    else
 383    {
 384  88 owner = get(group);
 385   
 386  88 if ( owner != null )
 387    {
 388  87 value = owner.fetch(var);
 389    }
 390    }
 391    }
 392   
 393  93 if ( value != null )
 394    {
 395  89 buffer.replace(begin,end+SUBST_END_LEN, value);
 396    }
 397    }
 398    }
 399    }
 400   
 401    }