InterfaceEntry.java revision 672:2bb058ce572e
1/*
2 * Copyright (c) 1999, 2004, 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;
44
45/**
46 * This is the symbol table entry for interfaces.
47 **/
48public class InterfaceEntry extends SymtabEntry implements InterfaceType
49{
50
51  protected InterfaceEntry ()
52  {
53    super ();
54  } // ctor
55
56  protected InterfaceEntry (InterfaceEntry that)
57  {
58    super (that);
59    _derivedFromNames = (Vector)that._derivedFromNames.clone ();
60    _derivedFrom      = (Vector)that._derivedFrom.clone ();
61    _methods          = (Vector)that._methods.clone ();
62    _allMethods       = (Vector)that._allMethods.clone ();
63    forwardedDerivers = (Vector)that.forwardedDerivers.clone ();
64    _contained        = (Vector)that._contained.clone ();
65    _interfaceType    = that._interfaceType;
66  } // ctor
67
68  protected InterfaceEntry (SymtabEntry that, IDLID clone)
69  {
70    super (that, clone);
71    if (module ().equals (""))
72      module (name ());
73    else if (!name ().equals (""))
74      module (module () + "/" + name ());
75  } // ctor
76
77  public boolean isAbstract()
78  {
79      return _interfaceType == ABSTRACT ;
80  }
81
82  public boolean isLocal()
83  {
84      return _interfaceType == LOCAL ;
85  }
86
87  public boolean isLocalServant()
88  {
89      return _interfaceType == LOCALSERVANT ;
90  }
91
92  public boolean isLocalSignature()
93  {
94      return _interfaceType == LOCAL_SIGNATURE_ONLY ;
95  }
96
97  public Object clone ()
98  {
99    return new InterfaceEntry (this);
100  } // clone
101
102  /** Invoke the interface generator.
103      @param symbolTable the symbol table is a hash table whose key is
104       a fully qualified type name and whose value is a SymtabEntry or
105       a subclass of SymtabEntry.
106      @param stream the stream to which the generator should sent its output.
107      @see SymtabEntry */
108  public void generate (Hashtable symbolTable, PrintWriter stream)
109  {
110    interfaceGen.generate (symbolTable, this, stream);
111  } // generate
112
113  /** Access the interface generator.
114      @return an object which implements the InterfaceGen interface.
115      @see InterfaceGen */
116  public Generator generator ()
117  {
118    return interfaceGen;
119  } // generator
120
121  /** Add an InterfaceEntry to the list of interfaces which this interface
122      is derivedFrom.  During parsing, the parameter to this method COULD
123      be a ForwardEntry, but when parsing is complete, calling derivedFrom
124      will return a vector which only contains InterfaceEntry's. */
125  public void addDerivedFrom (SymtabEntry derivedFrom)
126  {
127    _derivedFrom.addElement (derivedFrom);
128  } // addDerivedFrom
129
130  /** This method returns a vector of InterfaceEntry's. */
131  public Vector derivedFrom ()
132  {
133    return _derivedFrom;
134  } // derivedFrom
135
136  /** Add to the list of derivedFrom names. */
137  public void addDerivedFromName (String name)
138  {
139    _derivedFromNames.addElement (name);
140  } // addDerivedFromName
141
142  /** This method returns a vector of Strings, each of which is a fully
143      qualified name of an interface. This vector corresponds to the
144      derivedFrom vector.  The first element of this vector is the name
145      of the first element of the derivedFrom vector, etc. */
146  public Vector derivedFromNames ()
147  {
148    return _derivedFromNames;
149  } // derivedFromNames
150
151  /** Add a method/attribute to the list of methods. */
152  public void addMethod (MethodEntry method)
153  {
154    _methods.addElement (method);
155  } // addMethod
156
157  /** This is a vector of MethodEntry's.  These are the methods and
158      attributes contained within this Interface. */
159  public Vector methods ()
160  {
161    return _methods;
162  } // methods
163
164  /** Add a symbol table entry to this interface's contained vector. */
165  public void addContained (SymtabEntry entry)
166  {
167    _contained.addElement (entry);
168  } // addContained
169
170  /** This is a vector of SymtabEntry's.  Valid entries in this vector are:
171      AttributeEntry, ConstEntry, EnumEntry, ExceptionEntry, MethodEntry,
172      StructEntry, NativeEntry, TypedefEntry, UnionEntry.
173      Note that the methods vector is a subset of this vector. */
174  public Vector contained ()
175  {
176    return _contained;
177  } // contained
178
179  void methodsAddElement (MethodEntry method, Scanner scanner)
180  {
181    if (verifyMethod (method, scanner, false))
182    {
183      addMethod (method);
184      _allMethods.addElement (method);
185
186      // Add this method to the 'allMethods' list of any interfaces
187      // which may have inherited this one when it was a forward
188      // reference.
189      addToForwardedAllMethods (method, scanner);
190    }
191  } // methodsAddElement
192
193  void addToForwardedAllMethods (MethodEntry method, Scanner scanner)
194  {
195    Enumeration e = forwardedDerivers.elements ();
196    while (e.hasMoreElements ())
197    {
198      InterfaceEntry derived = (InterfaceEntry)e.nextElement ();
199      if (derived.verifyMethod (method, scanner, true))
200        derived._allMethods.addElement (method);
201    }
202  } // addToForwardedAllMethods
203
204  // Make sure a method by this name doesn't exist in this class or
205  // in this class's parents
206  private boolean verifyMethod (MethodEntry method, Scanner scanner, boolean clash)
207  {
208    boolean unique = true;
209    String  lcName = method.name ().toLowerCase ();
210    Enumeration e  = _allMethods.elements ();
211    while (e.hasMoreElements ())
212    {
213      MethodEntry emethod = (MethodEntry)e.nextElement ();
214
215      // Make sure the method doesn't exist either in its
216      // original name or in all lower case.  In IDL, identifiers
217      // which differ only in case are collisions.
218      String lceName = emethod.name ().toLowerCase ();
219      if (method != emethod && lcName.equals (lceName))
220      {
221        if (clash)
222          ParseException.methodClash (scanner, fullName (), method.name ());
223        else
224          ParseException.alreadyDeclared (scanner, method.name ());
225        unique = false;
226        break;
227      }
228    }
229    return unique;
230  } // verifyMethod
231
232  void derivedFromAddElement (SymtabEntry e, Scanner scanner)
233  {
234    addDerivedFrom (e);
235    addDerivedFromName (e.fullName ());
236    addParentType( e, scanner );
237  } // derivedFromAddElement
238
239  void addParentType (SymtabEntry e, Scanner scanner)
240  {
241    if (e instanceof ForwardEntry)
242      addToDerivers ((ForwardEntry)e);
243    else
244    { // e instanceof InterfaceEntry
245      InterfaceEntry derivedFrom = (InterfaceEntry)e;
246
247      // Compare all of the parent's methods to the methods on this
248      // interface, looking for name clashes:
249      for ( Enumeration enumeration = derivedFrom._allMethods.elements ();
250            enumeration.hasMoreElements (); )
251      {
252        MethodEntry method = (MethodEntry)enumeration.nextElement ();
253        if ( verifyMethod (method, scanner, true))
254          _allMethods.addElement (method);
255
256        // Add this method to the 'allMethods' list of any interfaces
257        // which may have inherited this one when it was a forward
258        // reference:
259        addToForwardedAllMethods (method, scanner);
260      }
261
262      // If any of the parent's parents are forward entries, make
263      // sure this interface gets added to their derivers list so
264      // that when the forward entry is defined, the 'allMethods'
265      // list of this interface can be updated.
266      lookForForwardEntrys (scanner, derivedFrom);
267    }
268  }  // addParentType
269
270  private void lookForForwardEntrys (Scanner scanner, InterfaceEntry entry)
271  {
272    Enumeration parents = entry.derivedFrom ().elements ();
273    while (parents.hasMoreElements ())
274    {
275      SymtabEntry parent = (SymtabEntry)parents.nextElement ();
276      if (parent instanceof ForwardEntry)
277        addToDerivers ((ForwardEntry)parent);
278      else if (parent == entry)
279        ParseException.selfInherit (scanner, entry.fullName ());
280      else // it must be an InterfaceEntry
281        lookForForwardEntrys (scanner, (InterfaceEntry)parent);
282    }
283  } // lookForForwardEntrys
284
285  public boolean replaceForwardDecl (ForwardEntry oldEntry, InterfaceEntry newEntry)
286  {
287    int index = _derivedFrom.indexOf( oldEntry );
288    if ( index >= 0 )
289      _derivedFrom.setElementAt( newEntry, index );
290    return (index >= 0);
291  } // replaceForwardDecl
292
293  private void addToDerivers (ForwardEntry forward)
294  {
295    // Add this interface to the derivers list on the forward entry
296    // so that when the forward entry is defined, the 'allMethods'
297    // list of this interface can be updated.
298    forward.derivers.addElement (this);
299    Enumeration e = forwardedDerivers.elements ();
300    while (e.hasMoreElements ())
301      forward.derivers.addElement ((InterfaceEntry)e.nextElement ());
302  } // addToDerivers
303
304  /** This method returns a vector of the elements in the state block.
305      If it is null, this is not a stateful interface.  If it is non-null,
306      but of zero length, then it is still stateful; it has no state
307      entries itself, but it has an ancestor which does. */
308  public Vector state ()
309  {
310    return _state;
311  } // state
312
313  public void initState ()
314  {
315    _state = new Vector ();
316  } // initState
317
318  public void addStateElement (InterfaceState state, Scanner scanner)
319  {
320    if (_state == null)
321      _state = new Vector ();
322    String name = state.entry.name ();
323    for (Enumeration e = _state.elements (); e.hasMoreElements ();)
324      if (name.equals (((InterfaceState) e.nextElement ()).entry.name ()))
325        ParseException.duplicateState (scanner, name);
326    _state.addElement (state);
327  } // state
328
329  public int getInterfaceType ()
330  {
331    return _interfaceType;
332  }
333
334  public void setInterfaceType (int type)
335  {
336    _interfaceType = type;
337  }
338
339  /** Get the allMethods vector. */
340  public Vector allMethods ()
341  {
342    return _allMethods;
343  }
344
345  private Vector  _derivedFromNames = new Vector();
346  private Vector  _derivedFrom      = new Vector();
347  private Vector  _methods          = new Vector();
348          Vector  _allMethods       = new Vector();
349          Vector  forwardedDerivers = new Vector();
350  private Vector  _contained        = new Vector();
351  private Vector  _state            = null;
352  private int _interfaceType         = NORMAL;
353
354  static  InterfaceGen interfaceGen;
355} // class InterfaceEntry
356