tikhomirov@61: /* tikhomirov@66: * Copyright (c) 2011 TMate Software Ltd tikhomirov@66: * tikhomirov@66: * This program is free software; you can redistribute it and/or modify tikhomirov@66: * it under the terms of the GNU General Public License as published by tikhomirov@66: * the Free Software Foundation; version 2 of the License. tikhomirov@66: * tikhomirov@66: * This program is distributed in the hope that it will be useful, tikhomirov@66: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@66: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@66: * GNU General Public License for more details. tikhomirov@66: * tikhomirov@66: * For information on how to redistribute this software under tikhomirov@66: * the terms of a license other than GNU General Public License tikhomirov@66: * contact TMate Software at support@svnkit.com tikhomirov@61: */ tikhomirov@66: package org.tmatesoft.hg.test; tikhomirov@61: tikhomirov@61: import java.io.File; tikhomirov@61: import java.util.LinkedList; tikhomirov@61: import java.util.List; tikhomirov@61: import java.util.Map; tikhomirov@61: import java.util.regex.Matcher; tikhomirov@61: import java.util.regex.Pattern; tikhomirov@61: tikhomirov@93: import org.tmatesoft.hg.core.Path; tikhomirov@94: import org.tmatesoft.hg.repo.HgStatusCollector; tikhomirov@93: import org.tmatesoft.hg.util.PathPool; tikhomirov@93: import org.tmatesoft.hg.util.PathRewrite; tikhomirov@93: tikhomirov@61: /** tikhomirov@61: * tikhomirov@66: * @author Artem Tikhomirov tikhomirov@66: * @author TMate Software Ltd. tikhomirov@61: */ tikhomirov@61: public class StatusOutputParser implements OutputParser { tikhomirov@61: tikhomirov@61: private final Pattern pattern; tikhomirov@93: // although using StatusCollector.Record is not really quite honest for testing, tikhomirov@93: // it's deemed acceptable as long as that class is primitive 'collect all results' tikhomirov@94: private HgStatusCollector.Record result = new HgStatusCollector.Record(); tikhomirov@93: private final PathPool pathHelper; tikhomirov@61: tikhomirov@61: public StatusOutputParser() { tikhomirov@61: // pattern = Pattern.compile("^([MAR?IC! ]) ([\\w \\.-/\\\\]+)$", Pattern.MULTILINE); tikhomirov@61: pattern = Pattern.compile("^([MAR?IC! ]) (.+)$", Pattern.MULTILINE); tikhomirov@93: pathHelper = new PathPool(new PathRewrite() { tikhomirov@93: tikhomirov@93: private final boolean winPathSeparator = File.separatorChar == '\\'; tikhomirov@93: tikhomirov@93: public String rewrite(String s) { tikhomirov@93: if (winPathSeparator) { tikhomirov@93: // Java impl always give slashed path, while Hg uses local, os-specific convention tikhomirov@93: s = s.replace('\\', '/'); tikhomirov@93: } tikhomirov@93: return s; tikhomirov@93: } tikhomirov@93: }); tikhomirov@61: } tikhomirov@61: tikhomirov@61: public void reset() { tikhomirov@94: result = new HgStatusCollector.Record(); tikhomirov@61: } tikhomirov@61: tikhomirov@61: public void parse(CharSequence seq) { tikhomirov@61: Matcher m = pattern.matcher(seq); tikhomirov@93: Path lastAdded = null; tikhomirov@61: while (m.find()) { tikhomirov@61: String fname = m.group(2); tikhomirov@61: switch ((int) m.group(1).charAt(0)) { tikhomirov@61: case (int) 'M' : { tikhomirov@93: result.modified(pathHelper.path(fname)); tikhomirov@61: break; tikhomirov@61: } tikhomirov@61: case (int) 'A' : { tikhomirov@93: result.added(lastAdded = pathHelper.path(fname)); tikhomirov@61: break; tikhomirov@61: } tikhomirov@61: case (int) 'R' : { tikhomirov@93: result.removed(pathHelper.path(fname)); tikhomirov@61: break; tikhomirov@61: } tikhomirov@61: case (int) '?' : { tikhomirov@93: result.unknown(pathHelper.path(fname)); tikhomirov@61: break; tikhomirov@61: } tikhomirov@61: case (int) 'I' : { tikhomirov@93: result.ignored(pathHelper.path(fname)); tikhomirov@61: break; tikhomirov@61: } tikhomirov@61: case (int) 'C' : { tikhomirov@93: result.clean(pathHelper.path(fname)); tikhomirov@61: break; tikhomirov@61: } tikhomirov@61: case (int) '!' : { tikhomirov@93: result.missing(pathHelper.path(fname)); tikhomirov@61: break; tikhomirov@61: } tikhomirov@61: case (int) ' ' : { tikhomirov@61: // last added is copy destination tikhomirov@61: // to get or to remove it - depends on what StatusCollector does in this case tikhomirov@93: result.copied(pathHelper.path(fname), lastAdded); tikhomirov@61: break; tikhomirov@61: } tikhomirov@61: } tikhomirov@61: } tikhomirov@61: } tikhomirov@61: tikhomirov@61: // tikhomirov@93: public List getModified() { tikhomirov@93: return result.getModified(); tikhomirov@61: } tikhomirov@61: tikhomirov@93: public List getAdded() { tikhomirov@93: List rv = new LinkedList(result.getAdded()); tikhomirov@93: for (Path p : result.getCopied().keySet()) { tikhomirov@93: rv.remove(p); // remove only one duplicate tikhomirov@61: } tikhomirov@93: return rv; tikhomirov@61: } tikhomirov@61: tikhomirov@93: public List getRemoved() { tikhomirov@93: return result.getRemoved(); tikhomirov@88: } tikhomirov@88: tikhomirov@93: public Map getCopied() { tikhomirov@93: return result.getCopied(); tikhomirov@93: } tikhomirov@93: tikhomirov@93: public List getClean() { tikhomirov@93: return result.getClean(); tikhomirov@93: } tikhomirov@93: tikhomirov@93: public List getMissing() { tikhomirov@93: return result.getMissing(); tikhomirov@93: } tikhomirov@93: tikhomirov@93: public List getUnknown() { tikhomirov@93: return result.getUnknown(); tikhomirov@93: } tikhomirov@93: tikhomirov@93: public List getIgnored() { tikhomirov@93: return result.getIgnored(); tikhomirov@61: } tikhomirov@61: }