/******************************************************************************* * Copyright (c) 2001, 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 java.util.logging.Level; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.xmi.XMIResource; import org.eclipse.jem.internal.java.adapters.IJavaClassAdaptor; import org.eclipse.jem.internal.java.adapters.nls.ResourceHandler; import org.eclipse.jem.java.*; import org.eclipse.jem.java.internal.impl.JavaClassImpl; import org.eclipse.jem.util.logger.proxy.Logger; /** * Reflect the class using standard java.reflect methods. * Creation date: (6/6/2000 4:42:50 PM) * @author: Administrator */ public class JavaClassJDKAdaptor extends JDKAdaptor implements IJavaClassAdaptor { protected Class sourceType = null; public JavaClassJDKAdaptor(Notifier target, JavaJDKAdapterFactory anAdapterFactory) { super(target, anAdapterFactory); } /** * addFields - reflect our fields */ protected void addFields() { XMIResource resource = (XMIResource) getJavaClassTarget().eResource(); List targetFields = getJavaClassTarget().getFieldsGen(); targetFields.clear(); java.lang.reflect.Field[] fields = {}; try { fields = getSourceType().getDeclaredFields(); } catch (NoClassDefFoundError error) { System.out.println(ResourceHandler.getString( "Could_Not_Reflect_Fields_ERROR_", new Object[] { getJavaClassTarget().getQualifiedName(), error.getMessage()})); //$NON-NLS-1$ } for (int i = 0; i < fields.length; i++) { targetFields.add(createJavaField(fields[i], resource)); } } /** * addMethods - reflect our methods */ protected void addMethods() { // We need to first do methods and then do constructors because the JDK treats them as two // different objects, which the Java Model treats them as both Method's. XMIResource resource = (XMIResource) getJavaClassTarget().eResource(); List targetMethods = getJavaClassTarget().getMethodsGen(); targetMethods.clear(); java.lang.reflect.Method[] methods = {}; try { methods = getSourceType().getDeclaredMethods(); } catch (NoClassDefFoundError error) { Logger logger = Logger.getLogger(); if (logger.isLoggingLevel(Level.WARNING)) { logger .log( ResourceHandler .getString( "Could_Not_Reflect_Methods_ERROR_", new Object[] { getJavaClassTarget().getQualifiedName(), error.toString()}), Level.WARNING); //$NON-NLS-1$ } } for (int i = 0; i < methods.length; i++) { targetMethods.add(createJavaMethod(methods[i], resource)); } // Now do the constructors java.lang.reflect.Constructor[] ctors = {}; try { ctors = getSourceType().getDeclaredConstructors(); } catch (NoClassDefFoundError error) { Logger logger = Logger.getLogger(); if (logger.isLoggingLevel(Level.WARNING)) { logger .log( ResourceHandler .getString( "Could_Not_Reflect_Constructors_ERROR_", new Object[] { getJavaClassTarget().getQualifiedName(), error.getMessage()}), Level.WARNING); //$NON-NLS-1$ } } for (int i = 0; i < ctors.length; i++) { targetMethods.add(createJavaMethod(ctors[i], resource)); } } /** * Clear the reflected fields list. */ protected boolean flushFields() { getJavaClassTarget().getFieldsGen().clear(); return true; } /** * Clear the implements list. */ protected boolean flushImplements() { getJavaClassTarget().getImplementsInterfacesGen().clear(); return true; } /** * Clear the reflected methods list. */ protected boolean flushMethods() { getJavaClassTarget().getMethodsGen().clear(); return true; } protected boolean flushInnerClasses() { getJavaClassTarget().getDeclaredClassesGen().clear(); return true; } protected boolean flushModifiers() { JavaClass javaClassTarget = (JavaClass) getTarget(); javaClassTarget.setAbstract(false); javaClassTarget.setFinal(false); javaClassTarget.setPublic(false); javaClassTarget.setKind(TypeKind.UNDEFINED_LITERAL); return true; } /** * @see org.eclipse.jem.java.adapters.JavaReflectionAdaptor#flushReflectedValues(boolean) */ protected boolean flushReflectedValues(boolean clearCachedModelObject) { boolean result = flushModifiers(); result &= flushSuper(); result &= flushImplements(); result &= flushMethods(); result &= flushFields(); result &= flushInnerClasses(); return result; } /** * @see org.eclipse.jem.java.adapters.JavaReflectionAdaptor#postFlushReflectedValuesIfNecessary() */ protected void postFlushReflectedValuesIfNecessary(boolean isExisting) { getJavaClassTarget().setReflected(false); super.postFlushReflectedValuesIfNecessary(isExisting); } /** * Set the supertype to be null. */ protected boolean flushSuper() { List targetSupers = getJavaClassTarget().primGetESuperTypes(); targetSupers.clear(); return true; } /** * Return the target typed to a JavaClass. */ protected JavaClassImpl getJavaClassTarget() { return (JavaClassImpl) getTarget(); } public Object getReflectionSource() { return getSourceType(); } /* (non-Javadoc) * @see org.eclipse.jem.internal.java.adapters.JavaReflectionAdaptor#hasReflectionSource() */ public boolean hasCachedReflectionSource() { return sourceType != null; } /** * getSourceType - return the java.lang.Class which describes our existing Java class */ protected Class getSourceType() { if (sourceType == null) { sourceType = getType((JavaClass) getTarget()); } return sourceType; } /** * 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); } /** * Return true if the sourceType is null or if it is a binary type. Reflection from the JDK is always from binary. */ public boolean isSourceTypeFromBinary() { return true; } /** * reflectValues - template method, subclasses override to pump values into target. on entry: name, containing package (and qualified name), and * document must be set. Return true if successful JavaClass adaptor: - set modifiers - set name - set reference to super - create methods - * create fields - add imports */ public boolean reflectValues() { super.reflectValues(); try { if (getSourceType() != null) { setModifiers(); setNaming(); try { setSuper(); } catch (InheritanceCycleException e) { Logger.getLogger().log(e); } setImplements(); addMethods(); addFields(); reflectInnerClasses(); setDeclaringClass(); getAdapterFactory().registerReflection(getSourceType().getName(), this); // addImports(); return true; } return false; } finally { //Don't cache the class beyond the operation of reflect values; //this enables dynamic swapping of the alternate class loader //for java reflection, as well as avoids potential memory leakage sourceType = null; } } protected void setDeclaringClass() { Class declaringType = getSourceType().getDeclaringClass(); if (declaringType != null) { // Need to get it and reflect it so that the declared type of this target is set correctly. We can just // set it ourselves directly because ECore would try to add it to the list of inner classes of the declaring type. This // would cause it to be added twice, once from the reflection caused by the inverse setting, and once from our doing // the inverse setting itself. ResourceSet set = getTargetResource().getResourceSet(); JavaClassImpl declaringClass = (JavaClassImpl) JavaRefFactory.eINSTANCE.reflectType(declaringType.getName(), set); declaringClass.getDeclaredClasses(); // This will cause it to put us into its list and also set our declaring class to this declaring type. } } /** * */ protected void reflectInnerClasses() { Class[] innerClasses = getSourceType().getClasses(); if (innerClasses.length != 0) { List declaredClasses = getJavaClassTarget().getDeclaredClassesGen(); JavaClass inner; ResourceSet set = getTargetResource().getResourceSet(); for (int i = 0; i < innerClasses.length; i++) { inner = (JavaClass) JavaRefFactory.eINSTANCE.reflectType(innerClasses[i].getName(), set); declaredClasses.add(inner); } } } /** * setImplements - set our implemented/super interfaces here For an interface, these are superclasses. For a class, these are implemented * interfaces. */ protected void setImplements() { Class[] interfaces = getSourceType().getInterfaces(); // needs work, the names above will be simple names if we are relfecting from a source file JavaClassImpl javaClassTarget = (JavaClassImpl) getTarget(); JavaClass ref; List intList = javaClassTarget.getImplementsInterfacesGen(); intList.clear(); for (int i = 0; i < interfaces.length; i++) { ref = createJavaClassRef(interfaces[i].getName()); intList.add(ref); } } /** * setModifiers - set the attribute values related to modifiers here */ protected void setModifiers() { JavaClass javaClassTarget = (JavaClass) getTarget(); javaClassTarget.setAbstract(java.lang.reflect.Modifier.isAbstract(getSourceType().getModifiers())); javaClassTarget.setFinal(java.lang.reflect.Modifier.isFinal(getSourceType().getModifiers())); javaClassTarget.setPublic(java.lang.reflect.Modifier.isPublic(getSourceType().getModifiers())); // Set type to class or interface, not yet handling EXCEPTION if (getSourceType().isInterface()) javaClassTarget.setKind(TypeKind.INTERFACE_LITERAL); else javaClassTarget.setKind(TypeKind.CLASS_LITERAL); } /** * setNaming - set the naming values here - qualified name (package name + name) must be set first, that is the path to the real Java class - ID - * simple name, identity within a package document - NO UUID!!! */ protected void setNaming() { // JavaClass javaClassTarget = (JavaClass) getTarget(); // javaClassTarget.refSetUUID((String) null); // ((XMIResource)javaClassTarget.eResource()).setID(javaClassTarget,getSimpleName(getSourceType().getName())); } /** * setSuper - set our supertype here, implemented interface are handled separately */ protected void setSuper() throws InheritanceCycleException { Class superClass = null; superClass = getSourceType().getSuperclass(); if (superClass != null) { JavaClass javaClassTarget = (JavaClass) getTarget(); javaClassTarget.setSupertype(createJavaClassRef(superClass.getName())); } } /** * Return true if the sourceType can be found. */ public boolean sourceTypeExists() { return getSourceType() != null; } public boolean reflectFieldsIfNecessary() { return reflectValuesIfNecessary(); } public boolean reflectMethodsIfNecessary() { return reflectValuesIfNecessary(); } }