/******************************************************************************* * Copyright (c) 2001, 2006 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; /* */ import java.util.logging.Level; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.ecore.*; import org.eclipse.emf.ecore.impl.ENotificationImpl; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.jem.internal.core.JEMPlugin; import org.eclipse.jem.internal.java.adapters.nls.ResourceHandler; import org.eclipse.jem.util.logger.proxy.Logger; /** * ReflectionAdaptor - a read adaptor base implementation which does a bulk * load of relflected values on the first request. * Subclasses can optimize to defer some properties. * Properties may also be deferred by setting their values with proxy references, * for example, for supertype and other referenced types. * Creation date: (6/6/2000 4:42:50 PM) * @author: Administrator */ public abstract class ReflectionAdaptor extends org.eclipse.emf.common.notify.impl.AdapterImpl implements ReadAdaptor { public static final char C_CLASS_MEMBER_DELIMITER = '.'; public static final char C_METHOD_PARM_DELIMITER = '('; public static final char C_METHODID_PARMID_DELIMITER = '-'; public static final char C_PARM_PARM_DELIMITER = ','; public static final char PATH_DELIMITER = '/'; // SW id contains & in xml file casues exception throw during load // public static final String S_CONSTRUCTOR_TOKEN = "&V";//$NON-NLS-1$ public static final String S_CONSTRUCTOR_TOKEN = "_V";//$NON-NLS-1$ // SW // cache a static empty String[] for no parm methods protected static String[] emptyStringArray = new String[0]; /** * Notification event type for special Reflection notifications. This will be the event type for the special ones, like REFLECTION_EVENT. * The listener should listen for this event type, and then check the feature for the type of special event (like REFLECTION_EVENT). * @since 1.1.0 */ public static final int EVENT = -3456; // Using a funny number to try to eliminate confliction with any other specials that may of occur from other code on the JavaClass. /** * Special notification event type. This is sent against a JavaClass (as the target) whenever reflection occurs. It will be * sent under the notification event type of REFLECTION_EVENT. * @since 1.1.0 */ public static final EAttribute REFLECTION_EVENT = EcoreFactory.eINSTANCE.createEAttribute(); /* * Fill in the name. Not really needed but it would be nice. */ static {REFLECTION_EVENT.setName("reflectValues");} //$NON-NLS-1$ protected boolean hasReflected = false; protected boolean isReflecting = false; public ReflectionAdaptor() { super(); } public ReflectionAdaptor(Notifier target) { super(); setTarget(target); } /** * Helper method to ensure full initialization of the target. Required * for serialization. */ public static void forceDeferredReadFor(EObject target) { ReflectionAdaptor adaptor = retrieveAdaptorFrom(target); if (adaptor != null) { adaptor.reflectValuesIfNecessary(); } } protected Resource getTargetResource() { if (getTarget() != null) return ((org.eclipse.emf.ecore.EObject) getTarget()).eResource(); return null; } /** * Helper method to fetch the adaptor from the object, and if it exists, get the adapted * value for the attribute. Overloaded for many-sided attributes where the return value would * otherwise be an enumeration; in this case will return an Array instead. */ public static Object getValue(EObject object, EReference attribute) { //FB ReflectionAdaptor adaptor = retrieveAdaptorFrom(object); //FB if (adaptor != null) //FB return adaptor.getValueIn(object, attribute); //FB return ((IReadAdaptable) object).primRefValue(attribute); return object.eGet(attribute); //FB } /*Helper method to fetch the adaptor from the object, and if it exists, get the adapted *value for the attribute. */ public static Object getValue(EObject object, EObject attribute) { //FB ReflectionAdaptor adaptor = retrieveAdaptorFrom(object); //FB if (adaptor != null) //FB return adaptor.getValueIn(object, attribute); //FB return ((IReadAdaptable) object).primRefValue(attribute); return object.eGet((EStructuralFeature)attribute); //FB } /** * getValueIn method comment. */ public Object getValueIn(EObject object, EObject attribute) { //FB reflectValuesIfNecessary(); //FB return ((IReadAdaptable) object).primRefValue(attribute); return object.eGet((EStructuralFeature)attribute); //FB } /** * isAdaptorForType method comment. */ public boolean isAdapterForType(Object type) { return (type == ReadAdaptor.TYPE_KEY); } /** * reflectValues - template method, subclasses override to pump values into target */ public abstract boolean reflectValues(); /** * Return a boolean indicating whether reflection had occurred. */ public synchronized boolean reflectValuesIfNecessary() { if (!hasReflected && !isReflecting) { try { isReflecting = true; EObject etarget = (EObject)getTarget(); if (!etarget.eIsProxy() && etarget.eResource() != null && etarget.eResource().getResourceSet() != null) hasReflected = reflectValues(); else hasReflected = false; // AS long we are a proxy or is not in a valid resource or set, we won't reflect. } catch (Exception e) { hasReflected = false; Logger logger = Logger.getLogger(); if (logger.isLoggingLevel(Level.WARNING)) { logger.log(ResourceHandler.getString("Failed_reflecting_values_ERROR_"), Level.WARNING); //$NON-NLS-1$ = "Failed reflecting values!!!" logger.logWarning(e); JEMPlugin.logWarning(ResourceHandler.getString("Failed_reflecting_values_ERROR_"), e); } } finally { isReflecting = false; getTarget().eNotify(new ENotificationImpl((InternalEObject)getTarget(), EVENT, REFLECTION_EVENT, null, null, Notification.NO_INDEX)); } } return hasReflected; } public static ReflectionAdaptor retrieveAdaptorFrom(EObject object) { synchronized (object) { return (ReflectionAdaptor)EcoreUtil.getRegisteredAdapter(object, ReadAdaptor.TYPE_KEY); } } }