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*/ 020package org.olap4j; 021 022import 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 */ 039public 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