blob: 0e735cd4ca25b6a70b87400d6be4f84078b8dc26 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jem.internal.java.adapters.jdk;
/*
*/
import java.util.List;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.jem.java.*;
import org.eclipse.jem.internal.java.adapters.IJavaMethodAdapter;
import org.eclipse.jem.internal.java.adapters.ReadAdaptor;
import org.eclipse.jem.java.internal.impl.MethodImpl;
/**
* Insert the type's description here.
* Creation date: (6/6/2000 4:42:50 PM)
* @author: Administrator
*/
public class JavaMethodJDKAdaptor extends JDKAdaptor implements IJavaMethodAdapter {
protected java.lang.reflect.AccessibleObject sourceAccessible = null; // Could be method or ctor.
protected Class parentType = null;
// cache a static empty Class[] for no parm methods
protected static Class[] emptyClassArray = new Class[0];
// cache a static empty String[], too
protected static String[] emptyStringArray = new String[0];
public JavaMethodJDKAdaptor(Notifier target, JavaJDKAdapterFactory anAdapterFactory) {
super(target, anAdapterFactory);
}
/**
* addExceptions - reflect our exception list
*/
protected void addExceptions() {
Class[] exceptions =
(getSourceAccessible() instanceof java.lang.reflect.Method)
? ((java.lang.reflect.Method) getSourceAccessible()).getExceptionTypes()
: ((java.lang.reflect.Constructor) getSourceAccessible()).getExceptionTypes();
// EList exList = (EList) javaMethodTarget.primRefValue(JavaRefPackage.eINSTANCE.getMethod_JavaExceptions());
List exList = getMethodTarget().getJavaExceptionsGen();
for (int i = 0; i < exceptions.length; i++) {
exList.add(createJavaClassRef(exceptions[i].getName()));
}
}
protected MethodImpl getMethodTarget() {
return (MethodImpl) getTarget();
}
/**
* addParameters - reflect our parms
*/
protected void addParameters() {
Class[] parmTypes =
(getSourceAccessible() instanceof java.lang.reflect.Method)
? ((java.lang.reflect.Method) getSourceAccessible()).getParameterTypes()
: ((java.lang.reflect.Constructor) getSourceAccessible()).getParameterTypes();
MethodImpl javaMethodTarget = getMethodTarget();
// List pList = (List) javaMethodTarget.primRefValue(JavaRefPackage.eINSTANCE.getMethod_Parameters());
List pList = javaMethodTarget.getParametersGen();
for (int i = 0; i < parmTypes.length; i++) {
pList.add(createJavaParameter(javaMethodTarget, "arg" + i, getTypeName(parmTypes[i]))); //$NON-NLS-1$
}
}
protected JavaClass getContainingJavaClass() {
return ((Method) getTarget()).getContainingJavaClass();
}
/**
* getParentType - return the Class which corresponds to our parent JavaClass
* we're going to do this a lot, so cache it.
*/
protected Class getParentType() {
if (parentType == null) {
Method targetMethod = (Method) getTarget();
JavaClass parentJavaClass = targetMethod.getContainingJavaClass();
JavaClassJDKAdaptor pa = (JavaClassJDKAdaptor) EcoreUtil.getAdapter(parentJavaClass.eAdapters(), ReadAdaptor.TYPE_KEY);
if (pa != null)
parentType = pa.getSourceType();
}
return parentType;
}
/**
* getParmTypeSignatures - return an array of Classes for our parameter types
* For reflection purposes, we can only rely on our ID, since our parms may
* not yet be known.
*/
protected Class[] getParmTypes() {
Method javaMethodTarget = (Method) getTarget();
String id = ((XMIResource) javaMethodTarget.eResource()).getID(javaMethodTarget);
String[] typeNames = getTypeNamesFromMethodID(id);
if (typeNames == null)
return emptyClassArray;
int n = typeNames.length;
if (n == 0)
return emptyClassArray;
Class[] types = new Class[n];
for (int i = 0; i < n; ++i) {
types[i] = getType(typeNames[i]);
}
return types;
}
public Object getReflectionSource() {
return getSourceAccessible();
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.java.adapters.JavaReflectionAdaptor#hasReflectionSource()
*/
public boolean hasCachedReflectionSource() {
return sourceAccessible != null;
}
/**
* getsourceMethod - return the java.lang.reflect.Method which describes our implementing method
*/
protected java.lang.reflect.AccessibleObject getSourceAccessible() {
if (sourceAccessible == null) {
Class parent = this.getParentType();
if (parent != null) {
Class[] parmTypes = this.getParmTypes();
try {
sourceAccessible = parent.getDeclaredMethod(((Method) getTarget()).getName(), parmTypes);
} catch (NoSuchMethodException e) {
// OK, can't reflect it
}
if (sourceAccessible == null) {
// It wasn't a method, try for constructor.
try {
sourceAccessible = parent.getDeclaredConstructor(parmTypes);
} catch (NoSuchMethodException e) {
// OK, can't reflect it
}
}
}
}
return sourceAccessible;
}
/**
* getValueIn method comment.
*/
public Object getValueIn(EObject object, EObject attribute) {
// At this point, this adapter does not dynamically compute any values,
// all values are pushed back into the target on the initial call.
return super.getValueIn(object, attribute);
}
/**
* reflectValues - template method, subclasses override to pump values into target.
* on entry: UUID, name, containing package (and qualified name), and document must be set.
* Method adaptor:
* - set modifiers
* - set name
* - set return type
* - add parameters
* - add exceptions
*/
public boolean reflectValues() {
if (getSourceAccessible() != null) {
((Method) getTarget()).setIsGenerated(false);
setModifiers();
setNaming();
setReturnType();
addParameters();
addExceptions();
return true;
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jem.internal.java.adapters.IJavaMethodAdapter#reflectGeneratedIfNecessary()
*/
public boolean reflectGeneratedIfNecessary() {
return reflectValuesIfNecessary();
}
public boolean reflectParamNamesIfNecessary() {
return reflectValuesIfNecessary();
}
/**
* setModifiers - set the attribute values related to modifiers here
*/
protected void setModifiers() {
Method methodTarget = (Method) getTarget();
int modifiers =
(getSourceAccessible() instanceof java.lang.reflect.Method)
? ((java.lang.reflect.Method) getSourceAccessible()).getModifiers()
: ((java.lang.reflect.Constructor) getSourceAccessible()).getModifiers();
methodTarget.setAbstract(java.lang.reflect.Modifier.isAbstract(modifiers));
methodTarget.setFinal(java.lang.reflect.Modifier.isFinal(modifiers));
methodTarget.setNative(java.lang.reflect.Modifier.isNative(modifiers));
methodTarget.setStatic(java.lang.reflect.Modifier.isStatic(modifiers));
methodTarget.setSynchronized(java.lang.reflect.Modifier.isSynchronized(modifiers));
methodTarget.setConstructor(getSourceAccessible() instanceof java.lang.reflect.Constructor);
// Set visibility
JavaClass javaClass = getContainingJavaClass();
if ((javaClass.getKind() == TypeKind.INTERFACE_LITERAL) || (java.lang.reflect.Modifier.isPublic(modifiers)))
methodTarget.setJavaVisibility(JavaVisibilityKind.PUBLIC_LITERAL);
else if (java.lang.reflect.Modifier.isPrivate(modifiers))
methodTarget.setJavaVisibility(JavaVisibilityKind.PRIVATE_LITERAL);
else if (java.lang.reflect.Modifier.isProtected(modifiers))
methodTarget.setJavaVisibility(JavaVisibilityKind.PROTECTED_LITERAL);
else
//Visibility must be package
methodTarget.setJavaVisibility(JavaVisibilityKind.PACKAGE_LITERAL);
}
/**
* setNaming - set the naming values here
* - qualified name must be set first, that is the path to the real Java class
* - ID
* - name-based UUID
*/
protected void setNaming() {
//
// naming is currently a no-op since the name and UUID must be set prior to reflection
// ...and ID is redundant with UUID.
// javaFieldTarget.setID(parent.getQualifiedName() + "_" + javaFieldTarget.getName());
}
/**
* setType - set our return type here
*/
protected void setReturnType() {
if (getSourceAccessible() instanceof java.lang.reflect.Method) {
Class type = ((java.lang.reflect.Method) getSourceAccessible()).getReturnType();
Method javaMethodTarget = (Method) getTarget();
/*
JavaParameter newParameter = createJavaParameter(javaMethodTarget, "result", getTypeName(type));//$NON-NLS-1$
newParameter.setParameterKind(MetaJavaParameterKind.RETURN);
javaMethodTarget.getParameters().add(newParameter);
*/
javaMethodTarget.setEType(createJavaClassRef(getTypeName(type)));
}
}
}