38 |
|
|
39 |
package gnu.CORBA; |
package gnu.CORBA; |
40 |
|
|
41 |
|
import gnu.CORBA.CDR.UnknownExceptionCtxHandler; |
42 |
|
import gnu.CORBA.CDR.cdrBufInput; |
43 |
import gnu.CORBA.CDR.cdrBufOutput; |
import gnu.CORBA.CDR.cdrBufOutput; |
44 |
|
import gnu.CORBA.CDR.cdrInput; |
45 |
|
import gnu.CORBA.GIOP.ServiceContext; |
46 |
|
|
47 |
import org.omg.CORBA.Any; |
import org.omg.CORBA.Any; |
48 |
import org.omg.CORBA.CompletionStatus; |
import org.omg.CORBA.CompletionStatus; |
49 |
import org.omg.CORBA.CompletionStatusHelper; |
import org.omg.CORBA.CompletionStatusHelper; |
50 |
import org.omg.CORBA.MARSHAL; |
import org.omg.CORBA.MARSHAL; |
|
import org.omg.CORBA.StructMember; |
|
51 |
import org.omg.CORBA.SystemException; |
import org.omg.CORBA.SystemException; |
52 |
import org.omg.CORBA.TCKind; |
import org.omg.CORBA.TCKind; |
53 |
import org.omg.CORBA.UNKNOWN; |
import org.omg.CORBA.UNKNOWN; |
54 |
import org.omg.CORBA.UserException; |
import org.omg.CORBA.UserException; |
55 |
|
import org.omg.CORBA.portable.IDLEntity; |
56 |
import org.omg.CORBA.portable.InputStream; |
import org.omg.CORBA.portable.InputStream; |
57 |
import org.omg.CORBA.portable.OutputStream; |
import org.omg.CORBA.portable.OutputStream; |
58 |
|
import org.omg.CORBA.portable.ValueBase; |
59 |
|
|
|
import java.lang.reflect.Constructor; |
|
60 |
import java.lang.reflect.Method; |
import java.lang.reflect.Method; |
61 |
|
import java.util.Map; |
62 |
|
import java.util.WeakHashMap; |
63 |
|
|
64 |
|
import javax.rmi.CORBA.Util; |
65 |
|
|
66 |
/** |
/** |
67 |
* Creates java objects from the agreed IDL names for the simple case when the |
* Creates java objects from the agreed IDL names for the simple case when the |
68 |
* CORBA object is directly mapped into the locally defined java class. |
* CORBA object is directly mapped into the locally defined java class. |
69 |
* |
* |
70 |
* @author Audrius Meskauskas (AudriusA@Bioinformatics.org) |
* @author Audrius Meskauskas (AudriusA@Bioinformatics.org) |
71 |
*/ |
*/ |
72 |
public class ObjectCreator |
public class ObjectCreator |
87 |
public static final String CLASSPATH_PREFIX = "gnu.CORBA."; |
public static final String CLASSPATH_PREFIX = "gnu.CORBA."; |
88 |
|
|
89 |
/** |
/** |
90 |
|
* Maps classes to they IDL or RMI names. Computing RMI name is an expensive |
91 |
|
* operations, so frequently used RMI keys are reused. The map must be weak to |
92 |
|
* ensure that the class can be unloaded, when applicable. |
93 |
|
*/ |
94 |
|
public static Map m_names = new WeakHashMap(); |
95 |
|
|
96 |
|
/** |
97 |
|
* Maps IDL strings into known classes. The map must be weak to ensure that |
98 |
|
* the class can be unloaded, when applicable. |
99 |
|
*/ |
100 |
|
public static Map m_classes = new WeakHashMap(); |
101 |
|
|
102 |
|
/** |
103 |
|
* Maps IDL types to they helpers. |
104 |
|
*/ |
105 |
|
public static Map m_helpers = new WeakHashMap(); |
106 |
|
|
107 |
|
/** |
108 |
* Try to instantiate an object with the given IDL name. The object must be |
* Try to instantiate an object with the given IDL name. The object must be |
109 |
* mapped to the local java class. The omg.org domain must be mapped into the |
* mapped to the local java class. The omg.org domain must be mapped into the |
110 |
* object in either org/omg or gnu/CORBA namespace. |
* object in either org/omg or gnu/CORBA namespace. |
111 |
* |
* |
112 |
* @param IDL name |
* @param IDL name |
113 |
* @return instantiated object instance or null if no such available. |
* @return instantiated object instance or null if no such available. |
114 |
*/ |
*/ |
115 |
public static java.lang.Object createObject(String idl, String suffix) |
public static java.lang.Object createObject(String idl, String suffix) |
116 |
{ |
{ |
117 |
try |
synchronized (m_classes) |
118 |
{ |
{ |
119 |
return Class.forName(toClassName(JAVA_PREFIX, idl) + suffix) |
Class known = (Class) (suffix == null ? m_classes.get(idl) |
120 |
.newInstance(); |
: m_classes.get(idl + 0xff + suffix)); |
121 |
} |
Object object; |
122 |
catch (Exception ex) |
|
123 |
{ |
if (known != null) |
|
try |
|
124 |
{ |
{ |
125 |
return Class.forName(toClassName(CLASSPATH_PREFIX, idl) + suffix) |
try |
126 |
.newInstance(); |
{ |
127 |
|
return known.newInstance(); |
128 |
|
} |
129 |
|
catch (Exception ex) |
130 |
|
{ |
131 |
|
RuntimeException rex = new RuntimeException(idl + " suffix " |
132 |
|
+ suffix, ex); |
133 |
|
throw rex; |
134 |
|
} |
135 |
} |
} |
136 |
catch (Exception exex) |
else |
137 |
{ |
{ |
138 |
return null; |
if (suffix == null) |
139 |
|
suffix = ""; |
140 |
|
try |
141 |
|
{ |
142 |
|
known = Class.forName(toClassName(JAVA_PREFIX, idl) + suffix); |
143 |
|
object = known.newInstance(); |
144 |
|
} |
145 |
|
catch (Exception ex) |
146 |
|
{ |
147 |
|
try |
148 |
|
{ |
149 |
|
known = Class.forName(toClassName(CLASSPATH_PREFIX, idl) |
150 |
|
+ suffix); |
151 |
|
object = known.newInstance(); |
152 |
|
} |
153 |
|
catch (Exception exex) |
154 |
|
{ |
155 |
|
return null; |
156 |
|
} |
157 |
|
} |
158 |
|
m_classes.put(idl + 0xff + suffix, known); |
159 |
|
return object; |
160 |
} |
} |
161 |
} |
} |
162 |
} |
} |
163 |
|
|
164 |
/** |
/** |
|
* Create the system exception with the given idl name. |
|
|
* |
|
|
* @param idl the exception IDL name, must match the syntax "IDL:<class/name>:1.0". |
|
|
* @param minor the exception minor code. |
|
|
* @param completed the exception completion status. |
|
|
* |
|
|
* @return the created exception. |
|
|
*/ |
|
|
public static SystemException createSystemException(String idl, int minor, |
|
|
CompletionStatus completed |
|
|
) |
|
|
{ |
|
|
try |
|
|
{ |
|
|
String cl = toClassName(JAVA_PREFIX, idl); |
|
|
Class exClass = Class.forName(cl); |
|
|
|
|
|
Constructor constructor = |
|
|
exClass.getConstructor(new Class[] |
|
|
{ |
|
|
String.class, int.class, CompletionStatus.class |
|
|
} |
|
|
); |
|
|
|
|
|
Object exception = |
|
|
constructor.newInstance(new Object[] |
|
|
{ |
|
|
" Remote exception " + idl + ", minor " + minor + ", " + |
|
|
completed + ".", new Integer(minor), completed |
|
|
} |
|
|
); |
|
|
|
|
|
return (SystemException) exception; |
|
|
} |
|
|
catch (Exception ex) |
|
|
{ |
|
|
ex.printStackTrace(); |
|
|
return new UNKNOWN("Unsupported system exception", minor, completed); |
|
|
} |
|
|
} |
|
|
|
|
|
/** |
|
165 |
* Read the system exception from the given stream. |
* Read the system exception from the given stream. |
166 |
* |
* |
167 |
* @param input the CDR stream to read from. |
* @param input the CDR stream to read from. |
168 |
|
* @param contexts the service contexts in request/reply header/ |
169 |
|
* |
170 |
* @return the exception that has been stored in the stream (IDL name, minor |
* @return the exception that has been stored in the stream (IDL name, minor |
171 |
* code and completion status). |
* code and completion status). |
172 |
*/ |
*/ |
173 |
public static SystemException readSystemException(InputStream input) |
public static SystemException readSystemException(InputStream input, |
174 |
|
ServiceContext[] contexts) |
175 |
{ |
{ |
176 |
|
SystemException exception; |
177 |
|
|
178 |
String idl = input.read_string(); |
String idl = input.read_string(); |
179 |
int minor = input.read_ulong(); |
int minor = input.read_ulong(); |
180 |
CompletionStatus status = CompletionStatusHelper.read(input); |
CompletionStatus completed = CompletionStatusHelper.read(input); |
181 |
|
|
182 |
|
try |
183 |
|
{ |
184 |
|
exception = (SystemException) createObject(idl, null); |
185 |
|
exception.minor = minor; |
186 |
|
exception.completed = completed; |
187 |
|
} |
188 |
|
catch (Exception ex) |
189 |
|
{ |
190 |
|
UNKNOWN u = new UNKNOWN("Unsupported system exception " + idl, minor, |
191 |
|
completed); |
192 |
|
u.initCause(ex); |
193 |
|
throw u; |
194 |
|
} |
195 |
|
|
196 |
|
try |
197 |
|
{ |
198 |
|
// If UnknownExceptionInfo is present in the contexts, read it and |
199 |
|
// set as a cause of this exception. |
200 |
|
ServiceContext uEx = ServiceContext.find( |
201 |
|
ServiceContext.UnknownExceptionInfo, contexts); |
202 |
|
|
203 |
SystemException exception = |
if (uEx != null) |
204 |
ObjectCreator.createSystemException(idl, minor, status); |
{ |
205 |
|
cdrBufInput in = new cdrBufInput(uEx.context_data); |
206 |
|
in.setOrb(in.orb()); |
207 |
|
if (input instanceof cdrInput) |
208 |
|
{ |
209 |
|
((cdrInput) input).cloneSettings(in); |
210 |
|
} |
211 |
|
|
212 |
|
Throwable t = UnknownExceptionCtxHandler.read(in, contexts); |
213 |
|
exception.initCause(t); |
214 |
|
} |
215 |
|
} |
216 |
|
catch (Exception ex) |
217 |
|
{ |
218 |
|
// Unsupported context format. Do not terminate as the user program may |
219 |
|
// not need it. |
220 |
|
} |
221 |
|
|
222 |
return exception; |
return exception; |
223 |
} |
} |
226 |
* Reads the user exception, having the given Id, from the input stream. The |
* Reads the user exception, having the given Id, from the input stream. The |
227 |
* id is expected to be in the form like |
* id is expected to be in the form like |
228 |
* 'IDL:test/org/omg/CORBA/ORB/communication/ourUserException:1.0' |
* 'IDL:test/org/omg/CORBA/ORB/communication/ourUserException:1.0' |
229 |
* |
* |
230 |
* @param idl the exception idl name. |
* @param idl the exception idl name. |
231 |
* @param input the stream to read from. |
* @param input the stream to read from. |
232 |
* |
* |
233 |
* @return the loaded exception. |
* @return the loaded exception. |
234 |
* @return null if the helper class cannot be found. |
* @return null if the helper class cannot be found. |
235 |
*/ |
*/ |
237 |
{ |
{ |
238 |
try |
try |
239 |
{ |
{ |
240 |
String helper = toHelperName(idl); |
Class helperClass = findHelper(idl); |
|
Class helperClass = Class.forName(helper); |
|
241 |
|
|
242 |
Method read = |
Method read = helperClass.getMethod("read", |
243 |
helperClass.getMethod("read", |
new Class[] { org.omg.CORBA.portable.InputStream.class }); |
|
new Class[] { org.omg.CORBA.portable.InputStream.class } |
|
|
); |
|
244 |
|
|
245 |
return (UserException) read.invoke(null, new Object[] { input }); |
return (UserException) read.invoke(null, new Object[] { input }); |
246 |
} |
} |
259 |
/** |
/** |
260 |
* Gets the helper class name from the string like |
* Gets the helper class name from the string like |
261 |
* 'IDL:test/org/omg/CORBA/ORB/communication/ourUserException:1.0' |
* 'IDL:test/org/omg/CORBA/ORB/communication/ourUserException:1.0' |
262 |
* |
* |
263 |
* @param IDL the idl name. |
* @param IDL the idl name. |
264 |
*/ |
*/ |
265 |
public static String toHelperName(String IDL) |
public static String toHelperName(String IDL) |
278 |
|
|
279 |
/** |
/** |
280 |
* Writes the system exception data to CDR output stream. |
* Writes the system exception data to CDR output stream. |
281 |
* |
* |
282 |
* @param output a stream to write data to. |
* @param output a stream to write data to. |
283 |
* @param ex an exception to write. |
* @param ex an exception to write. |
284 |
*/ |
*/ |
285 |
public static void writeSystemException(OutputStream output, |
public static void writeSystemException(OutputStream output, |
286 |
SystemException ex |
SystemException ex) |
|
) |
|
287 |
{ |
{ |
288 |
String exIDL = toIDL(ex.getClass().getName()); |
String exIDL = getRepositoryId(ex.getClass()); |
289 |
output.write_string(exIDL); |
output.write_string(exIDL); |
290 |
output.write_ulong(ex.minor); |
output.write_ulong(ex.minor); |
291 |
CompletionStatusHelper.write(output, ex.completed); |
CompletionStatusHelper.write(output, ex.completed); |
293 |
|
|
294 |
/** |
/** |
295 |
* Converts the given IDL name to class name. |
* Converts the given IDL name to class name. |
296 |
* |
* |
297 |
* @param IDL the idl name. |
* @param IDL the idl name. |
298 |
* |
* |
299 |
*/ |
*/ |
300 |
protected static String toClassName(String prefix, String IDL) |
protected static String toClassName(String prefix, String IDL) |
301 |
{ |
{ |
315 |
* Converts the given IDL name to class name and tries to load the matching |
* Converts the given IDL name to class name and tries to load the matching |
316 |
* class. The OMG prefix (omg.org) is replaced by the java prefix org.omg. No |
* class. The OMG prefix (omg.org) is replaced by the java prefix org.omg. No |
317 |
* other prefixes are added. |
* other prefixes are added. |
318 |
* |
* |
319 |
* @param IDL the idl name. |
* @param IDL the idl name. |
320 |
* |
* |
|
* TODO Cache the returned classes, avoiding these string manipulations each |
|
|
* time the conversion is required. |
|
|
* |
|
321 |
* @return the matching class or null if no such is available. |
* @return the matching class or null if no such is available. |
322 |
*/ |
*/ |
323 |
public static Class Idl2class(String IDL) |
public static Class Idl2class(String IDL) |
324 |
{ |
{ |
325 |
String s = IDL; |
synchronized (m_classes) |
|
int a = s.indexOf(':') + 1; |
|
|
int b = s.lastIndexOf(':'); |
|
|
|
|
|
s = IDL.substring(a, b); |
|
|
|
|
|
if (s.startsWith(OMG_PREFIX)) |
|
|
s = JAVA_PREFIX + s.substring(OMG_PREFIX.length()); |
|
|
|
|
|
String cn = s.replace('/', '.'); |
|
|
|
|
|
try |
|
326 |
{ |
{ |
327 |
return Class.forName(cn); |
Class c = (Class) m_classes.get(IDL); |
328 |
} |
|
329 |
catch (ClassNotFoundException ex) |
if (c != null) |
330 |
{ |
return c; |
331 |
return null; |
else |
332 |
|
{ |
333 |
|
String s = IDL; |
334 |
|
int a = s.indexOf(':') + 1; |
335 |
|
int b = s.lastIndexOf(':'); |
336 |
|
|
337 |
|
s = IDL.substring(a, b); |
338 |
|
|
339 |
|
if (s.startsWith(OMG_PREFIX)) |
340 |
|
s = JAVA_PREFIX + s.substring(OMG_PREFIX.length()); |
341 |
|
|
342 |
|
String cn = s.replace('/', '.'); |
343 |
|
|
344 |
|
try |
345 |
|
{ |
346 |
|
c = Class.forName(cn); |
347 |
|
m_classes.put(IDL, c); |
348 |
|
return c; |
349 |
|
} |
350 |
|
catch (ClassNotFoundException ex) |
351 |
|
{ |
352 |
|
return null; |
353 |
|
} |
354 |
|
} |
355 |
} |
} |
356 |
} |
} |
357 |
|
|
360 |
* and create an object instance with parameterless constructor. The OMG |
* and create an object instance with parameterless constructor. The OMG |
361 |
* prefix (omg.org) is replaced by the java prefix org.omg. No other prefixes |
* prefix (omg.org) is replaced by the java prefix org.omg. No other prefixes |
362 |
* are added. |
* are added. |
363 |
* |
* |
364 |
* @param IDL the idl name. |
* @param IDL the idl name. |
365 |
* |
* |
366 |
* @return instantiated object instance or null if such attempt was not |
* @return instantiated object instance or null if such attempt was not |
367 |
* successful. |
* successful. |
368 |
*/ |
*/ |
384 |
} |
} |
385 |
|
|
386 |
/** |
/** |
387 |
* Convert the class name to IDL name. |
* Convert the class name to IDL or RMI name (repository id). If the class |
388 |
* |
* inherits from IDLEntity, ValueBase or SystemException, returns repository |
389 |
* @param cn the class name. |
* Id in the IDL:(..) form. If it does not, returns repository Id in the |
390 |
* |
* RMI:(..) form. |
391 |
* @return the idl name. |
* |
392 |
*/ |
* @param cx the class for that the name must be computed. |
393 |
public static String toIDL(String cn) |
* |
394 |
{ |
* @return the idl or rmi name. |
395 |
if (cn.startsWith(JAVA_PREFIX)) |
*/ |
396 |
cn = OMG_PREFIX + cn.substring(JAVA_PREFIX.length()).replace('.', '/'); |
public static synchronized String getRepositoryId(Class cx) |
397 |
else if (cn.startsWith(CLASSPATH_PREFIX)) |
{ |
398 |
cn = |
String name = (String) m_names.get(cx); |
399 |
OMG_PREFIX + |
if (name != null) |
400 |
cn.substring(CLASSPATH_PREFIX.length()).replace('.', '/'); |
return name; |
401 |
|
|
402 |
|
String cn = cx.getName(); |
403 |
|
if (!(IDLEntity.class.isAssignableFrom(cx) |
404 |
|
|| ValueBase.class.isAssignableFrom(cx) || SystemException.class.isAssignableFrom(cx))) |
405 |
|
{ |
406 |
|
// Not an IDL entity. |
407 |
|
name = Util.createValueHandler().getRMIRepositoryID(cx); |
408 |
|
} |
409 |
|
else |
410 |
|
{ |
411 |
|
if (cn.startsWith(JAVA_PREFIX)) |
412 |
|
cn = OMG_PREFIX |
413 |
|
+ cn.substring(JAVA_PREFIX.length()).replace('.', '/'); |
414 |
|
else if (cn.startsWith(CLASSPATH_PREFIX)) |
415 |
|
cn = OMG_PREFIX |
416 |
|
+ cn.substring(CLASSPATH_PREFIX.length()).replace('.', '/'); |
417 |
|
|
418 |
return "IDL:" + cn + ":1.0"; |
name = "IDL:" + cn + ":1.0"; |
419 |
|
} |
420 |
|
m_names.put(cx, name); |
421 |
|
return name; |
422 |
} |
} |
423 |
|
|
424 |
/** |
/** |
425 |
* Insert the passed parameter into the given Any, assuming that the helper |
* Insert the passed parameter into the given Any, assuming that the helper |
426 |
* class is available. The helper class must have the "Helper" suffix and be |
* class is available. The helper class must have the "Helper" suffix and be |
427 |
* in the same package as the class of the object being inserted. |
* in the same package as the class of the object being inserted. |
428 |
* |
* |
429 |
* @param into the target to insert. |
* @param into the target to insert. |
430 |
* |
* |
431 |
* @param object the object to insert. It can be any object as far as the |
* @param object the object to insert. It can be any object as far as the |
432 |
* corresponding helper is provided. |
* corresponding helper is provided. |
433 |
* |
* |
434 |
* @return true on success, false otherwise. |
* @return true on success, false otherwise. |
435 |
*/ |
*/ |
436 |
public static boolean insertWithHelper(Any into, Object object) |
public static boolean insertWithHelper(Any into, Object object) |
440 |
String helperClassName = object.getClass().getName() + "Helper"; |
String helperClassName = object.getClass().getName() + "Helper"; |
441 |
Class helperClass = Class.forName(helperClassName); |
Class helperClass = Class.forName(helperClassName); |
442 |
|
|
443 |
Method insert = |
Method insert = helperClass.getMethod("insert", new Class[] { |
444 |
helperClass.getMethod("insert", |
Any.class, object.getClass() }); |
|
new Class[] { Any.class, object.getClass() } |
|
|
); |
|
445 |
|
|
446 |
insert.invoke(null, new Object[] { into, object }); |
insert.invoke(null, new Object[] { into, object }); |
447 |
|
|
463 |
{ |
{ |
464 |
cdrBufOutput output = new cdrBufOutput(); |
cdrBufOutput output = new cdrBufOutput(); |
465 |
|
|
466 |
String m_exception_id = toIDL(exception.getClass().getName()); |
String m_exception_id = getRepositoryId(exception.getClass()); |
467 |
output.write_string(m_exception_id); |
output.write_string(m_exception_id); |
468 |
output.write_ulong(exception.minor); |
output.write_ulong(exception.minor); |
469 |
CompletionStatusHelper.write(output, exception.completed); |
CompletionStatusHelper.write(output, exception.completed); |
520 |
if (!ok) |
if (!ok) |
521 |
throw new InternalError("Exception wrapping broken"); |
throw new InternalError("Exception wrapping broken"); |
522 |
} |
} |
523 |
|
|
524 |
|
/** |
525 |
|
* Find helper for the class with the given name. |
526 |
|
*/ |
527 |
|
public static Class findHelper(String idl) |
528 |
|
{ |
529 |
|
synchronized (m_helpers) |
530 |
|
{ |
531 |
|
Class c = (Class) m_helpers.get(idl); |
532 |
|
if (c != null) |
533 |
|
return c; |
534 |
|
try |
535 |
|
{ |
536 |
|
String helper = toHelperName(idl); |
537 |
|
c = Class.forName(helper); |
538 |
|
|
539 |
|
m_helpers.put(idl, c); |
540 |
|
return c; |
541 |
|
} |
542 |
|
catch (Exception ex) |
543 |
|
{ |
544 |
|
return null; |
545 |
|
} |
546 |
|
} |
547 |
|
|
548 |
|
} |
549 |
} |
} |