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

juzu.impl.router.CaptureGroupTransformation Maven / Gradle / Ivy

/*
 * Copyright 2013 eXo Platform SAS
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package juzu.impl.router;

import juzu.impl.router.regex.GroupType;
import juzu.impl.router.regex.RENode;
import juzu.impl.router.regex.REVisitor;

import java.util.LinkedList;

/**
 * @author Julien Viet
 * @version $Revision$
 */
class CaptureGroupTransformation extends REVisitor {

  /** . */
  private int depth;

  /** Top level group per disjunction. */
  private LinkedList groups;

  CaptureGroupTransformation() {
    this.depth = 0;
    this.groups = new LinkedList();
  }

  @Override
  protected void visit(RENode.Disjunction disjunction) throws RuntimeException {
    if (disjunction.hasAlternative()) {
      RENode.Alternative alternative = disjunction.getAlternative();
      if (alternative != null) {
        alternative.accept(this);

        //
        if (depth == 0) {
          if (groups.size() == 1 && groups.get(0).getQuantifier() == null) {
            // Do nothing
          }
          else {
            // We make all the top level groups non capturing
            for (RENode.Group group : groups) {
              group.setType(GroupType.NON_CAPTURING_GROUP);
            }

            // We add a capturing group for the disjunction
            RENode.Disjunction disjunction1 = new RENode.Disjunction((RENode.Alternative)null);
            RENode.Group group = new RENode.Group(disjunction1, GroupType.CAPTURING_GROUP);
            RENode.Alternative alternative1 = new RENode.Alternative(group);
            alternative.replaceBy(alternative1);
            disjunction1.setAlternative(alternative);
          }

          //
          groups.clear();
        }
      }
      else {
        if (depth == 0) {
          disjunction.setAlternative(
              new RENode.Alternative(
                  new RENode.Group(
                      new RENode.Disjunction(), GroupType.CAPTURING_GROUP)));
        }
      }
    }

    //
    if (disjunction.hasNext()) {
      RENode.Disjunction next = disjunction.getNext();
      if (next != null) {
        next.accept(this);
      }
      else {
        if (depth == 0) {
          disjunction.setNext(
              new RENode.Disjunction(
                  new RENode.Alternative(
                      new RENode.Group(
                          new RENode.Disjunction(), GroupType.CAPTURING_GROUP))));
        }
      }
    }
  }

  @Override
  protected void visit(RENode.Group expr) throws RuntimeException {
    if (depth == 0) {
      // We collect all capturing top level capturing groups
      if (expr.getType() == GroupType.CAPTURING_GROUP) {
        groups.add(expr);
      }
    }
    else {
      // We make nested capturing group as non capturing
      if (expr.getType() == GroupType.CAPTURING_GROUP) {
        expr.setType(GroupType.NON_CAPTURING_GROUP);
      }
    }

    //
    depth++;
    super.visit(expr);
    depth--;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy