1 /*****************************************************************
2 * Licensed to the Apache Software Foundation (ASF) under one *
3 * or more contributor license agreements. See the NOTICE file *
4 * distributed with this work for additional information *
5 * regarding copyright ownership. The ASF licenses this file *
6 * to you under the Apache License, Version 2.0 (the *
7 * "License"); you may not use this file except in compliance *
8 * with the License. You may obtain a copy of the License at *
9 * *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, *
13 * software distributed under the License is distributed on an *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
15 * KIND, either express or implied. See the License for the *
16 * specific language governing permissions and limitations *
17 * under the License. *
18 ****************************************************************/
19
20 package org.apache.jsieve;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.jsieve.exception.CommandException;
24 import org.apache.jsieve.exception.SyntaxException;
25
26 /***
27 * Specifies the positional extent of an element within the script being
28 * executed. In other words, this gives the line and column at which the elment
29 * starts and at which it ends.
30 */
31 public final class ScriptCoordinate {
32
33 private final int startLineNumber;
34
35 private final int startColumnNumber;
36
37 private final int endLineNumber;
38
39 private final int endColumnNumber;
40
41 public ScriptCoordinate(final int startLineNumber,
42 final int startColumnNumber, final int endLineNumber,
43 final int endColumnNumber) {
44 super();
45 this.startLineNumber = startLineNumber;
46 this.startColumnNumber = startColumnNumber;
47 this.endLineNumber = endLineNumber;
48 this.endColumnNumber = endColumnNumber;
49 }
50
51 /***
52 * Gets the number of the column where the elements ends.
53 *
54 * @return column number
55 */
56 public int getEndColumnNumber() {
57 return endColumnNumber;
58 }
59
60 /***
61 * Gets the number of the line where the element ends.
62 *
63 * @return line number
64 */
65 public int getEndLineNumber() {
66 return endLineNumber;
67 }
68
69 /***
70 * Gets the number of the column where the element start.
71 *
72 * @return column number
73 */
74 public int getStartColumnNumber() {
75 return startColumnNumber;
76 }
77
78 /***
79 * Gets the number of the line where the element starts.
80 *
81 * @return line number
82 */
83 public int getStartLineNumber() {
84 return startLineNumber;
85 }
86
87 /***
88 * Creates a syntax exception based on the given message containing details
89 * of the script position. The message should end with a full stop.
90 *
91 * @param message
92 * <code>CharSequence</code> containing the base message,
93 * not null
94 * @return <code>SyntaxException</code> with details of the script
95 * position appended to the message, not null
96 */
97 public SyntaxException syntaxException(CharSequence message) {
98 final Log logger = Logger.getLog();
99 if (logger.isWarnEnabled()) {
100 logger.warn(message);
101 }
102 logDiagnosticsInfo(logger);
103 final String fullMessage = addStartLineAndColumn(message);
104 final SyntaxException result = new SyntaxException(fullMessage);
105 return result;
106 }
107
108 /***
109 * Creates a command exception based on the given message containing details
110 * of the script position. The message should end with a full stop.
111 *
112 * @param message
113 * <code>CharSequence</code> containing the base message,
114 * not null
115 * @return <code>CommandException</code> with details of the script
116 * position appended to the message, not null
117 */
118 public CommandException commandException(CharSequence message) {
119 final Log logger = Logger.getLog();
120 if (logger.isWarnEnabled()) {
121 logger.warn(message);
122 }
123 logDiagnosticsInfo(logger);
124 final String fullMessage = addStartLineAndColumn(message);
125 final CommandException result = new CommandException(fullMessage);
126 return result;
127 }
128
129 /***
130 * Appends a standard position phrase to the given message. This message
131 * should end with a full stop.
132 *
133 * @param message
134 * <code>CharSequence</code> message, not null
135 * @return <code>String</code> containing the original message with
136 * positional phrase appended, not null
137 */
138 public String addStartLineAndColumn(CharSequence message) {
139 final StringBuffer buffer;
140 if (message instanceof StringBuffer) {
141 buffer = (StringBuffer) message;
142 } else {
143 buffer = new StringBuffer(message.toString());
144 }
145 buffer.append(" Line ");
146 buffer.append(startLineNumber);
147 buffer.append(" column ");
148 buffer.append(startColumnNumber);
149 buffer.append(".");
150 return buffer.toString();
151 }
152
153 /***
154 * Logs diagnotic information about the script coordinate.
155 *
156 * @param logger
157 * <code>Log</code>, not null
158 */
159 public void logDiagnosticsInfo(Log logger) {
160 if (logger.isInfoEnabled()) {
161 logger.info("Expression starts line " + startLineNumber
162 + " column " + startColumnNumber);
163 logger.info("Expression ends line " + endLineNumber + " column "
164 + endColumnNumber);
165 }
166 }
167
168 /***
169 * Logs diagnotic information about the script coordinate.
170 *
171 * @param logger
172 * <code>Log</code>, not null
173 */
174 public void debugDiagnostics(Log logger) {
175 if (logger.isDebugEnabled()) {
176 logger.debug("Expression starts line " + startLineNumber
177 + " column " + startColumnNumber);
178 logger.debug("Expression ends line " + endLineNumber + " column "
179 + endColumnNumber);
180 }
181 }
182 }