/******************************************************************************* * 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; /* */ import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.jem.java.JavaRefPackage; public abstract class JavaReflectionAdapterFactory extends AdapterFactoryImpl { // Maintain a mapping of the source objects to the adaptors which have // relfected from them. This allows a flush operation to force those // adapters to re-reflect. protected HashMap reflected = new HashMap(); /** * Key for the type of adapters that this factory creates. (Used in isFactoryForType()). */ public static final String TYPE_KEY = ReadAdaptor.TYPE_KEY; protected boolean isBusyIteratingReflected = false; protected Map registerQueue; protected List unregisterQueue; /** * JavaReflectionAdapterFactory constructor comment. */ public JavaReflectionAdapterFactory() { super(); } public Adapter createAdapter(Notifier target) { ReflectionAdaptor adapter = null; EObject object = (EObject) target; JavaRefPackage pack = getJavaRefPackage(); if (object.eClass() == pack.getJavaClass()) adapter = createJavaClassAdaptor(target); else if (object.eClass() == pack.getArrayType()) adapter = createArrayTypeAdaptor(target); else if (object.eClass() == pack.getMethod()) adapter = createJavaMethodAdaptor(target); else if (object.eClass() == pack.getField()) adapter = createJavaFieldAdaptor(target); return adapter; } protected ReflectionAdaptor createArrayTypeAdaptor(Notifier target) { return new JavaArrayTypeReflectionAdapter(target); } protected abstract ReflectionAdaptor createJavaClassAdaptor(Notifier target) ; protected abstract ReflectionAdaptor createJavaFieldAdaptor(Notifier target) ; protected abstract ReflectionAdaptor createJavaMethodAdaptor(Notifier target) ; // Flush the adapter for a source object public Notification disAssociateSource(String source) { return disAssociateSource(source, true); } public Notification disAssociateSource(String source, boolean doNotify) { JavaReflectionAdaptor a = (JavaReflectionAdaptor) reflected.get(source); Notification notification = null; if (a != null) { if (doNotify) a.releaseSourceType(); else notification = a.releaseSourceTypeNoNotification(); } return notification; } public void flushAll() {} // Flush the adapter for a source object public void flushReflection(String source) {} protected JavaRefPackage getJavaRefPackage() { return (JavaRefPackage) EPackage.Registry.INSTANCE.getEPackage(JavaRefPackage.eNS_URI); } public void registerReflection(String source, ReflectionAdaptor adapter) { if (isBusyIteratingReflected) { if (registerQueue == null) registerQueue = new HashMap(); registerQueue.put(source, adapter); } else reflected.put(source, adapter); } public void unregisterReflection(String source) { if (isBusyIteratingReflected) { if (unregisterQueue == null) unregisterQueue = new ArrayList(); unregisterQueue.add(source); } else reflected.remove(source); } public void disAssociateSourcePlusInner(String source) { disAssociateSourcePlusInner(source, true); } public Notification disAssociateSourcePlusInner(String source, boolean doNotify) { isBusyIteratingReflected = true; Notification notification = null; try { String innerName = source + '$'; Iterator it = reflected.entrySet().iterator(); Map.Entry entry; String key; JavaReflectionAdaptor adaptor; while (it.hasNext()) { entry = (Map.Entry) it.next(); key = (String) entry.getKey(); if (key.equals(source) || key.startsWith(innerName)) { adaptor = (JavaReflectionAdaptor) reflected.get(key); if (adaptor != null) { if (doNotify) adaptor.releaseSourceType(); else notification = adaptor.releaseSourceTypeNoNotification(); } } } } finally { finishedIteratingReflected(); } return notification; } protected void finishedIteratingReflected() { isBusyIteratingReflected = false; if (unregisterQueue != null && !unregisterQueue.isEmpty()) { for (int i = 0; i < unregisterQueue.size(); i++) { reflected.remove(unregisterQueue.get(i)); } unregisterQueue.clear(); } if (registerQueue != null && !registerQueue.isEmpty()) { Iterator it = registerQueue.entrySet().iterator(); Map.Entry entry; while (it.hasNext()) { entry = (Map.Entry) it.next(); reflected.put(entry.getKey(), entry.getValue()); } registerQueue.clear(); } } public boolean isFactoryForType(Object type) { return TYPE_KEY.equals(type); } }