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

org.jamon.parser.PathParser Maven / Gradle / Ivy

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.jamon.parser;

import java.io.IOException;

import org.jamon.api.Location;
import org.jamon.compiler.ParserErrorsImpl;
import org.jamon.node.AbsolutePathNode;
import org.jamon.node.AbstractPathNode;
import org.jamon.node.NamedAliasPathNode;
import org.jamon.node.PathElementNode;
import org.jamon.node.RelativePathNode;
import org.jamon.node.RootAliasPathNode;
import org.jamon.node.UpdirNode;

public class PathParser extends AbstractParser {
  public static final String GENERIC_PATH_ERROR = "Malformed path";

  public PathParser(PositionalPushbackReader reader, ParserErrorsImpl errors)
      throws IOException {
    super(reader, errors);
    path = parse();
  }

  public AbstractPathNode getPathNode() {
    return path;
  }

  private AbstractPathNode parse() throws IOException {
    AbstractPathNode path;
    Location location = reader.getNextLocation();
    int c = reader.read();
    switch (c) {
      case '/':
        path = readChar('/')
            ? (AbstractPathNode) new RootAliasPathNode(location)
            : (AbstractPathNode) new AbsolutePathNode(location);
        addToPath(path, false);
        break;
      case '.':
        reader.unread(c);
        path = new RelativePathNode(location);
        addToPath(path, true);
        break;
      default:
        if (Character.isJavaIdentifierStart((char) c)) {
          reader.unread(c);
          String identifier = readIdentifier(true);
          if ((c = reader.read()) == '/') {
            if ((c = reader.read()) == '/') {
              path = new NamedAliasPathNode(location, identifier);
              addToPath(path, false);
            }
            else {
              reader.unread(c);
              path = new RelativePathNode(location).addPathElement(
                new PathElementNode(location, identifier));
              addToPath(path, false);
            }
          }
          else {
            reader.unread(c);
            path = new RelativePathNode(location).addPathElement(
              new PathElementNode(location, identifier));
          }
        }
        else {
          addError(location, GENERIC_PATH_ERROR);
          path = new RelativePathNode(location);
        }
        break;
    }
    return path;
  }

  private void addToPath(AbstractPathNode path, boolean updirsAllowedAtStart)
  throws IOException {
    int c;
    StringBuilder identifier = new StringBuilder();
    boolean identStart = true;
    boolean updirsAllowed = updirsAllowedAtStart;
    Location location = reader.getNextLocation();
    while ((c = reader.read()) >= 0) {
      if (c == '/') {
        if (identStart) {
          addError(location, GENERIC_PATH_ERROR);
          return;
        }
        else {
          path.addPathElement(new PathElementNode(location, identifier.toString()));
          identifier = new StringBuilder();
          identStart = true;
          updirsAllowed = false;
          location = reader.getNextLocation();
        }
      }
      else if (c == '.') {
        if (updirsAllowed) {
          if (reader.read() == '.') {
            path.addPathElement(new UpdirNode(location));
            identifier = new StringBuilder();
            identStart = true;
            if ((c = reader.read()) == '/') {
              location = reader.getNextLocation();
            }
            else {
              if (Character.isJavaIdentifierPart((char) c)) {
                addError(location, GENERIC_PATH_ERROR);
                return;
              }
            }
          }
          else {
            addError(location, GENERIC_PATH_ERROR);
            return;
          }
        }
        else {
          addError(location, GENERIC_PATH_ERROR);
          return;
        }
      }
      else if (identStart
          ? Character.isJavaIdentifierStart((char) c)
          : Character.isJavaIdentifierPart((char) c)) {
        identStart = false;
        identifier.append((char) c);
      }
      else {
        reader.unread(c);
        break;
      }
    }
    if (!identStart) {
      path.addPathElement(new PathElementNode(location, identifier.toString()));
    }
    else {
      addError(reader.getCurrentNodeLocation(), GENERIC_PATH_ERROR);
    }
  }

  private final AbstractPathNode path;
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy