View Javadoc

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  package org.apache.commons.transaction.file;
18  
19  import java.io.PrintWriter;
20  import java.io.StringWriter;
21  
22  /**
23   * Signals any kind of error or failure state in a {@link ResourceManager}.
24   * 
25   * @version $Id: ResourceManagerException.java 493628 2007-01-07 01:42:48Z joerg $
26   */
27  public class ResourceManagerException extends Exception implements ResourceManagerErrorCodes {
28  
29      private static final int[] ERROR_CODES =
30          {
31              ERR_SYSTEM,
32              ERR_SYSTEM_INCONSISTENT,
33              ERR_NO_TX,
34              ERR_TXID_INVALID,
35              ERR_TX_INACTIVE,
36              ERR_TX_INCONSISTENT,
37              ERR_DUP_TX,
38              ERR_THREAD_INVALID,
39              ERR_ISOLATION_LEVEL_UNSUPPORTED,
40              ERR_RESOURCEID_INVALID,
41              ERR_RESOURCE_EXISTS,
42              ERR_NO_SUCH_RESOURCE,
43              ERR_LOCK,
44              ERR_NO_LOCK,
45              ERR_MARKED_FOR_ROLLBACK,
46              };
47  
48      private static final String[] ERROR_CODE_STRINGS =
49          {
50              "ERR_SYSTEM",
51              "ERR_SYSTEM_INCONSISTENT",
52              "ERR_NO_TX",
53              "ERR_TXID_INVALID",
54              "ERR_TX_INACTIVE",
55              "ERR_TX_INCONSISTENT",
56              "ERR_DUP_TX",
57              "ERR_THREAD_INVALID",
58              "ERR_ISOLATION_LEVEL_UNSUPPORTED",
59              "ERR_RESOURCEID_INVALID",
60              "ERR_RESOURCE_EXISTS",
61              "ERR_NO_SUCH_RESOURCE",
62              "ERR_LOCK",
63              "ERR_NO_LOCK",
64              "ERR_MARKED_FOR_ROLLBACK",
65              };
66  
67      private static final String[] ERROR_CODE_TEXTS =
68          {
69              "System error",
70              "Inconsistent system data",
71              "Unknown transaction",
72              "Invalid transaction id",
73              "Transaction inactive",
74              "Inconsistent transaction data",
75              "Duplicate transaction id",
76              "Thread of control is the one that not start tx",
77              "Isolation level unsupported",
78              "Specified resource id is invalid",
79              "Resource already exists",
80              "No such resource",
81              "Locking error",
82              "Could not acquire lock",
83              "Transaction already marked for rollback" };
84  
85      public static final String ERR_UNKNOWN_TEXT = "Unknown error";
86      public static final String ERR_UNKNOWN_CODE = "ERR_UNKNOWN";
87  
88      protected final int status;
89      protected final Object txId;
90  
91      protected static final String composeMessage(String msg, int status, Object txId, Throwable cause) {
92          String message = composeMessage(msg, status, txId);
93          StringBuffer messageBuffer = new StringBuffer(message);
94          messageBuffer.append("\nCaused by: ");
95          StringWriter sw = new StringWriter();
96          cause.printStackTrace(new PrintWriter(sw));
97          messageBuffer.append(sw.getBuffer());
98          return messageBuffer.toString();
99      }
100     
101     protected static final String composeMessage(String msg, int status, Object txId) {
102         StringBuffer composed = new StringBuffer();
103         if (txId != null) {
104             composed.append(txId).append(": ");
105         }
106         if (msg != null) {
107             composed.append(msg);
108             if (status != -1) {
109                 composed.append(" (").append(statusToCode(status)).append(')');
110             }
111         } else if (status != -1) {
112             composed.append(statusToText(status));
113         }
114 
115         return composed.toString();
116     }
117 
118     public static final String statusToText(int status) {
119         if (status == ERR_UNKNOWN) {
120             return ERR_UNKNOWN_TEXT;
121         } else {
122             int pos = -1;
123             for (int i = 0; i < ERROR_CODES.length; i++) {
124                 int code = ERROR_CODES[i];
125                 if (status == code) {
126                     pos = i;
127                     break;
128                 }
129             }
130             if (pos == -1) {
131                 return ERR_UNKNOWN_TEXT + ", code: " + status;
132             } else {
133                 return ERROR_CODE_TEXTS[pos];
134             }
135         }
136     }
137 
138     public static final String statusToCode(int status) {
139         if (status == ERR_UNKNOWN) {
140             return ERR_UNKNOWN_CODE;
141         } else {
142             int pos = -1;
143             for (int i = 0; i < ERROR_CODES.length; i++) {
144                 int code = ERROR_CODES[i];
145                 if (status == code) {
146                     pos = i;
147                     break;
148                 }
149             }
150             if (pos == -1) {
151                 return ERR_UNKNOWN_CODE + ": " + status;
152             } else {
153                 return ERROR_CODE_STRINGS[pos];
154             }
155         }
156     }
157 
158     public ResourceManagerException(String message, int status, Object txId) {
159         super(ResourceManagerException.composeMessage(message, status, txId));
160         this.status = status;
161         this.txId = txId;
162     }
163 
164     public ResourceManagerException(int status, Object txId) {
165         this(null, status, txId);
166     }
167 
168     public ResourceManagerException(String message) {
169         super(message);
170         this.status = ERR_UNKNOWN;
171         this.txId = null;
172     }
173 
174     public ResourceManagerException(String message, int status, Object txId, Throwable cause) {
175         // XXX can not do this, as 1.3 Throwable does not allow cause in ctor :( 
176 //        super(ResourceManagerException.composeMessage(message, status, txId), cause);
177         // for now format cause by ourselves
178         super(ResourceManagerException.composeMessage(message, status, txId, cause));
179         this.status = status;
180         this.txId = txId;
181     }
182 
183     public ResourceManagerException(String message, int status, Throwable cause) {
184         this(message, status, null, cause);
185     }
186 
187     public ResourceManagerException(String message, Throwable cause) {
188         this(message, ERR_UNKNOWN, cause);
189     }
190 
191     public ResourceManagerException(int status, Object txId, Throwable cause) {
192         this(null, status, txId, cause);
193     }
194 
195     public String statusToString() {
196         return ResourceManagerException.statusToText(status);
197     }
198 
199     public int getStatus() {
200         return status;
201     }
202 
203 }