View Javadoc
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, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.river.api.io;
20  
21  import java.io.IOException;
22  import java.io.ObjectInputStream;
23  import java.io.ObjectOutputStream;
24  import java.io.ObjectStreamField;
25  import org.apache.river.api.io.AtomicSerial.GetArg;
26  
27  /**
28   * Although most Throwable classes are serialized over AtomicMarshalOutputStream,
29   * only Throwable's fields are transferred.  If an Exception needs to serialize
30   * additional state, then AtomicException provides an abstract superclass,
31   * that serializes Throwable's fields for convenience.
32   * 
33   * @author peter
34   */
35  @AtomicSerial
36  public abstract class AtomicException extends Exception {
37      private static final long serialVersionUID = 1L;
38      
39      /**
40       * In earlier versions the extra fields will duplicate those of Throwable,
41       * so only ref id's will be sent, so the objects these fields refer to will
42       * only be sent once.
43       */
44      private static final ObjectStreamField[] serialPersistentFields = 
45  	{
46  	    new ObjectStreamField("message", String.class),
47  	    new ObjectStreamField("cause", Throwable.class),
48  	    new ObjectStreamField("stack", StackTraceElement[].class),
49  	    new ObjectStreamField("suppressed", Throwable[].class)
50  	}; 
51  
52      protected AtomicException(String message, Throwable cause,
53                          boolean enableSuppression,
54                          boolean writableStackTrace) 
55      {
56          super(message, cause, enableSuppression, writableStackTrace);
57      }
58      
59      protected AtomicException(String message, Throwable cause){
60  	super(message, cause);
61      }
62      
63      protected AtomicException(String message){
64  	super(message);
65      }
66      
67      protected AtomicException(){
68  	super();
69      }
70      
71      protected AtomicException(Throwable cause){
72  	super(cause);
73      }
74      
75      protected AtomicException(GetArg arg) throws IOException{
76  	this(arg.get("message", null, String.class),
77  	     arg.get("cause", null, Throwable.class),
78  	     arg.get("stack", null, StackTraceElement[].class),
79  	     arg.get("suppressed", null, Throwable[].class)
80  	);
81      }
82      
83      private AtomicException(String message, 
84  			      Throwable cause,
85  			      StackTraceElement[] stack,
86  			      Throwable[] suppressed) 
87      {
88          super(message, cause, true, true);
89  	if (stack != null) this.setStackTrace(stack); // defensively copied.2
90  	if (suppressed != null){
91  	    for (int i = 0, l = suppressed.length; i < l; i++){
92  		this.addSuppressed(suppressed[i]);
93  	    }
94  	}
95      }
96      
97      private void writeObject(ObjectOutputStream out) throws IOException {
98  	ObjectOutputStream.PutField pf = out.putFields();
99  	pf.put("message", super.getMessage());
100 	pf.put("cause", super.getCause());
101 	pf.put("stack", super.getStackTrace());
102 	pf.put("suppressed", super.getSuppressed());
103 	out.writeFields();
104     }
105     
106     private void readObject(ObjectInputStream in) 
107 	throws IOException, ClassNotFoundException
108     {
109 	in.defaultReadObject();
110     }
111 }