ValueEntry.java revision 608:7e06bf1dcb09
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
36package com.sun.tools.corba.se.idl;
37
38// NOTES:
39
40import java.io.PrintWriter;
41import java.util.Enumeration;
42import java.util.Hashtable;
43import java.util.Vector;
44import 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**/
50public 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
415