001: /*
002: * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025: /*
026: * COMPONENT_NAME: idl.parser
027: *
028: * ORIGINS: 27
029: *
030: * Licensed Materials - Property of IBM
031: * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999
032: * RMI-IIOP v1.0
033: *
034: * @(#)ValueEntry.java 1.21 07/05/05
035: */
036:
037: package com.sun.tools.corba.se.idl;
038:
039: // NOTES:
040:
041: import java.io.PrintWriter;
042: import java.util.Enumeration;
043: import java.util.Hashtable;
044: import java.util.Vector;
045: import com.sun.tools.corba.se.idl.constExpr.Expression;
046:
047: //<daz> import com.sun.tools.corba.se.idl.som.idlemit.TypeCode;
048:
049: /**
050: * This is the symbol table entry for values.
051: **/
052: public class ValueEntry extends InterfaceEntry {
053: protected ValueEntry() {
054: super ();
055: } // ctor
056:
057: protected ValueEntry(ValueEntry that) {
058: super (that);
059: _supportsNames = (Vector) that._supportsNames.clone();
060: _supports = (Vector) that._supports.clone();
061: _initializers = (Vector) that._initializers.clone();
062: _custom = that._custom;
063: _isSafe = that._isSafe;
064: } // ctor
065:
066: protected ValueEntry(SymtabEntry that, IDLID clone) {
067: super (that, clone);
068: } // ctor
069:
070: public Object clone() {
071: return new ValueEntry(this );
072: } // clone
073:
074: /** Invoke the interface generator.
075: @param symbolTable The symbol table is a hash table whose key is
076: a fully qualified type name and whose value is a SymtabEntry or
077: a subclass of SymtabEntry.
078: @param stream The stream to which the generator should sent its output.
079: @see SymtabEntry */
080: public void generate(Hashtable symbolTable, PrintWriter stream) {
081: valueGen.generate(symbolTable, this , stream);
082: } // generate
083:
084: /** Access the value generator.
085: @returns an object which implements the ValueGen interface.
086: @see ValueGen */
087: public Generator generator() {
088: return valueGen;
089: } // generator
090:
091: /** Add an InterfaceEntry to the list of interfaces which this value
092: supports. During parsing, the parameter to this method COULD be a
093: ForwardEntry, but when parsing is complete, calling supports will
094: return a vector which only contains InterfaceEntry's. */
095: public void addSupport(SymtabEntry supports) {
096: _supports.addElement(supports);
097: } // addSupport
098:
099: /** This method returns a vector of InterfaceEntry's. */
100: public Vector supports() {
101: return _supports;
102: } // supports
103:
104: /** Add to the list of support names. */
105: public void addSupportName(String name) {
106: _supportsNames.addElement(name);
107: } // addSupportName
108:
109: /** This method returns a vector of Strings, each of which is a fully
110: qualified name of an interface. This vector corresponds to the
111: supports vector. The first element of this vector is the name of
112: the first element of the supports vector, etc. */
113: public Vector supportsNames() {
114: return _supportsNames;
115: } // supportsNames
116:
117: /** Add a parent value type to the list of parent types for the value.
118: This method:
119: <UL>
120: <LI> Allows only the first added class to be concrete if the receiver is
121: concrete.
122: <LI> Does not allow any added classes to be concrete if the receiver is
123: abstract.
124: <LI> Does not allow duplicate classes to be added.
125: </UL> */
126: void derivedFromAddElement(SymtabEntry e, boolean isSafe,
127: Scanner scanner) {
128: if (((InterfaceType) e).getInterfaceType() != InterfaceType.ABSTRACT) {
129: if (isAbstract())
130: ParseException.nonAbstractParent2(scanner, fullName(),
131: e.fullName());
132: else if (derivedFrom().size() > 0)
133: ParseException.nonAbstractParent3(scanner, fullName(),
134: e.fullName());
135: }
136:
137: if (derivedFrom().contains(e))
138: ParseException.alreadyDerived(scanner, e.fullName(),
139: fullName());
140:
141: if (isSafe)
142: _isSafe = true;
143:
144: addDerivedFrom(e);
145: addDerivedFromName(e.fullName());
146: addParentType(e, scanner);
147: } // derivedFromAddElement
148:
149: void derivedFromAddElement(SymtabEntry e, Scanner scanner) {
150: // This code must check for duplicate interfaces being supported...
151: addSupport(e);
152: addSupportName(e.fullName());
153: addParentType(e, scanner);
154: } // derivedFromAddElement
155:
156: public boolean replaceForwardDecl(ForwardEntry oldEntry,
157: InterfaceEntry newEntry) {
158: if (super .replaceForwardDecl(oldEntry, newEntry))
159: return true;
160: int index = _supports.indexOf(oldEntry);
161: if (index >= 0)
162: _supports.setElementAt(newEntry, index);
163: return (index >= 0);
164: }
165:
166: void initializersAddElement(MethodEntry method, Scanner scanner) {
167: // Check to see if the parameter signature is a duplicate:
168: Vector params = method.parameters();
169: int args = params.size();
170: for (Enumeration e = _initializers.elements(); e
171: .hasMoreElements();) {
172: Vector params2 = ((MethodEntry) e.nextElement())
173: .parameters();
174: if (args == params2.size()) {
175: int i = 0;
176: for (; i < args; i++)
177: if (!((ParameterEntry) params.elementAt(i)).type()
178: .equals(
179: ((ParameterEntry) params2
180: .elementAt(i)).type()))
181: break;
182: if (i >= args)
183: ParseException.duplicateInit(scanner);
184: }
185: }
186: _initializers.addElement(method);
187: } // initializersAddElement
188:
189: public Vector initializers() {
190: return _initializers;
191: }
192:
193: /** Tag all methods introduced by the value type as 'value methods' so
194: they can be differentiated in the emitters from any interface methods
195: that the value type supports. */
196: public void tagMethods() {
197: for (Enumeration e = methods().elements(); e.hasMoreElements();)
198: ((MethodEntry) e.nextElement()).valueMethod(true);
199: }
200:
201: // <46082.03> Revert to "IDL:"-style (i.e., regular) repository ID.
202:
203: /** Calculate the 'repository ID' for the value. This method should not be
204: called before the complete value type has been parsed, since it computes
205: the repository ID by computing hashcodes using all information contained
206: in the value type definition, not just the value type's fully qualified
207: name.*/
208: /*
209: public void calcRepId ()
210: {
211: ValueRepositoryId repId = new ValueRepositoryId ();
212: repId.addType (this);
213: calcRepId (repId);
214: String scopedName = fullName ();
215: // KLR - following switched to new format 8/26/98 per Simon's request
216: repositoryID (new RepositoryID ( "H:" + repId.getHashcode() + ":" + scopedName));
217: } // calcRepId
218: */
219:
220: /*
221: public void calcRepId (ValueRepositoryId repId)
222: {
223: Vector baseClasses = derivedFrom ();
224: if (baseClasses.size () >= 1)
225: ((ValueEntry)baseClasses.elementAt (0)).calcRepId (repId);
226: Vector state = state ();
227: if (state != null)
228: for (Enumeration e = state.elements (); e.hasMoreElements ();)
229: calcTypedefType (((InterfaceState)e.nextElement ()).entry, repId);
230: } // calcRepId
231:
232: private void calcValueType (ValueEntry entry, ValueRepositoryId repId)
233: {
234: if (repId.isNewType (entry))
235: {
236: //<daz> repId.addValue (TypeCode.tk_value);
237: repId.addValue (org.omg.CORBA.TCKind._tk_value);
238: entry.calcRepId (repId);
239: }
240: } // calcValueType
241:
242: private void calcValueBoxType (ValueBoxEntry entry, ValueRepositoryId repId)
243: {
244: if (repId.isNewType (entry))
245: {
246: //<daz> repId.addValue (TypeCode.tk_value_box);
247: repId.addValue (org.omg.CORBA.TCKind._tk_value_box);
248: entry.calcRepId (repId);
249: }
250: } // calcValueBoxType
251:
252: private void calcTypedefType (TypedefEntry entry, ValueRepositoryId repId)
253: {
254: if (repId.isNewType (entry))
255: {
256: Vector arrayInfo = entry.arrayInfo ();
257: if (arrayInfo.size () > 0)
258: {
259: //<daz> repId.addValue (TypeCode.tk_array);
260: repId.addValue (org.omg.CORBA.TCKind._tk_array);
261: for (Enumeration e = arrayInfo.elements (); e.hasMoreElements ();)
262: repId.addValue (((Number)((Expression)e.nextElement ()).value ()).intValue ());
263: }
264: calcType (entry.type (), repId);
265: }
266: } // calcTypedefType
267:
268: private void calcType (SymtabEntry entry, ValueRepositoryId repId)
269: {
270: if (entry instanceof TypedefEntry)
271: calcTypedefType ((TypedefEntry)entry, repId);
272: else if (entry instanceof PrimitiveEntry)
273: calcPrimitiveType (entry, repId);
274: else if (entry instanceof InterfaceEntry)
275: //<daz> repId.addValue (TypeCode._tk_objref);
276: repId.addValue (org.omg.CORBA.TCKind._tk_objref);
277: else if (entry instanceof EnumEntry)
278: //<daz> repId.addValue (TypeCode._tk_enum);
279: repId.addValue (org.omg.CORBA.TCKind._tk_enum);
280: else if (entry instanceof StringEntry)
281: calcStringType ( (StringEntry) entry, repId);
282: else if (entry instanceof SequenceEntry)
283: calcSequenceType ( (SequenceEntry) entry, repId);
284: else if (entry instanceof StructEntry)
285: calcStructType ( (StructEntry) entry, repId);
286: else if (entry instanceof UnionEntry)
287: calcUnionType ( (UnionEntry) entry, repId);
288: else if (entry instanceof ValueBoxEntry)
289: calcValueBoxType ( (ValueBoxEntry) entry, repId);
290: else if (entry instanceof ValueEntry)
291: calcValueType ( (ValueEntry) entry, repId);
292: } // calcType
293:
294: private static Hashtable primTypes;
295:
296: private void calcPrimitiveType (SymtabEntry entry, ValueRepositoryId repId)
297: {
298: if (primTypes == null)
299: {
300: primTypes = new Hashtable ();
301: //<daz> primTypes.put ("short", new Integer (TypeCode.tk_short ));
302: primTypes.put ("short", new Integer (org.omg.CORBA.TCKind._tk_short ));
303: //<daz> primTypes.put ("long", new Integer (TypeCode.tk_long ));
304: primTypes.put ("long", new Integer (org.omg.CORBA.TCKind._tk_long ));
305: //<daz> primTypes.put ("unsigned short", new Integer (TypeCode.tk_ushort ));
306: primTypes.put ("unsigned short", new Integer (org.omg.CORBA.TCKind._tk_ushort ));
307: //<daz> primTypes.put ("unsigned long", new Integer (TypeCode.tk_ulong ));
308: primTypes.put ("unsigned long", new Integer (org.omg.CORBA.TCKind._tk_ulong ));
309: //<daz> primTypes.put ("char", new Integer (TypeCode.tk_char ));
310: primTypes.put ("char", new Integer (org.omg.CORBA.TCKind._tk_char ));
311: //<daz> primTypes.put ("wchar", new Integer (TypeCode.tk_wchar ));
312: primTypes.put ("wchar", new Integer (org.omg.CORBA.TCKind._tk_wchar ));
313: //<daz> primTypes.put ("float", new Integer (TypeCode.tk_float ));
314: primTypes.put ("float", new Integer (org.omg.CORBA.TCKind._tk_float ));
315: //<daz> primTypes.put ("double", new Integer (TypeCode.tk_double ));
316: primTypes.put ("double", new Integer (org.omg.CORBA.TCKind._tk_double ));
317: //<daz> primTypes.put ("boolean", new Integer (TypeCode.tk_boolean));
318: primTypes.put ("boolean", new Integer (org.omg.CORBA.TCKind._tk_boolean));
319: //<daz> primTypes.put ("octet", new Integer (TypeCode.tk_octet ));
320: primTypes.put ("octet", new Integer (org.omg.CORBA.TCKind._tk_octet ));
321: //<daz> primTypes.put ("any", new Integer (TypeCode.tk_any )); }
322: primTypes.put ("any", new Integer (org.omg.CORBA.TCKind._tk_any ));
323: }
324: repId.addValue (((Integer)primTypes.get (entry.name ())).intValue ());
325: } // calcPrimitiveType
326:
327: private void calcStringType (StringEntry entry, ValueRepositoryId repId)
328: {
329: repId.addValue (entry.name ().equals (Parser.overrideName ("string")) ?
330: //<daz> TypeCode.tk_string:
331: org.omg.CORBA.TCKind._tk_string :
332: //<daz> TypeCode.tk_wstring);
333: org.omg.CORBA.TCKind._tk_wstring);
334: if (entry.maxSize () != null)
335: try
336: {
337: repId.addValue ( ( (Number) (entry.maxSize ()).value ()). intValue ());
338: }
339: catch (Exception exception)
340: {}
341: } // calcStringType
342:
343: private void calcSequenceType (SequenceEntry entry, ValueRepositoryId repId)
344: {
345: //<daz> repId.addValue (TypeCode.tk_sequence);
346: repId.addValue (org.omg.CORBA.TCKind._tk_sequence);
347: if (entry.maxSize () != null)
348: try
349: {
350: repId.addValue (((Number)(entry.maxSize ()).value ()).intValue ());
351: }
352: catch (Exception exception)
353: {}
354: } // calcSequenceType
355:
356: private void calcStructType (StructEntry entry, ValueRepositoryId repId)
357: {
358: if (repId.isNewType (entry))
359: {
360: //<daz> repId.addValue (TypeCode.tk_struct);
361: repId.addValue (org.omg.CORBA.TCKind._tk_struct);
362: for (Enumeration e = entry.members ().elements (); e.hasMoreElements ();)
363: calcTypedefType ( (TypedefEntry) e.nextElement (), repId);
364: }
365: } // calcStructType
366:
367: private void calcUnionType (UnionEntry entry, ValueRepositoryId repId)
368: {
369: if (repId.isNewType (entry))
370: {
371: //<daz> repId.addValue (TypeCode.tk_union);
372: repId.addValue (org.omg.CORBA.TCKind._tk_union);
373: calcType (entry.type (), repId);
374: for (Enumeration e = entry.branches ().elements (); e.hasMoreElements ();)
375: calcTypedefType ( ( (UnionBranch) e.nextElement ()).typedef, repId);
376: }
377: } // calcUnionType
378: */
379:
380: /** Get the 'custom' marshaling property. */
381: public boolean isCustom() {
382: return _custom;
383: }
384:
385: /** Set the 'custom' marshaling property. */
386: public void setCustom(boolean isCustom) {
387: _custom = isCustom;
388: }
389:
390: /** Return whether or not the value type can be "safely" truncated to
391: its concrete parent type. */
392: public boolean isSafe() {
393: return _isSafe;
394: }
395:
396: private Vector _supportsNames = new Vector();
397: private Vector _supports = new Vector();
398: private Vector _initializers = new Vector();
399: private boolean _custom = false;
400: private boolean _isSafe = false;
401:
402: static ValueGen valueGen;
403: } // class ValueEntry
|