blob: 6262b082211db38849918e213fa551d7f7cfd046 [file] [log] [blame]
/**
* Copyright (c) 2011 Eike Stepper (Berlin, Germany) 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:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.emf.ecp.spi.core;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecp.core.ECPProject;
import org.eclipse.emf.ecp.core.ECPProjectManager;
import org.eclipse.emf.ecp.core.ECPProvider;
import org.eclipse.emf.ecp.core.ECPRepository;
import org.eclipse.emf.ecp.core.ECPRepositoryManager;
import org.eclipse.emf.ecp.core.util.ECPModelContext;
import org.eclipse.emf.ecp.core.util.ECPModelContextAdapter;
import org.eclipse.emf.ecp.core.util.ECPModelContextProvider;
import org.eclipse.emf.ecp.core.util.ECPUtil;
import org.eclipse.emf.ecp.internal.core.util.Disposable;
import org.eclipse.emf.ecp.internal.core.util.Element;
import org.eclipse.emf.ecp.spi.core.util.AdapterProvider;
import org.eclipse.emf.ecp.spi.core.util.InternalChildrenList;
import org.eclipse.emf.ecp.spi.core.util.ModelWrapper;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Platform;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @author Eike Stepper
*/
public class DefaultProvider extends Element implements InternalProvider
{
private final Disposable disposable = new Disposable(this)
{
@Override
protected void doDispose()
{
uiProvider = null;
for (ECPRepository repository : ECPRepositoryManager.INSTANCE.getRepositories())
{
if (repository.getProvider().getName().equals(getName()))
{
handleLifecycle(repository, LifecycleEvent.DISPOSE);
}
}
for (ECPProject project : ECPProjectManager.INSTANCE.getProjects())
{
if (project.getProvider().getName().equals(getName()))
{
handleLifecycle(project, LifecycleEvent.DISPOSE);
}
}
DefaultProvider.this.doDispose();
}
};
private String label;
private String description;
private AdapterProvider uiProvider;
protected DefaultProvider(String name)
{
super(name);
label = name;
description = "";
}
public String getType()
{
return TYPE;
}
public final InternalProvider getProvider()
{
return this;
}
public final String getLabel()
{
return label;
}
public final void setLabel(String label)
{
this.label = label;
}
public final String getDescription()
{
return description;
}
public final void setDescription(String description)
{
this.description = description;
}
public final AdapterProvider getUIProvider()
{
return uiProvider;
}
public final void setUIProvider(AdapterProvider uiProvider)
{
this.uiProvider = uiProvider;
}
public <T> T getAdapter(Object adaptable, Class<T> adapterType)
{
if (uiProvider != null)
{
return uiProvider.getAdapter(adaptable, adapterType);
}
return null;
}
/**
* Returns an object which is an instance of the given class associated with this object. Returns <code>null</code> if
* no such object can be found.
* <p>
* This implementation of the method declared by <code>IAdaptable</code> passes the request along to the platform's
* adapter manager; roughly <code>Platform.getAdapterManager().getAdapter(this, adapter)</code>. Subclasses may
* override this method (however, if they do so, they should invoke the method on their superclass to ensure that the
* Platform's adapter manager is consulted).
* </p>
*
* @param adapterType
* the class to adapt to
* @return the adapted object or <code>null</code>
* @see IAdaptable#getAdapter(Class)
*/
public Object getAdapter(@SuppressWarnings("rawtypes") Class adapterType)
{
return Platform.getAdapterManager().getAdapter(this, adapterType);
}
public final InternalRepository[] getAllRepositories()
{
List<InternalRepository> result = new ArrayList<InternalRepository>();
for (ECPRepository repository : ECPRepositoryManager.INSTANCE.getRepositories())
{
if (!ECPUtil.isDisposed(repository))
{
ECPProvider provider = repository.getProvider();
if (provider.equals(this))
{
result.add((InternalRepository)repository);
}
}
}
// TODO Consider to cache the result
return result.toArray(new InternalRepository[result.size()]);
}
public final InternalProject[] getOpenProjects()
{
List<InternalProject> result = new ArrayList<InternalProject>();
for (ECPProject project : ECPProjectManager.INSTANCE.getProjects())
{
if (project.isOpen())
{
ECPRepository repository = project.getRepository();
if (!ECPUtil.isDisposed(repository))
{
if (repository.getProvider().equals(this))
{
result.add((InternalProject)project);
}
}
}
}
// TODO Consider to cache the result
return result.toArray(new InternalProject[result.size()]);
}
public final boolean isDisposed()
{
return disposable.isDisposed();
}
public final void dispose()
{
disposable.dispose();
}
public final void addDisposeListener(DisposeListener listener)
{
disposable.addDisposeListener(listener);
}
public final void removeDisposeListener(DisposeListener listener)
{
disposable.removeDisposeListener(listener);
}
protected void doDispose()
{
}
public EditingDomain createEditingDomain(InternalProject project)
{
CommandStack commandStack = createCommandStack(project);
EditingDomain editingDomain = new AdapterFactoryEditingDomain(InternalProvider.EMF_ADAPTER_FACTORY, commandStack);
editingDomain.getResourceSet().eAdapters().add(new ECPModelContextAdapter(project));
return editingDomain;
}
protected CommandStack createCommandStack(InternalProject project)
{
return new BasicCommandStack();
}
public boolean canAddRepositories()
{
return true;
}
public boolean isSlow(Object parent)
{
return false;
}
public ECPModelContext getModelContext(Object element)
{
if (element instanceof ECPModelContext)
{
return (ECPModelContext)element;
}
if (element instanceof ECPModelContextProvider)
{
return ((ECPModelContextProvider)element).getModelContext(element);
}
if (element instanceof ModelWrapper)
{
return ((ModelWrapper<?, ?>)element).getContext();
}
if (element instanceof EObject)
{
EObject eObject = (EObject)element;
ECPModelContext context = getModelContextFromAdapter(eObject);
if (context != null)
{
return context;
}
element = eObject.eResource();
}
if (element instanceof Resource)
{
Resource resource = (Resource)element;
ECPModelContext context = getModelContextFromAdapter(resource);
if (context != null)
{
return context;
}
element = resource.getResourceSet();
}
if (element instanceof ResourceSet)
{
ResourceSet resourceSet = (ResourceSet)element;
ECPModelContext context = getModelContextFromAdapter(resourceSet);
if (context != null)
{
return context;
}
}
return null;
}
private ECPModelContext getModelContextFromAdapter(Notifier notifier)
{
ECPModelContextAdapter adapter = (ECPModelContextAdapter)EcoreUtil.getAdapter(notifier.eAdapters(),
ECPModelContextAdapter.class);
if (adapter != null)
{
return adapter.getContext();
}
return null;
}
public void fillChildren(ECPModelContext context, Object parent, InternalChildrenList childrenList)
{
if (parent == ECPProjectManager.INSTANCE)
{
childrenList.addChildren(ECPProjectManager.INSTANCE.getProjects());
}
else if (parent == ECPRepositoryManager.INSTANCE)
{
childrenList.addChildren(ECPRepositoryManager.INSTANCE.getRepositories());
}
else
{
// Get the adapter from the factory.
ITreeItemContentProvider treeItemContentProvider = (ITreeItemContentProvider)EMF_ADAPTER_FACTORY.adapt(parent,
ITreeItemContentProvider.class);
// Either delegate the call or return nothing.
if (treeItemContentProvider != null)
{
Collection<?> children = treeItemContentProvider.getChildren(parent);
childrenList.addChildren(children);
}
}
}
public void handleLifecycle(ECPModelContext context, LifecycleEvent event)
{
// TODO Trace properly
String providerClass = getClass().getSimpleName();
String contextClass = context.getClass().getSimpleName();
System.out.println(providerClass + " received " + event + " for " + contextClass + " " + context);
}
}