private List matchAccessLogItem()

in common/common-access-log/src/main/java/org/apache/servicecomb/common/accessLog/core/parser/impl/VertxRestAccessLogPatternParser.java [169:216]


  private List<AccessLogItemLocation> matchAccessLogItem(String rawPattern) {
    List<AccessLogItemLocation> locationList = new ArrayList<>();
    int cursor = 0;
    while (cursor < rawPattern.length()) {
      AccessLogItemLocation candidate = null;
      for (VertxRestAccessLogItemMeta meta : metaList) {
        if (null != candidate && null == meta.getSuffix()) {
          // TODO:
          // if user define item("%{","}ab") and item("%{_","}abc") and the pattern is "%{_var}ab}abc"
          // currently the result is item("%{","_var","}ab"), plaintext("}abc")
          // is this acceptable?

          // We've gotten an AccessLogItem with suffix, so there is no need to match those without suffix,
          // just break this match loop
          cursor = candidate.tail;
          break;
        }
        if (rawPattern.startsWith(meta.getPrefix(), cursor)) {
          if (null == meta.getSuffix()) {
            // for simple type AccessLogItem, there is no need to try to match the next item.
            candidate = new AccessLogItemLocation(cursor, meta);
            cursor = candidate.tail;
            break;
          }
          // for configurable type, like %{...}i, more check is needed
          // e.g. "%{varName1}o ${varName2}i" should be divided into
          // ResponseHeaderItem with varName="varName1" and RequestHeaderItem with varName="varName2"
          // INSTEAD OF RequestHeaderItem with varName="varName1}o ${varName2"
          int rear = rawPattern.indexOf(meta.getSuffix(), cursor);
          if (rear < 0) {
            continue;
          }
          if (null == candidate || rear < candidate.suffixIndex) {
            candidate = new AccessLogItemLocation(cursor, rear, meta);
          }
          // There is a matched item which is in front of this item, so this item is ignored.
        }
      }

      if (candidate == null) {
        ++cursor;
        continue;
      }
      locationList.add(candidate);
    }

    return locationList;
  }