ORBUtility.java revision 785:75f2ddcbe5d6
1/*
2 * Copyright (c) 2000, 2013, 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 */
25
26package com.sun.corba.se.impl.orbutil;
27
28import java.lang.Character;
29import java.lang.reflect.Field;
30import java.lang.reflect.Method;
31import java.rmi.NoSuchObjectException;
32import java.security.AccessController;
33import java.security.PermissionCollection;
34import java.security.Policy;
35import java.security.PrivilegedAction;
36import java.security.ProtectionDomain;
37import java.security.PrivilegedActionException;
38import java.security.PrivilegedExceptionAction;
39import java.util.HashMap;
40import java.util.HashSet;
41import java.util.Hashtable;
42import java.util.Iterator;
43import java.util.Enumeration;
44import java.util.StringTokenizer;
45import java.util.NoSuchElementException;
46
47import javax.rmi.CORBA.ValueHandler;
48import javax.rmi.CORBA.ValueHandlerMultiFormat;
49import javax.rmi.CORBA.Util;
50
51import org.omg.CORBA.StructMember ;
52import org.omg.CORBA.TypeCode ;
53import org.omg.CORBA.Any ;
54import org.omg.CORBA.TCKind ;
55import org.omg.CORBA.SystemException ;
56import org.omg.CORBA.CompletionStatus ;
57import org.omg.CORBA.DATA_CONVERSION ;
58import org.omg.CORBA.BAD_PARAM ;
59import org.omg.CORBA.BAD_OPERATION ;
60import org.omg.CORBA.INTERNAL ;
61import org.omg.CORBA.TypeCodePackage.BadKind ;
62import org.omg.CORBA.portable.OutputStream ;
63import org.omg.CORBA.portable.InputStream ;
64
65import com.sun.corba.se.pept.transport.ContactInfoList ;
66
67import com.sun.corba.se.spi.ior.IOR ;
68import com.sun.corba.se.spi.presentation.rmi.StubAdapter ;
69import com.sun.corba.se.spi.orb.ORB ;
70import com.sun.corba.se.spi.orb.ORBVersion ;
71import com.sun.corba.se.spi.orb.ORBVersionFactory ;
72import com.sun.corba.se.spi.protocol.CorbaClientDelegate ;
73import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
74import com.sun.corba.se.spi.transport.CorbaContactInfoList ;
75import com.sun.corba.se.spi.logging.CORBALogDomains ;
76import com.sun.corba.se.spi.ior.iiop.IIOPProfile;
77import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate;
78
79import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
80import com.sun.corba.se.impl.corba.CORBAObjectImpl ;
81import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
82import com.sun.corba.se.impl.logging.OMGSystemException ;
83import com.sun.corba.se.impl.ior.iiop.JavaSerializationComponent;
84
85import sun.corba.SharedSecrets;
86
87/**
88 *  Handy class full of static functions that don't belong in util.Utility for pure ORB reasons.
89 */
90public final class ORBUtility {
91    private ORBUtility() {}
92
93    private static ORBUtilSystemException wrapper = ORBUtilSystemException.get(
94        CORBALogDomains.UTIL ) ;
95    private static OMGSystemException omgWrapper = OMGSystemException.get(
96        CORBALogDomains.UTIL ) ;
97
98    private static StructMember[] members = null;
99
100    private static StructMember[] systemExceptionMembers (ORB orb) {
101        if (members == null) {
102            members = new StructMember[3];
103            members[0] = new StructMember("id", orb.create_string_tc(0), null);
104            members[1] = new StructMember("minor", orb.get_primitive_tc(TCKind.tk_long), null);
105            members[2] = new StructMember("completed", orb.get_primitive_tc(TCKind.tk_long), null);
106        }
107        return members;
108    }
109
110    private static TypeCode getSystemExceptionTypeCode(ORB orb, String repID, String name) {
111        synchronized (TypeCode.class) {
112            return orb.create_exception_tc(repID, name, systemExceptionMembers(orb));
113        }
114    }
115
116    private static boolean isSystemExceptionTypeCode(TypeCode type, ORB orb) {
117        StructMember[] systemExceptionMembers = systemExceptionMembers(orb);
118        try {
119            return (type.kind().value() == TCKind._tk_except &&
120                    type.member_count() == 3 &&
121                    type.member_type(0).equal(systemExceptionMembers[0].type) &&
122                    type.member_type(1).equal(systemExceptionMembers[1].type) &&
123                    type.member_type(2).equal(systemExceptionMembers[2].type));
124        } catch (BadKind ex) {
125            return false;
126        } catch (org.omg.CORBA.TypeCodePackage.Bounds ex) {
127            return false;
128        }
129    }
130
131    /**
132     * Static method for writing a CORBA standard exception to an Any.
133     * @param any The Any to write the SystemException into.
134     */
135    public static void insertSystemException(SystemException ex, Any any) {
136        OutputStream out = any.create_output_stream();
137        ORB orb = (ORB)(out.orb());
138        String name = ex.getClass().getName();
139        String repID = ORBUtility.repositoryIdOf(name);
140        out.write_string(repID);
141        out.write_long(ex.minor);
142        out.write_long(ex.completed.value());
143        any.read_value(out.create_input_stream(),
144            getSystemExceptionTypeCode(orb, repID, name));
145    }
146
147    public static SystemException extractSystemException(Any any) {
148        InputStream in = any.create_input_stream();
149        ORB orb = (ORB)(in.orb());
150        if ( ! isSystemExceptionTypeCode(any.type(), orb)) {
151            throw wrapper.unknownDsiSysex(CompletionStatus.COMPLETED_MAYBE);
152        }
153        return ORBUtility.readSystemException(in);
154    }
155
156    /**
157     * Return default ValueHandler
158     */
159    public static ValueHandler createValueHandler() {
160        ValueHandler vh;
161        try {
162            vh = AccessController.doPrivileged(new PrivilegedExceptionAction<ValueHandler>() {
163                public ValueHandler run() throws Exception {
164        return Util.createValueHandler();
165    }
166            });
167        } catch (PrivilegedActionException e) {
168            throw new InternalError(e.getCause());
169        }
170        return vh;
171    }
172
173    /**
174     * Returns true if it was accurately determined that the remote ORB is
175     * a foreign (non-JavaSoft) ORB.  Note:  If passed the ORBSingleton, this
176     * will return false.
177     */
178    public static boolean isForeignORB(ORB orb)
179    {
180        if (orb == null)
181            return false;
182
183        try {
184            return orb.getORBVersion().equals(ORBVersionFactory.getFOREIGN());
185        } catch (SecurityException se) {
186            return false;
187        }
188    }
189
190    /** Unmarshal a byte array to an integer.
191        Assume the bytes are in BIGENDIAN order.
192        i.e. array[offset] is the most-significant-byte
193        and  array[offset+3] is the least-significant-byte.
194        @param array The array of bytes.
195        @param offset The offset from which to start unmarshalling.
196    */
197    public static int bytesToInt(byte[] array, int offset)
198    {
199        int b1, b2, b3, b4;
200
201        b1 = (array[offset++] << 24) & 0xFF000000;
202        b2 = (array[offset++] << 16) & 0x00FF0000;
203        b3 = (array[offset++] << 8)  & 0x0000FF00;
204        b4 = (array[offset++] << 0)  & 0x000000FF;
205
206        return (b1 | b2 | b3 | b4);
207    }
208
209    /** Marshal an integer to a byte array.
210        The bytes are in BIGENDIAN order.
211        i.e. array[offset] is the most-significant-byte
212        and  array[offset+3] is the least-significant-byte.
213        @param array The array of bytes.
214        @param offset The offset from which to start marshalling.
215    */
216    public static void intToBytes(int value, byte[] array, int offset)
217    {
218        array[offset++] = (byte)((value >>> 24) & 0xFF);
219        array[offset++] = (byte)((value >>> 16) & 0xFF);
220        array[offset++] = (byte)((value >>> 8) & 0xFF);
221        array[offset++] = (byte)((value >>> 0) & 0xFF);
222    }
223
224    /** Converts an Ascii Character into Hexadecimal digit
225     */
226    public static int hexOf( char x )
227    {
228        int val;
229
230        val = x - '0';
231        if (val >=0 && val <= 9)
232            return val;
233
234        val = (x - 'a') + 10;
235        if (val >= 10 && val <= 15)
236            return val;
237
238        val = (x - 'A') + 10;
239        if (val >= 10 && val <= 15)
240            return val;
241
242        throw wrapper.badHexDigit() ;
243    }
244
245    // method moved from util.Utility
246
247    /**
248     * Static method for writing a CORBA standard exception to a stream.
249     * @param strm The OutputStream to use for marshaling.
250     */
251    public static void writeSystemException(SystemException ex, OutputStream strm)
252    {
253        String s;
254
255        s = repositoryIdOf(ex.getClass().getName());
256        strm.write_string(s);
257        strm.write_long(ex.minor);
258        strm.write_long(ex.completed.value());
259    }
260
261    /**
262     * Static method for reading a CORBA standard exception from a stream.
263     * @param strm The InputStream to use for unmarshaling.
264     */
265    public static SystemException readSystemException(InputStream strm)
266    {
267        try {
268            String name = classNameOf(strm.read_string());
269            SystemException ex = (SystemException)SharedSecrets.
270                getJavaCorbaAccess().loadClass(name).newInstance();
271            ex.minor = strm.read_long();
272            ex.completed = CompletionStatus.from_int(strm.read_long());
273            return ex;
274        } catch ( Exception ex ) {
275            throw wrapper.unknownSysex( CompletionStatus.COMPLETED_MAYBE, ex );
276        }
277    }
278
279    /**
280     * Get the class name corresponding to a particular repository Id.
281     * This is used by the system to unmarshal (instantiate) the
282     * appropriate exception class for an marshaled as the value of
283     * its repository Id.
284     * @param repositoryId The repository Id for which we want a class name.
285     */
286    public static String classNameOf(String repositoryId)
287    {
288        String className=null;
289
290        className = (String) exceptionClassNames.get(repositoryId);
291        if (className == null)
292            className = "org.omg.CORBA.UNKNOWN";
293
294        return className;
295    }
296
297    /**
298     * Return true if this repositoryId is a SystemException.
299     * @param repositoryId The repository Id to check.
300     */
301    public static boolean isSystemException(String repositoryId)
302    {
303        String className=null;
304
305        className = (String) exceptionClassNames.get(repositoryId);
306        if (className == null)
307            return false;
308        else
309            return true;
310    }
311
312    /**
313     * @return the Java serialization encoding version.
314     */
315    public static byte getEncodingVersion(ORB orb, IOR ior) {
316
317        // Is Java serialization enabled?
318        // Check the JavaSerializationComponent (tagged component)
319        // in the IIOPProfile. If present, the peer ORB's GIOP is capable
320        // of using Java serialization instead of CDR serialization.
321        // In such a case, use Java serialization, iff the java serialization
322        // versions match.
323
324        if (orb.getORBData().isJavaSerializationEnabled()) {
325            IIOPProfile prof = ior.getProfile();
326            IIOPProfileTemplate profTemp =
327                (IIOPProfileTemplate) prof.getTaggedProfileTemplate();
328            java.util.Iterator iter = profTemp.iteratorById(
329                                  ORBConstants.TAG_JAVA_SERIALIZATION_ID);
330            if (iter.hasNext()) {
331                JavaSerializationComponent jc =
332                    (JavaSerializationComponent) iter.next();
333                byte jcVersion = jc.javaSerializationVersion();
334                if (jcVersion >= Message.JAVA_ENC_VERSION) {
335                    return Message.JAVA_ENC_VERSION;
336                } else if (jcVersion > Message.CDR_ENC_VERSION) {
337                    return jc.javaSerializationVersion();
338                } else {
339                    // throw error?
340                    // Since encodingVersion is <= 0 (CDR_ENC_VERSION).
341                }
342            }
343        }
344        return Message.CDR_ENC_VERSION; // default
345    }
346
347    /**
348     * Get the repository id corresponding to a particular class.
349     * This is used by the system to write the
350     * appropriate repository id for a system exception.
351     * @param name The class name of the system exception.
352     */
353    public static String repositoryIdOf(String name)
354    {
355        String id;
356
357        id = (String) exceptionRepositoryIds.get(name);
358        if (id == null)
359            id = "IDL:omg.org/CORBA/UNKNOWN:1.0";
360
361        return id;
362    }
363
364    private static final Hashtable exceptionClassNames = new Hashtable();
365    private static final Hashtable exceptionRepositoryIds = new Hashtable();
366
367    static {
368
369        //
370        // construct repositoryId -> className hashtable
371        //
372        exceptionClassNames.put("IDL:omg.org/CORBA/BAD_CONTEXT:1.0",
373                                "org.omg.CORBA.BAD_CONTEXT");
374        exceptionClassNames.put("IDL:omg.org/CORBA/BAD_INV_ORDER:1.0",
375                                "org.omg.CORBA.BAD_INV_ORDER");
376        exceptionClassNames.put("IDL:omg.org/CORBA/BAD_OPERATION:1.0",
377                                "org.omg.CORBA.BAD_OPERATION");
378        exceptionClassNames.put("IDL:omg.org/CORBA/BAD_PARAM:1.0",
379                                "org.omg.CORBA.BAD_PARAM");
380        exceptionClassNames.put("IDL:omg.org/CORBA/BAD_TYPECODE:1.0",
381                                "org.omg.CORBA.BAD_TYPECODE");
382        exceptionClassNames.put("IDL:omg.org/CORBA/COMM_FAILURE:1.0",
383                                "org.omg.CORBA.COMM_FAILURE");
384        exceptionClassNames.put("IDL:omg.org/CORBA/DATA_CONVERSION:1.0",
385                                "org.omg.CORBA.DATA_CONVERSION");
386        exceptionClassNames.put("IDL:omg.org/CORBA/IMP_LIMIT:1.0",
387                                "org.omg.CORBA.IMP_LIMIT");
388        exceptionClassNames.put("IDL:omg.org/CORBA/INTF_REPOS:1.0",
389                                "org.omg.CORBA.INTF_REPOS");
390        exceptionClassNames.put("IDL:omg.org/CORBA/INTERNAL:1.0",
391                                "org.omg.CORBA.INTERNAL");
392        exceptionClassNames.put("IDL:omg.org/CORBA/INV_FLAG:1.0",
393                                "org.omg.CORBA.INV_FLAG");
394        exceptionClassNames.put("IDL:omg.org/CORBA/INV_IDENT:1.0",
395                                "org.omg.CORBA.INV_IDENT");
396        exceptionClassNames.put("IDL:omg.org/CORBA/INV_OBJREF:1.0",
397                                "org.omg.CORBA.INV_OBJREF");
398        exceptionClassNames.put("IDL:omg.org/CORBA/MARSHAL:1.0",
399                                "org.omg.CORBA.MARSHAL");
400        exceptionClassNames.put("IDL:omg.org/CORBA/NO_MEMORY:1.0",
401                                "org.omg.CORBA.NO_MEMORY");
402        exceptionClassNames.put("IDL:omg.org/CORBA/FREE_MEM:1.0",
403                                "org.omg.CORBA.FREE_MEM");
404        exceptionClassNames.put("IDL:omg.org/CORBA/NO_IMPLEMENT:1.0",
405                                "org.omg.CORBA.NO_IMPLEMENT");
406        exceptionClassNames.put("IDL:omg.org/CORBA/NO_PERMISSION:1.0",
407                                "org.omg.CORBA.NO_PERMISSION");
408        exceptionClassNames.put("IDL:omg.org/CORBA/NO_RESOURCES:1.0",
409                                "org.omg.CORBA.NO_RESOURCES");
410        exceptionClassNames.put("IDL:omg.org/CORBA/NO_RESPONSE:1.0",
411                                "org.omg.CORBA.NO_RESPONSE");
412        exceptionClassNames.put("IDL:omg.org/CORBA/OBJ_ADAPTER:1.0",
413                                "org.omg.CORBA.OBJ_ADAPTER");
414        exceptionClassNames.put("IDL:omg.org/CORBA/INITIALIZE:1.0",
415                                "org.omg.CORBA.INITIALIZE");
416        exceptionClassNames.put("IDL:omg.org/CORBA/PERSIST_STORE:1.0",
417                                "org.omg.CORBA.PERSIST_STORE");
418        exceptionClassNames.put("IDL:omg.org/CORBA/TRANSIENT:1.0",
419                                "org.omg.CORBA.TRANSIENT");
420        exceptionClassNames.put("IDL:omg.org/CORBA/UNKNOWN:1.0",
421                                "org.omg.CORBA.UNKNOWN");
422        exceptionClassNames.put("IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0",
423                                "org.omg.CORBA.OBJECT_NOT_EXIST");
424
425        // SystemExceptions from OMG Transactions Service Spec
426        exceptionClassNames.put("IDL:omg.org/CORBA/INVALID_TRANSACTION:1.0",
427                                "org.omg.CORBA.INVALID_TRANSACTION");
428        exceptionClassNames.put("IDL:omg.org/CORBA/TRANSACTION_REQUIRED:1.0",
429                                "org.omg.CORBA.TRANSACTION_REQUIRED");
430        exceptionClassNames.put("IDL:omg.org/CORBA/TRANSACTION_ROLLEDBACK:1.0",
431                                "org.omg.CORBA.TRANSACTION_ROLLEDBACK");
432
433        // from portability RTF 98-07-01.txt
434        exceptionClassNames.put("IDL:omg.org/CORBA/INV_POLICY:1.0",
435                                "org.omg.CORBA.INV_POLICY");
436
437        // from orbrev/00-09-01 (CORBA 2.4 Draft Specification)
438        exceptionClassNames.
439            put("IDL:omg.org/CORBA/TRANSACTION_UNAVAILABLE:1.0",
440                                "org.omg.CORBA.TRANSACTION_UNAVAILABLE");
441        exceptionClassNames.put("IDL:omg.org/CORBA/TRANSACTION_MODE:1.0",
442                                "org.omg.CORBA.TRANSACTION_MODE");
443
444        // Exception types introduced between CORBA 2.4 and 3.0
445        exceptionClassNames.put("IDL:omg.org/CORBA/CODESET_INCOMPATIBLE:1.0",
446                                "org.omg.CORBA.CODESET_INCOMPATIBLE");
447        exceptionClassNames.put("IDL:omg.org/CORBA/REBIND:1.0",
448                                "org.omg.CORBA.REBIND");
449        exceptionClassNames.put("IDL:omg.org/CORBA/TIMEOUT:1.0",
450                                "org.omg.CORBA.TIMEOUT");
451        exceptionClassNames.put("IDL:omg.org/CORBA/BAD_QOS:1.0",
452                                "org.omg.CORBA.BAD_QOS");
453
454        // Exception types introduced in CORBA 3.0
455        exceptionClassNames.put("IDL:omg.org/CORBA/INVALID_ACTIVITY:1.0",
456                                "org.omg.CORBA.INVALID_ACTIVITY");
457        exceptionClassNames.put("IDL:omg.org/CORBA/ACTIVITY_COMPLETED:1.0",
458                                "org.omg.CORBA.ACTIVITY_COMPLETED");
459        exceptionClassNames.put("IDL:omg.org/CORBA/ACTIVITY_REQUIRED:1.0",
460                                "org.omg.CORBA.ACTIVITY_REQUIRED");
461
462        //
463        // construct className -> repositoryId hashtable
464        //
465        Enumeration keys = exceptionClassNames.keys();
466        java.lang.Object s;
467        String rId;
468        String cName;
469
470        try{
471            while (keys.hasMoreElements()) {
472                s = keys.nextElement();
473                rId = (String) s;
474                cName = (String) exceptionClassNames.get(rId);
475                exceptionRepositoryIds.put (cName, rId);
476            }
477        } catch (NoSuchElementException e) { }
478    }
479
480    /** Parse a version string such as "1.1.6" or "jdk1.2fcs" into
481        a version array of integers {1, 1, 6} or {1, 2}.
482        A string of "n." or "n..m" is equivalent to "n.0" or "n.0.m" respectively.
483    */
484    public static int[] parseVersion(String version) {
485        if (version == null)
486            return new int[0];
487        char[] s = version.toCharArray();
488        //find the maximum span of the string "n.n.n..." where n is an integer
489        int start = 0;
490        for (; start < s.length  && (s[start] < '0' || s[start] > '9'); ++start)
491            if (start == s.length)      //no digit found
492                return new int[0];
493        int end = start + 1;
494        int size = 1;
495        for (; end < s.length; ++end)
496            if (s[end] == '.')
497                ++size;
498            else if (s[end] < '0' || s[end] > '9')
499                break;
500        int[] val = new int[size];
501        for (int i = 0; i < size; ++i) {
502            int dot = version.indexOf('.', start);
503            if (dot == -1 || dot > end)
504                dot = end;
505            if (start >= dot)   //cases like "n." or "n..m"
506                val[i] = 0;     //convert equivalent to "n.0" or "n.0.m"
507            else
508                val[i] = Integer.parseInt(version.substring(start, dot));
509            start = dot + 1;
510        }
511        return val;
512    }
513
514    /** Compare two version arrays.
515        Return 1, 0 or -1 if v1 is greater than, equal to, or less than v2.
516    */
517    public static int compareVersion(int[] v1, int[] v2) {
518        if (v1 == null)
519            v1 = new int[0];
520        if (v2 == null)
521            v2 = new int[0];
522        for (int i = 0; i < v1.length; ++i) {
523            if (i >= v2.length || v1[i] > v2[i])        //v1 is longer or greater than v2
524                return 1;
525            if (v1[i] < v2[i])
526                return -1;
527        }
528        return v1.length == v2.length ? 0 : -1;
529    }
530
531    /** Compare two version strings.
532        Return 1, 0 or -1 if v1 is greater than, equal to, or less than v2.
533    */
534    public static synchronized int compareVersion(String v1, String v2) {
535        return compareVersion(parseVersion(v1), parseVersion(v2));
536    }
537
538    private static String compressClassName( String name )
539    {
540        // Note that this must end in . in order to be renamed correctly.
541        String prefix = "com.sun.corba.se." ;
542        if (name.startsWith( prefix ) ) {
543            return "(ORB)." + name.substring( prefix.length() ) ;
544        } else
545            return name ;
546    }
547
548    // Return a compressed representation of the thread name.  This is particularly
549    // useful on the server side, where there are many SelectReaderThreads, and
550    // we need a short unambiguous name for such threads.
551    public static String getThreadName( Thread thr )
552    {
553        if (thr == null)
554            return "null" ;
555
556        // This depends on the formatting in SelectReaderThread and CorbaConnectionImpl.
557        // Pattern for SelectReaderThreads:
558        // SelectReaderThread CorbaConnectionImpl[ <host> <post> <state>]
559        // Any other pattern in the Thread's name is just returned.
560        String name = thr.getName() ;
561        StringTokenizer st = new StringTokenizer( name ) ;
562        int numTokens = st.countTokens() ;
563        if (numTokens != 5)
564            return name ;
565
566        String[] tokens = new String[numTokens] ;
567        for (int ctr=0; ctr<numTokens; ctr++ )
568            tokens[ctr] = st.nextToken() ;
569
570        if( !tokens[0].equals("SelectReaderThread"))
571            return name ;
572
573        return "SelectReaderThread[" + tokens[2] + ":" + tokens[3] + "]" ;
574    }
575
576    private static String formatStackTraceElement( StackTraceElement ste )
577    {
578        return compressClassName( ste.getClassName() ) + "." + ste.getMethodName() +
579            (ste.isNativeMethod() ? "(Native Method)" :
580             (ste.getFileName() != null && ste.getLineNumber() >= 0 ?
581              "(" + ste.getFileName() + ":" + ste.getLineNumber() + ")" :
582              (ste.getFileName() != null ?  "("+ste.getFileName()+")" : "(Unknown Source)")));
583    }
584
585    private static void printStackTrace( StackTraceElement[] trace )
586    {
587        System.out.println( "    Stack Trace:" ) ;
588        // print the stack trace, ommitting the zeroth element, which is
589        // always this method.
590        for ( int ctr = 1; ctr < trace.length; ctr++ ) {
591            System.out.print( "        >" ) ;
592            System.out.println( formatStackTraceElement( trace[ctr] ) ) ;
593        }
594    }
595
596    //
597    // Implements all dprint calls in this package.
598    //
599    public static synchronized void dprint(java.lang.Object obj, String msg) {
600        System.out.println(
601            compressClassName( obj.getClass().getName() ) + "("  +
602            getThreadName( Thread.currentThread() ) + "): " + msg);
603    }
604
605    public static synchronized void dprint(String className, String msg) {
606        System.out.println(
607            compressClassName( className ) + "("  +
608            getThreadName( Thread.currentThread() ) + "): " + msg);
609    }
610
611    public synchronized void dprint(String msg) {
612        ORBUtility.dprint(this, msg);
613    }
614
615    public static synchronized void dprintTrace(Object obj, String msg) {
616        ORBUtility.dprint(obj, msg);
617
618        Throwable thr = new Throwable() ;
619        printStackTrace( thr.getStackTrace() ) ;
620    }
621
622    public static synchronized void dprint(java.lang.Object caller,
623        String msg, Throwable t)
624    {
625        System.out.println(
626            compressClassName( caller.getClass().getName() ) +
627            '(' + Thread.currentThread() + "): " + msg);
628
629        if (t != null)
630            printStackTrace( t.getStackTrace() ) ;
631    }
632
633    public static String[] concatenateStringArrays( String[] arr1, String[] arr2 )
634    {
635        String[] result = new String[
636            arr1.length + arr2.length ] ;
637
638        for (int ctr = 0; ctr<arr1.length; ctr++)
639            result[ctr] = arr1[ctr] ;
640
641        for (int ctr = 0; ctr<arr2.length; ctr++)
642            result[ctr + arr1.length] = arr2[ctr] ;
643
644        return result ;
645    }
646
647    /**
648     * Throws the CORBA equivalent of a java.io.NotSerializableException
649     *
650     * Duplicated from util/Utility for Pure ORB reasons.  There are two
651     * reasons for this:
652     *
653     * 1) We can't introduce dependencies on the util version from outside
654     * of the io/util packages since it will not exist in the pure ORB
655     * build running on JDK 1.3.x.
656     *
657     * 2) We need to pick up the correct minor code from OMGSystemException.
658     */
659    public static void throwNotSerializableForCorba(String className) {
660        throw omgWrapper.notSerializable( CompletionStatus.COMPLETED_MAYBE,
661            className ) ;
662    }
663
664    /**
665     * Returns the maximum stream format version supported by our
666     * ValueHandler.
667     */
668    public static byte getMaxStreamFormatVersion() {
669        ValueHandler vh;
670        try {
671            vh = AccessController.doPrivileged(new PrivilegedExceptionAction<ValueHandler>() {
672                public ValueHandler run() throws Exception {
673                    return Util.createValueHandler();
674                }
675            });
676        } catch (PrivilegedActionException e) {
677            throw new InternalError(e.getCause());
678        }
679
680        if (!(vh instanceof javax.rmi.CORBA.ValueHandlerMultiFormat))
681            return ORBConstants.STREAM_FORMAT_VERSION_1;
682        else
683            return ((ValueHandlerMultiFormat)vh).getMaximumStreamFormatVersion();
684    }
685
686    public static CorbaClientDelegate makeClientDelegate( IOR ior )
687    {
688        ORB orb = ior.getORB() ;
689        CorbaContactInfoList ccil = orb.getCorbaContactInfoListFactory().create( ior ) ;
690        CorbaClientDelegate del = orb.getClientDelegateFactory().create(ccil);
691        return del ;
692    }
693
694    /** This method is used to create untyped object references.
695    */
696    public static org.omg.CORBA.Object makeObjectReference( IOR ior )
697    {
698        CorbaClientDelegate del = makeClientDelegate( ior ) ;
699        org.omg.CORBA.Object objectImpl = new CORBAObjectImpl() ;
700        StubAdapter.setDelegate( objectImpl, del ) ;
701        return objectImpl ;
702    }
703
704    /** This method obtains an IOR from a CORBA object reference.
705    * It will return null if obj is a local object, a null object,
706    * or an object implemented by a different ORB.  It will
707    * throw BAD_OPERATION if obj is an unconnected RMI-IIOP object.
708    * @return IOR the IOR that represents this objref.  This will
709    * never be null.
710    * @exception BAD_OPERATION (from oi._get_delegate) if obj is a
711    * normal objref, but does not have a delegate set.
712    * @exception BAD_PARAM if obj is a local object, or else was
713    * created by a foreign ORB.
714    */
715    public static IOR getIOR( org.omg.CORBA.Object obj )
716    {
717        if (obj == null)
718            throw wrapper.nullObjectReference() ;
719
720        IOR ior = null ;
721        if (StubAdapter.isStub(obj)) {
722            org.omg.CORBA.portable.Delegate del = StubAdapter.getDelegate(
723                obj ) ;
724
725            if (del instanceof CorbaClientDelegate) {
726                CorbaClientDelegate cdel = (CorbaClientDelegate)del ;
727                ContactInfoList cil = cdel.getContactInfoList() ;
728
729                if (cil instanceof CorbaContactInfoList) {
730                    CorbaContactInfoList ccil = (CorbaContactInfoList)cil ;
731                    ior = ccil.getTargetIOR() ;
732                    if (ior == null)
733                        throw wrapper.nullIor() ;
734
735                    return ior ;
736                } else {
737                    // This is our code, but the ContactInfoList is not a
738                    // CorbaContactInfoList.  This should not happen, because
739                    // we are in the CORBA application of the DCSA framework.
740                    // This is a coding error, and thus an INTERNAL exception
741                    // should be thrown.
742                    // XXX needs minor code
743                    throw new INTERNAL() ;
744                }
745            }
746
747            // obj is implemented by a foreign ORB, because the Delegate is not a
748            // ClientDelegate.
749            // XXX this case could be handled by marshalling and
750            // unmarshalling.  However, object_to_string cannot be used
751            // here, as it is implemented with getIOR.  Note that this
752            // will require access to an ORB, so that we can create streams
753            // as needed.  The ORB is available simply as io._orb().
754            throw wrapper.objrefFromForeignOrb() ;
755        } else
756            throw wrapper.localObjectNotAllowed() ;
757    }
758
759    /** Obtains an IOR for the object reference obj, first connecting it to
760    * the ORB if necessary.
761    * @return IOR the IOR that represents this objref.  This will
762    * never be null.
763    * @exception BAD_OPERATION if the object could not be connected,
764    * if a connection attempt was needed.
765    * @exception BAD_PARAM if obj is a local object, or else was
766    * created by a foreign ORB.
767    */
768    public static IOR connectAndGetIOR( ORB orb, org.omg.CORBA.Object obj )
769    {
770        IOR result ;
771        try {
772            result = getIOR( obj ) ;
773        } catch (BAD_OPERATION bop) {
774            if (StubAdapter.isStub(obj)) {
775                try {
776                    StubAdapter.connect( obj, orb ) ;
777                } catch (java.rmi.RemoteException exc) {
778                    throw wrapper.connectingServant( exc ) ;
779                }
780            } else {
781                orb.connect( obj ) ;
782            }
783
784            result = getIOR( obj ) ;
785        }
786
787        return result ;
788    }
789
790    public static String operationNameAndRequestId(CorbaMessageMediator m)
791    {
792        return "op/" + m.getOperationName() + " id/" + m.getRequestId();
793    }
794
795    public static boolean isPrintable(char c)
796    {
797        if (Character.isJavaIdentifierStart(c)) {
798            // Letters and $ _
799            return true;
800        }
801        if (Character.isDigit(c)) {
802            return true;
803        }
804        switch (Character.getType(c)) {
805        case Character.MODIFIER_SYMBOL : return true; // ` ^
806        case Character.DASH_PUNCTUATION : return true; // -
807        case Character.MATH_SYMBOL : return true; // = ~ + | < >
808        case Character.OTHER_PUNCTUATION : return true; // !@#%&*;':",./?
809        case Character.START_PUNCTUATION : return true; // ( [ {
810        case Character.END_PUNCTUATION : return true; // ) ] }
811        }
812        return false;
813    }
814
815    public static String getClassSecurityInfo(final Class cl)
816    {
817        // Returns a String which looks similar to:
818        // PermissionCollection java.security.Permissions@1053693 ...
819        // (java.io.FilePermission <<ALL FILES>> ....)
820        // (java.io.FilePermission /export0/sunwappserv/lib/- ...)
821        // ... other permissions ...
822        // Domain ProtectionDomain  (file:/export0/sunwappserv/lib-)
823        // java.security.Permissions@141fedb (
824        // (java.io.FilePermission <<ALL FILES>> ...)
825        // (java.io.FilePermission /var/tmp//- ...)
826
827        String result =
828            (String)AccessController.doPrivileged(new PrivilegedAction() {
829                public java.lang.Object run() {
830                    StringBuffer sb = new StringBuffer(500);
831                    ProtectionDomain pd = cl.getProtectionDomain();
832                    Policy policy = Policy.getPolicy();
833                    PermissionCollection pc = policy.getPermissions(pd);
834                    sb.append("\nPermissionCollection ");
835                    sb.append(pc.toString());
836                    // Don't need to add 'Protection Domain' string, it's
837                    // in ProtectionDomain.toString() already.
838                    sb.append(pd.toString());
839                    return sb.toString();
840                }
841            });
842        return result;
843    }
844}
845
846// End of file.
847