Tue, 28 Dec 2010 15:52:36 -0800
6962318: Update copyright year
Reviewed-by: xdono
1 /*
2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.corba.se.impl.presentation.rmi ;
28 import java.io.Serializable ;
29 import java.io.Externalizable ;
31 import javax.rmi.PortableRemoteObject ;
32 import javax.rmi.CORBA.Util ;
34 import java.rmi.RemoteException ;
35 import java.rmi.UnexpectedException ;
37 import org.omg.CORBA.UserException ;
39 import org.omg.CORBA_2_3.portable.InputStream ;
40 import org.omg.CORBA_2_3.portable.OutputStream ;
41 import org.omg.CORBA.portable.ApplicationException ;
43 import java.lang.reflect.Method ;
45 import com.sun.corba.se.spi.logging.CORBALogDomains ;
46 import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
48 public class ExceptionHandlerImpl implements ExceptionHandler
49 {
50 private ExceptionRW[] rws ;
52 private final ORBUtilSystemException wrapper ;
54 ///////////////////////////////////////////////////////////////////////////////
55 // ExceptionRW interface and implementations.
56 // Used to read and write exceptions.
57 ///////////////////////////////////////////////////////////////////////////////
59 public interface ExceptionRW
60 {
61 Class getExceptionClass() ;
63 String getId() ;
65 void write( OutputStream os, Exception ex ) ;
67 Exception read( InputStream is ) ;
68 }
70 public abstract class ExceptionRWBase implements ExceptionRW
71 {
72 private Class cls ;
73 private String id ;
75 public ExceptionRWBase( Class cls )
76 {
77 this.cls = cls ;
78 }
80 public Class getExceptionClass()
81 {
82 return cls ;
83 }
85 public String getId()
86 {
87 return id ;
88 }
90 void setId( String id )
91 {
92 this.id = id ;
93 }
94 }
96 public class ExceptionRWIDLImpl extends ExceptionRWBase
97 {
98 private Method readMethod ;
99 private Method writeMethod ;
101 public ExceptionRWIDLImpl( Class cls )
102 {
103 super( cls ) ;
105 String helperName = cls.getName() + "Helper" ;
106 ClassLoader loader = cls.getClassLoader() ;
107 Class helperClass ;
109 try {
110 helperClass = Class.forName( helperName, true, loader ) ;
111 Method idMethod = helperClass.getDeclaredMethod( "id", (Class[])null ) ;
112 setId( (String)idMethod.invoke( null, (Object[])null ) ) ;
113 } catch (Exception ex) {
114 throw wrapper.badHelperIdMethod( ex, helperName ) ;
115 }
117 try {
118 Class[] argTypes = new Class[] {
119 org.omg.CORBA.portable.OutputStream.class, cls } ;
120 writeMethod = helperClass.getDeclaredMethod( "write",
121 argTypes ) ;
122 } catch (Exception ex) {
123 throw wrapper.badHelperWriteMethod( ex, helperName ) ;
124 }
126 try {
127 Class[] argTypes = new Class[] {
128 org.omg.CORBA.portable.InputStream.class } ;
129 readMethod = helperClass.getDeclaredMethod( "read", argTypes ) ;
130 } catch (Exception ex) {
131 throw wrapper.badHelperReadMethod( ex, helperName ) ;
132 }
133 }
135 public void write( OutputStream os, Exception ex )
136 {
137 try {
138 Object[] args = new Object[] { os, ex } ;
139 writeMethod.invoke( null, args ) ;
140 } catch (Exception exc) {
141 throw wrapper.badHelperWriteMethod( exc,
142 writeMethod.getDeclaringClass().getName() ) ;
143 }
144 }
146 public Exception read( InputStream is )
147 {
148 try {
149 Object[] args = new Object[] { is } ;
150 return (Exception)readMethod.invoke( null, args ) ;
151 } catch (Exception ex) {
152 throw wrapper.badHelperReadMethod( ex,
153 readMethod.getDeclaringClass().getName() ) ;
154 }
155 }
156 }
158 public class ExceptionRWRMIImpl extends ExceptionRWBase
159 {
160 public ExceptionRWRMIImpl( Class cls )
161 {
162 super( cls ) ;
163 setId( IDLNameTranslatorImpl.getExceptionId( cls ) ) ;
164 }
166 public void write( OutputStream os, Exception ex )
167 {
168 os.write_string( getId() ) ;
169 os.write_value( ex, getExceptionClass() ) ;
170 }
172 public Exception read( InputStream is )
173 {
174 is.read_string() ; // read and ignore!
175 return (Exception)is.read_value( getExceptionClass() ) ;
176 }
177 }
179 ///////////////////////////////////////////////////////////////////////////////
181 public ExceptionHandlerImpl( Class[] exceptions )
182 {
183 wrapper = ORBUtilSystemException.get(
184 CORBALogDomains.RPC_PRESENTATION ) ;
186 int count = 0 ;
187 for (int ctr=0; ctr<exceptions.length; ctr++) {
188 Class cls = exceptions[ctr] ;
189 if (!RemoteException.class.isAssignableFrom(cls))
190 count++ ;
191 }
193 rws = new ExceptionRW[count] ;
195 int index = 0 ;
196 for (int ctr=0; ctr<exceptions.length; ctr++) {
197 Class cls = exceptions[ctr] ;
198 if (!RemoteException.class.isAssignableFrom(cls)) {
199 ExceptionRW erw = null ;
200 if (UserException.class.isAssignableFrom(cls))
201 erw = new ExceptionRWIDLImpl( cls ) ;
202 else
203 erw = new ExceptionRWRMIImpl( cls ) ;
205 /* The following check is not performed
206 * in order to maintain compatibility with
207 * rmic. See bug 4989312.
209 // Check for duplicate repository ID
210 String repositoryId = erw.getId() ;
211 int duplicateIndex = findDeclaredException( repositoryId ) ;
212 if (duplicateIndex > 0) {
213 ExceptionRW duprw = rws[duplicateIndex] ;
214 String firstClassName =
215 erw.getExceptionClass().getName() ;
216 String secondClassName =
217 duprw.getExceptionClass().getName() ;
218 throw wrapper.duplicateExceptionRepositoryId(
219 firstClassName, secondClassName, repositoryId ) ;
220 }
222 */
224 rws[index++] = erw ;
225 }
226 }
227 }
229 private int findDeclaredException( Class cls )
230 {
231 for (int ctr = 0; ctr < rws.length; ctr++) {
232 Class next = rws[ctr].getExceptionClass() ;
233 if (next.isAssignableFrom(cls))
234 return ctr ;
235 }
237 return -1 ;
238 }
240 private int findDeclaredException( String repositoryId )
241 {
242 for (int ctr=0; ctr<rws.length; ctr++) {
243 // This may occur when rws has not been fully
244 // populated, in which case the search should just fail.
245 if (rws[ctr]==null)
246 return -1 ;
248 String rid = rws[ctr].getId() ;
249 if (repositoryId.equals( rid ))
250 return ctr ;
251 }
253 return -1 ;
254 }
256 public boolean isDeclaredException( Class cls )
257 {
258 return findDeclaredException( cls ) >= 0 ;
259 }
261 public void writeException( OutputStream os, Exception ex )
262 {
263 int index = findDeclaredException( ex.getClass() ) ;
264 if (index < 0)
265 throw wrapper.writeUndeclaredException( ex,
266 ex.getClass().getName() ) ;
268 rws[index].write( os, ex ) ;
269 }
271 public Exception readException( ApplicationException ae )
272 {
273 // Note that the exception ID is present in both ae
274 // and in the input stream from ae. The exception
275 // reader must actually read the exception ID from
276 // the stream.
277 InputStream is = (InputStream)ae.getInputStream() ;
278 String excName = ae.getId() ;
279 int index = findDeclaredException( excName ) ;
280 if (index < 0) {
281 excName = is.read_string() ;
282 Exception res = new UnexpectedException( excName ) ;
283 res.initCause( ae ) ;
284 return res ;
285 }
287 return rws[index].read( is ) ;
288 }
290 // This is here just for the dynamicrmiiiop test
291 public ExceptionRW getRMIExceptionRW( Class cls )
292 {
293 return new ExceptionRWRMIImpl( cls ) ;
294 }
295 }