001package edu.pdx.cs.joy.grader; 002 003import java.io.BufferedReader; 004import java.io.IOException; 005import java.io.Reader; 006import java.util.regex.Matcher; 007import java.util.regex.Pattern; 008 009public class GitConfigParser { 010 static final Pattern PROPERTY_PATTERN = Pattern.compile("\\s+(.*) = (.*)"); 011 static final Pattern REMOTE_PATTERN = Pattern.compile("\\[remote \"(.*)\"]"); 012 private final Reader reader; 013 private String currentSection; 014 015 public GitConfigParser(Reader reader) { 016 this.reader = reader; 017 } 018 019 public void parse(Callback callback) throws IOException { 020 try (BufferedReader br = new BufferedReader(this.reader)) { 021 for (String line = br.readLine(); line != null; line = br.readLine()) { 022 parseLine(line, callback); 023 } 024 025 endCurrentSection(callback); 026 } 027 028 } 029 030 private void endCurrentSection(Callback callback) { 031 callback.endSection(currentSection); 032 } 033 034 private void parseLine(String line, Callback callback) { 035 if (line.startsWith("[core]")) { 036 endCurrentSection(callback); 037 startCoreSection(callback); 038 039 } else if (line.startsWith("[remote ")) { 040 endCurrentSection(callback); 041 startRemoteSection(line, callback); 042 043 } else if (line.contains(" = ")) { 044 parseProperty(line, callback); 045 } 046 047 } 048 049 private void startCoreSection(Callback callback) { 050 this.currentSection = "core"; 051 callback.startCoreSection(); 052 } 053 054 private void startRemoteSection(String line, Callback callback) { 055 Matcher matcher = REMOTE_PATTERN.matcher(line); 056 if (!matcher.matches()) { 057 throw new IllegalStateException("Cannot parse line with remote: \"" + line + "\""); 058 } 059 060 String remoteName = matcher.group(1); 061 this.currentSection = remoteName; 062 callback.startRemoteSection(remoteName); 063 } 064 065 private void parseProperty(String line, Callback callback) { 066 Matcher matcher = PROPERTY_PATTERN.matcher(line); 067 if (!matcher.matches()) { 068 throw new IllegalStateException("Cannot parse line with property: \"" + line + "\""); 069 } 070 071 String propertyName = matcher.group(1); 072 String propertyValue = matcher.group(2); 073 074 callback.property(propertyName, propertyValue); 075 } 076 077 public interface Callback { 078 void startCoreSection(); 079 080 void property(String name, String value); 081 082 void endSection(String name); 083 084 void startRemoteSection(String name); 085 } 086}