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.spi;
017
018 import org.ini4j.Config;
019 import org.ini4j.InvalidFileFormatException;
020
021 import java.io.IOException;
022 import java.io.InputStream;
023 import java.io.Reader;
024
025 import java.net.URL;
026
027 import java.util.Locale;
028
029 public class IniParser extends AbstractParser
030 {
031 private static final String COMMENTS = ";#";
032 private static final String OPERATORS = ":=";
033 static final char SECTION_BEGIN = '[';
034 static final char SECTION_END = ']';
035
036 public IniParser()
037 {
038 super(OPERATORS, COMMENTS);
039 }
040
041 public static IniParser newInstance()
042 {
043 return ServiceFinder.findService(IniParser.class);
044 }
045
046 public static IniParser newInstance(Config config)
047 {
048 IniParser instance = newInstance();
049
050 instance.setConfig(config);
051
052 return instance;
053 }
054
055 public void parse(InputStream input, IniHandler handler) throws IOException, InvalidFileFormatException
056 {
057 parse(newIniSource(input, handler), handler);
058 }
059
060 public void parse(Reader input, IniHandler handler) throws IOException, InvalidFileFormatException
061 {
062 parse(newIniSource(input, handler), handler);
063 }
064
065 public void parse(URL input, IniHandler handler) throws IOException, InvalidFileFormatException
066 {
067 parse(newIniSource(input, handler), handler);
068 }
069
070 private void parse(IniSource source, IniHandler handler) throws IOException, InvalidFileFormatException
071 {
072 handler.startIni();
073 String sectionName = null;
074
075 for (String line = source.readLine(); line != null; line = source.readLine())
076 {
077 if (line.charAt(0) == SECTION_BEGIN)
078 {
079 if (sectionName != null)
080 {
081 handler.endSection();
082 }
083
084 sectionName = parseSectionLine(line, source, handler);
085 }
086 else
087 {
088 if (sectionName == null)
089 {
090 if (getConfig().isGlobalSection())
091 {
092 sectionName = getConfig().getGlobalSectionName();
093 handler.startSection(sectionName);
094 }
095 else
096 {
097 parseError(line, source.getLineNumber());
098 }
099 }
100
101 parseOptionLine(line, handler, source.getLineNumber());
102 }
103 }
104
105 if (sectionName != null)
106 {
107 handler.endSection();
108 }
109
110 handler.endIni();
111 }
112
113 private String parseSectionLine(String line, IniSource source, IniHandler handler) throws InvalidFileFormatException
114 {
115 String sectionName;
116
117 if (line.charAt(line.length() - 1) != SECTION_END)
118 {
119 parseError(line, source.getLineNumber());
120 }
121
122 sectionName = unescapeFilter(line.substring(1, line.length() - 1).trim());
123 if ((sectionName.length() == 0) && !getConfig().isUnnamedSection())
124 {
125 parseError(line, source.getLineNumber());
126 }
127
128 if (getConfig().isLowerCaseSection())
129 {
130 sectionName = sectionName.toLowerCase(Locale.getDefault());
131 }
132
133 handler.startSection(sectionName);
134
135 return sectionName;
136 }
137 }