tikhomirov@695: /* tikhomirov@695: * Copyright (c) 2013 TMate Software Ltd tikhomirov@695: * tikhomirov@695: * This program is free software; you can redistribute it and/or modify tikhomirov@695: * it under the terms of the GNU General Public License as published by tikhomirov@695: * the Free Software Foundation; version 2 of the License. tikhomirov@695: * tikhomirov@695: * This program is distributed in the hope that it will be useful, tikhomirov@695: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@695: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@695: * GNU General Public License for more details. tikhomirov@695: * tikhomirov@695: * For information on how to redistribute this software under tikhomirov@695: * the terms of a license other than GNU General Public License tikhomirov@695: * contact TMate Software at support@hg4j.com tikhomirov@695: */ tikhomirov@695: package org.tmatesoft.hg.internal; tikhomirov@695: tikhomirov@695: import org.tmatesoft.hg.core.Nodeid; tikhomirov@695: import org.tmatesoft.hg.internal.RevlogStream.Inspector; tikhomirov@695: import org.tmatesoft.hg.repo.HgRepository; tikhomirov@695: import org.tmatesoft.hg.repo.HgRuntimeException; tikhomirov@695: tikhomirov@695: /** tikhomirov@695: * Does almost nothing, facilitates chains of inspectors and sharing certain information between them tikhomirov@695: * tikhomirov@695: * @author Artem Tikhomirov tikhomirov@695: * @author TMate Software Ltd. tikhomirov@695: */ tikhomirov@695: public abstract class RevlogDelegate implements RevlogStream.Inspector { tikhomirov@695: tikhomirov@695: private final Inspector next; tikhomirov@695: private Nodeid nid; tikhomirov@695: private final RevlogDelegate nextAsRD; tikhomirov@695: tikhomirov@695: protected RevlogDelegate(RevlogStream.Inspector nextInChain) { tikhomirov@695: next = nextInChain; tikhomirov@695: if (nextInChain instanceof RevlogDelegate) { tikhomirov@695: // additional benefits tikhomirov@695: nextAsRD = (RevlogDelegate) nextInChain; tikhomirov@695: } else { tikhomirov@695: nextAsRD = null; tikhomirov@695: } tikhomirov@695: } tikhomirov@695: tikhomirov@695: /** tikhomirov@695: * iterates index only and ensures pre/post processing is invoked for the chain tikhomirov@695: */ tikhomirov@695: public void walk(HgRepository hgRepo, RevlogStream stream, int from, int to) { tikhomirov@695: // hgRepo is handy for present uses, but is generally not appropriate, tikhomirov@695: // it's ok to refactor and let subclasses get what they need through e.g. a cons tikhomirov@695: stream.iterate(from, to, false, this); tikhomirov@695: postWalk(hgRepo); tikhomirov@695: } tikhomirov@695: tikhomirov@695: // does nothing but gives a chance to delegate to handle the same tikhomirov@695: protected void postWalk(HgRepository hgRepo) { tikhomirov@695: if (nextAsRD != null) { tikhomirov@695: nextAsRD.postWalk(hgRepo); tikhomirov@695: } tikhomirov@695: } tikhomirov@695: tikhomirov@695: /** tikhomirov@695: * @return Nodeid of current revision if already known, or a new instance otherwise. tikhomirov@695: * The value will propagate to subsequent {@link RevlogDelegate RevlogDelegates}, if any tikhomirov@695: */ tikhomirov@695: protected Nodeid getRevision(byte[] nodeid) { tikhomirov@695: if (nid == null) { tikhomirov@695: nid = Nodeid.fromBinary(nodeid, 0); tikhomirov@695: } tikhomirov@695: return nid; tikhomirov@695: } tikhomirov@695: tikhomirov@695: protected void setRevision(Nodeid nodeid) { tikhomirov@695: nid = nodeid; tikhomirov@695: } tikhomirov@695: tikhomirov@695: public void next(int revisionIndex, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) throws HgRuntimeException { tikhomirov@695: if (next != null) { tikhomirov@695: if (nextAsRD != null) { tikhomirov@695: nextAsRD.setRevision(nid); // null is fine tikhomirov@695: } tikhomirov@695: next.next(revisionIndex, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, nodeid, data); tikhomirov@695: } tikhomirov@695: nid = null; // forget it, get ready for the next iteration tikhomirov@695: } tikhomirov@695: }