FooterLine.java

  1. /*
  2.  * Copyright (C) 2009, Google Inc. and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */

  10. package org.eclipse.jgit.revwalk;

  11. import java.nio.charset.Charset;

  12. import org.eclipse.jgit.util.RawParseUtils;

  13. /**
  14.  * Single line at the end of a message, such as a "Signed-off-by: someone".
  15.  * <p>
  16.  * These footer lines tend to be used to represent additional information about
  17.  * a commit, like the path it followed through reviewers before finally being
  18.  * accepted into the project's main repository as an immutable commit.
  19.  *
  20.  * @see RevCommit#getFooterLines()
  21.  */
  22. public final class FooterLine {
  23.     private final byte[] buffer;

  24.     private final Charset enc;

  25.     private final int keyStart;

  26.     private final int keyEnd;

  27.     private final int valStart;

  28.     private final int valEnd;

  29.     FooterLine(final byte[] b, final Charset e, final int ks, final int ke,
  30.             final int vs, final int ve) {
  31.         buffer = b;
  32.         enc = e;
  33.         keyStart = ks;
  34.         keyEnd = ke;
  35.         valStart = vs;
  36.         valEnd = ve;
  37.     }

  38.     /**
  39.      * Whether keys match
  40.      *
  41.      * @param key
  42.      *            key to test this line's key name against.
  43.      * @return true if {@code key.getName().equalsIgnorecase(getKey())}.
  44.      */
  45.     public boolean matches(FooterKey key) {
  46.         final byte[] kRaw = key.raw;
  47.         final int len = kRaw.length;
  48.         int bPtr = keyStart;
  49.         if (keyEnd - bPtr != len)
  50.             return false;
  51.         for (int kPtr = 0; kPtr < len;) {
  52.             byte b = buffer[bPtr++];
  53.             if ('A' <= b && b <= 'Z')
  54.                 b += (byte) ('a' - 'A');
  55.             if (b != kRaw[kPtr++])
  56.                 return false;
  57.         }
  58.         return true;
  59.     }

  60.     /**
  61.      * Get key name of this footer.
  62.      *
  63.      * @return key name of this footer; that is the text before the ":" on the
  64.      *         line footer's line. The text is decoded according to the commit's
  65.      *         specified (or assumed) character encoding.
  66.      */
  67.     public String getKey() {
  68.         return RawParseUtils.decode(enc, buffer, keyStart, keyEnd);
  69.     }

  70.     /**
  71.      * Get value of this footer.
  72.      *
  73.      * @return value of this footer; that is the text after the ":" and any
  74.      *         leading whitespace has been skipped. May be the empty string if
  75.      *         the footer has no value (line ended with ":"). The text is
  76.      *         decoded according to the commit's specified (or assumed)
  77.      *         character encoding.
  78.      */
  79.     public String getValue() {
  80.         return RawParseUtils.decode(enc, buffer, valStart, valEnd);
  81.     }

  82.     /**
  83.      * Extract the email address (if present) from the footer.
  84.      * <p>
  85.      * If there is an email address looking string inside of angle brackets
  86.      * (e.g. "&lt;a@b&gt;"), the return value is the part extracted from inside the
  87.      * brackets. If no brackets are found, then {@link #getValue()} is returned
  88.      * if the value contains an '@' sign. Otherwise, null.
  89.      *
  90.      * @return email address appearing in the value of this footer, or null.
  91.      */
  92.     public String getEmailAddress() {
  93.         final int lt = RawParseUtils.nextLF(buffer, valStart, '<');
  94.         if (valEnd <= lt) {
  95.             final int at = RawParseUtils.nextLF(buffer, valStart, '@');
  96.             if (valStart < at && at < valEnd)
  97.                 return getValue();
  98.             return null;
  99.         }
  100.         final int gt = RawParseUtils.nextLF(buffer, lt, '>');
  101.         if (valEnd < gt)
  102.             return null;
  103.         return RawParseUtils.decode(enc, buffer, lt, gt - 1);
  104.     }

  105.     /** {@inheritDoc} */
  106.     @Override
  107.     public String toString() {
  108.         return getKey() + ": " + getValue(); //$NON-NLS-1$
  109.     }
  110. }