Package org.exist.xslt.pattern

Source Code of org.exist.xslt.pattern.Pattern

/*
*  eXist Open Source Native XML Database
*  Copyright (C) 2008-2010 The eXist Project
*  http://exist-db.org
*  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 2
*  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, write to the Free Software
*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*  $Id$
*/
package org.exist.xslt.pattern;

import java.io.IOException;
import java.io.Reader;
import java.text.NumberFormat;

import org.apache.log4j.Logger;
import org.exist.source.Source;
import org.exist.source.StringSource;
import org.exist.xquery.AnalyzeContextInfo;
import org.exist.xquery.AnyNodeTest;
import org.exist.xquery.Constants;
import org.exist.xquery.LocationStep;
import org.exist.xquery.PathExpr;
import org.exist.xquery.StaticXQueryException;
import org.exist.xquery.XPathException;
import org.exist.xquery.XQueryContext;
import org.exist.xquery.parser.XQueryLexer;
import org.exist.xquery.parser.XQueryParser;
import org.exist.xquery.parser.XQueryTreeParser;
import org.exist.xquery.util.ExpressionDumper;
import org.exist.xslt.XSLContext;
import org.exist.xslt.expression.XSLPathExpr;

import antlr.RecognitionException;
import antlr.TokenStreamException;
import antlr.collections.AST;

/**
* [1]    Pattern    ::=    PathPattern <br>
*    | Pattern '|' PathPattern <br>
* [2]    PathPattern    ::=    RelativePathPattern <br>
*    | '/' RelativePathPattern? <br>
*    | '//' RelativePathPattern <br>
*    | IdKeyPattern (('/' | '//') RelativePathPattern)? <br>
* [3]    RelativePathPattern    ::=    PatternStep (('/' | '//') RelativePathPattern)? <br>
* [4]    PatternStep    ::=    PatternAxis? NodeTest XP PredicateListXP <br>
* [5]    PatternAxis    ::=    ('child' '::' | 'attribute' '::' | '@') <br>
* [6]    IdKeyPattern    ::=    'id' '(' IdValue ')' <br>
*    | 'key' '(' StringLiteralXP ',' KeyValue ')' <br>
* [7]    IdValue    ::=    StringLiteralXP | VarRef XP <br>
* [8]    KeyValue    ::=    Literal XP | VarRef XP <br>
* <br>
* The constructs NodeTest XP, PredicateList XP, VarRef XP, Literal XP, and StringLiteral XP are part of the XPath expression language, and are defined in [XPath 2.0].
*
* @author <a href="mailto:shabanovd@gmail.com">Dmitriy Shabanov</a>
*
*/
public class Pattern {

    private final static Logger LOG = Logger.getLogger(Pattern.class);
 
    static final String ELEMENT = "element()";
    static final String ELEMENT_A = "element(*)";
    static final String ATTRIBUTE = "attribute()";
    static final String ATTRIBUTE_A = "attribute(*)";

    //enclose expression
  public static XSLPathExpr parse(XQueryContext context, String str) throws XPathException {
    if (!(str != null && str.startsWith("{") && str.endsWith("}"))) {
      return null;
    }
   
    XSLPathExpr expr = new XSLPathExpr((XSLContext) context);
    parse(context, str.substring(1, str.length() - 1), expr);
   
    return expr;
  }

  public static void parse(XQueryContext context, String pattern, XSLPathExpr content) throws XPathException {
    boolean xpointer = false;
   
    //TODO: rewrite RootNode?
    if (pattern.equals("//")) {
      content.add(new LocationStep(context, Constants.SELF_AXIS, new AnyNodeTest()));
      return;
    }
    if (pattern.equals("/")) {
      content.add(new LocationStep(context, Constants.SELF_AXIS, new AnyNodeTest()));
      return;
    }
   
    Source source = new StringSource(pattern);
        Reader reader;
    try {
      reader = source.getReader();
    } catch (IOException e1) {
      return;//TODO: report error???
    }
   
      long start = System.currentTimeMillis();
        XQueryLexer lexer = new XQueryLexer(context, reader);
    XQueryParser parser = new XQueryParser(lexer);
    XQueryTreeParser treeParser = new XQueryTreeParser(context);
    try {
            if (xpointer)
                parser.xpointer();
            else
                parser.xpath();
            if (parser.foundErrors()) {
              LOG.debug(parser.getErrorMessage());
              throw new StaticXQueryException(
                parser.getErrorMessage());
            }

            AST ast = parser.getAST();
            if (ast == null)
                throw new XPathException("Unknown XQuery parser error: the parser returned an empty syntax tree.");

            PathExpr expr = new PathExpr(context);
            if (xpointer)
                treeParser.xpointer(ast, expr);
            else
                treeParser.xpath(ast, expr);
            if (treeParser.foundErrors()) {
                throw new StaticXQueryException(
                treeParser.getErrorMessage(),
                treeParser.getLastException());
            }

            expr.analyze(new AnalyzeContextInfo(context));

//            if (context.optimizationsEnabled()) {
//                Optimizer optimizer = new Optimizer(context);
//                expr.accept(optimizer);
//                if (optimizer.hasOptimized()) {
//                    context.reset(true);
//                    expr.resetState(true);
//                    expr.analyze(new AnalyzeContextInfo());
//                }
//            }

            // Log the query if it is not too large, but avoid
            // dumping huge queries to the log
            if (context.getExpressionCount() < 150) {
                LOG.debug("Query diagnostics:\n" + ExpressionDumper.dump(expr));
            } else {
                LOG.debug("Query diagnostics:\n" + "[skipped: more than 150 expressions]");
            }
            if (LOG.isDebugEnabled()) {
              NumberFormat nf = NumberFormat.getNumberInstance();
              LOG.debug("Compilation took "  +  nf.format(System.currentTimeMillis() - start) + " ms");
            }
            //return

            content.add(expr);

    } catch (RecognitionException e) {
      LOG.debug("Error compiling query: " + e.getMessage(), e);
      String msg = e.getMessage();
      if (msg.endsWith(", found 'null'"))
        msg = msg.substring(0, msg.length() - ", found 'null'".length());
            throw new StaticXQueryException(e.getLine(), e.getColumn(), msg);
        } catch (TokenStreamException e) {
          LOG.debug("Error compiling query: " + e.getMessage(), e);
            throw new StaticXQueryException(e.getMessage(), e);
        }
  }
}
TOP

Related Classes of org.exist.xslt.pattern.Pattern

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.