All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.named_data.jndn.util.regex.NdnRegexTopMatcher Maven / Gradle / Ivy

/**
 * Copyright (C) 2017-2018 Regents of the University of California.
 * @author: Yingdi Yu 
 * @author: Jeff Thompson 
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see .
 * A copy of the GNU Lesser General Public License is in the file COPYING.
 */

package net.named_data.jndn.util.regex;

import net.named_data.jndn.Name;

public class NdnRegexTopMatcher extends NdnRegexMatcherBase {
  public NdnRegexTopMatcher(String expr, String expand)
    throws NdnRegexMatcherBase.Error
  {
    super(expr, NdnRegexExprType.TOP);
    expand_ = expand;

    compile();
  }

  public NdnRegexTopMatcher(String expr) throws NdnRegexMatcherBase.Error
  {
    super(expr, NdnRegexExprType.TOP);
    expand_ = "";

    compile();
  }

  public final boolean
  match(Name name) throws NdnRegexMatcherBase.Error
  {
    isSecondaryUsed_ = false;

    matchResult_.clear();

    if (primaryMatcher_.match(name, 0, name.size())) {
      matchResult_.clear();
      for (Name.Component component : primaryMatcher_.getMatchResult())
        matchResult_.add(component);
      return true;
    }
    else {
      if (secondaryMatcher_ != null &&
          secondaryMatcher_.match(name, 0, name.size())) {
        matchResult_.clear();
        for (Name.Component component : secondaryMatcher_.getMatchResult())
          matchResult_.add(component);
        isSecondaryUsed_ = true;
        return true;
      }

      return false;
    }
  }

  public boolean
  match(Name name, int offset, int len) throws NdnRegexMatcherBase.Error
  {
    return match(name);
  }

  public Name
  expand(String expandStr) throws NdnRegexMatcherBase.Error
  {
    Name result = new Name();

    NdnRegexBackrefManager backrefManager =
      (isSecondaryUsed_ ? secondaryBackrefManager_ : primaryBackrefManager_);

    int backrefNo = backrefManager.size();

    String expand;

    if (!expandStr.equals(""))
      expand = expandStr;
    else
      expand = expand_;

    int[] offset = new int[] { 0 };
    while (offset[0] < expand.length()) {
      String item = getItemFromExpand(expand, offset);
      if (item.charAt(0) == '<')
        result.append(item.substring(1, item.length() - 1));

      if (item.charAt(0) == '\\') {
        int index = Integer.parseInt(item.substring(1, item.length()));

        if (0 == index) {
          for (Name.Component component : matchResult_)
            result.append(component);
        }
        else if (index <= backrefNo) {
          for (Name.Component component : backrefManager.getBackref
                                            (index - 1).getMatchResult())
            result.append(component);
        }
        else
          throw new NdnRegexMatcherBase.Error("Exceed the range of back reference");
      }
    }

    return result;
  }

  public Name
  expand() throws NdnRegexMatcherBase.Error
  {
    return expand("");
  }

  public static NdnRegexTopMatcher
  fromName(Name name, boolean hasAnchor) throws NdnRegexMatcherBase.Error
  {
    String regexStr = "^";

    for (int i = 0; i < name.size(); ++i) {
      regexStr += "<";
      regexStr += convertSpecialChar(name.get(i).toEscapedString());
      regexStr += ">";
    }

    if (hasAnchor)
      regexStr += "$";

    return new NdnRegexTopMatcher(regexStr);
  }

  public static NdnRegexTopMatcher
  fromName(Name name) throws NdnRegexMatcherBase.Error
  {
    return fromName(name, false);
  }

  protected void
  compile() throws NdnRegexMatcherBase.Error
  {
    String errMsg = "Error: RegexTopMatcher.Compile(): ";

    String expr = expr_;

    if ('$' != expr.charAt(expr.length() - 1))
      expr = expr + "<.*>*";
    else
      expr = expr.substring(0, expr.length() - 1);

    if ('^' != expr.charAt(0))
      secondaryMatcher_ = new NdnRegexPatternListMatcher
        ("<.*>*" + expr, secondaryBackrefManager_);
    else
      expr = expr.substring(1, expr.length());

    primaryMatcher_ = new NdnRegexPatternListMatcher
      (expr, primaryBackrefManager_);
  }

  static private String
  getItemFromExpand(String expand, int[] offset)
    throws NdnRegexMatcherBase.Error
  {
    int begin = offset[0];

    if (expand.charAt(offset[0]) == '\\') {
      ++offset[0];
      if (offset[0] >= expand.length())
        throw new NdnRegexMatcherBase.Error("Wrong format of expand string!");

      while (offset[0] < expand.length() &&
             expand.charAt(offset[0]) <= '9' && expand.charAt(offset[0]) >= '0') {
        ++offset[0];
        if (offset[0] > expand.length())
          throw new NdnRegexMatcherBase.Error("Wrong format of expand string!");
      }

      if (offset[0] > begin + 1)
        return expand.substring(begin, offset[0]);
      else
        throw new NdnRegexMatcherBase.Error("Wrong format of expand string!");
    }
    else if (expand.charAt(offset[0]) == '<') {
      ++offset[0];
      if (offset[0] >= expand.length())
        throw new NdnRegexMatcherBase.Error("Wrong format of expand string!");

      int left = 1;
      int right = 0;
      while (right < left) {
        if (expand.charAt(offset[0]) == '<')
          ++left;
        if (expand.charAt(offset[0]) == '>')
          ++right;

        ++offset[0];
        if (offset[0] >= expand.length())
          throw new NdnRegexMatcherBase.Error("Wrong format of expand string!");
      }

      return expand.substring(begin, offset[0]);
    }
    else
      throw new NdnRegexMatcherBase.Error("Wrong format of expand string!");
  }

  private static String
  convertSpecialChar(String str)
  {
    String newStr = "";
    for (int i = 0; i < str.length(); ++i) {
      char c = str.charAt(i);
      if (c == '.' ||
          c == '[' ||
          c == '{' ||
          c == '}' ||
          c == '(' ||
          c == ')' ||
          c == '\\' ||
          c == '*' ||
          c == '+' ||
          c == '?' ||
          c == '|' ||
          c == '^' ||
          c == '$') {
        newStr += '\\';
        newStr += c;
      }
      else
        newStr += c;
    }

    return newStr;
  }

  private final String expand_;
  private NdnRegexPatternListMatcher primaryMatcher_ = null;
  private NdnRegexPatternListMatcher secondaryMatcher_ = null;
  private final NdnRegexBackrefManager primaryBackrefManager_ =
     new NdnRegexBackrefManager();
  private final NdnRegexBackrefManager secondaryBackrefManager_ =
     new NdnRegexBackrefManager();
  private boolean isSecondaryUsed_ = false;
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy