/** * Copyright (c) 2002-2010 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 - Initial API and implementation */ package org.eclipse.emf.edit.provider; import java.util.HashMap; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.edit.EMFEditPlugin; /** * This abstract class provides support for creating {@link IItemProviderDecorator}s * for the adapters created by another {@link AdapterFactory}. */ public abstract class DecoratorAdapterFactory implements AdapterFactory, ComposeableAdapterFactory, IChangeNotifier, IDisposable { protected HashMap<Object, IItemProviderDecorator> itemProviderDecorators = new HashMap<Object, IItemProviderDecorator>(); /** * This keeps the {@link org.eclipse.emf.common.notify.AdapterFactory} being decorated. */ protected AdapterFactory decoratedAdapterFactory; /** * This is used to implement the {@link ComposeableAdapterFactory} interface. */ protected ComposedAdapterFactory parentAdapterFactory; /** * This keeps track of all the Viewers. */ protected ChangeNotifier changeNotifier = new ChangeNotifier(); /** * This creates an instance that decorates the adapters from the given adapter factory. */ public DecoratorAdapterFactory(AdapterFactory decoratedAdapterFactory) { this.decoratedAdapterFactory = decoratedAdapterFactory; } /** * This just delegates to the {@link #decoratedAdapterFactory}. */ public boolean isFactoryForType(Object type) { return decoratedAdapterFactory.isFactoryForType(type); } /** * This returns the adapter factory whose adapters are being decorated. */ public AdapterFactory getDecoratedAdapterFactory() { return decoratedAdapterFactory; } /** * This sets the adapter factory whose adapters will be decorated. */ public void setDecoratedAdapterFactory(AdapterFactory decoratedAdapterFactory) { this.decoratedAdapterFactory = decoratedAdapterFactory; } /** * This is called when a new decorator is needed by {@link #adapt(Object,Object)}. */ protected abstract IItemProviderDecorator createItemProviderDecorator(Object target, Object Type); /** * All adapter creation is delegated to this method, which yields decorated item providers. * It hooks up the decorators created by {@link #createItemProviderDecorator} * to the adapters returned by {@link #decoratedAdapterFactory}. */ public Object adapt(Object target, Object type) { Object adapter = decoratedAdapterFactory.adapt(target, type); if (adapter instanceof IChangeNotifier) { IItemProviderDecorator itemProviderDecorator = itemProviderDecorators.get(adapter); if (itemProviderDecorator == null) { itemProviderDecorator = createItemProviderDecorator(target, type); itemProviderDecorators.put(adapter, itemProviderDecorator); itemProviderDecorator.setDecoratedItemProvider((IChangeNotifier)adapter); } return itemProviderDecorator; } return adapter; } /** * This delegates to {@link #adapt(Object,Object)} */ public Adapter adapt(Notifier target, Object type) { return (Adapter)adapt((Object)target, type); } /** * This interface is not support; an exception will be thrown. */ public Adapter adaptNew(Notifier target, Object type) { throw new RuntimeException (EMFEditPlugin.INSTANCE.getString ("_EXC_Method_not_implemented", new Object [] { this.getClass() + "adaptNew(Notifier target, Object type)" })); } public void adaptAllNew(Notifier target) { decoratedAdapterFactory.adaptAllNew(target); } /** * This returns the root adapter factory that delegates to this factory. */ public ComposeableAdapterFactory getRootAdapterFactory() { return parentAdapterFactory == null ? this : parentAdapterFactory.getRootAdapterFactory(); } /** * This sets the direct parent adapter factory into which this factory is composed. */ public void setParentAdapterFactory(ComposedAdapterFactory parentAdapterFactory) { this.parentAdapterFactory = parentAdapterFactory; } public void addListener(INotifyChangedListener notifyChangedListener) { changeNotifier.addListener(notifyChangedListener); } public void removeListener(INotifyChangedListener notifyChangedListener) { changeNotifier.removeListener(notifyChangedListener); } public void fireNotifyChanged(Notification notification) { changeNotifier.fireNotifyChanged(notification); if (parentAdapterFactory != null) { parentAdapterFactory.fireNotifyChanged(notification); } } public void dispose() { for (Object object : itemProviderDecorators.values()) { if (object instanceof IDisposable) { ((IDisposable)object).dispose(); } } } }