/******************************************************************************* * 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))); } } }