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 }