KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > iiop > rmi > ContainerAnalysis


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.iiop.rmi;
23
24 import java.lang.reflect.Method JavaDoc;
25 import java.lang.reflect.Field JavaDoc;
26 import java.lang.reflect.Modifier JavaDoc;
27
28 import java.io.ObjectStreamClass JavaDoc;
29 import java.io.Serializable JavaDoc;
30 import java.io.Externalizable JavaDoc;
31 import java.util.ArrayList JavaDoc;
32
33 /**
34  * Common base class of ValueAnalysis and InterfaceAnalysis.
35  *
36  * Routines here are conforming to the "Java(TM) Language to IDL Mapping
37  * Specification", version 1.1 (01-06-07).
38  *
39  * @author <a HREF="mailto:osh@sparre.dk">Ole Husgaard</a>
40  * @version $Revision: 37459 $
41  */

42 public abstract class ContainerAnalysis
43    extends ClassAnalysis
44 {
45    // Constants -----------------------------------------------------
46

47    /** Flags a method as overloaded. */
48    protected final byte M_OVERLOADED = 1;
49
50    /** Flags a method as the accessor of a read-write property. */
51    protected final byte M_READ = 2;
52
53    /** Flags a method as the mutator of a read-write property. */
54    protected final byte M_WRITE = 4;
55
56    /** Flags a method as the accessor of a read-only property. */
57    protected final byte M_READONLY = 8;
58
59    /** Flags a method as being inherited. */
60    protected final byte M_INHERITED = 16;
61
62    /**
63     * Flags a method as being the writeObject() method
64     * used for serialization.
65     */

66    protected final byte M_WRITEOBJECT = 32;
67
68
69    /** Flags a field as being a constant (public final static). */
70    protected final byte F_CONSTANT = 1;
71
72    /**
73     * Flags a field as being the special <code> public final static
74     * java.io.ObjectStreamField[] serialPersistentFields</code> field.
75     */

76    protected final byte F_SPFFIELD = 2;
77
78    // Attributes ----------------------------------------------------
79

80    /**
81     * Array of all java methods.
82     */

83    protected Method JavaDoc[] methods;
84
85    /**
86     * Array with flags for all java methods.
87     */

88    protected byte[] m_flags;
89
90    /**
91     * Index of the mutator for read-write attributes.
92     * Only entries <code>i</code> where <code>(m_flags[i]&M_READ) != 0</code>
93     * are used. These entries contain the index of the mutator method
94     * corresponding to the accessor method.
95     */

96    protected int[] mutators;
97
98    /**
99     * Array of all java fields.
100     */

101    protected Field JavaDoc[] fields;
102
103    /**
104     * Array with flags for all java fields.
105     */

106    protected byte[] f_flags;
107
108    /**
109     * The class hash code, as specified in "The Common Object Request
110     * Broker: Architecture and Specification" (01-02-33), section 10.6.2.
111     */

112    protected long classHashCode = 0;
113
114    /**
115     * The repository ID.
116     * This is in the RMI hashed format, like
117     * "RMI:java.util.Hashtable:C03324C0EA357270:13BB0F25214AE4B8".
118     */

119    protected String JavaDoc repositoryId;
120
121    /**
122     * The prefix and postfix of members repository ID.
123     * These are used to calculate member repository IDs and are like
124     * "RMI:java.util.Hashtable." and ":C03324C0EA357270:13BB0F25214AE4B8".
125     */

126    protected String JavaDoc memberPrefix, memberPostfix;
127
128    /**
129     * Array of analysis of the interfaces implemented/extended here.
130     */

131    protected InterfaceAnalysis[] interfaces;
132
133    /**
134     * Array of analysis of the abstract base valuetypes implemented/extended here.
135     */

136    protected ValueAnalysis[] abstractBaseValuetypes;
137
138    /**
139     * Array of attributes.
140     */

141    protected AttributeAnalysis[] attributes;
142
143    /**
144     * Array of Constants.
145     */

146    protected ConstantAnalysis[] constants;
147
148    /**
149     * Array of operations.
150     */

151    protected OperationAnalysis[] operations;
152
153
154    // Static --------------------------------------------------------
155

156    private static final org.jboss.logging.Logger logger =
157                org.jboss.logging.Logger.getLogger(ContainerAnalysis.class);
158
159    // Constructors -------------------------------------------------
160

161    protected ContainerAnalysis(Class JavaDoc cls)
162    {
163       super(cls);
164
165       if (cls == java.lang.Object JavaDoc.class ||
166           cls == java.io.Serializable JavaDoc.class ||
167           cls == java.io.Externalizable JavaDoc.class)
168          throw new IllegalArgumentException JavaDoc("Cannot analyze special class: " +
169                                             cls.getName());
170
171       this.cls = cls;
172    }
173
174    protected void doAnalyze()
175       throws RMIIIOPViolationException
176    {
177       analyzeInterfaces();
178       analyzeMethods();
179       analyzeFields();
180       calculateClassHashCode();
181       calculateRepositoryId();
182       analyzeAttributes();
183       analyzeConstants();
184       analyzeOperations();
185       fixupOverloadedOperationNames();
186    }
187
188    // Public --------------------------------------------------------
189

190    /**
191     * Return the interfaces.
192     */

193    public InterfaceAnalysis[] getInterfaces()
194    {
195       logger.debug(cls + " Interface count: " + interfaces.length);
196       return (InterfaceAnalysis[])interfaces.clone();
197    }
198
199    /**
200     * Return the abstract base valuetypes.
201     */

202    public ValueAnalysis[] getAbstractBaseValuetypes()
203    {
204       logger.debug(cls + " Abstract base valuetype count: " + abstractBaseValuetypes.length);
205       return (ValueAnalysis[])abstractBaseValuetypes.clone();
206    }
207
208    /**
209     * Return the attributes.
210     */

211    public AttributeAnalysis[] getAttributes()
212    {
213       logger.debug(cls + " Attribute count: " + attributes.length);
214       return (AttributeAnalysis[])attributes.clone();
215    }
216
217    /**
218     * Return the constants.
219     */

220    public ConstantAnalysis[] getConstants()
221    {
222       logger.debug(cls + " Constants count: " + constants.length);
223       return (ConstantAnalysis[])constants.clone();
224    }
225
226    /**
227     * Return the operations.
228     */

229    public OperationAnalysis[] getOperations()
230    {
231       logger.debug(cls + " Operations count: " + operations.length);
232       return (OperationAnalysis[])operations.clone();
233    }
234
235    /**
236     * Return the repository ID.
237     */

238    public String JavaDoc getRepositoryId()
239    {
240       return repositoryId;
241    }
242
243    /**
244     * Return a repository ID for a member.
245     *
246     * @param memberName The Java name of the member.
247     */

248    public String JavaDoc getMemberRepositoryId(String JavaDoc memberName)
249    {
250       return memberPrefix + escapeIRName(memberName) + memberPostfix;
251    }
252
253    /**
254     * Return the fully qualified IDL module name that this
255     * analysis should be placed in.
256     */

257    public String JavaDoc getIDLModuleName()
258    {
259       if (idlModuleName == null) {
260          String JavaDoc pkgName = cls.getPackage().getName();
261          StringBuffer JavaDoc b = new StringBuffer JavaDoc();
262
263          while (!"".equals(pkgName)) {
264             int idx = pkgName.indexOf('.');
265             String JavaDoc n = (idx == -1) ? pkgName : pkgName.substring(0, idx);
266
267             b.append("::").append(Util.javaToIDLName(n));
268
269             pkgName = (idx == -1) ? "" : pkgName.substring(idx+1);
270          }
271          idlModuleName = b.toString();
272       }
273       return idlModuleName;
274    }
275
276    // Protected -----------------------------------------------------
277

278    /**
279     * Convert an integer to a 16-digit hex string.
280     */

281    protected String JavaDoc toHexString(int i)
282    {
283       String JavaDoc s = Integer.toHexString(i).toUpperCase();
284  
285       if (s.length() < 8)
286          return "00000000".substring(0, 8 - s.length()) + s;
287       else
288          return s;
289    }
290    /**
291     * Convert a long to a 16-digit hex string.
292     */

293    protected String JavaDoc toHexString(long l)
294    {
295       String JavaDoc s = Long.toHexString(l).toUpperCase();
296  
297       if (s.length() < 16)
298          return "0000000000000000".substring(0, 16 - s.length()) + s;
299       else
300          return s;
301    }
302
303    /**
304     * Check if a method is an accessor.
305     */

306    protected boolean isAccessor(Method JavaDoc m)
307    {
308      Class JavaDoc returnType = m.getReturnType();
309  
310      if (!m.getName().startsWith("get"))
311         if (!m.getName().startsWith("is") || !(returnType == Boolean.TYPE))
312            return false;
313      if (returnType == Void.TYPE)
314          return false;
315      if (m.getParameterTypes().length != 0)
316          return false;
317
318      return hasNonAppExceptions(m);
319    }
320  
321    /**
322     * Check if a method is a mutator.
323     */

324    protected boolean isMutator(Method JavaDoc m)
325    {
326      if (!m.getName().startsWith("set"))
327          return false;
328      if (m.getReturnType() != Void.TYPE)
329          return false;
330      if (m.getParameterTypes().length != 1)
331          return false;
332      return hasNonAppExceptions(m);
333    }
334  
335    /**
336     * Check if a method throws anything checked other than
337     * java.rmi.RemoteException and its subclasses.
338     */

339    protected boolean hasNonAppExceptions(Method JavaDoc m)
340    {
341       Class JavaDoc[] ex = m.getExceptionTypes();
342  
343       for (int i = 0; i < ex.length; ++i)
344          if (!java.rmi.RemoteException JavaDoc.class.isAssignableFrom(ex[i]))
345             return false;
346       return true;
347    }
348
349    /**
350     * Analyze the fields of the class.
351     * This will fill in the <code>fields</code> and <code>f_flags</code>
352     * arrays.
353     */

354    protected void analyzeFields()
355    {
356       logger.debug(cls + " analyzeFields");
357
358       //fields = cls.getFields();
359
fields = cls.getDeclaredFields();
360       f_flags = new byte[fields.length];
361
362       for (int i = 0; i < fields.length; ++i) {
363          int mods = fields[i].getModifiers();
364
365          if (Modifier.isFinal(mods) &&
366              Modifier.isStatic(mods) &&
367              Modifier.isPublic(mods))
368            f_flags[i] |= F_CONSTANT;
369       }
370
371       logger.debug(cls + " analyzeFields fields=" + fields.length);
372    }
373
374    /**
375     * Analyze the interfaces of the class.
376     * This will fill in the <code>interfaces</code> array.
377     */

378    protected void analyzeInterfaces()
379       throws RMIIIOPViolationException
380    {
381       logger.debug(cls + " analyzeInterfaces");
382
383       Class JavaDoc[] intfs = cls.getInterfaces();
384       ArrayList JavaDoc a = new ArrayList JavaDoc();
385       ArrayList JavaDoc b = new ArrayList JavaDoc();
386
387       for (int i = 0; i < intfs.length; ++i) {
388          // Ignore java.rmi.Remote
389
if (intfs[i] == java.rmi.Remote JavaDoc.class)
390             continue;
391          // Ignore java.io.Serializable
392
if (intfs[i] == java.io.Serializable JavaDoc.class)
393             continue;
394          // Ignore java.io.Externalizable
395
if (intfs[i] == java.io.Externalizable JavaDoc.class)
396             continue;
397          if (!RmiIdlUtil.isAbstractValueType(intfs[i])) {
398             a.add(InterfaceAnalysis.getInterfaceAnalysis(intfs[i]));
399          }
400          else {
401             b.add(ValueAnalysis.getValueAnalysis(intfs[i]));
402          }
403       }
404
405       interfaces = new InterfaceAnalysis[a.size()];
406       interfaces = (InterfaceAnalysis[])a.toArray(interfaces);
407
408       abstractBaseValuetypes = new ValueAnalysis[b.size()];
409       abstractBaseValuetypes = (ValueAnalysis[])b.toArray(abstractBaseValuetypes);
410
411       logger.debug(cls + " analyzeInterfaces interfaces=" + interfaces.length + " abstractBaseValueTypes=" + abstractBaseValuetypes.length);
412    }
413
414    /**
415     * Analyze the methods of the class.
416     * This will fill in the <code>methods</code> and <code>m_flags</code>
417     * arrays.
418     */

419    protected void analyzeMethods()
420    {
421       logger.debug(cls + " analyzeMethods");
422
423       // The dynamic stub and skeleton strategy generation mechanism
424
// requires the inclusion of inherited methods in the analysis of
425
// remote interfaces. To speed things up, inherited methods are
426
// not considered in the analysis of a class or non-remote interface.
427
if (cls.isInterface() && java.rmi.Remote JavaDoc.class.isAssignableFrom(cls))
428          methods = cls.getMethods();
429       else
430          methods = cls.getDeclaredMethods();
431       m_flags = new byte[methods.length];
432       mutators = new int[methods.length];
433  
434       // Find read-write properties
435
for (int i = 0; i < methods.length; ++i)
436          mutators[i] = -1; // no mutator here
437
for (int i = 0; i < methods.length; ++i) {
438          logger.debug("analyzeMethods(): method["+i+"].getName()=\"" +
439                       methods[i].getName() + "\".");
440
441          if (isAccessor(methods[i]) && (m_flags[i]&M_READ) == 0) {
442             String JavaDoc attrName = attributeReadName(methods[i].getName());
443             Class JavaDoc iReturn = methods[i].getReturnType();
444             for (int j = i+1; j < methods.length; ++j) {
445                if (isMutator(methods[j]) && (m_flags[j]&M_WRITE) == 0 &&
446                    attrName.equals(attributeWriteName(methods[j].getName()))) {
447                   Class JavaDoc[] jParams = methods[j].getParameterTypes();
448                   if (jParams.length == 1 && jParams[0] == iReturn) {
449                      m_flags[i] |= M_READ;
450                      m_flags[j] |= M_WRITE;
451                      mutators[i] = j;
452                      break;
453                   }
454                }
455             }
456          } else if (isMutator(methods[i]) && (m_flags[i]&M_WRITE) == 0) {
457             String JavaDoc attrName = attributeWriteName(methods[i].getName());
458             Class JavaDoc[] iParams = methods[i].getParameterTypes();
459             for (int j = i+1; j < methods.length; ++j) {
460                if (isAccessor(methods[j]) && (m_flags[j]&M_READ) == 0 &&
461                    attrName.equals(attributeReadName(methods[j].getName()))) {
462                   Class JavaDoc jReturn = methods[j].getReturnType();
463                   if (iParams.length == 1 && iParams[0] == jReturn) {
464                      m_flags[i] |= M_WRITE;
465                      m_flags[j] |= M_READ;
466                      mutators[j] = i;
467                      break;
468                   }
469                }
470             }
471          }
472       }
473  
474       // Find read-only properties
475
for (int i = 0; i < methods.length; ++i)
476          if ((m_flags[i] & (M_READ|M_WRITE)) == 0 && isAccessor(methods[i]))
477             m_flags[i] |= M_READONLY;
478
479       // Check for overloaded and inherited methods
480
for (int i = 0; i < methods.length; ++i) {
481          if ((m_flags[i] & (M_READ|M_WRITE|M_READONLY)) == 0) {
482             String JavaDoc iName = methods[i].getName();
483
484             for (int j = i+1; j < methods.length; ++j) {
485                if (iName.equals(methods[j].getName())) {
486                   m_flags[i] |= M_OVERLOADED;
487                   m_flags[j] |= M_OVERLOADED;
488                }
489             }
490          }
491
492          if (methods[i].getDeclaringClass() != cls)
493             m_flags[i] |= M_INHERITED;
494       }
495
496       logger.debug(cls + " analyzeMethods methods=" + methods.length);
497    }
498
499    /**
500     * Convert an attribute read method name in Java format to
501     * an attribute name in Java format.
502     */

503    protected String JavaDoc attributeReadName(String JavaDoc name)
504    {
505       if (name.startsWith("get"))
506          name = name.substring(3);
507       else if (name.startsWith("is"))
508          name = name.substring(2);
509       else
510          throw new IllegalArgumentException JavaDoc("Not an accessor: " + name);
511
512       return name;
513    }
514
515    /**
516     * Convert an attribute write method name in Java format to
517     * an attribute name in Java format.
518     */

519    protected String JavaDoc attributeWriteName(String JavaDoc name)
520    {
521       if (name.startsWith("set"))
522          name = name.substring(3);
523       else
524          throw new IllegalArgumentException JavaDoc("Not an accessor: " + name);
525
526       return name;
527    }
528
529    /**
530     * Analyse constants.
531     * This will fill in the <code>constants</code> array.
532     */

533    protected void analyzeConstants()
534       throws RMIIIOPViolationException
535    {
536       logger.debug(cls + " analyzeConstants");
537
538       ArrayList JavaDoc a = new ArrayList JavaDoc();
539
540       for (int i = 0; i < fields.length; ++i) {
541          logger.debug("f_flags["+i+"]=" + f_flags[i]);
542          if ((f_flags[i] & F_CONSTANT) == 0)
543             continue;
544
545          Class JavaDoc type = fields[i].getType();
546
547          // Only map primitives and java.lang.String
548
if (!type.isPrimitive() && type != java.lang.String JavaDoc.class) {
549             // It is an RMI/IIOP violation for interfaces.
550
if (cls.isInterface())
551                throw new RMIIIOPViolationException(
552                       "Field \"" + fields[i].getName() + "\" of interface \"" +
553                       cls.getName() + "\" is a constant, but not of one " +
554                       "of the primitive types, or String.", "1.2.3");
555
556             continue;
557          }
558
559          String JavaDoc name = fields[i].getName();
560
561          Object JavaDoc value;
562          try {
563             value = fields[i].get(null);
564          } catch (Exception JavaDoc ex) {
565             throw new RuntimeException JavaDoc(ex.toString());
566          }
567
568          logger.debug("Constant["+i+"] name= " + name);
569          logger.debug("Constant["+i+"] type= " + type.getName());
570          logger.debug("Constant["+i+"] value= " + value);
571             a.add(new ConstantAnalysis(name, type, value));
572       }
573
574       constants = new ConstantAnalysis[a.size()];
575       constants = (ConstantAnalysis[])a.toArray(constants);
576       logger.debug(cls + " analyzeConstants constant=" + a.size());
577    }
578
579    /**
580     * Analyse attributes.
581     * This will fill in the <code>attributes</code> array.
582     */

583    protected void analyzeAttributes()
584       throws RMIIIOPViolationException
585    {
586       logger.debug(cls + " analyzeAttributes");
587
588       ArrayList JavaDoc a = new ArrayList JavaDoc();
589
590       for (int i = 0; i < methods.length; ++i) {
591          logger.debug("m_flags["+i+"]=" + m_flags[i]);
592          //if ((m_flags[i]&M_INHERITED) != 0)
593
// continue;
594

595          if ((m_flags[i] & (M_READ|M_READONLY)) != 0) {
596             // Read method of an attribute.
597
String JavaDoc name = attributeReadName(methods[i].getName());
598
599             logger.debug("Attribute["+i+"] name= " + name);
600             if ((m_flags[i]&M_READONLY) != 0)
601                a.add(new AttributeAnalysis(name, methods[i]));
602             else
603                a.add(new AttributeAnalysis(name, methods[i],
604                                            methods[mutators[i]]));
605          }
606       }
607
608       attributes = new AttributeAnalysis[a.size()];
609       attributes = (AttributeAnalysis[])a.toArray(attributes);
610
611       logger.debug(cls + " analyzeAttributes attributes=" + a.size());
612    }
613
614    /**
615     * Analyse operations.
616     * This will fill in the <code>operations</code> array.
617     * This implementation just creates an empty array; override
618     * in subclasses for a real analysis.
619     */

620    protected void analyzeOperations()
621       throws RMIIIOPViolationException
622    {
623       logger.debug(cls + " analyzeOperations");
624       operations = new OperationAnalysis[0];
625       logger.debug(cls + " analyzeOperations operations=" + operations.length);
626    }
627
628    /**
629     * Fixup overloaded operation names.
630     * As specified in section 1.3.2.6.
631     */

632    protected void fixupOverloadedOperationNames()
633       throws RMIIIOPViolationException
634    {
635       for (int i = 0; i < methods.length; ++i) {
636          if ((m_flags[i]&M_OVERLOADED) == 0)
637             continue;
638
639          // Find the operation
640
OperationAnalysis oa = null;
641          String JavaDoc javaName = methods[i].getName();
642          for (int opIdx = 0; oa == null && opIdx < operations.length; ++opIdx)
643             if (operations[opIdx].getMethod().equals(methods[i]))
644                oa = operations[opIdx];
645
646          if (oa == null)
647             continue; // This method is not mapped.
648

649          // Calculate new IDL name
650
ParameterAnalysis[] parms = oa.getParameters();
651          StringBuffer JavaDoc b = new StringBuffer JavaDoc(oa.getIDLName());
652          if (parms.length == 0)
653             b.append("__");
654          for (int j = 0; j < parms.length; ++j) {
655             String JavaDoc s = parms[j].getTypeIDLName();
656
657             if (s.startsWith("::"))
658                s = s.substring(2);
659
660             if (s.startsWith("_")) {
661                // remove leading underscore in IDL escaped identifier
662
s = s.substring(1);
663             }
664
665             b.append('_');
666
667             while (!"".equals(s)) {
668                int idx = s.indexOf("::");
669
670                b.append('_');
671
672                if (idx == -1) {
673                   b.append(s);
674                   s = "";
675                } else {
676                   b.append(s.substring(0, idx));
677                   if (s.length() > idx + 2 && s.charAt(idx + 2) == '_') {
678                      // remove leading underscore in IDL escaped identifier
679
s = s.substring(idx + 3);
680                   } else {
681                      s = s.substring(idx + 2);
682                   }
683                }
684             }
685          }
686
687          // Set new IDL name
688
oa.setIDLName(b.toString());
689       }
690    }
691
692    /**
693     * Fixup names differing only in case.
694     * As specified in section 1.3.2.7.
695     */

696    protected void fixupCaseNames()
697       throws RMIIIOPViolationException
698    {
699       ArrayList JavaDoc entries = getContainedEntries();
700       boolean[] clash = new boolean[entries.size()];
701       String JavaDoc[] upperNames = new String JavaDoc[entries.size()];
702
703       for (int i = 0; i < entries.size(); ++i) {
704          AbstractAnalysis aa = (AbstractAnalysis)entries.get(i);
705
706          clash[i] = false;
707          upperNames[i] = aa.getIDLName().toUpperCase();
708
709          for (int j = 0; j < i; ++j) {
710             if (upperNames[i].equals(upperNames[j])) {
711                clash[i] = true;
712                clash[j] = true;
713             }
714          }
715       }
716
717       for (int i = 0; i < entries.size(); ++i) {
718          if (!clash[i])
719             continue;
720
721          AbstractAnalysis aa = (AbstractAnalysis)entries.get(i);
722          boolean noUpper = true;
723          String JavaDoc name = aa.getIDLName();
724          StringBuffer JavaDoc b = new StringBuffer JavaDoc(name);
725          b.append('_');
726          for (int j = 0; j < name.length(); ++j) {
727             if (!Character.isUpperCase(name.charAt(j)))
728                continue;
729             if (noUpper)
730                noUpper = false;
731             else
732                b.append('_');
733             b.append(j);
734          }
735
736          aa.setIDLName(b.toString());
737       }
738    }
739
740    /**
741     * Return a list of all the entries contained here.
742     *
743     * @param entries The list of entries contained here. Entries in this list
744     * must be subclasses of <code>AbstractAnalysis</code>.
745     */

746    abstract protected ArrayList JavaDoc getContainedEntries();
747
748    /**
749     * Return the class hash code, as specified in "The Common Object
750     * Request Broker: Architecture and Specification" (01-02-33),
751     * section 10.6.2.
752     */

753    protected void calculateClassHashCode()
754    {
755       // The simple cases
756
if (cls.isInterface())
757          classHashCode = 0;
758       else if (!Serializable JavaDoc.class.isAssignableFrom(cls))
759          classHashCode = 0;
760       else if (Externalizable JavaDoc.class.isAssignableFrom(cls))
761          classHashCode = 1;
762       else // Go ask Util class for the hash code
763
classHashCode = Util.getClassHashCode(cls);
764    }
765
766    /**
767     * Escape non-ISO characters for an IR name.
768     */

769    protected String JavaDoc escapeIRName(String JavaDoc name)
770    {
771       StringBuffer JavaDoc b = new StringBuffer JavaDoc();
772
773       for (int i = 0; i < name.length(); ++i) {
774          char c = name.charAt(i);
775  
776          if (c < 256)
777             b.append(c);
778          else
779             b.append("\\U").append(toHexString((int)c));
780       }
781       return b.toString();
782    }
783
784    /**
785     * Return the IR global ID of the given class or interface.
786     * This is described in section 1.3.5.7.
787     * The returned string is in the RMI hashed format, like
788     * "RMI:java.util.Hashtable:C03324C0EA357270:13BB0F25214AE4B8".
789     */

790    protected void calculateRepositoryId()
791    {
792       if (cls.isArray() || cls.isPrimitive())
793          throw new IllegalArgumentException JavaDoc("Not a class or interface.");
794
795       if (cls.isInterface() &&
796           org.omg.CORBA.Object JavaDoc.class.isAssignableFrom(cls) &&
797           org.omg.CORBA.portable.IDLEntity JavaDoc.class.isAssignableFrom(cls)) {
798
799          StringBuffer JavaDoc b = new StringBuffer JavaDoc("IDL:");
800          b.append(cls.getPackage().getName().replace('.', '/'));
801          b.append('/');
802          String JavaDoc base = cls.getName();
803          base = base.substring(base.lastIndexOf('.')+1);
804          b.append(base).append(":1.0");
805          repositoryId = b.toString();
806       }
807       else {
808          StringBuffer JavaDoc b = new StringBuffer JavaDoc("RMI:");
809          b.append(escapeIRName(cls.getName()));
810          memberPrefix = b.toString() + ".";
811          String JavaDoc hashStr = toHexString(classHashCode);
812          b.append(':').append(hashStr);
813          ObjectStreamClass JavaDoc osClass = ObjectStreamClass.lookup(cls);
814          if (osClass != null) {
815             long serialVersionUID = osClass.getSerialVersionUID();
816             String JavaDoc SVUID = toHexString(serialVersionUID);
817             
818             if (classHashCode != serialVersionUID)
819                b.append(':').append(SVUID);
820             memberPostfix = ":" + hashStr + ":" + SVUID;
821          } else
822             memberPostfix = ":" + hashStr;
823          
824          repositoryId = b.toString();
825       }
826    }
827
828    // Private ------------------------------------------------------
829

830    /**
831     * A cache for the fully qualified IDL name of the IDL module we
832     * belong to.
833     */

834    private String JavaDoc idlModuleName = null;
835
836 }
837
Popular Tags