package hudson.plugins.mercurial;
import edu.umd.cs.findbugs.annotations.SuppressWarnings;
import org.apache.commons.io.IOUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* Parses the <tt>.hgrc</tt> file.
*/
final class HgRc {
private final Map<String,Section> sections = new TreeMap<String,Section>();
public HgRc(File repository) throws IOException {
this(load(repository), getHgRcFile(repository));
}
private static Reader load(File repository) throws IOException {
File hgrc = getHgRcFile(repository);
if(!hgrc.exists())
throw new IOException("No such file: "+hgrc);
// TODO: what is the encoding of hgrc?
return new FileReader(hgrc);
}
@SuppressWarnings("SBSC_USE_STRINGBUFFER_CONCATENATION")
HgRc(Reader input, File hgrc) throws IOException {
try {
BufferedReader r = new BufferedReader(input);
String line;
Section current=null;
String key=null,value=null;
while((line=r.readLine())!=null) {
if(line.length()==0) continue;
switch(line.charAt(0)) {
case ';':
case '#':
// comment
break;
case '[':
// section
if(key!=null) {
// commit the previous value
current.add(key,value);
key=null;
}
Matcher m = SECTION_HEADER.matcher(line);
if(!m.matches()) {
LOGGER.warning("Failed to parse "+hgrc+" : "+line);
continue;
}
current = createSection(m.group(1));
break;
case ' ':
case '\t':
// continuation of previous value
while(line.length()>0 && Character.isWhitespace(line.charAt(0)))
line = line.substring(1);
value += line;
continue;
default:
// key=value line
m = KEY_VALUE.matcher(line);
if(!m.matches()) {
LOGGER.warning("Failed to parse "+hgrc+" : "+line);
continue;
}
if(key!=null) // commit the previous value
current.add(key,value);
key = m.group(1);
value = m.group(2);
continue;
}
}
if(key!=null)
// commit the last value
current.add(key,value);
} finally {
IOUtils.closeQuietly(input);
}
}
public static File getHgRcFile(File repository) {
return new File(repository,".hg/hgrc");
}
private Section createSection(String name) {
Section s = sections.get(name);
if(s==null)
sections.put(name,s=new Section());
return s;
}
/**
* Gets the section. If no such section exists, return an empty constant section.
*/
public Section getSection(String name) {
Section s = sections.get(name);
if(s==null) s=NULL;
return s;
}
@Override
public String toString() {
return sections.toString();
}
public static final class Section {
private final Map<String,String> values = new TreeMap<String, String>();
public void add(String key, String value) {
values.put(key,value);
}
public String get(String key) {
return values.get(key);
}
@Override
public String toString() {
return values.toString();
}
}
private static final Pattern SECTION_HEADER = Pattern.compile("\\[(\\w+)\\].*");
private static final Pattern KEY_VALUE = Pattern.compile("([^:=\\s][^:=]*?)\\s*[=:]\\s*(.*)");
private static final Logger LOGGER = Logger.getLogger(HgRc.class.getName());
private static final Section NULL = new Section();
}