001 /*
002 // $Id: OlapException.java 485 2012-01-17 06:57:57Z jhyde $
003 //
004 // Licensed to Julian Hyde under one or more contributor license
005 // agreements. See the NOTICE file distributed with this work for
006 // additional information regarding copyright ownership.
007 //
008 // Julian Hyde licenses this file to you under the Apache License,
009 // Version 2.0 (the "License"); you may not use this file except in
010 // compliance with the License. You may obtain a copy of the License at:
011 //
012 // http://www.apache.org/licenses/LICENSE-2.0
013 //
014 // Unless required by applicable law or agreed to in writing, software
015 // distributed under the License is distributed on an "AS IS" BASIS,
016 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 // See the License for the specific language governing permissions and
018 // limitations under the License.
019 */
020 package org.olap4j;
021
022 import java.sql.*;
023
024 /**
025 * <p>An exception describing an error accessing an OLAP database.</p>
026 *
027 * <p>Since olap4j extends JDBC, it is natural that <code>OlapException</code>
028 * should extend JDBC's {@link SQLException}. The implementation by an olap4j
029 * driver of a JDBC method which is declared to throw a SQLException may, if the
030 * driver chooses, throw instead an OlapException.</p>
031 *
032 * <p>OlapException provides some additional information to help an OLAP client
033 * identify the location of the error. This information is
034 *
035 * @author jhyde
036 * @version $Id: OlapException.java 485 2012-01-17 06:57:57Z jhyde $
037 * @since Oct 23, 2006
038 */
039 public class OlapException extends SQLException {
040 private Region region;
041 private Object context;
042
043 /**
044 * Constructs an <code>OlapException</code> object with a given
045 * <code>reason</code>, <code>SQLState</code> and
046 * <code>vendorCode</code>.
047 *
048 * @param reason a description of the exception
049 * @param sqlState an XOPEN or SQL 99 code identifying the exception
050 * @param vendorCode a database vendor-specific exception code
051 */
052 public OlapException(String reason, String sqlState, int vendorCode) {
053 super(reason, sqlState, vendorCode);
054 }
055
056 /**
057 * Constructs an <code>OlapException</code> object with the given reason and
058 * SQLState; the <code>vendorCode</code> field defaults to 0.
059 *
060 * @param reason a description of the exception
061 * @param sqlState an XOPEN or SQL 99 code identifying the exception
062 */
063 public OlapException(String reason, String sqlState) {
064 super(reason, sqlState);
065 }
066
067 /**
068 * Constructs an <code>OlapException</code> object with a reason;
069 * the <code>sqlState</code> field defaults to <code>null</code>, and
070 * the <code>vendorCode</code> field defaults to 0.
071 *
072 * @param reason a description of the exception
073 */
074 public OlapException(String reason) {
075 super(reason);
076 }
077
078 /**
079 * Constructs an <code>OlapException</code> object;
080 * the <code>reason</code> field defaults to null,
081 * the <code>sqlState</code> field defaults to <code>null</code>, and
082 * the <code>vendorCode</code> field defaults to 0.
083 */
084 public OlapException() {
085 super();
086 }
087
088 /**
089 * Constructs an <code>OlapException</code> object with a given
090 * <code>cause</code>.
091 * The <code>SQLState</code> is initialized
092 * to <code>null</code> and the vendor code is initialized to 0.
093 * The <code>reason</code> is initialized to <code>null</code> if
094 * <code>cause==null</code> or to <code>cause.toString()</code> if
095 * <code>cause!=null</code>.
096 * <p>
097 * @param cause the underlying reason for this <code>OlapException</code>
098 * (which is saved for later retrieval by the <code>getCause()</code>
099 * method); may be null indicating the cause is non-existent or unknown.
100 */
101 public OlapException(Throwable cause) {
102 super();
103 initCause(cause);
104 }
105
106 /**
107 * Constructs an <code>OlapException</code> object with a given
108 * <code>reason</code> and <code>cause</code>.
109 *
110 * @param reason the detail message (which is saved for later retrieval
111 * by the {@link #getMessage()} method).
112 * @param cause the cause (which is saved for later retrieval by the
113 * {@link #getCause()} method). (A <tt>null</tt> value is
114 * permitted, and indicates that the cause is nonexistent or
115 * unknown.)
116 */
117 public OlapException(String reason, Throwable cause) {
118 // Cannot call super(reason, cause) because
119 // SQLException(String, Throwable) only exists from JDK 1.6.
120 super(reason);
121 initCause(cause);
122 }
123
124 /**
125 * Constructs an <code>OlapException</code> object with a given
126 * <code>reason</code>, <code>SQLState</code> and <code>cause</code>.
127 * The vendor code is initialized to 0.
128 *
129 * @param reason a description of the exception.
130 * @param sqlState an XOPEN or SQL:2003 code identifying the exception
131 * @param cause the underlying reason for this <code>OlapException</code>
132 * (which is saved for later retrieval by the
133 * <code>getCause()</code> method); may be null indicating
134 * the cause is non-existent or unknown.
135 */
136 public OlapException(String reason, String sqlState, Throwable cause) {
137 // Cannot call SQLException(String, String, Throwable); it only
138 // exists from JDK 1.6
139 super(reason, sqlState);
140 initCause(cause);
141 }
142
143 /**
144 * Constructs an <code>OlapException</code> object with a given
145 * <code>reason</code>, <code>SQLState</code>, <code>vendorCode</code>
146 * and <code>cause</code>.
147 *
148 * @param reason a description of the exception
149 * @param sqlState an XOPEN or SQL:2003 code identifying the exception
150 * @param vendorCode a database vendor-specific exception code
151 * @param cause the underlying reason for this <code>OlapException</code>
152 * (which is saved for later retrieval by the <code>getCause()</code>
153 * method);
154 * may be null indicating the cause is non-existent or unknown.
155 */
156 public OlapException(
157 String reason,
158 String sqlState,
159 int vendorCode,
160 Throwable cause)
161 {
162 // Cannot call SQLException(String, String, int, Throwable); it only
163 // exists from JDK 1.6
164 super(reason, sqlState, vendorCode);
165 initCause(cause);
166 }
167
168 /**
169 * Sets the textual region where the exception occurred.
170 *
171 * @param region Textual region
172 */
173 public void setRegion(Region region) {
174 this.region = region;
175 }
176
177 /**
178 * Returns the textual region where the exception occurred, or null if no
179 * region can be identified.
180 *
181 * @return Region where the exception occurred
182 */
183 public Region getRegion() {
184 return region;
185 }
186
187 /**
188 * Sets the context where the exception occurred.
189 *
190 * @param context Context where the exception occurred
191 * @throws IllegalArgumentException If context is not a {@link Cell}
192 * or a {@link Position}
193 */
194 public void setContext(Object context) {
195 if (!(context instanceof Cell)
196 && !(context instanceof Position))
197 {
198 throw new IllegalArgumentException(
199 "expected Cell or Position");
200 }
201 this.context = context;
202 }
203
204 /**
205 * Returns the context where the exception occurred.
206 * Typically a {@link Cell} or a {@link Position}, or null.
207 *
208 * @return context where the exception occurred, or null
209 */
210 public Object getContext() {
211 return context;
212 }
213
214 /**
215 * Description of the position of a syntax or validation error in the source
216 * MDX string.
217 *
218 * <p>Row and column positions are 1-based and inclusive. For example,
219 * in</p>
220 *
221 * <blockquote>
222 * <pre>
223 * SELECT { [Measures].MEMBERS } ON COLUMNS,
224 * { } ON ROWS
225 * FROM [Sales]
226 * </pre>
227 * </blockquote>
228 *
229 * <p>the <code>SELECT</code> keyword occupies positions (1, 1) through
230 * (1, 6), and would have a <code>Region(startLine=1, startColumn=1,
231 * endColumn=1, endLine=6)</code>.</p>
232 */
233 public static final class Region {
234 public final int startLine;
235 public final int startColumn;
236 public final int endLine;
237 public final int endColumn;
238
239 protected Region(
240 int startLine,
241 int startColumn,
242 int endLine,
243 int endColumn)
244 {
245 this.startLine = startLine;
246 this.startColumn = startColumn;
247 this.endColumn = endLine;
248 this.endLine = endColumn;
249 }
250
251 public String toString() {
252 if (startLine == endColumn && startColumn == endLine) {
253 return "line " + startLine + ", column " + startColumn;
254 } else {
255 return "line " + startLine + ", column " + startColumn
256 + " through line " + endLine + ", column " + endColumn;
257 }
258 }
259 }
260 }
261
262 // End OlapException.java