diff options
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java')
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java | 164 |
1 files changed, 99 insertions, 65 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java index 0805e5068c..c6d50d35f1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java @@ -1,64 +1,44 @@ /* * Copyright (C) 2008-2010, Google Inc. - * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> - * and other copyright owners as documented in the project's IP log. + * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others * - * This program and the accompanying materials are made available - * under the terms of the Eclipse Distribution License v1.0 which - * accompanies this distribution, is reproduced below, and is - * available at http://www.eclipse.org/org/documents/edl-v10.php + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * - Neither the name of the Eclipse Foundation, Inc. nor the - * names of its contributors may be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * SPDX-License-Identifier: BSD-3-Clause */ package org.eclipse.jgit.treewalk; +import static org.eclipse.jgit.lib.Constants.DOT_GIT_ATTRIBUTES; +import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH; +import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; +import static org.eclipse.jgit.lib.Constants.OBJ_TREE; +import static org.eclipse.jgit.lib.Constants.TYPE_TREE; +import static org.eclipse.jgit.lib.Constants.encode; + import java.io.IOException; +import java.io.InputStream; import java.util.Arrays; +import java.util.Collections; +import org.eclipse.jgit.attributes.AttributesNode; +import org.eclipse.jgit.attributes.AttributesRule; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.AnyObjectId; -import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.MutableObjectId; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectReader; -/** Parses raw Git trees from the canonical semi-text/semi-binary format. */ +/** + * Parses raw Git trees from the canonical semi-text/semi-binary format. + */ public class CanonicalTreeParser extends AbstractTreeIterator { private static final byte[] EMPTY = {}; + private static final byte[] ATTRS = encode(DOT_GIT_ATTRIBUTES); private byte[] raw; @@ -71,7 +51,9 @@ public class CanonicalTreeParser extends AbstractTreeIterator { /** Offset one past the current entry (first byte of next entry). */ private int nextPtr; - /** Create a new parser. */ + /** + * Create a new parser. + */ public CanonicalTreeParser() { reset(EMPTY); } @@ -91,10 +73,10 @@ public class CanonicalTreeParser extends AbstractTreeIterator { * messages if data corruption is found. * @throws MissingObjectException * the object supplied is not available from the repository. - * @throws IncorrectObjectTypeException + * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException * the object supplied as an argument is not actually a tree and * cannot be parsed as though it were a tree. - * @throws IOException + * @throws java.io.IOException * a loose object or pack file could not be read. */ public CanonicalTreeParser(final byte[] prefix, final ObjectReader reader, @@ -104,12 +86,14 @@ public class CanonicalTreeParser extends AbstractTreeIterator { reset(reader, treeId); } - private CanonicalTreeParser(final CanonicalTreeParser p) { + private CanonicalTreeParser(CanonicalTreeParser p) { super(p); } /** - * @return the parent of this tree parser + * Get the parent of this tree parser. + * + * @return the parent of this tree parser. * @deprecated internal use only */ @Deprecated @@ -123,7 +107,8 @@ public class CanonicalTreeParser extends AbstractTreeIterator { * @param treeData * the raw tree content. */ - public void reset(final byte[] treeData) { + public void reset(byte[] treeData) { + attributesNode = null; raw = treeData; prevPtr = -1; currPtr = 0; @@ -144,10 +129,10 @@ public class CanonicalTreeParser extends AbstractTreeIterator { * @return the root level parser. * @throws MissingObjectException * the object supplied is not available from the repository. - * @throws IncorrectObjectTypeException + * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException * the object supplied as an argument is not actually a tree and * cannot be parsed as though it were a tree. - * @throws IOException + * @throws java.io.IOException * a loose object or pack file could not be read. */ public CanonicalTreeParser resetRoot(final ObjectReader reader, @@ -160,7 +145,11 @@ public class CanonicalTreeParser extends AbstractTreeIterator { return p; } - /** @return this iterator, or its parent, if the tree is at eof. */ + /** + * Get this iterator, or its parent, if the tree is at eof. + * + * @return this iterator, or its parent, if the tree is at eof. + */ public CanonicalTreeParser next() { CanonicalTreeParser p = this; for (;;) { @@ -191,15 +180,15 @@ public class CanonicalTreeParser extends AbstractTreeIterator { * messages if data corruption is found. * @throws MissingObjectException * the object supplied is not available from the repository. - * @throws IncorrectObjectTypeException + * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException * the object supplied as an argument is not actually a tree and * cannot be parsed as though it were a tree. - * @throws IOException + * @throws java.io.IOException * a loose object or pack file could not be read. */ - public void reset(final ObjectReader reader, final AnyObjectId id) + public void reset(ObjectReader reader, AnyObjectId id) throws IncorrectObjectTypeException, IOException { - reset(reader.open(id, Constants.OBJ_TREE).getCachedBytes()); + reset(reader.open(id, OBJ_TREE).getCachedBytes()); } @Override @@ -209,7 +198,7 @@ public class CanonicalTreeParser extends AbstractTreeIterator { idBuffer.fromRaw(idBuffer(), idOffset()); if (!FileMode.TREE.equals(mode)) { final ObjectId me = idBuffer.toObjectId(); - throw new IncorrectObjectTypeException(me, Constants.TYPE_TREE); + throw new IncorrectObjectTypeException(me, TYPE_TREE); } return createSubtreeIterator0(reader, idBuffer); } @@ -226,7 +215,7 @@ public class CanonicalTreeParser extends AbstractTreeIterator { * @param id * ObjectId of the tree to open. * @return a new parser that walks over the current subtree. - * @throws IOException + * @throws java.io.IOException * a loose object or pack file could not be read. */ public final CanonicalTreeParser createSubtreeIterator0( @@ -237,7 +226,8 @@ public class CanonicalTreeParser extends AbstractTreeIterator { return p; } - public CanonicalTreeParser createSubtreeIterator(final ObjectReader reader) + @Override + public CanonicalTreeParser createSubtreeIterator(ObjectReader reader) throws IncorrectObjectTypeException, IOException { return createSubtreeIterator(reader, new MutableObjectId()); } @@ -254,7 +244,7 @@ public class CanonicalTreeParser extends AbstractTreeIterator { @Override public int idOffset() { - return nextPtr - Constants.OBJECT_ID_LENGTH; + return nextPtr - OBJECT_ID_LENGTH; } @Override @@ -268,6 +258,7 @@ public class CanonicalTreeParser extends AbstractTreeIterator { return currPtr == 0; } + @Override public boolean eof() { return currPtr == raw.length; } @@ -292,7 +283,7 @@ public class CanonicalTreeParser extends AbstractTreeIterator { prevPtr = ptr; while (raw[ptr] != 0) ptr++; - ptr += Constants.OBJECT_ID_LENGTH + 1; + ptr += OBJECT_ID_LENGTH + 1; } if (delta != 0) throw new ArrayIndexOutOfBoundsException(delta); @@ -328,7 +319,7 @@ public class CanonicalTreeParser extends AbstractTreeIterator { trace[delta] = ptr; while (raw[ptr] != 0) ptr++; - ptr += Constants.OBJECT_ID_LENGTH + 1; + ptr += OBJECT_ID_LENGTH + 1; } if (trace[1] == -1) throw new ArrayIndexOutOfBoundsException(delta); @@ -353,16 +344,59 @@ public class CanonicalTreeParser extends AbstractTreeIterator { tmp = pathOffset; for (;; tmp++) { c = raw[ptr++]; - if (c == 0) + if (c == 0) { break; - try { - path[tmp] = c; - } catch (ArrayIndexOutOfBoundsException e) { + } + if (tmp >= path.length) { growPath(tmp); - path[tmp] = c; } + path[tmp] = c; } pathLen = tmp; - nextPtr = ptr + Constants.OBJECT_ID_LENGTH; + nextPtr = ptr + OBJECT_ID_LENGTH; + } + + /** + * Retrieve the {@link org.eclipse.jgit.attributes.AttributesNode} for the + * current entry. + * + * @param reader + * {@link org.eclipse.jgit.lib.ObjectReader} used to parse the + * .gitattributes entry. + * @return {@link org.eclipse.jgit.attributes.AttributesNode} for the + * current entry. + * @throws java.io.IOException + * if an IO error occurred + * @since 4.2 + */ + public AttributesNode getEntryAttributesNode(ObjectReader reader) + throws IOException { + if (attributesNode == null) { + attributesNode = findAttributes(reader); + } + return attributesNode.getRules().isEmpty() ? null : attributesNode; + } + + private AttributesNode findAttributes(ObjectReader reader) + throws IOException { + CanonicalTreeParser itr = new CanonicalTreeParser(); + itr.reset(raw); + if (itr.findFile(ATTRS)) { + return loadAttributes(reader, itr.getEntryObjectId()); + } + return noAttributes(); + } + + private static AttributesNode loadAttributes(ObjectReader reader, + AnyObjectId id) throws IOException { + AttributesNode r = new AttributesNode(); + try (InputStream in = reader.open(id, OBJ_BLOB).openStream()) { + r.parse(in); + } + return r.getRules().isEmpty() ? noAttributes() : r; + } + + private static AttributesNode noAttributes() { + return new AttributesNode(Collections.<AttributesRule> emptyList()); } } |