/*
* #%L
* JavaHg
* %%
* Copyright (C) 2011 aragost Trifork ag
* %%
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* #L%
*/
package com.aragost.javahg.commands;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.aragost.javahg.Changeset;
import com.aragost.javahg.Repository;
import com.aragost.javahg.commands.flags.TagsCommandFlags;
import com.aragost.javahg.internals.UnexpectedCommandOutputException;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
* Command class for executing <tt>hg tags</tt>. Set flags from
* {@link TagsCommandFlags} and see the {@link #execute()} method for
* how to run the command.
*/
public class TagsCommand extends TagsCommandFlags {
/**
* Tags pattern. Matching groups: 1: name 2: nodeId 3: local
*/
private static final Pattern TAGS_PATTERN = Pattern.compile("^(.*) (?:[-0-9]+):([a-f0-9]+)( local)?$"); //$NON-NLS-1$
protected boolean includeTip;
public TagsCommand(Repository repository) {
super(repository);
cmdAppend("-v");
withDebugFlag();
}
/**
* Whether tip should be included. Default false
*
* @return this
*/
public TagsCommand includeTip() {
this.includeTip = true;
return this;
}
/**
* Return a map mapping tag names to changeset with the tag.
* <p>
* The command 'hg tags' returns the pseudo tag 'tip', this is not
* returned here.
*
* @return map mapping tag name to changeset
*/
public List<Tag> execute() {
List<Tag> result = Lists.newArrayList();
Repository repository = getRepository();
for (Iterator<String> iter = launchIterator(); iter.hasNext();) {
String line = iter.next();
Tag tag = fromLine(repository, line);
if (includeTip || !tag.getName().equals("tip")) {
result.add(tag);
}
}
return result;
}
/**
* Return alternative mapping of changeset node hash to list of
* tags.
* <p>
* The command 'hg tags' returns the pseudo tag 'tip', this is not
* returned here.
*
* @return map mapping changeset to tags at that node.
*/
public Map<Changeset, List<Tag>> executeReverse() {
Map<Changeset, List<Tag>> result = Maps.newHashMap();
Repository repository = getRepository();
for (Iterator<String> iter = launchIterator(); iter.hasNext();) {
Tag tag = fromLine(repository, iter.next());
if (includeTip || !tag.getName().equals("tip")) {
Changeset changeset = tag.getChangeset();
List<Tag> tagList = result.get(changeset);
if (tagList == null) {
tagList = Lists.newArrayList();
result.put(changeset, tagList);
}
tagList.add(tag);
}
}
return result;
}
private Tag fromLine(Repository repository, String line) {
Matcher m = TAGS_PATTERN.matcher(line);
if (m.matches()) {
return new Tag(m.group(1).trim(), repository.changeset(m.group(2)),
m.group(3) != null);
}
throw new UnexpectedCommandOutputException(this, line);
}
}