View Javadoc
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  
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  
45  /**
46   * This is the symbol table entry for interfaces.
47   **/
48  public 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       @returns 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