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 @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