Dead
[official-gcc.git] / gomp-20050608-branch / libjava / gnu / CORBA / ObjectCreator.java
blob9f215fc64ee6d824d27908cdde692a179f6d188f
1 /* ObjectCreator.java --
2 Copyright (C) 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package gnu.CORBA;
41 import gnu.CORBA.CDR.UnknownExceptionCtxHandler;
42 import gnu.CORBA.CDR.BufferredCdrInput;
43 import gnu.CORBA.CDR.BufferedCdrOutput;
44 import gnu.CORBA.CDR.AbstractCdrInput;
45 import gnu.CORBA.GIOP.ServiceContext;
46 import gnu.CORBA.typecodes.RecordTypeCode;
47 // GCJ LOCAL - We don't have this yet.
48 // import gnu.classpath.VMStackWalker;
50 import org.omg.CORBA.Any;
51 import org.omg.CORBA.CompletionStatus;
52 import org.omg.CORBA.CompletionStatusHelper;
53 import org.omg.CORBA.MARSHAL;
54 import org.omg.CORBA.SystemException;
55 import org.omg.CORBA.TCKind;
56 import org.omg.CORBA.UNKNOWN;
57 import org.omg.CORBA.UserException;
58 import org.omg.CORBA.portable.IDLEntity;
59 import org.omg.CORBA.portable.InputStream;
60 import org.omg.CORBA.portable.OutputStream;
61 import org.omg.CORBA.portable.ValueBase;
63 import java.lang.reflect.Method;
64 import java.util.Map;
65 import java.util.WeakHashMap;
67 import javax.rmi.CORBA.Util;
69 /**
70 * Creates java objects from the agreed IDL names for the simple case when the
71 * CORBA object is directly mapped into the locally defined java class.
73 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
75 public class ObjectCreator
77 /**
78 * The standard OMG prefix.
80 public static final String OMG_PREFIX = "omg.org/";
82 /**
83 * The standard java prefix.
85 public static final String JAVA_PREFIX = "org.omg.";
87 /**
88 * The prefix for classes that are placed instide the gnu.CORBA namespace.
90 public static final String CLASSPATH_PREFIX = "gnu.CORBA.";
92 /**
93 * Maps classes to they IDL or RMI names. Computing RMI name is an expensive
94 * operations, so frequently used RMI keys are reused. The map must be weak to
95 * ensure that the class can be unloaded, when applicable.
97 public static Map m_names = new WeakHashMap();
99 /**
100 * Maps IDL strings into known classes. The map must be weak to ensure that
101 * the class can be unloaded, when applicable.
103 public static Map m_classes = new WeakHashMap();
106 * Maps IDL types to they helpers.
108 public static Map m_helpers = new WeakHashMap();
111 * Try to instantiate an object with the given IDL name. The object must be
112 * mapped to the local java class. The omg.org domain must be mapped into the
113 * object in either org/omg or gnu/CORBA namespace.
115 * @param IDL name
116 * @return instantiated object instance or null if no such available.
118 public static java.lang.Object createObject(String idl, String suffix)
120 synchronized (m_classes)
122 Class known = (Class) (suffix == null ? m_classes.get(idl)
123 : m_classes.get(idl + 0xff + suffix));
124 Object object;
126 if (known != null)
130 return known.newInstance();
132 catch (Exception ex)
134 RuntimeException rex = new RuntimeException(idl + " suffix "
135 + suffix, ex);
136 throw rex;
139 else
141 if (suffix == null)
142 suffix = "";
145 known = forName(toClassName(JAVA_PREFIX, idl) + suffix);
146 object = known.newInstance();
148 catch (Exception ex)
152 known = forName(toClassName(CLASSPATH_PREFIX, idl)
153 + suffix);
154 object = known.newInstance();
156 catch (Exception exex)
158 return null;
161 m_classes.put(idl + 0xff + suffix, known);
162 return object;
168 * Read the system exception from the given stream.
170 * @param input the CDR stream to read from.
171 * @param contexts the service contexts in request/reply header/
173 * @return the exception that has been stored in the stream (IDL name, minor
174 * code and completion status).
176 public static SystemException readSystemException(InputStream input,
177 ServiceContext[] contexts)
179 SystemException exception;
181 String idl = input.read_string();
182 int minor = input.read_ulong();
183 CompletionStatus completed = CompletionStatusHelper.read(input);
187 exception = (SystemException) createObject(idl, null);
188 exception.minor = minor;
189 exception.completed = completed;
191 catch (Exception ex)
193 UNKNOWN u = new UNKNOWN("Unsupported system exception " + idl, minor,
194 completed);
195 u.initCause(ex);
196 throw u;
201 // If UnknownExceptionInfo is present in the contexts, read it and
202 // set as a cause of this exception.
203 ServiceContext uEx = ServiceContext.find(
204 ServiceContext.UnknownExceptionInfo, contexts);
206 if (uEx != null)
208 BufferredCdrInput in = new BufferredCdrInput(uEx.context_data);
209 in.setOrb(in.orb());
210 if (input instanceof AbstractCdrInput)
212 ((AbstractCdrInput) input).cloneSettings(in);
215 Throwable t = UnknownExceptionCtxHandler.read(in, contexts);
216 exception.initCause(t);
219 catch (Exception ex)
221 // Unsupported context format. Do not terminate as the user program may
222 // not need it.
225 return exception;
229 * Reads the user exception, having the given Id, from the input stream. The
230 * id is expected to be in the form like
231 * 'IDL:test/org/omg/CORBA/ORB/communication/ourUserException:1.0'
233 * @param idl the exception idl name.
234 * @param input the stream to read from.
236 * @return the loaded exception.
237 * @return null if the helper class cannot be found.
239 public static UserException readUserException(String idl, InputStream input)
243 Class helperClass = findHelper(idl);
245 Method read = helperClass.getMethod("read",
246 new Class[] { org.omg.CORBA.portable.InputStream.class });
248 return (UserException) read.invoke(null, new Object[] { input });
250 catch (MARSHAL mex)
252 // This one is ok to throw
253 throw mex;
255 catch (Exception ex)
257 ex.printStackTrace();
258 return null;
263 * Gets the helper class name from the string like
264 * 'IDL:test/org/omg/CORBA/ORB/communication/ourUserException:1.0'
266 * @param IDL the idl name.
268 public static String toHelperName(String IDL)
270 String s = IDL;
271 int a = s.indexOf(':') + 1;
272 int b = s.lastIndexOf(':');
274 s = IDL.substring(a, b);
276 if (s.startsWith(OMG_PREFIX))
277 s = JAVA_PREFIX + s.substring(OMG_PREFIX.length());
279 return s.replace('/', '.') + "Helper";
283 * Writes the system exception data to CDR output stream.
285 * @param output a stream to write data to.
286 * @param ex an exception to write.
288 public static void writeSystemException(OutputStream output,
289 SystemException ex)
291 String exIDL = getRepositoryId(ex.getClass());
292 output.write_string(exIDL);
293 output.write_ulong(ex.minor);
294 CompletionStatusHelper.write(output, ex.completed);
298 * Converts the given IDL name to class name.
300 * @param IDL the idl name.
303 protected static String toClassName(String prefix, String IDL)
305 String s = IDL;
306 int a = s.indexOf(':') + 1;
307 int b = s.lastIndexOf(':');
309 s = IDL.substring(a, b);
311 if (s.startsWith(OMG_PREFIX))
312 s = prefix + s.substring(OMG_PREFIX.length());
314 return s.replace('/', '.');
318 * Converts the given IDL name to class name and tries to load the matching
319 * class. The OMG prefix (omg.org) is replaced by the java prefix org.omg. No
320 * other prefixes are added.
322 * @param IDL the idl name.
324 * @return the matching class or null if no such is available.
326 public static Class Idl2class(String IDL)
328 synchronized (m_classes)
330 Class c = (Class) m_classes.get(IDL);
332 if (c != null)
333 return c;
334 else
336 String s = IDL;
337 int a = s.indexOf(':') + 1;
338 int b = s.lastIndexOf(':');
340 s = IDL.substring(a, b);
342 if (s.startsWith(OMG_PREFIX))
343 s = JAVA_PREFIX + s.substring(OMG_PREFIX.length());
345 String cn = s.replace('/', '.');
349 c = forName(cn);
350 m_classes.put(IDL, c);
351 return c;
353 catch (ClassNotFoundException ex)
355 return null;
362 * Converts the given IDL name to class name, tries to load the matching class
363 * and create an object instance with parameterless constructor. The OMG
364 * prefix (omg.org) is replaced by the java prefix org.omg. No other prefixes
365 * are added.
367 * @param IDL the idl name.
369 * @return instantiated object instance or null if such attempt was not
370 * successful.
372 public static java.lang.Object Idl2Object(String IDL)
374 Class cx = Idl2class(IDL);
378 if (cx != null)
379 return cx.newInstance();
380 else
381 return null;
383 catch (Exception ex)
385 return null;
390 * Convert the class name to IDL or RMI name (repository id). If the class
391 * inherits from IDLEntity, ValueBase or SystemException, returns repository
392 * Id in the IDL:(..) form. If it does not, returns repository Id in the
393 * RMI:(..) form.
395 * @param cx the class for that the name must be computed.
397 * @return the idl or rmi name.
399 public static synchronized String getRepositoryId(Class cx)
401 String name = (String) m_names.get(cx);
402 if (name != null)
403 return name;
405 String cn = cx.getName();
406 if (!(IDLEntity.class.isAssignableFrom(cx)
407 || ValueBase.class.isAssignableFrom(cx) || SystemException.class.isAssignableFrom(cx)))
409 // Not an IDL entity.
410 name = Util.createValueHandler().getRMIRepositoryID(cx);
412 else
414 if (cn.startsWith(JAVA_PREFIX))
415 cn = OMG_PREFIX
416 + cn.substring(JAVA_PREFIX.length()).replace('.', '/');
417 else if (cn.startsWith(CLASSPATH_PREFIX))
418 cn = OMG_PREFIX
419 + cn.substring(CLASSPATH_PREFIX.length()).replace('.', '/');
421 name = "IDL:" + cn + ":1.0";
423 m_names.put(cx, name);
424 return name;
428 * Insert the passed parameter into the given Any, assuming that the helper
429 * class is available. The helper class must have the "Helper" suffix and be
430 * in the same package as the class of the object being inserted.
432 * @param into the target to insert.
434 * @param object the object to insert. It can be any object as far as the
435 * corresponding helper is provided.
437 * @return true on success, false otherwise.
439 public static boolean insertWithHelper(Any into, Object object)
443 String helperClassName = object.getClass().getName() + "Helper";
444 Class helperClass = forName(helperClassName);
446 Method insert = helperClass.getMethod("insert", new Class[] {
447 Any.class, object.getClass() });
449 insert.invoke(null, new Object[] { into, object });
451 return true;
453 catch (Exception exc)
455 // Failed due some reason.
456 return false;
461 * Insert the system exception into the given Any.
463 public static boolean insertSysException(Any into, SystemException exception)
467 BufferedCdrOutput output = new BufferedCdrOutput();
469 String m_exception_id = getRepositoryId(exception.getClass());
470 output.write_string(m_exception_id);
471 output.write_ulong(exception.minor);
472 CompletionStatusHelper.write(output, exception.completed);
474 String name = getDefaultName(m_exception_id);
476 GeneralHolder h = new GeneralHolder(output);
478 into.insert_Streamable(h);
480 RecordTypeCode r = new RecordTypeCode(TCKind.tk_except);
481 r.setId(m_exception_id);
482 r.setName(name);
483 into.type(r);
485 return true;
487 catch (Exception ex)
489 ex.printStackTrace();
490 return false;
495 * Get the type name from the IDL string.
497 public static String getDefaultName(String idl)
499 int f1 = idl.lastIndexOf("/");
500 int p1 = (f1 < 0) ? 0 : f1;
501 int p2 = idl.indexOf(":", p1);
502 if (p2 < 0)
503 p2 = idl.length();
505 String name = idl.substring(f1 + 1, p2);
506 return name;
510 * Insert this exception into the given Any. On failure, insert the UNKNOWN
511 * exception.
513 public static void insertException(Any into, Throwable exception)
515 boolean ok = false;
516 if (exception instanceof SystemException)
517 ok = insertSysException(into, (SystemException) exception);
518 else if (exception instanceof UserException)
519 ok = insertWithHelper(into, exception);
521 if (!ok)
522 ok = insertSysException(into, new UNKNOWN());
523 if (!ok)
524 throw new InternalError("Exception wrapping broken");
528 * Find helper for the class with the given name.
530 public static Class findHelper(String idl)
532 synchronized (m_helpers)
534 Class c = (Class) m_helpers.get(idl);
535 if (c != null)
536 return c;
539 String helper = toHelperName(idl);
540 c = forName(helper);
542 m_helpers.put(idl, c);
543 return c;
545 catch (Exception ex)
547 return null;
553 * Load the class with the given name. This method tries to use the context
554 * class loader first. If this fails, it searches for the suitable class
555 * loader in the caller stack trace. This method is a central point where all
556 * requests to find a class by name are delegated.
558 public static Class forName(String className) throws ClassNotFoundException
562 return Class.forName(className, true,
563 Thread.currentThread().getContextClassLoader());
565 catch (ClassNotFoundException nex)
568 * Returns the first user defined class loader on the call stack, or
569 * null when no non-null class loader was found.
572 // GCJ LOCAL - We don't have VMStackWalker yet.
573 // We only try the SystemClassLoader for now.
574 // Class[] ctx = VMStackWalker.getClassContext();
575 // for (int i = 0; i < ctx.length; i++)
576 // {
577 // // Since we live in a class loaded by the bootstrap
578 // // class loader, getClassLoader is safe to call without
579 // // needing to be wrapped in a privileged action.
580 // ClassLoader cl = ctx[i].getClassLoader();
581 ClassLoader cl = ClassLoader.getSystemClassLoader();
584 if (cl != null)
585 return Class.forName(className, true, cl);
587 catch (ClassNotFoundException nex2)
589 // Try next.
591 // }
594 throw new ClassNotFoundException(className);