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    }