001: /*
002: * Copyright 1999-2004 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: * @(#)InterfaceEntry.java 1.22 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:
046: /**
047: * This is the symbol table entry for interfaces.
048: **/
049: public class InterfaceEntry extends SymtabEntry implements
050: InterfaceType {
051:
052: protected InterfaceEntry() {
053: super ();
054: } // ctor
055:
056: protected InterfaceEntry(InterfaceEntry that) {
057: super (that);
058: _derivedFromNames = (Vector) that._derivedFromNames.clone();
059: _derivedFrom = (Vector) that._derivedFrom.clone();
060: _methods = (Vector) that._methods.clone();
061: _allMethods = (Vector) that._allMethods.clone();
062: forwardedDerivers = (Vector) that.forwardedDerivers.clone();
063: _contained = (Vector) that._contained.clone();
064: _interfaceType = that._interfaceType;
065: } // ctor
066:
067: protected InterfaceEntry(SymtabEntry that, IDLID clone) {
068: super (that, clone);
069: if (module().equals(""))
070: module(name());
071: else if (!name().equals(""))
072: module(module() + "/" + name());
073: } // ctor
074:
075: public boolean isAbstract() {
076: return _interfaceType == ABSTRACT;
077: }
078:
079: public boolean isLocal() {
080: return _interfaceType == LOCAL;
081: }
082:
083: public boolean isLocalServant() {
084: return _interfaceType == LOCALSERVANT;
085: }
086:
087: public boolean isLocalSignature() {
088: return _interfaceType == LOCAL_SIGNATURE_ONLY;
089: }
090:
091: public Object clone() {
092: return new InterfaceEntry(this );
093: } // clone
094:
095: /** Invoke the interface generator.
096: @param symbolTable the symbol table is a hash table whose key is
097: a fully qualified type name and whose value is a SymtabEntry or
098: a subclass of SymtabEntry.
099: @param stream the stream to which the generator should sent its output.
100: @see SymtabEntry */
101: public void generate(Hashtable symbolTable, PrintWriter stream) {
102: interfaceGen.generate(symbolTable, this , stream);
103: } // generate
104:
105: /** Access the interface generator.
106: @returns an object which implements the InterfaceGen interface.
107: @see InterfaceGen */
108: public Generator generator() {
109: return interfaceGen;
110: } // generator
111:
112: /** Add an InterfaceEntry to the list of interfaces which this interface
113: is derivedFrom. During parsing, the parameter to this method COULD
114: be a ForwardEntry, but when parsing is complete, calling derivedFrom
115: will return a vector which only contains InterfaceEntry's. */
116: public void addDerivedFrom(SymtabEntry derivedFrom) {
117: _derivedFrom.addElement(derivedFrom);
118: } // addDerivedFrom
119:
120: /** This method returns a vector of InterfaceEntry's. */
121: public Vector derivedFrom() {
122: return _derivedFrom;
123: } // derivedFrom
124:
125: /** Add to the list of derivedFrom names. */
126: public void addDerivedFromName(String name) {
127: _derivedFromNames.addElement(name);
128: } // addDerivedFromName
129:
130: /** This method returns a vector of Strings, each of which is a fully
131: qualified name of an interface. This vector corresponds to the
132: derivedFrom vector. The first element of this vector is the name
133: of the first element of the derivedFrom vector, etc. */
134: public Vector derivedFromNames() {
135: return _derivedFromNames;
136: } // derivedFromNames
137:
138: /** Add a method/attribute to the list of methods. */
139: public void addMethod(MethodEntry method) {
140: _methods.addElement(method);
141: } // addMethod
142:
143: /** This is a vector of MethodEntry's. These are the methods and
144: attributes contained within this Interface. */
145: public Vector methods() {
146: return _methods;
147: } // methods
148:
149: /** Add a symbol table entry to this interface's contained vector. */
150: public void addContained(SymtabEntry entry) {
151: _contained.addElement(entry);
152: } // addContained
153:
154: /** This is a vector of SymtabEntry's. Valid entries in this vector are:
155: AttributeEntry, ConstEntry, EnumEntry, ExceptionEntry, MethodEntry,
156: StructEntry, NativeEntry, TypedefEntry, UnionEntry.
157: Note that the methods vector is a subset of this vector. */
158: public Vector contained() {
159: return _contained;
160: } // contained
161:
162: void methodsAddElement(MethodEntry method, Scanner scanner) {
163: if (verifyMethod(method, scanner, false)) {
164: addMethod(method);
165: _allMethods.addElement(method);
166:
167: // Add this method to the 'allMethods' list of any interfaces
168: // which may have inherited this one when it was a forward
169: // reference.
170: addToForwardedAllMethods(method, scanner);
171: }
172: } // methodsAddElement
173:
174: void addToForwardedAllMethods(MethodEntry method, Scanner scanner) {
175: Enumeration e = forwardedDerivers.elements();
176: while (e.hasMoreElements()) {
177: InterfaceEntry derived = (InterfaceEntry) e.nextElement();
178: if (derived.verifyMethod(method, scanner, true))
179: derived._allMethods.addElement(method);
180: }
181: } // addToForwardedAllMethods
182:
183: // Make sure a method by this name doesn't exist in this class or
184: // in this class's parents
185: private boolean verifyMethod(MethodEntry method, Scanner scanner,
186: boolean clash) {
187: boolean unique = true;
188: String lcName = method.name().toLowerCase();
189: Enumeration e = _allMethods.elements();
190: while (e.hasMoreElements()) {
191: MethodEntry emethod = (MethodEntry) e.nextElement();
192:
193: // Make sure the method doesn't exist either in its
194: // original name or in all lower case. In IDL, identifiers
195: // which differ only in case are collisions.
196: String lceName = emethod.name().toLowerCase();
197: if (method != emethod && lcName.equals(lceName)) {
198: if (clash)
199: ParseException.methodClash(scanner, fullName(),
200: method.name());
201: else
202: ParseException.alreadyDeclared(scanner, method
203: .name());
204: unique = false;
205: break;
206: }
207: }
208: return unique;
209: } // verifyMethod
210:
211: void derivedFromAddElement(SymtabEntry e, Scanner scanner) {
212: addDerivedFrom(e);
213: addDerivedFromName(e.fullName());
214: addParentType(e, scanner);
215: } // derivedFromAddElement
216:
217: void addParentType(SymtabEntry e, Scanner scanner) {
218: if (e instanceof ForwardEntry)
219: addToDerivers((ForwardEntry) e);
220: else { // e instanceof InterfaceEntry
221: InterfaceEntry derivedFrom = (InterfaceEntry) e;
222:
223: // Compare all of the parent's methods to the methods on this
224: // interface, looking for name clashes:
225: for (Enumeration enumeration = derivedFrom._allMethods
226: .elements(); enumeration.hasMoreElements();) {
227: MethodEntry method = (MethodEntry) enumeration
228: .nextElement();
229: if (verifyMethod(method, scanner, true))
230: _allMethods.addElement(method);
231:
232: // Add this method to the 'allMethods' list of any interfaces
233: // which may have inherited this one when it was a forward
234: // reference:
235: addToForwardedAllMethods(method, scanner);
236: }
237:
238: // If any of the parent's parents are forward entries, make
239: // sure this interface gets added to their derivers list so
240: // that when the forward entry is defined, the 'allMethods'
241: // list of this interface can be updated.
242: lookForForwardEntrys(scanner, derivedFrom);
243: }
244: } // addParentType
245:
246: private void lookForForwardEntrys(Scanner scanner,
247: InterfaceEntry entry) {
248: Enumeration parents = entry.derivedFrom().elements();
249: while (parents.hasMoreElements()) {
250: SymtabEntry parent = (SymtabEntry) parents.nextElement();
251: if (parent instanceof ForwardEntry)
252: addToDerivers((ForwardEntry) parent);
253: else if (parent == entry)
254: ParseException.selfInherit(scanner, entry.fullName());
255: else
256: // it must be an InterfaceEntry
257: lookForForwardEntrys(scanner, (InterfaceEntry) parent);
258: }
259: } // lookForForwardEntrys
260:
261: public boolean replaceForwardDecl(ForwardEntry oldEntry,
262: InterfaceEntry newEntry) {
263: int index = _derivedFrom.indexOf(oldEntry);
264: if (index >= 0)
265: _derivedFrom.setElementAt(newEntry, index);
266: return (index >= 0);
267: } // replaceForwardDecl
268:
269: private void addToDerivers(ForwardEntry forward) {
270: // Add this interface to the derivers list on the forward entry
271: // so that when the forward entry is defined, the 'allMethods'
272: // list of this interface can be updated.
273: forward.derivers.addElement(this );
274: Enumeration e = forwardedDerivers.elements();
275: while (e.hasMoreElements())
276: forward.derivers.addElement((InterfaceEntry) e
277: .nextElement());
278: } // addToDerivers
279:
280: /** This method returns a vector of the elements in the state block.
281: If it is null, this is not a stateful interface. If it is non-null,
282: but of zero length, then it is still stateful; it has no state
283: entries itself, but it has an ancestor which does. */
284: public Vector state() {
285: return _state;
286: } // state
287:
288: public void initState() {
289: _state = new Vector();
290: } // initState
291:
292: public void addStateElement(InterfaceState state, Scanner scanner) {
293: if (_state == null)
294: _state = new Vector();
295: String name = state.entry.name();
296: for (Enumeration e = _state.elements(); e.hasMoreElements();)
297: if (name.equals(((InterfaceState) e.nextElement()).entry
298: .name()))
299: ParseException.duplicateState(scanner, name);
300: _state.addElement(state);
301: } // state
302:
303: public int getInterfaceType() {
304: return _interfaceType;
305: }
306:
307: public void setInterfaceType(int type) {
308: _interfaceType = type;
309: }
310:
311: /** Get the allMethods vector. */
312: public Vector allMethods() {
313: return _allMethods;
314: }
315:
316: private Vector _derivedFromNames = new Vector();
317: private Vector _derivedFrom = new Vector();
318: private Vector _methods = new Vector();
319: Vector _allMethods = new Vector();
320: Vector forwardedDerivers = new Vector();
321: private Vector _contained = new Vector();
322: private Vector _state = null;
323: private int _interfaceType = NORMAL;
324:
325: static InterfaceGen interfaceGen;
326: } // class InterfaceEntry
|