/*
Copyright (C) 2011 monte
This file is part of PSP NetParty.
PSP NetParty is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package pspnetparty.lib;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import java.util.Set;
import pspnetparty.lib.constants.AppConstants;
public class IniFile {
private HashMap<String, HashMap<String, String>> sectionMap = new LinkedHashMap<String, HashMap<String, String>>();
private HashMap<String, String> rootSection = new LinkedHashMap<String, String>();
private boolean hasChanged = false;
private String iniFilePath;
public IniFile(String iniPath) throws IOException {
if (Utility.isEmpty(iniPath)) {
throw new IllegalArgumentException();
}
iniFilePath = iniPath;
BufferedReader bufferedReader = null;
File file = new File(iniPath);
if (file.isFile()) {
try {
FileInputStream fileInputStream = new FileInputStream(file);
InputStreamReader streamReader = new InputStreamReader(fileInputStream, AppConstants.CHARSET);
bufferedReader = new BufferedReader(streamReader);
bufferedReader.mark(1);
if (bufferedReader.read() != 65279) {
bufferedReader.reset();
}
HashMap<String, String> currentSection = rootSection;
String line;
while ((line = bufferedReader.readLine()) != null) {
line = line.trim();
if (Utility.isEmpty(line) || line.startsWith("'"))
continue;
if (line.startsWith("[") && line.endsWith("]")) {
String section = line.substring(1, line.length() - 1);
currentSection = sectionMap.get(section);
if (currentSection == null) {
currentSection = new LinkedHashMap<String, String>();
sectionMap.put(section, currentSection);
}
} else {
String[] keyValue = line.split("=", 2);
if (keyValue.length == 2) {
String key = keyValue[0].trim();
String value = keyValue[1].trim();
currentSection.put(key, value);
}
}
}
} catch (IOException e) {
throw e;
} finally {
if (bufferedReader != null)
bufferedReader.close();
}
} else {
FileWriter writer = new FileWriter(iniPath, false);
writer.close();
}
}
public IniSection getSection(String section) {
HashMap<String, String> map = Utility.isEmpty(section) ? rootSection : sectionMap.get(section);
if (map == null) {
map = new LinkedHashMap<String, String>();
sectionMap.put(section, map);
}
final HashMap<String, String> settings = map;
return new IniSection() {
@Override
public void set(String key, String value) {
settings.put(key, value);
hasChanged = true;
}
@Override
public void set(String key, boolean value) {
set(key, value ? "Yes" : "No");
}
@Override
public void set(String key, int value) {
set(key, Integer.toString(value));
}
@Override
public void set(String key, int[] values) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < values.length; i++) {
sb.append(values[i]);
sb.append(',');
}
if (sb.length() > 0)
sb.deleteCharAt(sb.length() - 1);
set(key, sb.toString());
}
@Override
public void remove(String key) {
settings.remove(key);
hasChanged = true;
}
@Override
public String get(String key, String defaultValue) {
if (settings.containsKey(key)) {
return settings.get(key);
}
set(key, defaultValue);
return defaultValue;
}
@Override
public int get(String key, int defaultValue) {
String string = settings.get(key);
if (string == null) {
set(key, Integer.toString(defaultValue));
return defaultValue;
}
try {
int value = Integer.parseInt(string);
return value;
} catch (NumberFormatException e) {
set(key, Integer.toString(defaultValue));
return defaultValue;
}
}
@Override
public boolean get(String key, boolean defaultValue) {
String string = settings.get(key);
if (string == null) {
set(key, defaultValue ? "Yes" : "No");
return defaultValue;
}
return "Yes".equals(string);
}
@Override
public int[] get(String key, int[] defaultValues) {
try {
String string = settings.get(key);
if (string != null) {
String[] tokens = string.split(",");
if (tokens.length == defaultValues.length) {
int[] values = new int[tokens.length];
for (int i = 0; i < tokens.length; i++) {
values[i] = Integer.parseInt(tokens[i]);
}
return values;
}
}
} catch (NumberFormatException e) {
}
set(key, defaultValues);
return defaultValues;
}
@Override
public Set<Entry<String, String>> entrySet() {
return settings.entrySet();
}
};
}
public void saveToIni() throws IOException {
saveToIni(null);
}
public void saveToIni(String newFilePath) throws IOException {
if (!hasChanged)
return;
iniFilePath = Utility.isEmpty(newFilePath) ? iniFilePath : newFilePath;
FileOutputStream fileOutputStream = new FileOutputStream(iniFilePath, false);
OutputStreamWriter streamWriter = new OutputStreamWriter(fileOutputStream, AppConstants.CHARSET);
BufferedWriter bufferedWriter = new BufferedWriter(streamWriter);
PrintWriter printWriter = new PrintWriter(bufferedWriter);
appendSettings(printWriter, rootSection);
for (Entry<String, HashMap<String, String>> entry : sectionMap.entrySet()) {
printWriter.println("[" + entry.getKey() + "]");
appendSettings(printWriter, entry.getValue());
printWriter.println();
}
printWriter.close();
hasChanged = false;
}
private void appendSettings(PrintWriter writer, HashMap<String, String> props) {
for (Entry<String, String> entry : props.entrySet()) {
String value = entry.getValue();
if (value == null)
value = "";
writer.printf("%s=%s", entry.getKey(), value);
writer.println();
}
}
public static void main(String[] args) throws Exception {
IniFile parser = new IniFile("Test.ini");
parser.saveToIni("Test2.ini");
}
}