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
18package java.util.regex;
19
20import java.util.Arrays;
21
22/**
23 * Encapsulates a syntax error that occurred during the compilation of a
24 * {@link Pattern}. Might include a detailed description, the original regular
25 * expression, and the index at which the error occurred.
26 *
27 * @see Pattern#compile(String)
28 * @see Pattern#compile(java.lang.String,int)
29 */
30public class PatternSyntaxException extends IllegalArgumentException {
31
32    private static final long serialVersionUID = -3864639126226059218L;
33
34    /**
35     * Holds the description of the syntax error, or null if the description is
36     * not known.
37     */
38    private String desc;
39
40    /**
41     * Holds the syntactically incorrect regular expression, or null if the
42     * regular expression is not known.
43     */
44    private String pattern;
45
46    /**
47     * Holds the index around which the error occured, or -1, in case it is
48     * unknown.
49     */
50    private int index = -1;
51
52    /**
53     * Creates a new PatternSyntaxException for a given message, pattern, and
54     * error index.
55     *
56     * @param description
57     *            the description of the syntax error, or {@code null} if the
58     *            description is not known.
59     * @param pattern
60     *            the syntactically incorrect regular expression, or
61     *            {@code null} if the regular expression is not known.
62     * @param index
63     *            the character index around which the error occurred, or -1 if
64     *            the index is not known.
65     */
66    public PatternSyntaxException(String description, String pattern, int index) {
67        this.desc = description;
68        this.pattern = pattern;
69        this.index = index;
70    }
71
72    /**
73     * Returns the syntactically incorrect regular expression.
74     *
75     * @return the regular expression.
76     *
77     */
78    public String getPattern() {
79        return pattern;
80    }
81
82    /**
83     * Returns a detailed error message for the exception. The message is
84     * potentially multi-line, and it might include a detailed description, the
85     * original regular expression, and the index at which the error occurred.
86     *
87     * @return the error message.
88     */
89    @Override
90    public String getMessage() {
91        StringBuilder sb = new StringBuilder();
92        if (desc != null) {
93            sb.append(desc);
94        }
95
96        if (index >= 0) {
97            if (desc != null) {
98                sb.append(' ');
99            }
100            sb.append("near index ");
101            sb.append(index);
102            sb.append(':');
103        }
104
105        if (pattern != null) {
106            sb.append('\n');
107            sb.append(pattern);
108
109            if (index >= 0) {
110                char[] spaces = new char[index];
111                Arrays.fill(spaces, ' ');
112                sb.append('\n');
113                sb.append(spaces);
114                sb.append('^');
115            }
116        }
117
118        return sb.toString();
119    }
120
121    /**
122     * Returns the description of the syntax error, or {@code null} if the
123     * description is not known.
124     *
125     * @return the description.
126     */
127    public String getDescription() {
128        return desc;
129    }
130
131    /**
132     * Returns the character index around which the error occurred, or -1 if the
133     * index is not known.
134     *
135     * @return the index.
136     *
137     */
138    public int getIndex() {
139        return index;
140    }
141}
142