Back to home page

OSCL-LXR

 
 

    


0001 /**
0002  * Licensed to the Apache Software Foundation (ASF) under one
0003  * or more contributor license agreements.  See the NOTICE file
0004  * distributed with this work for additional information
0005  * regarding copyright ownership.  The ASF licenses this file
0006  * to you under the Apache License, Version 2.0 (the
0007  * "License"); you may not use this file except in compliance
0008  * with the License.  You may obtain a copy of the License at
0009  *
0010  *     http://www.apache.org/licenses/LICENSE-2.0
0011  *
0012  * Unless required by applicable law or agreed to in writing, software
0013  * distributed under the License is distributed on an "AS IS" BASIS,
0014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0015  * See the License for the specific language governing permissions and
0016  * limitations under the License.
0017  */
0018 
0019 package org.apache.hive.service.cli;
0020 
0021 import java.sql.SQLException;
0022 import java.util.ArrayList;
0023 import java.util.List;
0024 
0025 import org.apache.hive.service.rpc.thrift.TStatus;
0026 import org.apache.hive.service.rpc.thrift.TStatusCode;
0027 
0028 /**
0029  * HiveSQLException.
0030  *
0031  */
0032 public class HiveSQLException extends SQLException {
0033 
0034   /**
0035    *
0036    */
0037   private static final long serialVersionUID = -6095254671958748094L;
0038 
0039   /**
0040    *
0041    */
0042   public HiveSQLException() {
0043     super();
0044   }
0045 
0046   /**
0047    * @param reason
0048    */
0049   public HiveSQLException(String reason) {
0050     super(reason);
0051   }
0052 
0053   /**
0054    * @param cause
0055    */
0056   public HiveSQLException(Throwable cause) {
0057     super(cause);
0058   }
0059 
0060   /**
0061    * @param reason
0062    * @param sqlState
0063    */
0064   public HiveSQLException(String reason, String sqlState) {
0065     super(reason, sqlState);
0066   }
0067 
0068   /**
0069    * @param reason
0070    * @param cause
0071    */
0072   public HiveSQLException(String reason, Throwable cause) {
0073     super(reason, cause);
0074   }
0075 
0076   /**
0077    * @param reason
0078    * @param sqlState
0079    * @param vendorCode
0080    */
0081   public HiveSQLException(String reason, String sqlState, int vendorCode) {
0082     super(reason, sqlState, vendorCode);
0083   }
0084 
0085   /**
0086    * @param reason
0087    * @param sqlState
0088    * @param cause
0089    */
0090   public HiveSQLException(String reason, String sqlState, Throwable cause) {
0091     super(reason, sqlState, cause);
0092   }
0093 
0094   /**
0095    * @param reason
0096    * @param sqlState
0097    * @param vendorCode
0098    * @param cause
0099    */
0100   public HiveSQLException(String reason, String sqlState, int vendorCode, Throwable cause) {
0101     super(reason, sqlState, vendorCode, cause);
0102   }
0103 
0104   public HiveSQLException(TStatus status) {
0105     // TODO: set correct vendorCode field
0106     super(status.getErrorMessage(), status.getSqlState(), status.getErrorCode());
0107     if (status.getInfoMessages() != null) {
0108       initCause(toCause(status.getInfoMessages()));
0109     }
0110   }
0111 
0112   /**
0113    * Converts current object to a {@link TStatus} object
0114    * @return a {@link TStatus} object
0115    */
0116   public TStatus toTStatus() {
0117     // TODO: convert sqlState, etc.
0118     TStatus tStatus = new TStatus(TStatusCode.ERROR_STATUS);
0119     tStatus.setSqlState(getSQLState());
0120     tStatus.setErrorCode(getErrorCode());
0121     tStatus.setErrorMessage(getMessage());
0122     tStatus.setInfoMessages(toString(this));
0123     return tStatus;
0124   }
0125 
0126   /**
0127    * Converts the specified {@link Exception} object into a {@link TStatus} object
0128    * @param e a {@link Exception} object
0129    * @return a {@link TStatus} object
0130    */
0131   public static TStatus toTStatus(Exception e) {
0132     if (e instanceof HiveSQLException) {
0133       return ((HiveSQLException)e).toTStatus();
0134     }
0135     TStatus tStatus = new TStatus(TStatusCode.ERROR_STATUS);
0136     tStatus.setErrorMessage(e.getMessage());
0137     tStatus.setInfoMessages(toString(e));
0138     return tStatus;
0139   }
0140 
0141   /**
0142    * Converts a {@link Throwable} object into a flattened list of texts including its stack trace
0143    * and the stack traces of the nested causes.
0144    * @param ex  a {@link Throwable} object
0145    * @return    a flattened list of texts including the {@link Throwable} object's stack trace
0146    *            and the stack traces of the nested causes.
0147    */
0148   public static List<String> toString(Throwable ex) {
0149     return toString(ex, null);
0150   }
0151 
0152   private static List<String> toString(Throwable cause, StackTraceElement[] parent) {
0153     StackTraceElement[] trace = cause.getStackTrace();
0154     int m = trace.length - 1;
0155     if (parent != null) {
0156       int n = parent.length - 1;
0157       while (m >= 0 && n >= 0 && trace[m].equals(parent[n])) {
0158         m--;
0159         n--;
0160       }
0161     }
0162     List<String> detail = enroll(cause, trace, m);
0163     cause = cause.getCause();
0164     if (cause != null) {
0165       detail.addAll(toString(cause, trace));
0166     }
0167     return detail;
0168   }
0169 
0170   private static List<String> enroll(Throwable ex, StackTraceElement[] trace, int max) {
0171     List<String> details = new ArrayList<String>();
0172     StringBuilder builder = new StringBuilder();
0173     builder.append('*').append(ex.getClass().getName()).append(':');
0174     builder.append(ex.getMessage()).append(':');
0175     builder.append(trace.length).append(':').append(max);
0176     details.add(builder.toString());
0177     for (int i = 0; i <= max; i++) {
0178       builder.setLength(0);
0179       builder.append(trace[i].getClassName()).append(':');
0180       builder.append(trace[i].getMethodName()).append(':');
0181       String fileName = trace[i].getFileName();
0182       builder.append(fileName == null ? "" : fileName).append(':');
0183       builder.append(trace[i].getLineNumber());
0184       details.add(builder.toString());
0185     }
0186     return details;
0187   }
0188 
0189   /**
0190    * Converts a flattened list of texts including the stack trace and the stack
0191    * traces of the nested causes into a {@link Throwable} object.
0192    * @param details a flattened list of texts including the stack trace and the stack
0193    *                traces of the nested causes
0194    * @return        a {@link Throwable} object
0195    */
0196   public static Throwable toCause(List<String> details) {
0197     return toStackTrace(details, null, 0);
0198   }
0199 
0200   private static Throwable toStackTrace(List<String> details, StackTraceElement[] parent, int index) {
0201     String detail = details.get(index++);
0202     if (!detail.startsWith("*")) {
0203       return null;  // should not be happened. ignore remaining
0204     }
0205     int i1 = detail.indexOf(':');
0206     int i3 = detail.lastIndexOf(':');
0207     int i2 = detail.substring(0, i3).lastIndexOf(':');
0208     String exceptionClass = detail.substring(1, i1);
0209     String exceptionMessage = detail.substring(i1 + 1, i2);
0210     Throwable ex = newInstance(exceptionClass, exceptionMessage);
0211 
0212     Integer length = Integer.valueOf(detail.substring(i2 + 1, i3));
0213     Integer unique = Integer.valueOf(detail.substring(i3 + 1));
0214 
0215     int i = 0;
0216     StackTraceElement[] trace = new StackTraceElement[length];
0217     for (; i <= unique; i++) {
0218       detail = details.get(index++);
0219       int j1 = detail.indexOf(':');
0220       int j3 = detail.lastIndexOf(':');
0221       int j2 = detail.substring(0, j3).lastIndexOf(':');
0222       String className = detail.substring(0, j1);
0223       String methodName = detail.substring(j1 + 1, j2);
0224       String fileName = detail.substring(j2 + 1, j3);
0225       if (fileName.isEmpty()) {
0226         fileName = null;
0227       }
0228       int lineNumber = Integer.valueOf(detail.substring(j3 + 1));
0229       trace[i] = new StackTraceElement(className, methodName, fileName, lineNumber);
0230     }
0231     int common = trace.length - i;
0232     if (common > 0) {
0233       System.arraycopy(parent, parent.length - common, trace, trace.length - common, common);
0234     }
0235     if (details.size() > index) {
0236       ex.initCause(toStackTrace(details, trace, index));
0237     }
0238     ex.setStackTrace(trace);
0239     return ex;
0240   }
0241 
0242   private static Throwable newInstance(String className, String message) {
0243     try {
0244       return (Throwable)Class.forName(className).getConstructor(String.class).newInstance(message);
0245     } catch (Exception e) {
0246       return new RuntimeException(className + ":" + message);
0247     }
0248   }
0249 }