View Javadoc
1   /*
2    * Copyright (c) 1999, 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  /*
26   * COMPONENT_NAME: idl.parser
27   *
28   * ORIGINS: 27
29   *
30   * Licensed Materials - Property of IBM
31   * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999
32   * RMI-IIOP v1.0
33   *
34   */
35  
36  package com.sun.tools.corba.se.idl;
37  
38  // NOTES:
39  
40  import java.io.PrintWriter;
41  import java.util.Enumeration;
42  import java.util.Hashtable;
43  import java.util.Vector;
44  import com.sun.tools.corba.se.idl.constExpr.Expression;
45  //<daz> import com.sun.tools.corba.se.idl.som.idlemit.TypeCode;
46  
47  /**
48  * This is the symbol table entry for values.
49  **/
50  public class ValueEntry extends InterfaceEntry
51  {
52    protected ValueEntry ()
53    {
54      super ();
55    } // ctor
56  
57    protected ValueEntry (ValueEntry that)
58    {
59       super (that);
60      _supportsNames = (Vector)that._supportsNames.clone ();
61      _supports      = (Vector)that._supports.clone ();
62      _initializers  = (Vector)that._initializers.clone ();
63      _custom        = that._custom;
64      _isSafe        = that._isSafe;
65    } // ctor
66  
67    protected ValueEntry (SymtabEntry that, IDLID clone)
68    {
69      super (that, clone);
70    } // ctor
71  
72    public Object clone ()
73    {
74      return new ValueEntry (this);
75    } // clone
76  
77    /** Invoke the interface generator.
78        @param symbolTable The symbol table is a hash table whose key is
79         a fully qualified type name and whose value is a SymtabEntry or
80         a subclass of SymtabEntry.
81        @param stream The stream to which the generator should sent its output.
82        @see SymtabEntry */
83    public void generate (Hashtable symbolTable, PrintWriter stream)
84    {
85      valueGen.generate (symbolTable, this, stream);
86    } // generate
87  
88    /** Access the value generator.
89        @returns an object which implements the ValueGen interface.
90        @see ValueGen */
91    public Generator generator ()
92    {
93      return valueGen;
94    } // generator
95  
96    /** Add an InterfaceEntry to the list of interfaces which this value
97        supports.  During parsing, the parameter to this method COULD be a
98        ForwardEntry, but when parsing is complete, calling supports will
99        return a vector which only contains InterfaceEntry's. */
100   public void addSupport (SymtabEntry supports)
101   {
102     _supports.addElement (supports);
103   } // addSupport
104 
105   /** This method returns a vector of InterfaceEntry's. */
106   public Vector supports ()
107   {
108     return _supports;
109   } // supports
110 
111   /** Add to the list of support names. */
112   public void addSupportName (String name)
113   {
114     _supportsNames.addElement (name);
115   } // addSupportName
116 
117   /** This method returns a vector of Strings, each of which is a fully
118       qualified name of an interface. This vector corresponds to the
119       supports vector.  The first element of this vector is the name of
120       the first element of the supports vector, etc. */
121   public Vector supportsNames ()
122   {
123     return _supportsNames;
124   } // supportsNames
125 
126   /** Add a parent value type to the list of parent types for the value.
127       This method:
128       <UL>
129         <LI> Allows only the first added class to be concrete if the receiver is
130              concrete.
131         <LI> Does not allow any added classes to be concrete if the receiver is
132              abstract.
133         <LI> Does not allow duplicate classes to be added.
134       </UL> */
135   void derivedFromAddElement (SymtabEntry e, boolean isSafe, Scanner scanner)
136   {
137     if (((InterfaceType)e).getInterfaceType() != InterfaceType.ABSTRACT) {
138       if (isAbstract ())
139         ParseException.nonAbstractParent2 (scanner, fullName (), e.fullName ());
140       else if (derivedFrom ().size () > 0)
141         ParseException.nonAbstractParent3 (scanner, fullName (), e.fullName ());
142     }
143 
144     if (derivedFrom ().contains (e))
145       ParseException.alreadyDerived (scanner, e.fullName (), fullName ());
146 
147     if (isSafe)
148       _isSafe = true;
149 
150     addDerivedFrom (e);
151     addDerivedFromName (e.fullName ());
152     addParentType (e, scanner);
153   } // derivedFromAddElement
154 
155   void derivedFromAddElement (SymtabEntry e, Scanner scanner)
156   {
157     // This code must check for duplicate interfaces being supported...
158     addSupport (e);
159     addSupportName (e.fullName ());
160     addParentType (e, scanner);
161   } // derivedFromAddElement
162 
163   public boolean replaceForwardDecl (ForwardEntry oldEntry, InterfaceEntry newEntry)
164   {
165     if (super.replaceForwardDecl (oldEntry, newEntry))
166       return true;
167     int index = _supports.indexOf (oldEntry);
168     if ( index >= 0)
169       _supports.setElementAt (newEntry, index);
170     return (index >= 0);
171   }
172 
173   void initializersAddElement (MethodEntry method, Scanner scanner)
174   {
175     // Check to see if the parameter signature is a duplicate:
176     Vector params = method.parameters ();
177     int    args   = params.size ();
178     for (Enumeration e = _initializers.elements (); e.hasMoreElements ();)
179     {
180       Vector params2 = ( (MethodEntry) e.nextElement ()).parameters ();
181       if (args == params2.size ())
182       {
183         int i = 0;
184         for (; i < args; i++)
185           if (!((ParameterEntry)params.elementAt (i)).type ().equals (
186                 ((ParameterEntry)params2.elementAt (i)).type ()))
187             break;
188         if (i >= args)
189           ParseException.duplicateInit (scanner);
190       }
191     }
192     _initializers.addElement (method);
193   } // initializersAddElement
194 
195   public Vector initializers ()
196   {
197     return _initializers;
198   }
199 
200   /** Tag all methods introduced by the value type as 'value methods' so
201       they can be differentiated in the emitters from any interface methods
202       that the value type supports. */
203   public void tagMethods ()
204   {
205     for (Enumeration e = methods ().elements (); e.hasMoreElements ();)
206       ((MethodEntry)e.nextElement ()).valueMethod (true);
207   }
208 
209   // <46082.03> Revert to "IDL:"-style (i.e., regular) repository ID.
210 
211   /** Calculate the 'repository ID' for the value. This method should not be
212       called before the complete value type has been parsed, since it computes
213       the repository ID by computing hashcodes using all information contained
214       in the value type definition, not just the value type's fully qualified
215       name.*/
216   /*
217   public void calcRepId ()
218   {
219     ValueRepositoryId repId = new ValueRepositoryId ();
220     repId.addType (this);
221     calcRepId (repId);
222     String scopedName = fullName ();
223     // KLR - following switched to new format 8/26/98 per Simon's request
224     repositoryID (new RepositoryID ( "H:" + repId.getHashcode() + ":" + scopedName));
225   } // calcRepId
226   */
227 
228   /*
229   public void calcRepId (ValueRepositoryId repId)
230   {
231     Vector baseClasses = derivedFrom ();
232     if (baseClasses.size () >= 1)
233       ((ValueEntry)baseClasses.elementAt (0)).calcRepId (repId);
234     Vector state = state ();
235     if (state != null)
236       for (Enumeration e = state.elements (); e.hasMoreElements ();)
237         calcTypedefType (((InterfaceState)e.nextElement ()).entry, repId);
238   } // calcRepId
239 
240   private void calcValueType (ValueEntry entry, ValueRepositoryId repId)
241   {
242     if (repId.isNewType (entry))
243     {
244       //<daz> repId.addValue (TypeCode.tk_value);
245       repId.addValue (org.omg.CORBA.TCKind._tk_value);
246       entry.calcRepId (repId);
247     }
248   } // calcValueType
249 
250   private void calcValueBoxType (ValueBoxEntry entry, ValueRepositoryId repId)
251   {
252     if (repId.isNewType (entry))
253     {
254       //<daz> repId.addValue (TypeCode.tk_value_box);
255       repId.addValue (org.omg.CORBA.TCKind._tk_value_box);
256       entry.calcRepId (repId);
257     }
258   } // calcValueBoxType
259 
260   private void calcTypedefType (TypedefEntry entry, ValueRepositoryId repId)
261   {
262     if (repId.isNewType (entry))
263     {
264       Vector arrayInfo = entry.arrayInfo ();
265       if (arrayInfo.size () > 0)
266       {
267         //<daz> repId.addValue (TypeCode.tk_array);
268         repId.addValue (org.omg.CORBA.TCKind._tk_array);
269         for (Enumeration e = arrayInfo.elements (); e.hasMoreElements ();)
270           repId.addValue (((Number)((Expression)e.nextElement ()).value ()).intValue ());
271       }
272       calcType (entry.type (), repId);
273     }
274   } // calcTypedefType
275 
276   private void calcType (SymtabEntry entry, ValueRepositoryId repId)
277   {
278     if (entry instanceof TypedefEntry)
279       calcTypedefType ((TypedefEntry)entry, repId);
280     else if (entry instanceof PrimitiveEntry)
281       calcPrimitiveType (entry, repId);
282     else if (entry instanceof InterfaceEntry)
283       //<daz> repId.addValue (TypeCode._tk_objref);
284       repId.addValue (org.omg.CORBA.TCKind._tk_objref);
285     else if (entry instanceof EnumEntry)
286       //<daz> repId.addValue (TypeCode._tk_enum);
287      repId.addValue (org.omg.CORBA.TCKind._tk_enum);
288     else if (entry instanceof StringEntry)
289      calcStringType ( (StringEntry) entry, repId);
290     else if (entry instanceof SequenceEntry)
291      calcSequenceType ( (SequenceEntry) entry, repId);
292     else if (entry instanceof StructEntry)
293       calcStructType ( (StructEntry) entry, repId);
294     else if (entry instanceof UnionEntry)
295       calcUnionType ( (UnionEntry) entry, repId);
296     else if (entry instanceof ValueBoxEntry)
297       calcValueBoxType ( (ValueBoxEntry) entry, repId);
298     else if (entry instanceof ValueEntry)
299       calcValueType ( (ValueEntry) entry, repId);
300   } // calcType
301 
302   private static Hashtable primTypes;
303 
304   private void calcPrimitiveType (SymtabEntry entry, ValueRepositoryId repId)
305   {
306     if (primTypes == null)
307     {
308       primTypes = new Hashtable ();
309       //<daz> primTypes.put ("short",          new Integer (TypeCode.tk_short  ));
310       primTypes.put ("short",          new Integer (org.omg.CORBA.TCKind._tk_short  ));
311       //<daz> primTypes.put ("long",           new Integer (TypeCode.tk_long   ));
312       primTypes.put ("long",           new Integer (org.omg.CORBA.TCKind._tk_long   ));
313       //<daz> primTypes.put ("unsigned short", new Integer (TypeCode.tk_ushort ));
314       primTypes.put ("unsigned short", new Integer (org.omg.CORBA.TCKind._tk_ushort ));
315       //<daz> primTypes.put ("unsigned long",  new Integer (TypeCode.tk_ulong  ));
316       primTypes.put ("unsigned long",  new Integer (org.omg.CORBA.TCKind._tk_ulong  ));
317       //<daz> primTypes.put ("char",           new Integer (TypeCode.tk_char   ));
318       primTypes.put ("char",           new Integer (org.omg.CORBA.TCKind._tk_char   ));
319       //<daz> primTypes.put ("wchar",          new Integer (TypeCode.tk_wchar  ));
320       primTypes.put ("wchar",          new Integer (org.omg.CORBA.TCKind._tk_wchar  ));
321       //<daz> primTypes.put ("float",          new Integer (TypeCode.tk_float  ));
322       primTypes.put ("float",          new Integer (org.omg.CORBA.TCKind._tk_float  ));
323       //<daz> primTypes.put ("double",         new Integer (TypeCode.tk_double ));
324       primTypes.put ("double",         new Integer (org.omg.CORBA.TCKind._tk_double ));
325       //<daz> primTypes.put ("boolean",        new Integer (TypeCode.tk_boolean));
326       primTypes.put ("boolean",        new Integer (org.omg.CORBA.TCKind._tk_boolean));
327       //<daz> primTypes.put ("octet",          new Integer (TypeCode.tk_octet  ));
328       primTypes.put ("octet",          new Integer (org.omg.CORBA.TCKind._tk_octet  ));
329       //<daz> primTypes.put ("any",            new Integer (TypeCode.tk_any    )); }
330       primTypes.put ("any",            new Integer (org.omg.CORBA.TCKind._tk_any    ));
331     }
332     repId.addValue (((Integer)primTypes.get (entry.name ())).intValue ());
333   } // calcPrimitiveType
334 
335   private void calcStringType (StringEntry entry, ValueRepositoryId repId)
336   {
337     repId.addValue (entry.name ().equals (Parser.overrideName ("string")) ?
338         //<daz> TypeCode.tk_string:
339         org.omg.CORBA.TCKind._tk_string :
340         //<daz> TypeCode.tk_wstring);
341         org.omg.CORBA.TCKind._tk_wstring);
342     if (entry.maxSize () != null)
343       try
344       {
345         repId.addValue ( ( (Number) (entry.maxSize ()).value ()). intValue ());
346       }
347       catch (Exception exception)
348       {}
349   } // calcStringType
350 
351   private void calcSequenceType (SequenceEntry entry, ValueRepositoryId repId)
352   {
353     //<daz> repId.addValue (TypeCode.tk_sequence);
354     repId.addValue (org.omg.CORBA.TCKind._tk_sequence);
355     if (entry.maxSize () != null)
356       try
357       {
358         repId.addValue (((Number)(entry.maxSize ()).value ()).intValue ());
359       }
360       catch (Exception exception)
361       {}
362   } // calcSequenceType
363 
364   private void calcStructType (StructEntry entry, ValueRepositoryId repId)
365   {
366     if (repId.isNewType (entry))
367     {
368       //<daz> repId.addValue (TypeCode.tk_struct);
369       repId.addValue (org.omg.CORBA.TCKind._tk_struct);
370       for (Enumeration e = entry.members ().elements (); e.hasMoreElements ();)
371         calcTypedefType ( (TypedefEntry) e.nextElement (), repId);
372     }
373   } // calcStructType
374 
375   private void calcUnionType (UnionEntry entry, ValueRepositoryId repId)
376   {
377     if (repId.isNewType (entry))
378     {
379       //<daz> repId.addValue (TypeCode.tk_union);
380       repId.addValue (org.omg.CORBA.TCKind._tk_union);
381       calcType (entry.type (), repId);
382       for (Enumeration e = entry.branches ().elements (); e.hasMoreElements ();)
383         calcTypedefType ( ( (UnionBranch) e.nextElement ()).typedef, repId);
384     }
385   } // calcUnionType
386 */
387 
388   /** Get the 'custom' marshaling property. */
389   public boolean isCustom ()
390   {
391     return _custom;
392   }
393 
394   /** Set the 'custom' marshaling property. */
395   public void setCustom (boolean isCustom)
396   {
397     _custom = isCustom;
398   }
399 
400   /** Return whether or not the value type can be "safely" truncated to
401       its concrete parent type. */
402   public boolean isSafe ()
403   {
404     return _isSafe;
405   }
406 
407   private Vector   _supportsNames = new Vector ();
408   private Vector   _supports      = new Vector ();
409   private Vector   _initializers  = new Vector ();
410   private boolean  _custom        = false;
411   private boolean  _isSafe        = false;
412 
413   static  ValueGen valueGen;
414 } // class ValueEntry