Mercurial > hg4j
changeset 104:54562de502f7
Preliminary tags implementation
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 28 Jan 2011 17:51:54 +0100 |
parents | 0b2dcca7de9f |
children | 0617dd31477f |
files | src/org/tmatesoft/hg/repo/HgRepository.java src/org/tmatesoft/hg/repo/HgTags.java |
diffstat | 2 files changed, 121 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/HgRepository.java Fri Jan 28 04:57:46 2011 +0100 +++ b/src/org/tmatesoft/hg/repo/HgRepository.java Fri Jan 28 17:51:54 2011 +0100 @@ -119,6 +119,12 @@ public final HgTags getTags() { if (tags == null) { tags = new HgTags(); + try { + tags.readGlobal(new File(repoDir.getParentFile(), ".hgtags")); + tags.readLocal(new File(repoDir, "localtags")); + } catch (IOException ex) { + ex.printStackTrace(); // FIXME log or othewise report + } } return tags; }
--- a/src/org/tmatesoft/hg/repo/HgTags.java Fri Jan 28 04:57:46 2011 +0100 +++ b/src/org/tmatesoft/hg/repo/HgTags.java Fri Jan 28 17:51:54 2011 +0100 @@ -16,25 +16,135 @@ */ package org.tmatesoft.hg.repo; -import java.util.Collections; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.TreeMap; import org.tmatesoft.hg.core.Nodeid; /** - * FIXME Place-holder, implement + * @see http://mercurial.selenic.com/wiki/TagDesign * * @author Artem Tikhomirov * @author TMate Software Ltd. */ public class HgTags { + // global tags come from ".hgtags" + // local come from ".hg/localtags" + + private final Map<Nodeid, List<String>> globalToName; + private final Map<Nodeid, List<String>> localToName; + private final Map<String, List<Nodeid>> globalFromName; + private final Map<String, List<Nodeid>> localFromName; + + + /*package-local*/ HgTags() { + globalToName = new HashMap<Nodeid, List<String>>(); + localToName = new HashMap<Nodeid, List<String>>(); + globalFromName = new TreeMap<String, List<Nodeid>>(); + localFromName = new TreeMap<String, List<Nodeid>>(); + } + + /*package-local*/ void readLocal(File localTags) throws IOException { + if (localTags == null || localTags.isDirectory()) { + throw new IllegalArgumentException(String.valueOf(localTags)); + } + read(localTags, localToName, localFromName); + } + + /*package-local*/ void readGlobal(File globalTags) throws IOException { + if (globalTags == null || globalTags.isDirectory()) { + throw new IllegalArgumentException(String.valueOf(globalTags)); + } + read(globalTags, globalToName, globalFromName); + } + + private void read(File f, Map<Nodeid,List<String>> nid2name, Map<String, List<Nodeid>> name2nid) throws IOException { + if (!f.canRead()) { + return; + } + BufferedReader r = null; + try { + r = new BufferedReader(new FileReader(f)); + read(r, nid2name, name2nid); + } finally { + if (r != null) { + r.close(); + } + } + } + + private void read(BufferedReader reader, Map<Nodeid,List<String>> nid2name, Map<String, List<Nodeid>> name2nid) throws IOException { + String line; + while ((line = reader.readLine()) != null) { + line = line.trim(); + if (line.length() == 0) { + continue; + } + if (line.length() < 40+2 /*nodeid, space and at least single-char tagname*/) { + System.out.println("Bad tags line:" + line); // FIXME log or otherwise report (IStatus analog?) + continue; + } + int spacePos = line.indexOf(' '); + if (spacePos != -1) { + assert spacePos == 40; + final byte[] nodeidBytes = line.substring(0, spacePos).getBytes(); + Nodeid nid = Nodeid.fromAscii(nodeidBytes, 0, nodeidBytes.length); + String tagName = line.substring(spacePos+1); + List<Nodeid> nids = name2nid.get(tagName); + if (nids == null) { + nids = new LinkedList<Nodeid>(); + // tagName is substring of full line, thus need a copy to let the line be GC'ed + // new String(tagName.toCharArray()) is more expressive, but results in 1 extra arraycopy + tagName = new String(tagName); + name2nid.put(tagName, nids); + } + // XXX repo.getNodeidCache().nodeid(nid); + ((LinkedList<Nodeid>) nids).addFirst(nid); + List<String> revTags = nid2name.get(nid); + if (revTags == null) { + revTags = new LinkedList<String>(); + nid2name.put(nid, revTags); + } + revTags.add(tagName); + } else { + System.out.println("Bad tags line:" + line); // FIXME see above + } + } + } public List<String> tags(Nodeid nid) { - return Collections.emptyList(); + ArrayList<String> rv = new ArrayList<String>(5); + List<String> l; + if ((l = localToName.get(nid)) != null) { + rv.addAll(l); + } + if ((l = globalToName.get(nid)) != null) { + rv.addAll(l); + } + return rv; } public boolean isTagged(Nodeid nid) { - // TODO implement - return false; + return localToName.containsKey(nid) || globalToName.containsKey(nid); + } + + public List<Nodeid> tagged(String tagName) { + ArrayList<Nodeid> rv = new ArrayList<Nodeid>(5); + List<Nodeid> l; + if ((l = localFromName.get(tagName)) != null) { + rv.addAll(l); + } + if ((l = globalFromName.get(tagName)) != null) { + rv.addAll(l); + } + return rv; } }