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