Coverage Report - org.ini4j.spi.IniSource
 
Classes in this File Line Coverage Branch Coverage Complexity
IniSource
100%
71/71
93%
43/46
3.091
 
 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.spi;
 17  
 
 18  
 import org.ini4j.Config;
 19  
 
 20  
 import java.io.IOException;
 21  
 import java.io.InputStream;
 22  
 import java.io.LineNumberReader;
 23  
 import java.io.Reader;
 24  
 
 25  
 import java.net.URL;
 26  
 
 27  
 class IniSource
 28  
 {
 29  
     public static final char INCLUDE_BEGIN = '<';
 30  
     public static final char INCLUDE_END = '>';
 31  
     public static final char INCLUDE_OPTIONAL = '?';
 32  
     private static final char ESCAPE_CHAR = '\\';
 33  
     private URL _base;
 34  
     private IniSource _chain;
 35  
     private final String _commentChars;
 36  
     private final Config _config;
 37  
     private final HandlerBase _handler;
 38  
     private final LineNumberReader _reader;
 39  
 
 40  
     IniSource(InputStream input, HandlerBase handler, String comments, Config config)
 41  
     {
 42  11
         this(new UnicodeInputStreamReader(input, config.getFileEncoding()), handler, comments, config);
 43  11
     }
 44  
 
 45  
     IniSource(Reader input, HandlerBase handler, String comments, Config config)
 46  135
     {
 47  135
         _reader = new LineNumberReader(input);
 48  135
         _handler = handler;
 49  135
         _commentChars = comments;
 50  135
         _config = config;
 51  135
     }
 52  
 
 53  
     IniSource(URL input, HandlerBase handler, String comments, Config config) throws IOException
 54  
     {
 55  31
         this(new UnicodeInputStreamReader(input.openStream(), config.getFileEncoding()), handler, comments, config);
 56  30
         _base = input;
 57  30
     }
 58  
 
 59  
     int getLineNumber()
 60  
     {
 61  
         int ret;
 62  
 
 63  3464
         if (_chain == null)
 64  
         {
 65  3433
             ret = _reader.getLineNumber();
 66  
         }
 67  
         else
 68  
         {
 69  31
             ret = _chain.getLineNumber();
 70  
         }
 71  
 
 72  3464
         return ret;
 73  
     }
 74  
 
 75  
     String readLine() throws IOException
 76  
     {
 77  
         String line;
 78  
 
 79  4155
         if (_chain == null)
 80  
         {
 81  4120
             line = readLineLocal();
 82  
         }
 83  
         else
 84  
         {
 85  35
             line = _chain.readLine();
 86  35
             if (line == null)
 87  
             {
 88  4
                 _chain = null;
 89  4
                 line = readLine();
 90  
             }
 91  
         }
 92  
 
 93  4155
         return line;
 94  
     }
 95  
 
 96  
     private void close() throws IOException
 97  
     {
 98  117
         _reader.close();
 99  117
     }
 100  
 
 101  
     private int countEndingEscapes(String line)
 102  
     {
 103  3965
         int escapeCount = 0;
 104  
 
 105  4039
         for (int i = line.length() - 1; (i >= 0) && (line.charAt(i) == ESCAPE_CHAR); i--)
 106  
         {
 107  74
             escapeCount++;
 108  
         }
 109  
 
 110  3965
         return escapeCount;
 111  
     }
 112  
 
 113  
     private void handleComment(StringBuilder buff)
 114  
     {
 115  4961
         if (buff.length() != 0)
 116  
         {
 117  790
             buff.deleteCharAt(buff.length() - 1);
 118  790
             _handler.handleComment(buff.toString());
 119  790
             buff.delete(0, buff.length());
 120  
         }
 121  4961
     }
 122  
 
 123  
     private String handleInclude(String input) throws IOException
 124  
     {
 125  4003
         String line = input;
 126  
 
 127  4003
         if (_config.isInclude() && (line.length() > 2) && (line.charAt(0) == INCLUDE_BEGIN) && (line.charAt(line.length() - 1) == INCLUDE_END))
 128  
         {
 129  5
             line = line.substring(1, line.length() - 1).trim();
 130  5
             boolean optional = line.charAt(0) == INCLUDE_OPTIONAL;
 131  
 
 132  5
             if (optional)
 133  
             {
 134  2
                 line = line.substring(1).trim();
 135  
             }
 136  
 
 137  5
             URL loc = (_base == null) ? new URL(line) : new URL(_base, line);
 138  
 
 139  5
             if (optional)
 140  
             {
 141  
                 try
 142  
                 {
 143  2
                     _chain = new IniSource(loc, _handler, _commentChars, _config);
 144  
                 }
 145  1
                 catch (IOException x)
 146  
                 {
 147  
                     assert true;
 148  
                 }
 149  
                 finally
 150  
                 {
 151  2
                     line = readLine();
 152  2
                 }
 153  
             }
 154  
             else
 155  
             {
 156  3
                 _chain = new IniSource(loc, _handler, _commentChars, _config);
 157  3
                 line = readLine();
 158  
             }
 159  
         }
 160  
 
 161  4003
         return line;
 162  
     }
 163  
 
 164  
     private String readLineLocal() throws IOException
 165  
     {
 166  4120
         String line = readLineSkipComments();
 167  
 
 168  4120
         if (line == null)
 169  
         {
 170  117
             close();
 171  
         }
 172  
         else
 173  
         {
 174  4003
             line = handleInclude(line);
 175  
         }
 176  
 
 177  4120
         return line;
 178  
     }
 179  
 
 180  
     private String readLineSkipComments() throws IOException
 181  
     {
 182  
         String line;
 183  4120
         StringBuilder comment = new StringBuilder();
 184  4120
         StringBuilder buff = new StringBuilder();
 185  
 
 186  7334
         for (line = _reader.readLine(); line != null; line = _reader.readLine())
 187  
         {
 188  7217
             line = line.trim();
 189  7217
             if (line.length() == 0)
 190  
             {
 191  830
                 handleComment(comment);
 192  
             }
 193  6387
             else if ((_commentChars.indexOf(line.charAt(0)) >= 0) && (buff.length() == 0))
 194  
             {
 195  2318
                 comment.append(line.substring(1));
 196  2318
                 comment.append(_config.getLineSeparator());
 197  
             }
 198  
             else
 199  
             {
 200  4069
                 handleComment(comment);
 201  4069
                 if (!_config.isEscapeNewline() || ((countEndingEscapes(line) & 1) == 0))
 202  
                 {
 203  4003
                     buff.append(line);
 204  4003
                     line = buff.toString();
 205  
 
 206  4003
                     break;
 207  
                 }
 208  
 
 209  66
                 buff.append(line.subSequence(0, line.length() - 1));
 210  
             }
 211  
         }
 212  
 
 213  
         // handle end comments
 214  4120
         if ((line == null) && (comment.length() != 0))
 215  
         {
 216  62
             handleComment(comment);
 217  
         }
 218  
 
 219  4120
         return line;
 220  
     }
 221  
 }