1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.jxpath.ri;
19
20 import java.io.StringReader;
21
22 import org.apache.commons.jxpath.JXPathInvalidSyntaxException;
23 import org.apache.commons.jxpath.ri.parser.ParseException;
24 import org.apache.commons.jxpath.ri.parser.TokenMgrError;
25 import org.apache.commons.jxpath.ri.parser.XPathParser;
26
27 /**
28 * XPath parser.
29 */
30 public class Parser {
31
32 private static final XPathParser PARSER = new XPathParser(new StringReader(""));
33
34 /**
35 * Add escapes to the specified String.
36 *
37 * @param string incoming String
38 * @return String
39 */
40 private static String addEscapes(final String string) {
41 // Piggy-back on the code generated by JavaCC
42 return TokenMgrError.addEscapes(string);
43 }
44
45 /**
46 * Describe a parse position.
47 *
48 * @param expression to parse
49 * @param position parse position
50 * @return String
51 */
52 private static String describePosition(final String expression, final int position) {
53 if (position <= 0) {
54 return "at the beginning of the expression";
55 }
56 if (position >= expression.length()) {
57 return "- expression incomplete";
58 }
59 return "after: '" + addEscapes(expression.substring(0, position)) + "'";
60 }
61
62 /**
63 * Parses the XPath expression. Throws a JXPathException in case of a syntax error.
64 *
65 * @param expression to parse
66 * @param compiler the compiler
67 * @return parsed Object
68 */
69 public static Object parseExpression(final String expression, final Compiler compiler) {
70 synchronized (PARSER) {
71 PARSER.setCompiler(compiler);
72 Object expr;
73 try {
74 PARSER.ReInit(new StringReader(expression));
75 expr = PARSER.parseExpression();
76 } catch (final TokenMgrError e) {
77 throw new JXPathInvalidSyntaxException("Invalid XPath: '" + addEscapes(expression) + "'. Invalid symbol '"
78 + addEscapes(String.valueOf(e.getCharacter())) + "' " + describePosition(expression, e.getPosition()));
79 } catch (final ParseException e) {
80 throw new JXPathInvalidSyntaxException(
81 "Invalid XPath: '" + addEscapes(expression) + "'. Syntax error " + describePosition(expression, e.currentToken.beginColumn));
82 }
83 return expr;
84 }
85 }
86
87 /**
88 * Constructs a new instance.
89 *
90 *@deprecated Will be private in the next major version.
91 */
92 @Deprecated
93 public Parser() {
94 // empty
95 }
96 }