tikhomirov@69: /* tikhomirov@69: * Copyright (c) 2011 TMate Software Ltd tikhomirov@69: * tikhomirov@69: * This program is free software; you can redistribute it and/or modify tikhomirov@69: * it under the terms of the GNU General Public License as published by tikhomirov@69: * the Free Software Foundation; version 2 of the License. tikhomirov@69: * tikhomirov@69: * This program is distributed in the hope that it will be useful, tikhomirov@69: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@69: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@69: * GNU General Public License for more details. tikhomirov@69: * tikhomirov@69: * For information on how to redistribute this software under tikhomirov@69: * the terms of a license other than GNU General Public License tikhomirov@102: * contact TMate Software at support@hg4j.com tikhomirov@69: */ tikhomirov@69: package org.tmatesoft.hg.internal; tikhomirov@69: tikhomirov@69: import java.io.BufferedReader; tikhomirov@69: import java.io.File; tikhomirov@69: import java.io.FileReader; tikhomirov@69: import java.io.IOException; tikhomirov@69: import java.util.ArrayList; tikhomirov@69: import java.util.Collections; tikhomirov@69: import java.util.LinkedHashMap; tikhomirov@69: import java.util.List; tikhomirov@69: import java.util.Map; tikhomirov@69: tikhomirov@69: /** tikhomirov@69: * tikhomirov@69: * @author Artem Tikhomirov tikhomirov@69: * @author TMate Software Ltd. tikhomirov@69: */ tikhomirov@69: public class ConfigFile { tikhomirov@69: tikhomirov@69: private List sections; tikhomirov@69: private List> content; tikhomirov@69: tikhomirov@114: ConfigFile() { tikhomirov@69: } tikhomirov@69: tikhomirov@69: public void addLocation(File path) { tikhomirov@69: read(path); tikhomirov@69: } tikhomirov@69: tikhomirov@114: public boolean hasSection(String sectionName) { tikhomirov@114: return sections == null ? false : sections.indexOf(sectionName) == -1; tikhomirov@114: } tikhomirov@114: tikhomirov@114: // XXX perhaps, should be moved to subclass HgRepoConfig, as it is not common operation for any config file tikhomirov@114: public boolean hasEnabledExtension(String extensionName) { tikhomirov@114: int x = sections != null ? sections.indexOf("extensions") : -1; tikhomirov@114: if (x == -1) { tikhomirov@114: return false; tikhomirov@114: } tikhomirov@114: String value = content.get(x).get(extensionName); tikhomirov@114: return value != null && !"!".equals(value); tikhomirov@114: } tikhomirov@114: tikhomirov@69: public List getSectionNames() { tikhomirov@114: return sections == null ? Collections.emptyList() : Collections.unmodifiableList(sections); tikhomirov@69: } tikhomirov@69: tikhomirov@69: public Map getSection(String sectionName) { tikhomirov@114: if (sections == null) { tikhomirov@114: return Collections.emptyMap(); tikhomirov@114: } tikhomirov@69: int x = sections.indexOf(sectionName); tikhomirov@69: if (x == -1) { tikhomirov@69: return Collections.emptyMap(); tikhomirov@69: } tikhomirov@69: return Collections.unmodifiableMap(content.get(x)); tikhomirov@69: } tikhomirov@69: tikhomirov@114: public boolean getBoolean(String sectionName, String key, boolean defaultValue) { tikhomirov@114: String value = getSection(sectionName).get(key); tikhomirov@114: if (value == null) { tikhomirov@114: return defaultValue; tikhomirov@114: } tikhomirov@114: for (String s : new String[] { "true", "yes", "on", "1" }) { tikhomirov@114: if (s.equalsIgnoreCase(value)) { tikhomirov@114: return true; tikhomirov@114: } tikhomirov@114: } tikhomirov@114: return false; tikhomirov@114: } tikhomirov@128: tikhomirov@128: public String getString(String sectionName, String key, String defaultValue) { tikhomirov@128: String value = getSection(sectionName).get(key); tikhomirov@128: return value == null ? defaultValue : value; tikhomirov@128: } tikhomirov@114: tikhomirov@114: // TODO handle %include and %unset directives tikhomirov@114: // TODO "" and lists tikhomirov@69: private void read(File f) { tikhomirov@114: if (f == null || !f.canRead()) { tikhomirov@114: return; tikhomirov@114: } tikhomirov@69: if (sections == null) { tikhomirov@69: sections = new ArrayList(); tikhomirov@69: content = new ArrayList>(); tikhomirov@69: } tikhomirov@69: try { tikhomirov@69: BufferedReader br = new BufferedReader(new FileReader(f)); tikhomirov@69: String line; tikhomirov@69: String sectionName = ""; tikhomirov@69: Map section = new LinkedHashMap(); tikhomirov@69: while ((line = br.readLine()) != null) { tikhomirov@69: line = line.trim(); tikhomirov@136: int x; tikhomirov@136: if ((x = line.indexOf('#')) != -1) { tikhomirov@136: // do not keep comments in memory, get new, shorter string tikhomirov@136: line = new String(line.substring(0, x).trim()); tikhomirov@136: } tikhomirov@69: if (line.length() <= 2) { // a=b or [a] are at least of length 3 tikhomirov@69: continue; tikhomirov@69: } tikhomirov@69: if (line.charAt(0) == '[' && line.charAt(line.length() - 1) == ']') { tikhomirov@69: sectionName = line.substring(1, line.length() - 1); tikhomirov@69: if (sections.indexOf(sectionName) == -1) { tikhomirov@69: sections.add(sectionName); tikhomirov@69: content.add(section = new LinkedHashMap()); tikhomirov@69: } else { tikhomirov@69: section = null; // drop cached value tikhomirov@69: } tikhomirov@69: } else if ((x = line.indexOf('=')) != -1) { tikhomirov@136: // share char[] of the original string tikhomirov@69: String key = line.substring(0, x).trim(); tikhomirov@69: String value = line.substring(x+1).trim(); tikhomirov@69: if (section == null) { tikhomirov@69: int i = sections.indexOf(sectionName); tikhomirov@69: assert i >= 0; tikhomirov@69: section = content.get(i); tikhomirov@69: } tikhomirov@69: if (sectionName.length() == 0) { tikhomirov@69: // add fake section only if there are any values tikhomirov@69: sections.add(sectionName); tikhomirov@69: content.add(section); tikhomirov@69: } tikhomirov@69: section.put(key, value); tikhomirov@69: } tikhomirov@69: } tikhomirov@73: br.close(); tikhomirov@69: } catch (IOException ex) { tikhomirov@69: ex.printStackTrace(); // XXX shall outer world care? tikhomirov@69: } tikhomirov@69: ((ArrayList) sections).trimToSize(); tikhomirov@69: ((ArrayList) content).trimToSize(); tikhomirov@69: assert sections.size() == content.size(); tikhomirov@69: } tikhomirov@69: }