| /****************************************************************************** |
| * 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; |
| } |
| } |