blob: cb546efa24635a2e7b8986f38f73a17d31b9f7fc [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2002, 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.gmf.runtime.diagram.core.services;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gmf.runtime.common.core.service.ExecutionStrategy;
import org.eclipse.gmf.runtime.common.core.service.IOperation;
import org.eclipse.gmf.runtime.common.core.service.Service;
import org.eclipse.gmf.runtime.diagram.core.internal.DiagramPlugin;
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
import org.eclipse.gmf.runtime.diagram.core.providers.IViewProvider;
import org.eclipse.gmf.runtime.diagram.core.providers.ViewProviderConfiguration;
import org.eclipse.gmf.runtime.diagram.core.services.view.CreateChildViewOperation;
import org.eclipse.gmf.runtime.diagram.core.services.view.CreateDiagramViewOperation;
import org.eclipse.gmf.runtime.diagram.core.services.view.CreateEdgeViewOperation;
import org.eclipse.gmf.runtime.diagram.core.services.view.CreateNodeViewOperation;
import org.eclipse.gmf.runtime.diagram.core.services.view.CreateViewForKindOperation;
import org.eclipse.gmf.runtime.diagram.core.services.view.CreateViewOperation;
import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter;
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.View;
/**
** A service for manipulating the notational models
* @author melaasar, mmostafa
*/
final public class ViewService
extends Service
implements IViewProvider {
/**
* A descriptor for <code>ISemanticProvider</code> defined
* by a configuration element.
*/
protected static class ProviderDescriptor
extends Service.ProviderDescriptor {
/** the provider configuration parsed from XML */
private ViewProviderConfiguration providerConfiguration;
/**
* Constructs a <code>ISemanticProvider</code> descriptor for
* the specified configuration element.
*
* @param element The configuration element describing the provider.
*/
public ProviderDescriptor(IConfigurationElement element) {
super(element);
this.providerConfiguration = ViewProviderConfiguration
.parse(element);
assert null != providerConfiguration : "Null providerConfiguration in ProviderDescriptor";//$NON-NLS-1$
}
/**
* @see org.eclipse.gmf.runtime.common.core.service.IProvider#provides(org.eclipse.gmf.runtime.common.core.service.IOperation)
*/
public boolean provides(IOperation operation) {
if (!policyInitialized){
policy = getPolicy();
policyInitialized = true;
}
if (policy != null)
return policy.provides(operation);
if (provider == null) {
if (isSupportedInExtention(operation)) {
providerConfiguration = null;
return getProvider().provides(operation);
}
return false;
}
return getProvider().provides(operation);
}
/**
* Cheks if the operation is supported by the XML extension
* @param operation
* @return
*/
private boolean isSupportedInExtention(IOperation operation) {
if (operation instanceof CreateViewOperation) {
CreateViewOperation o = (CreateViewOperation) operation;
Class viewKind = o.getViewKind();
IAdaptable semanticAdapter = o.getSemanticAdapter();
String semanticHint = o.getSemanticHint();
View containerView = null;
if (o instanceof CreateChildViewOperation) {
CreateChildViewOperation cvo = (CreateChildViewOperation) o;
containerView = cvo.getContainerView();
}
return providerConfiguration.supports(viewKind,
semanticAdapter, containerView, semanticHint);
}
return false;
}
/**
* the default implementation is overriden here to make it easier to debug
* XML providers, now when you select the ProviderDescriptor in the debug
* window the provider class name will be displayed
* @return the provider class name
*/
public String toString() {
return getElement().getAttribute("class"); //$NON-NLS-1$
//return (super.toString();
}
}
/**
* The singleton instance of the notation service.
*/
private final static ViewService instance = new ViewService();
static {
instance.configureProviders(DiagramPlugin.getPluginId(), "viewProviders"); //$NON-NLS-1$
}
/**
* Retrieves the singleton instance of the notation service.
*
* @return The notation service singleton.
*/
public static ViewService getInstance() {
return instance;
}
/**
* creates an instance
*/
protected ViewService() {
super(true, false);
}
/**
* @see org.eclipse.gmf.runtime.common.core.service.Service#newProviderDescriptor(org.eclipse.core.runtime.IConfigurationElement)
*/
protected Service.ProviderDescriptor newProviderDescriptor(
IConfigurationElement element) {
return new ProviderDescriptor(element);
}
/**
* @see org.eclipse.gmf.runtime.common.core.service.Service#createPriorityCache()
*/
protected Map createPriorityCache() {
return new HashMap();
}
/**
* @see org.eclipse.gmf.runtime.common.core.service.Service#getCacheKey(org.eclipse.gmf.runtime.common.core.service.IOperation)
*/
protected Object getCachingKey(IOperation operation) {
return ((CreateViewOperation) operation).getCachingKey();
}
/**
* Executes the specified operation using the FIRST execution
* strategy.
* @return The result of executing the model operation.
* @param operation The model operation to be executed.
*/
private Object execute(IOperation operation) {
List results = execute(ExecutionStrategy.FIRST, operation);
return results.isEmpty() ? null : results.get(0);
}
/**
* A convenience method to determine whether there is a provider
* that can create a view with the given parameters
* @param viewKind
* @param semanticAdapter adapts to either <code>Integer<code> or <code>IReference</code>
* @param containerView
* @param semanticHint
* @param index
* @param preferencesHint
* The preference hint that is to be used to find the appropriate
* preference store from which to retrieve diagram preference
* values. The preference hint is mapped to a preference store in
* the preference registry <@link DiagramPreferencesRegistry>.
* @return boolean
*/
public final boolean provides(Class viewKind, IAdaptable semanticAdapter,
View containerView, String semanticHint, int index,
boolean persisted, PreferencesHint preferencesHint) {
assert (viewKind == Diagram.class ||
viewKind == Edge.class ||
viewKind == Node.class ) :
"The default View service does not support " + viewKind.getName() + " as a view kind";//$NON-NLS-1$ //$NON-NLS-2$
/* if the semantic adapter adapters to the semantic kind */
if (semanticAdapter != null) {
if (semanticAdapter.getAdapter(CreateElementRequest.class) != null) {
return providerExistsFor(new CreateViewForKindOperation(
viewKind, semanticAdapter, containerView, semanticHint,
index, preferencesHint));
}
}
if (viewKind == Diagram.class)
return providerExistsFor(new CreateDiagramViewOperation(
semanticAdapter, semanticHint, preferencesHint));
else if (viewKind == Edge.class)
return providerExistsFor(new CreateEdgeViewOperation(
semanticAdapter, containerView, semanticHint, index, persisted, preferencesHint));
else if (viewKind == Node.class)
return providerExistsFor(new CreateNodeViewOperation(
semanticAdapter, containerView, semanticHint, index, persisted, preferencesHint));
return false;
}
private boolean providerExistsFor(IOperation operation) {
return provides(operation);
}
/**
* A convenience method to create a view with the given parameters
* @param viewKind
* @param semanticAdapter adapts to <code>IReference<code>
* @param containerView
* @param semanticHint
* @param index
* @param preferencesHint
* The preference hint that is to be used to find the appropriate
* preference store from which to retrieve diagram preference
* values. The preference hint is mapped to a preference store in
* the preference registry <@link DiagramPreferencesRegistry>.
* @return IView
*/
public final View createView(Class viewKind, IAdaptable semanticAdapter,
View containerView, String semanticHint, int index,
boolean persisted, PreferencesHint preferencesHint) {
assert (viewKind == Diagram.class ||
viewKind == Edge.class ||
viewKind == Node.class ) :
"The default View service does not support " + viewKind.getName() + " as a view kind";//$NON-NLS-1$ //$NON-NLS-2$
if (viewKind == Diagram.class)
return createDiagram(semanticAdapter, semanticHint, preferencesHint);
else if (viewKind == Edge.class)
return createEdge(semanticAdapter, containerView,
semanticHint, index, persisted, preferencesHint);
else if (viewKind == Node.class)
return createNode(semanticAdapter, containerView, semanticHint,
index, persisted, preferencesHint);
return null;
}
/* (non-Javadoc)
* @see org.eclipse.gmf.runtime.diagram.core.providers.IViewProvider#createDiagram(org.eclipse.core.runtime.IAdaptable, java.lang.String, org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint)
*/
public final Diagram createDiagram(IAdaptable semanticAdapter,
String diagramKindType, PreferencesHint preferencesHint) {
Diagram view = (Diagram) execute(new CreateDiagramViewOperation(
semanticAdapter, diagramKindType, preferencesHint));
return view;
}
/**
* Creates a diagram with the given context and kind
*
* @param context
* The diagram element context
* @param kind
* diagram kind, check {@link ViewType} for predefined values
* @param preferencesHint
* The preference hint that is to be used to find the appropriate
* preference store from which to retrieve diagram preference
* values. The preference hint is mapped to a preference store in
* the preference registry <@link DiagramPreferencesRegistry>.
* @return A newly created <code>Diagram</code>
*/
public static Diagram createDiagram(EObject context, String kind,
PreferencesHint preferencesHint) {
IAdaptable viewModel = (context != null) ? new EObjectAdapter(context)
: null;
String viewType = (kind != null) ? kind : ""; //$NON-NLS-1$
return ViewService.getInstance().createDiagram(viewModel, viewType,
preferencesHint);
}
/**
* Creates a diagram with a kind
* @param kind
* diagram kind, check {@link ViewType} for predefined values
* @param preferencesHint
* The preference hint that is to be used to find the appropriate
* preference store from which to retrieve diagram preference
* values. The preference hint is mapped to a preference store in
* the preference registry <@link DiagramPreferencesRegistry>.
* @return A newly created <code>Diagram</code>
*/
public static Diagram createDiagram(String kind,
PreferencesHint preferencesHint) {
return ViewService.createDiagram((EObject)null, kind,
preferencesHint);
}
/**
* Creates a node for a given eObject and with a given type and inserts it
* into a given container
*
* @param container
* The node view container
* @param eObject
* The node view object context
* @param type
* The node view type, check {@link ViewType} for predefined
* values
* @param preferencesHint
* The preference hint that is to be used to find the appropriate
* preference store from which to retrieve diagram preference
* values. The preference hint is mapped to a preference store in
* the preference registry <@link DiagramPreferencesRegistry>.
* @return A newly created <code>Node</code>
*/
public static Node createNode(View container, EObject eObject, String type,
PreferencesHint preferencesHint) {
assert null != container : "The container is null";//$NON-NLS-1$
IAdaptable viewModel = (eObject != null) ? new EObjectAdapter(eObject)
: null;
String viewType = (type != null) ? type : ""; //$NON-NLS-1$
View view = ViewService.getInstance().createNode(viewModel, container,
viewType, ViewUtil.APPEND, preferencesHint);
return (view != null) ? (Node) view : null;
}
/**
* Creates a node for a with a given type and inserts it thegiven container
*
* @param container
* The node view container
* @param type
* The node view type, check {@link ViewType} for predefined
* values
* @param preferencesHint
* The preference hint that is to be used to find the appropriate
* preference store from which to retrieve diagram preference
* values. The preference hint is mapped to a preference store in
* the preference registry <@link DiagramPreferencesRegistry>.
* @return A newly created <code>Node</code>
*/
public static Node createNode(View container,String type,
PreferencesHint preferencesHint) {
return ViewService.createNode(container,(EObject)null,type,
preferencesHint);
}
/**
* Creates an edge for a given eObject and with a given type and connects it
* between a given source and a given target
*
* @param source
* The edge's source view
* @param target
* The edge's target view
* @param eObject
* The edge view object context
* @param type
* The edge view type, check {@link ViewType} for predefined
* values
* @param preferencesHint
* The preference hint that is to be used to find the appropriate
* preference store from which to retrieve diagram preference
* values. The preference hint is mapped to a preference store in
* the preference registry <@link DiagramPreferencesRegistry>.
* @return A newly created <code>Edge</code>
*/
public static Edge createEdge(View source, View target, EObject eObject,
String type, PreferencesHint preferencesHint) {
assert source != null : "The source is null"; //$NON-NLS-1$
assert target != null : "The target is null"; //$NON-NLS-1$
assert source.getDiagram() !=null : "The source is detached"; //$NON-NLS-1$
assert target.getDiagram() !=null : "The target is detached"; //$NON-NLS-1$
IAdaptable viewModel = (eObject != null) ? new EObjectAdapter(eObject)
: null;
Edge edge = (Edge)ViewService.getInstance().createEdge(viewModel,source.getDiagram(),
type, ViewUtil.APPEND, preferencesHint);
if (edge != null) {
edge.setSource(source);
edge.setTarget(target);
}
return edge;
}
/**
* Creates an edge with a given type and connects it between the given
* source and target
*
* @param source
* The edge's source view
* @param target
* The edge's target view
* @param type
* The edge view type, check {@link ViewType} for predefined
* values
* @param preferencesHint
* The preference hint that is to be used to find the appropriate
* preference store from which to retrieve diagram preference
* values. The preference hint is mapped to a preference store in
* the preference registry <@link DiagramPreferencesRegistry>.
* @return A newly created <code>Edge</code>
*/
public static Edge createEdge(View source, View target,
String type, PreferencesHint preferencesHint) {
return ViewService.createEdge(source,target,(EObject)null,
type,preferencesHint);
}
/* (non-Javadoc)
* @see org.eclipse.gmf.runtime.diagram.core.providers.IViewProvider#createEdge(org.eclipse.core.runtime.IAdaptable, org.eclipse.gmf.runtime.notation.View, java.lang.String, int, boolean, org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint)
*/
public final Edge createEdge(IAdaptable semanticAdapter,
View containerView, String semanticHint, int index,
boolean persisted, PreferencesHint preferencesHint) {
Edge edge = (Edge) execute(new CreateEdgeViewOperation(
semanticAdapter, containerView, semanticHint, index, persisted, preferencesHint));
return edge;
}
/**
* @param semanticAdapter
* @param containerView
* @param semanticHint
* @param index
* @param preferencesHint
* The preference hint that is to be used to find the appropriate
* preference store from which to retrieve diagram preference
* values. The preference hint is mapped to a preference store in
* the preference registry <@link DiagramPreferencesRegistry>.
* @return
*/
public final View createEdge(IAdaptable semanticAdapter,
View containerView, String semanticHint, int index, PreferencesHint preferencesHint) {
return createEdge(semanticAdapter, containerView,
semanticHint, index, true, preferencesHint);
}
/**
* creates a persisted Node
* @param semanticElement
* @param containerView
* @param semanticHint
* @param index
* @param preferencesHint
* The preference hint that is to be used to find the appropriate
* preference store from which to retrieve diagram preference
* values. The preference hint is mapped to a preference store in
* the preference registry <@link DiagramPreferencesRegistry>.
* @return the created node
*/
public final Node createNode(IAdaptable semanticElement,
View containerView, String semanticHint, int index, PreferencesHint preferencesHint) {
return createNode(semanticElement, containerView, semanticHint,
index, true, preferencesHint);
}
/**
* creates a Node
* @param semanticElement
* @param containerView
* @param semanticHint
* @param persisted
* @param index
* @param preferencesHint
* The preference hint that is to be used to find the appropriate
* preference store from which to retrieve diagram preference
* values. The preference hint is mapped to a preference store in
* the preference registry <@link DiagramPreferencesRegistry>.
* @return the created node
*/
public Node createNode(IAdaptable semanticAdapter,
View containerView, String semanticHint, int index,
boolean persisted, PreferencesHint preferencesHint) {
Node node = (Node) execute(new CreateNodeViewOperation(
semanticAdapter, containerView, semanticHint, index, persisted, preferencesHint));
return node;
}
}