0N/A/*
2362N/A * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A/*
0N/A * Licensed Materials - Property of IBM
0N/A * RMI-IIOP v1.0
0N/A * Copyright IBM Corp. 1998 1999 All Rights Reserved
0N/A *
0N/A */
0N/A
0N/Apackage sun.rmi.rmic.iiop;
0N/A
0N/Aimport java.util.Vector;
0N/Aimport sun.tools.java.CompilerError;
0N/Aimport sun.tools.java.ClassNotFound;
0N/Aimport sun.tools.java.ClassDefinition;
0N/Aimport sun.tools.java.MemberDefinition;
0N/A
0N/A/**
0N/A * ImplementationType represents any non-special class which implements
0N/A * one or more interfaces which inherit from java.rmi.Remote.
0N/A * <p>
0N/A * The static forImplementation(...) method must be used to obtain an instance,
0N/A * and will return null if the ClassDefinition is non-conforming.
0N/A *
0N/A * @author Bryan Atsatt
0N/A */
0N/Apublic class ImplementationType extends ClassType {
0N/A
0N/A //_____________________________________________________________________
0N/A // Public Interfaces
0N/A //_____________________________________________________________________
0N/A
0N/A /**
0N/A * Create an ImplementationType for the given class.
0N/A *
0N/A * If the class is not a properly formed or if some other error occurs, the
0N/A * return value will be null, and errors will have been reported to the
0N/A * supplied BatchEnvironment.
0N/A */
0N/A public static ImplementationType forImplementation(ClassDefinition classDef,
0N/A ContextStack stack,
0N/A boolean quiet) {
0N/A if (stack.anyErrors()) return null;
0N/A
0N/A boolean doPop = false;
0N/A ImplementationType result = null;
0N/A
0N/A try {
0N/A // Do we already have it?
0N/A
0N/A sun.tools.java.Type theType = classDef.getType();
0N/A Type existing = getType(theType,stack);
0N/A
0N/A if (existing != null) {
0N/A
0N/A if (!(existing instanceof ImplementationType)) return null; // False hit.
0N/A
0N/A // Yep, so return it...
0N/A
0N/A return (ImplementationType) existing;
0N/A
0N/A }
0N/A
0N/A // Could this be an implementation?
0N/A
0N/A if (couldBeImplementation(quiet,stack,classDef)) {
0N/A
0N/A // Yes, so check it...
0N/A
0N/A ImplementationType it = new ImplementationType(stack, classDef);
0N/A putType(theType,it,stack);
0N/A stack.push(it);
0N/A doPop = true;
0N/A
0N/A if (it.initialize(stack,quiet)) {
0N/A stack.pop(true);
0N/A result = it;
0N/A } else {
0N/A removeType(theType,stack);
0N/A stack.pop(false);
0N/A }
0N/A }
0N/A } catch (CompilerError e) {
0N/A if (doPop) stack.pop(false);
0N/A }
0N/A
0N/A return result;
0N/A }
0N/A
0N/A /**
0N/A * Return a string describing this type.
0N/A */
0N/A public String getTypeDescription () {
0N/A return "Implementation";
0N/A }
0N/A
0N/A
0N/A //_____________________________________________________________________
0N/A // Internal Interfaces
0N/A //_____________________________________________________________________
0N/A
0N/A /**
0N/A * Create a ImplementationType instance for the given class. The resulting
0N/A * object is not yet completely initialized.
0N/A */
0N/A private ImplementationType(ContextStack stack, ClassDefinition classDef) {
0N/A super(TYPE_IMPLEMENTATION | TM_CLASS | TM_COMPOUND,classDef,stack); // Use special constructor.
0N/A }
0N/A
0N/A
0N/A private static boolean couldBeImplementation(boolean quiet, ContextStack stack,
0N/A ClassDefinition classDef) {
0N/A boolean result = false;
0N/A BatchEnvironment env = stack.getEnv();
0N/A
0N/A try {
0N/A if (!classDef.isClass()) {
0N/A failedConstraint(17,quiet,stack,classDef.getName());
0N/A } else {
0N/A result = env.defRemote.implementedBy(env, classDef.getClassDeclaration());
0N/A if (!result) failedConstraint(8,quiet,stack,classDef.getName());
0N/A }
0N/A } catch (ClassNotFound e) {
0N/A classNotFound(stack,e);
0N/A }
0N/A
0N/A return result;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Initialize this instance.
0N/A */
0N/A private boolean initialize (ContextStack stack, boolean quiet) {
0N/A
0N/A boolean result = false;
0N/A ClassDefinition theClass = getClassDefinition();
0N/A
0N/A if (initParents(stack)) {
0N/A
0N/A // Make up our collections...
0N/A
0N/A Vector directInterfaces = new Vector();
0N/A Vector directMethods = new Vector();
0N/A
0N/A // Check interfaces...
0N/A
0N/A try {
0N/A if (addRemoteInterfaces(directInterfaces,true,stack) != null) {
0N/A
0N/A boolean haveRemote = false;
0N/A
0N/A // Get methods from all interfaces...
0N/A
0N/A for (int i = 0; i < directInterfaces.size(); i++) {
0N/A InterfaceType theInt = (InterfaceType) directInterfaces.elementAt(i);
0N/A if (theInt.isType(TYPE_REMOTE) ||
0N/A theInt.isType(TYPE_JAVA_RMI_REMOTE)) {
0N/A haveRemote = true;
0N/A }
0N/A
0N/A copyRemoteMethods(theInt,directMethods);
0N/A }
0N/A
0N/A // Make sure we have at least one remote interface...
0N/A
0N/A if (!haveRemote) {
0N/A failedConstraint(8,quiet,stack,getQualifiedName());
0N/A return false;
0N/A }
0N/A
0N/A // Now check the methods to ensure we have the
0N/A // correct throws clauses...
0N/A
0N/A if (checkMethods(theClass,directMethods,stack,quiet)) {
0N/A
0N/A // We're ok, so pass 'em up...
0N/A
0N/A result = initialize(directInterfaces,directMethods,null,stack,quiet);
0N/A }
0N/A }
0N/A } catch (ClassNotFound e) {
0N/A classNotFound(stack,e);
0N/A }
0N/A }
0N/A
0N/A return result;
}
private static void copyRemoteMethods(InterfaceType type, Vector list) {
if (type.isType(TYPE_REMOTE)) {
// Copy all the unique methods from type...
Method[] allMethods = type.getMethods();
for (int i = 0; i < allMethods.length; i++) {
Method theMethod = allMethods[i];
if (!list.contains(theMethod)) {
list.addElement(theMethod);
}
}
// Now recurse thru all inherited interfaces...
InterfaceType[] allInterfaces = type.getInterfaces();
for (int i = 0; i < allInterfaces.length; i++) {
copyRemoteMethods(allInterfaces[i],list);
}
}
}
// Walk all methods of the class, and for each that is already in
// the list, call setImplExceptions()...
private boolean checkMethods(ClassDefinition theClass, Vector list,
ContextStack stack, boolean quiet) {
// Convert vector to array...
Method[] methods = new Method[list.size()];
list.copyInto(methods);
for (MemberDefinition member = theClass.getFirstMember();
member != null;
member = member.getNextMember()) {
if (member.isMethod() && !member.isConstructor()
&& !member.isInitializer()) {
// It's a method...
if (!updateExceptions(member,methods,stack,quiet)) {
return false;
}
}
}
return true;
}
private boolean updateExceptions (MemberDefinition implMethod, Method[] list,
ContextStack stack, boolean quiet) {
int length = list.length;
String implMethodSig = implMethod.toString();
for (int i = 0; i < length; i++) {
Method existingMethod = list[i];
MemberDefinition existing = existingMethod.getMemberDefinition();
// Do we have a matching method?
if (implMethodSig.equals(existing.toString())) {
// Yes, so create exception list...
try {
ValueType[] implExcept = getMethodExceptions(implMethod,quiet,stack);
existingMethod.setImplExceptions(implExcept);
} catch (Exception e) {
return false;
}
}
}
return true;
}
}