tikhomirov@542: /* tikhomirov@542: * Copyright (c) 2013 TMate Software Ltd tikhomirov@542: * tikhomirov@542: * This program is free software; you can redistribute it and/or modify tikhomirov@542: * it under the terms of the GNU General Public License as published by tikhomirov@542: * the Free Software Foundation; version 2 of the License. tikhomirov@542: * tikhomirov@542: * This program is distributed in the hope that it will be useful, tikhomirov@542: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@542: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@542: * GNU General Public License for more details. tikhomirov@542: * tikhomirov@542: * For information on how to redistribute this software under tikhomirov@542: * the terms of a license other than GNU General Public License tikhomirov@542: * contact TMate Software at support@hg4j.com tikhomirov@542: */ tikhomirov@629: package org.tmatesoft.hg.core; tikhomirov@542: tikhomirov@562: import org.tmatesoft.hg.core.HgCallbackTargetException; tikhomirov@556: import org.tmatesoft.hg.internal.Callback; tikhomirov@556: import org.tmatesoft.hg.internal.Experimental; tikhomirov@629: import org.tmatesoft.hg.repo.HgDataFile; tikhomirov@555: import org.tmatesoft.hg.util.Adaptable; tikhomirov@542: tikhomirov@542: /** tikhomirov@603: * Client's sink for revision differences, diff/annotate functionality. tikhomirov@603: * tikhomirov@603: * When implemented, clients shall not expect new {@link Block blocks} instances in each call. tikhomirov@603: * tikhomirov@603: * In case more information about annotated revision is needed, inspector instances may supply tikhomirov@603: * {@link RevisionDescriptor.Recipient} through {@link Adaptable}. tikhomirov@542: * tikhomirov@542: * @author Artem Tikhomirov tikhomirov@542: * @author TMate Software Ltd. tikhomirov@603: * @since 1.1 tikhomirov@542: */ tikhomirov@603: @Callback tikhomirov@556: @Experimental(reason="Unstable API") tikhomirov@603: public interface HgBlameInspector { tikhomirov@569: tikhomirov@603: void same(EqualBlock block) throws HgCallbackTargetException; tikhomirov@603: void added(AddBlock block) throws HgCallbackTargetException; tikhomirov@603: void changed(ChangeBlock block) throws HgCallbackTargetException; tikhomirov@603: void deleted(DeleteBlock block) throws HgCallbackTargetException; tikhomirov@562: tikhomirov@562: /** tikhomirov@554: * Represents content of a block, either as a sequence of bytes or a tikhomirov@554: * sequence of smaller blocks (lines), if appropriate (according to usage context). tikhomirov@554: * tikhomirov@554: * This approach allows line-by-line access to content data along with complete byte sequence for the whole block, i.e. tikhomirov@554: *
tikhomirov@554: * BlockData bd = addBlock.addedLines() tikhomirov@554: * // bd describes data from the addition completely. tikhomirov@554: * // elements of the BlockData are lines tikhomirov@554: * bd.elementCount() == addBlock.totalAddedLines(); tikhomirov@554: * // one cat obtain complete addition with tikhomirov@554: * byte[] everythingAdded = bd.asArray(); tikhomirov@554: * // or iterate line by line tikhomirov@554: * for (int i = 0; i < bd.elementCount(); i++) { tikhomirov@554: * byte[] lineContent = bd.elementAt(i); tikhomirov@554: * String line = new String(lineContent, fileEncodingCharset); tikhomirov@554: * } tikhomirov@554: * where bd.elementAt(0) is the line at index addBlock.firstAddedLine() tikhomirov@554: *tikhomirov@554: * tikhomirov@554: * LineData or ChunkData? tikhomirov@554: */ tikhomirov@554: public interface BlockData { tikhomirov@554: BlockData elementAt(int index); tikhomirov@554: int elementCount(); tikhomirov@554: byte[] asArray(); tikhomirov@554: } tikhomirov@554: tikhomirov@555: /** tikhomirov@603: * {@link HgBlameInspector} may optionally request extra information about revisions tikhomirov@555: * being inspected, denoting itself as a {@link RevisionDescriptor.Recipient}. This class tikhomirov@555: * provides complete information about file revision under annotation now. tikhomirov@555: */ tikhomirov@555: public interface RevisionDescriptor { tikhomirov@555: /** tikhomirov@555: * @return complete source of the diff origin, never
null
tikhomirov@555: */
tikhomirov@555: BlockData origin();
tikhomirov@555: /**
tikhomirov@555: * @return complete source of the diff target, never null
tikhomirov@555: */
tikhomirov@555: BlockData target();
tikhomirov@555: /**
tikhomirov@555: * @return changeset revision index of original file, or {@link HgRepository#NO_REVISION} if it's the very first revision
tikhomirov@555: */
tikhomirov@555: int originChangesetIndex();
tikhomirov@555: /**
tikhomirov@555: * @return changeset revision index of the target file
tikhomirov@555: */
tikhomirov@555: int targetChangesetIndex();
tikhomirov@555: /**
tikhomirov@555: * @return true
if this revision is merge
tikhomirov@555: */
tikhomirov@555: boolean isMerge();
tikhomirov@555: /**
tikhomirov@555: * @return changeset revision index of the second, merged parent
tikhomirov@555: */
tikhomirov@555: int mergeChangesetIndex();
tikhomirov@555: /**
tikhomirov@556: * @return revision index of the change in target file's revlog
tikhomirov@555: */
tikhomirov@555: int fileRevisionIndex();
tikhomirov@555:
tikhomirov@555: /**
tikhomirov@569: * @return file object under blame (target file)
tikhomirov@569: */
tikhomirov@569: HgDataFile file();
tikhomirov@569:
tikhomirov@569: /**
tikhomirov@555: * Implement to indicate interest in {@link RevisionDescriptor}.
tikhomirov@555: *
tikhomirov@555: * Note, instance of {@link RevisionDescriptor} is the same for
tikhomirov@555: * {@link #start(RevisionDescriptor)} and {@link #done(RevisionDescriptor)}
tikhomirov@555: * methods, and not necessarily a new one (i.e. ==
) for the next
tikhomirov@555: * revision announced.
tikhomirov@555: */
tikhomirov@555: @Callback
tikhomirov@555: public interface Recipient {
tikhomirov@555: /**
tikhomirov@555: * Comes prior to any change {@link Block blocks}
tikhomirov@555: */
tikhomirov@562: void start(RevisionDescriptor revisionDescription) throws HgCallbackTargetException;
tikhomirov@555: /**
tikhomirov@555: * Comes after all change {@link Block blocks} were dispatched
tikhomirov@555: */
tikhomirov@562: void done(RevisionDescriptor revisionDescription) throws HgCallbackTargetException;
tikhomirov@555: }
tikhomirov@555: }
tikhomirov@555:
tikhomirov@556: /**
tikhomirov@556: * Each change block comes from a single origin, blocks that are result of a merge
tikhomirov@556: * have {@link #originChangesetIndex()} equal to {@link RevisionDescriptor#mergeChangesetIndex()}.
tikhomirov@556: */
tikhomirov@542: public interface Block {
tikhomirov@545: int originChangesetIndex();
tikhomirov@545: int targetChangesetIndex();
tikhomirov@542: }
tikhomirov@542:
tikhomirov@545: public interface EqualBlock extends Block {
tikhomirov@545: int originStart();
tikhomirov@545: int targetStart();
tikhomirov@545: int length();
tikhomirov@554: BlockData content();
tikhomirov@545: }
tikhomirov@545:
tikhomirov@542: public interface AddBlock extends Block {
tikhomirov@556: /**
tikhomirov@709: * @return line index in the origin (first parent in case of merge) where this block is inserted
tikhomirov@556: */
tikhomirov@709: int insertedAt();
tikhomirov@709: /**
tikhomirov@709: * @return line index in the second (merge) parent, if this block comes into target as a result of a merge, or -1 otherwise.
tikhomirov@709: */
tikhomirov@709: int mergeLineAt();
tikhomirov@556: /**
tikhomirov@556: * @return line index of the first added line in the target revision
tikhomirov@556: */
tikhomirov@542: int firstAddedLine();
tikhomirov@556: /**
tikhomirov@556: * @return number of added lines in this block
tikhomirov@556: */
tikhomirov@542: int totalAddedLines();
tikhomirov@556: /**
tikhomirov@556: * @return content of added lines
tikhomirov@556: */
tikhomirov@554: BlockData addedLines();
tikhomirov@542: }
tikhomirov@542: public interface DeleteBlock extends Block {
tikhomirov@556: /**
tikhomirov@556: * @return line index in the target revision were this deleted block would be
tikhomirov@556: */
tikhomirov@556: int removedAt();
tikhomirov@556: /**
tikhomirov@556: * @return line index of the first removed line in the original revision
tikhomirov@556: */
tikhomirov@542: int firstRemovedLine();
tikhomirov@556: /**
tikhomirov@556: * @return number of deleted lines in this block
tikhomirov@556: */
tikhomirov@542: int totalRemovedLines();
tikhomirov@556: /**
tikhomirov@556: * @return content of deleted lines
tikhomirov@556: */
tikhomirov@554: BlockData removedLines();
tikhomirov@542: }
tikhomirov@542: public interface ChangeBlock extends AddBlock, DeleteBlock {
tikhomirov@542: }
tikhomirov@542: }