diff options
Diffstat (limited to 'plugins/infra/core/org.eclipse.papyrus.infra.core/src')
46 files changed, 6500 insertions, 6500 deletions
diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/IElementWithSemantic.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/IElementWithSemantic.java index 0be681e1237..8dfa9d89fb7 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/IElementWithSemantic.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/IElementWithSemantic.java @@ -1,34 +1,34 @@ -/*****************************************************************************
- * Copyright (c) 2010 CEA LIST.
- *
- *
- * 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:
- * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
- */
-package org.eclipse.papyrus.infra.core;
-
-/**
- *
- * all implementation is used to give the semantic element form a wrapper
- *
- * the implementation can call method getAdapter for example for notation
- * element return semantic element, for edit part return the semantic element
- * and not the view...
- */
-public interface IElementWithSemantic {
-
- /**
- * return the semantic element linked to this wrapper
- *
- * @param wrapper
- * an object that wrapped or are linked to a semantic element
- * <B>cannot be null</B>
- * @return null or the semantic element
- */
- public Object getSemanticElement(Object wrapper);
-}
+/***************************************************************************** + * Copyright (c) 2010 CEA LIST. + * + * + * 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: + * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation + */ +package org.eclipse.papyrus.infra.core; + +/** + * + * all implementation is used to give the semantic element form a wrapper + * + * the implementation can call method getAdapter for example for notation + * element return semantic element, for edit part return the semantic element + * and not the view... + */ +public interface IElementWithSemantic { + + /** + * return the semantic element linked to this wrapper + * + * @param wrapper + * an object that wrapped or are linked to a semantic element + * <B>cannot be null</B> + * @return null or the semantic element + */ + public Object getSemanticElement(Object wrapper); +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/clipboard/ICopierFactory.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/clipboard/ICopierFactory.java index 66a0d710d86..db4d759ccd3 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/clipboard/ICopierFactory.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/clipboard/ICopierFactory.java @@ -1,130 +1,130 @@ -/*****************************************************************************
- * Copyright (c) 2016 Christian W. Damus 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:
- * Christian W. Damus - Initial API and implementation
- *
- *****************************************************************************/
-
-package org.eclipse.papyrus.infra.core.clipboard;
-
-import java.util.function.BiPredicate;
-import java.util.function.Supplier;
-
-import org.eclipse.emf.ecore.EFactory;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
-import org.eclipse.papyrus.infra.core.internal.clipboard.CopierFactory;
-
-/**
- * An extensible factory for EMF {@link Copier}s used for copy/paste
- * operations in Papyrus. Extensions are registered on the
- * {@code org.eclipse.papyrus.infra.core.copier} extension point.
- *
- * @since 3.0
- *
- * @see EcoreUtil.Copier
- */
-@FunctionalInterface
-public interface ICopierFactory extends Supplier<EcoreUtil.Copier> {
-
- /**
- * Obtains a copier factory suitable for most copy/paste operations.
- * The result is configured from the extension point.
- *
- * @param resourceSet
- * a resource set context in which to look for registered
- * {@link EFactory} instances for creation of new objects
- * @return a copier factory
- */
- static ICopierFactory getInstance(ResourceSet resourceSet) {
- return getInstance(resourceSet, true);
- }
-
- /**
- * Obtains a copier factory with the option of not using original references.
- * The result is configured from the extension point.
- *
- * @param resourceSet
- * a resource set context in which to look for registered
- * {@link EFactory} instances for creation of new objects
- * @param useOriginalReferences
- * whether non-copied references should be used while copying
- *
- * @return a copier factory
- */
- static ICopierFactory getInstance(ResourceSet resourceSet, boolean useOriginalReferences) {
- return new CopierFactory(resourceSet, useOriginalReferences);
- }
-
- //
- // Nested types
- //
-
- /**
- * Configuration protocol for the {@linkplain ICopierFactory copier factory}
- * that {@link Configurator} extensions use to tweak the behaviour of
- * the copiers that it creates.
- *
- * @noextend This interface is not intended to be extended by clients.
- * @noimplement This interface is not intended to be implemented by clients.
- *
- * @since 2.2
- */
- interface Configuration {
- /**
- * Queries whether the copier to be configured resolves references
- * in its copying. {@link Configurator}s may need to know this to determine
- * how to configure it.
- *
- * @return whether the copier resolves references
- */
- boolean isResolveReferences();
-
- /**
- * Queries whether the copier to be configured uses original references
- * in its copying. {@link Configurator}s may need to know this to determine
- * how to configure it.
- *
- * @return whether the copier uses original references
- */
- boolean isUseOriginalReferences();
-
- /**
- * Adds a filter matching references that should not be copied for
- * select objects.
- *
- * @param filter
- * a filter that matches some reference for some object
- * that should not have that reference copied
- */
- void filterReferences(BiPredicate<? super EReference, ? super EObject> filter);
- }
-
- /**
- * Extension protocol for the {@linkplain ICopierFactory copier factory}
- * that allows plug-ins to customize the behaviour of the copiers that it creates.
- * Instances are registered on the {@code org.eclipse.papyrus.infra.core.copier}
- * extension point.
- *
- * @since 2.2
- */
- @FunctionalInterface
- interface Configurator {
- /**
- * Installs configurations for the copier factory.
- *
- * @param copierConfiguration
- * the configuration to update
- */
- void configureCopier(Configuration copierConfiguration);
- }
-}
+/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus 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: + * Christian W. Damus - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.infra.core.clipboard; + +import java.util.function.BiPredicate; +import java.util.function.Supplier; + +import org.eclipse.emf.ecore.EFactory; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.util.EcoreUtil.Copier; +import org.eclipse.papyrus.infra.core.internal.clipboard.CopierFactory; + +/** + * An extensible factory for EMF {@link Copier}s used for copy/paste + * operations in Papyrus. Extensions are registered on the + * {@code org.eclipse.papyrus.infra.core.copier} extension point. + * + * @since 3.0 + * + * @see EcoreUtil.Copier + */ +@FunctionalInterface +public interface ICopierFactory extends Supplier<EcoreUtil.Copier> { + + /** + * Obtains a copier factory suitable for most copy/paste operations. + * The result is configured from the extension point. + * + * @param resourceSet + * a resource set context in which to look for registered + * {@link EFactory} instances for creation of new objects + * @return a copier factory + */ + static ICopierFactory getInstance(ResourceSet resourceSet) { + return getInstance(resourceSet, true); + } + + /** + * Obtains a copier factory with the option of not using original references. + * The result is configured from the extension point. + * + * @param resourceSet + * a resource set context in which to look for registered + * {@link EFactory} instances for creation of new objects + * @param useOriginalReferences + * whether non-copied references should be used while copying + * + * @return a copier factory + */ + static ICopierFactory getInstance(ResourceSet resourceSet, boolean useOriginalReferences) { + return new CopierFactory(resourceSet, useOriginalReferences); + } + + // + // Nested types + // + + /** + * Configuration protocol for the {@linkplain ICopierFactory copier factory} + * that {@link Configurator} extensions use to tweak the behaviour of + * the copiers that it creates. + * + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + * + * @since 2.2 + */ + interface Configuration { + /** + * Queries whether the copier to be configured resolves references + * in its copying. {@link Configurator}s may need to know this to determine + * how to configure it. + * + * @return whether the copier resolves references + */ + boolean isResolveReferences(); + + /** + * Queries whether the copier to be configured uses original references + * in its copying. {@link Configurator}s may need to know this to determine + * how to configure it. + * + * @return whether the copier uses original references + */ + boolean isUseOriginalReferences(); + + /** + * Adds a filter matching references that should not be copied for + * select objects. + * + * @param filter + * a filter that matches some reference for some object + * that should not have that reference copied + */ + void filterReferences(BiPredicate<? super EReference, ? super EObject> filter); + } + + /** + * Extension protocol for the {@linkplain ICopierFactory copier factory} + * that allows plug-ins to customize the behaviour of the copiers that it creates. + * Instances are registered on the {@code org.eclipse.papyrus.infra.core.copier} + * extension point. + * + * @since 2.2 + */ + @FunctionalInterface + interface Configurator { + /** + * Installs configurations for the copier factory. + * + * @param copierConfiguration + * the configuration to update + */ + void configureCopier(Configuration copierConfiguration); + } +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/editor/BackboneException.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/editor/BackboneException.java index 4e2efcdb27b..542e01782f2 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/editor/BackboneException.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/editor/BackboneException.java @@ -1,71 +1,71 @@ -/*****************************************************************************
- * Copyright (c) 2008 CEA LIST.
- *
- *
- * 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:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.editor;
-
-/**
- * Root of Backbone Exception
- *
- * @author dumoulin
- *
- */
-public class BackboneException extends Exception {
-
- /**
- * serial version UID
- *
- * @generated
- */
- private static final long serialVersionUID = 4859634627616979417L;
-
- /**
- * Creates a new BackboneException.
- */
- public BackboneException() {
- super();
- }
-
- /**
- * Creates a new BackboneException with the specified message.
- *
- * @param message
- * the message of the exception
- */
- public BackboneException(String message) {
- super(message);
- }
-
- /**
- * Creates a new BackboneException with the specified cause.
- *
- * @param cause
- * the cause of the exception
- */
- public BackboneException(Throwable cause) {
- super(cause);
- }
-
- /**
- * Creates a new BackboneException with a specified message and the
- * specified cause.
- *
- * @param message
- * the message of the exception
- * @param cause
- * the cause of the exception
- */
- public BackboneException(String arg0, Throwable arg1) {
- super(arg0, arg1);
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2008 CEA LIST. + * + * + * 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: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.editor; + +/** + * Root of Backbone Exception + * + * @author dumoulin + * + */ +public class BackboneException extends Exception { + + /** + * serial version UID + * + * @generated + */ + private static final long serialVersionUID = 4859634627616979417L; + + /** + * Creates a new BackboneException. + */ + public BackboneException() { + super(); + } + + /** + * Creates a new BackboneException with the specified message. + * + * @param message + * the message of the exception + */ + public BackboneException(String message) { + super(message); + } + + /** + * Creates a new BackboneException with the specified cause. + * + * @param cause + * the cause of the exception + */ + public BackboneException(Throwable cause) { + super(cause); + } + + /** + * Creates a new BackboneException with a specified message and the + * specified cause. + * + * @param message + * the message of the exception + * @param cause + * the cause of the exception + */ + public BackboneException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/editor/DiResourceSetServiceFactory.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/editor/DiResourceSetServiceFactory.java index c861af10b54..6b2088ccd6f 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/editor/DiResourceSetServiceFactory.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/editor/DiResourceSetServiceFactory.java @@ -1,67 +1,67 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.editor;
-
-import org.eclipse.papyrus.infra.core.resource.ModelSet;
-import org.eclipse.papyrus.infra.core.services.IServiceFactory;
-import org.eclipse.papyrus.infra.core.services.ServiceException;
-import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
-
-/**
- * A service factory to create the {@link ModelSet} service. This provide a
- * nickname for {@link ModelSet} service. This serviceFactory depends on {@link ModelSet} service.
- *
- * @author cedric dumoulin
- *
- */
-public class DiResourceSetServiceFactory implements IServiceFactory {
-
- /**
- * The sashModelMangr.
- */
- private ModelSet modelSet;
-
- /**
- * @see org.eclipse.papyrus.infra.core.services.IService#init(org.eclipse.papyrus.infra.core.services.ServicesRegistry)
- *
- * @param servicesRegistry
- * @throws ServiceException
- */
- @Override
- public void init(ServicesRegistry servicesRegistry) throws ServiceException {
- // Get required services
- modelSet = servicesRegistry.getService(ModelSet.class);
-
- }
-
- /**
- * @see org.eclipse.papyrus.infra.core.services.IService#startService()
- *
- * @throws ServiceException
- */
- @Override
- public void startService() throws ServiceException {
- }
-
- /**
- * @see org.eclipse.papyrus.infra.core.services.IService#disposeService()
- *
- * @throws ServiceException
- */
- @Override
- public void disposeService() throws ServiceException {
- }
-
- /**
- * @see org.eclipse.papyrus.infra.core.services.IServiceFactory#createServiceInstance()
- *
- * @return
- * @throws ServiceException
- */
- @Override
- public Object createServiceInstance() throws ServiceException {
- return modelSet;
- }
-
-}
+/** + * + */ +package org.eclipse.papyrus.infra.core.editor; + +import org.eclipse.papyrus.infra.core.resource.ModelSet; +import org.eclipse.papyrus.infra.core.services.IServiceFactory; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.services.ServicesRegistry; + +/** + * A service factory to create the {@link ModelSet} service. This provide a + * nickname for {@link ModelSet} service. This serviceFactory depends on {@link ModelSet} service. + * + * @author cedric dumoulin + * + */ +public class DiResourceSetServiceFactory implements IServiceFactory { + + /** + * The sashModelMangr. + */ + private ModelSet modelSet; + + /** + * @see org.eclipse.papyrus.infra.core.services.IService#init(org.eclipse.papyrus.infra.core.services.ServicesRegistry) + * + * @param servicesRegistry + * @throws ServiceException + */ + @Override + public void init(ServicesRegistry servicesRegistry) throws ServiceException { + // Get required services + modelSet = servicesRegistry.getService(ModelSet.class); + + } + + /** + * @see org.eclipse.papyrus.infra.core.services.IService#startService() + * + * @throws ServiceException + */ + @Override + public void startService() throws ServiceException { + } + + /** + * @see org.eclipse.papyrus.infra.core.services.IService#disposeService() + * + * @throws ServiceException + */ + @Override + public void disposeService() throws ServiceException { + } + + /** + * @see org.eclipse.papyrus.infra.core.services.IServiceFactory#createServiceInstance() + * + * @return + * @throws ServiceException + */ + @Override + public Object createServiceInstance() throws ServiceException { + return modelSet; + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/editor/ModelSetServiceFactory.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/editor/ModelSetServiceFactory.java index 185172c1f33..a6750571ee4 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/editor/ModelSetServiceFactory.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/editor/ModelSetServiceFactory.java @@ -1,124 +1,124 @@ -/*****************************************************************************
- * Copyright (c) 2011, 2015 CEA LIST, Christian W. Damus, 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:
- * CEA LIST - Initial API and implementation
- * Christian W. Damus (CEA) - bug 431953 (pre-requisite refactoring of ModelSet service start-up)
- * Christian W. Damus - bug 468030
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.editor;
-
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.papyrus.infra.core.language.ILanguageService;
-import org.eclipse.papyrus.infra.core.resource.ModelSet;
-import org.eclipse.papyrus.infra.core.services.IServiceFactory;
-import org.eclipse.papyrus.infra.core.services.ModelSetServiceAdapter;
-import org.eclipse.papyrus.infra.core.services.ServiceException;
-import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
-
-/**
- * A service starting the ModelSet
- *
- * @author cedric dumoulin
- *
- */
-public class ModelSetServiceFactory implements IServiceFactory {
-
- private ServicesRegistry serviceRegistry;
-
- /** The ModelSet */
- private ModelSet service;
-
- /**
- *
- * @see org.eclipse.papyrus.infra.core.services.IService#init(org.eclipse.papyrus.infra.core.services.ServicesRegistry)
- *
- * @param servicesRegistry
- * @throws ServiceException
- */
- @Override
- public void init(ServicesRegistry servicesRegistry) throws ServiceException {
- this.serviceRegistry = servicesRegistry;
- }
-
- @Override
- public void startService() throws ServiceException {
- // If the language service is available (optional dependency), the ModelSet will want to use it, so start it
- try {
- serviceRegistry.startServicesByClassKeys(ILanguageService.class);
- } catch (ServiceException e) {
- // It's okay: the language service is optional
- }
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.core.services.IService#disposeService()
- *
- * @throws ServiceException
- */
- @Override
- public void disposeService() throws ServiceException {
- if (service != null) {
- try {
- setServiceRegistry(service, null);
- } finally {
- service.unload();
- }
- }
- }
-
- /**
- * Create the service served by this factory.
- */
- @Override
- public final Object createServiceInstance() throws ServiceException {
- if (service == null) {
- service = createModelSet();
- setServiceRegistry(service, serviceRegistry);
- }
-
- return service;
- }
-
- @SuppressWarnings("deprecation")
- protected ModelSet createModelSet() {
- // Return a DiResourceSet for backward compatibility
- // TODO return a ModelSet once DiResourceSet is removed
- return new org.eclipse.papyrus.infra.core.utils.DiResourceSet();
- }
-
- public static ServicesRegistry getServiceRegistry(ResourceSet resourceSet) {
- ModelSetServiceAdapter adapter = ModelSetServiceAdapter.getInstance(resourceSet);
- return (adapter == null) ? null : adapter.getServiceRegistry();
- }
-
- /**
- * Associates a resource set with a service registry.
- *
- * @param resourceSet
- * a resource set. Must not be {@code null}
- * @param serviceRegistry
- * a service registry. May be {@code null} to remove a previous association
- */
- public static void setServiceRegistry(ResourceSet resourceSet, ServicesRegistry serviceRegistry) throws ServiceException {
- if (serviceRegistry != null) {
- ModelSetServiceAdapter adapter = new ModelSetServiceAdapter(resourceSet);
- adapter.init(serviceRegistry);
- adapter.startService();
- } else {
- ModelSetServiceAdapter adapter = ModelSetServiceAdapter.getInstance(resourceSet);
- if (adapter != null) {
- adapter.stopService();
- }
- }
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2011, 2015 CEA LIST, Christian W. Damus, 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: + * CEA LIST - Initial API and implementation + * Christian W. Damus (CEA) - bug 431953 (pre-requisite refactoring of ModelSet service start-up) + * Christian W. Damus - bug 468030 + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.editor; + +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.papyrus.infra.core.language.ILanguageService; +import org.eclipse.papyrus.infra.core.resource.ModelSet; +import org.eclipse.papyrus.infra.core.services.IServiceFactory; +import org.eclipse.papyrus.infra.core.services.ModelSetServiceAdapter; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.services.ServicesRegistry; + +/** + * A service starting the ModelSet + * + * @author cedric dumoulin + * + */ +public class ModelSetServiceFactory implements IServiceFactory { + + private ServicesRegistry serviceRegistry; + + /** The ModelSet */ + private ModelSet service; + + /** + * + * @see org.eclipse.papyrus.infra.core.services.IService#init(org.eclipse.papyrus.infra.core.services.ServicesRegistry) + * + * @param servicesRegistry + * @throws ServiceException + */ + @Override + public void init(ServicesRegistry servicesRegistry) throws ServiceException { + this.serviceRegistry = servicesRegistry; + } + + @Override + public void startService() throws ServiceException { + // If the language service is available (optional dependency), the ModelSet will want to use it, so start it + try { + serviceRegistry.startServicesByClassKeys(ILanguageService.class); + } catch (ServiceException e) { + // It's okay: the language service is optional + } + } + + /** + * + * @see org.eclipse.papyrus.infra.core.services.IService#disposeService() + * + * @throws ServiceException + */ + @Override + public void disposeService() throws ServiceException { + if (service != null) { + try { + setServiceRegistry(service, null); + } finally { + service.unload(); + } + } + } + + /** + * Create the service served by this factory. + */ + @Override + public final Object createServiceInstance() throws ServiceException { + if (service == null) { + service = createModelSet(); + setServiceRegistry(service, serviceRegistry); + } + + return service; + } + + @SuppressWarnings("deprecation") + protected ModelSet createModelSet() { + // Return a DiResourceSet for backward compatibility + // TODO return a ModelSet once DiResourceSet is removed + return new org.eclipse.papyrus.infra.core.utils.DiResourceSet(); + } + + public static ServicesRegistry getServiceRegistry(ResourceSet resourceSet) { + ModelSetServiceAdapter adapter = ModelSetServiceAdapter.getInstance(resourceSet); + return (adapter == null) ? null : adapter.getServiceRegistry(); + } + + /** + * Associates a resource set with a service registry. + * + * @param resourceSet + * a resource set. Must not be {@code null} + * @param serviceRegistry + * a service registry. May be {@code null} to remove a previous association + */ + public static void setServiceRegistry(ResourceSet resourceSet, ServicesRegistry serviceRegistry) throws ServiceException { + if (serviceRegistry != null) { + ModelSetServiceAdapter adapter = new ModelSetServiceAdapter(resourceSet); + adapter.init(serviceRegistry); + adapter.startService(); + } else { + ModelSetServiceAdapter adapter = ModelSetServiceAdapter.getInstance(resourceSet); + if (adapter != null) { + adapter.stopService(); + } + } + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/BadClassNameException.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/BadClassNameException.java index a19478bc4cb..e3a4603326a 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/BadClassNameException.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/BadClassNameException.java @@ -1,88 +1,88 @@ -/*****************************************************************************
- * Copyright (c) 2008 CEA LIST.
- *
- *
- * 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:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.extension;
-
-import org.eclipse.core.runtime.IConfigurationElement;
-
-
-/**
- * Exception thrown as an extension point is parsed at runtime. More accurately,
- * it is thrown when one attribute of an extension point that should describe a
- * class name does not correspond to a class in the classpath.
- *
- * @author Cedric Dumoulin
- * @author Patrick Tessier
- * @author schnekenburger
- */
-public class BadClassNameException extends ExtensionException {
-
- /**
- * the name of{@link IConfigurationElement} that is bad build
- */
- private String iconfigurationElementName;
-
- /**
- * the name of the attribute of the {@link IConfigurationElement}
- */
- private String attributeName;
-
- private Exception e = null;
-
- /**
- * serial version UID
- *
- * @generated
- */
- private static final long serialVersionUID = 1161426240944647521L;
-
- /**
- * constructor with an exception
- *
- * @param element
- * the IConfigurationElement that raised the error
- * @param attributeName
- * the bad construct attibute
- * @param e
- * the associated exception
- */
- public BadClassNameException(String msg, String iConfigurationElementName, String attributeName, final Exception e) {
- super(msg);
- this.iconfigurationElementName = iConfigurationElementName;
- this.attributeName = attributeName;
- this.e = e;
- }
-
- /**
- * constructor without an exception
- *
- * @param element
- * the IConfigurationElement that raised the error
- * @param attributeName
- * the bad construct attibute
- */
- public BadClassNameException(String msg, String iConfigurationElementName, String attributeName) {
- super(msg);
- this.iconfigurationElementName = iConfigurationElementName;
- this.attributeName = attributeName;
- }
-
- /**
- *
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- return super.toString() + " for the extension point " + iconfigurationElementName + "." + attributeName + " " + e;
- }
-}
+/***************************************************************************** + * Copyright (c) 2008 CEA LIST. + * + * + * 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: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.extension; + +import org.eclipse.core.runtime.IConfigurationElement; + + +/** + * Exception thrown as an extension point is parsed at runtime. More accurately, + * it is thrown when one attribute of an extension point that should describe a + * class name does not correspond to a class in the classpath. + * + * @author Cedric Dumoulin + * @author Patrick Tessier + * @author schnekenburger + */ +public class BadClassNameException extends ExtensionException { + + /** + * the name of{@link IConfigurationElement} that is bad build + */ + private String iconfigurationElementName; + + /** + * the name of the attribute of the {@link IConfigurationElement} + */ + private String attributeName; + + private Exception e = null; + + /** + * serial version UID + * + * @generated + */ + private static final long serialVersionUID = 1161426240944647521L; + + /** + * constructor with an exception + * + * @param element + * the IConfigurationElement that raised the error + * @param attributeName + * the bad construct attibute + * @param e + * the associated exception + */ + public BadClassNameException(String msg, String iConfigurationElementName, String attributeName, final Exception e) { + super(msg); + this.iconfigurationElementName = iConfigurationElementName; + this.attributeName = attributeName; + this.e = e; + } + + /** + * constructor without an exception + * + * @param element + * the IConfigurationElement that raised the error + * @param attributeName + * the bad construct attibute + */ + public BadClassNameException(String msg, String iConfigurationElementName, String attributeName) { + super(msg); + this.iconfigurationElementName = iConfigurationElementName; + this.attributeName = attributeName; + } + + /** + * + * {@inheritDoc} + */ + @Override + public String toString() { + return super.toString() + " for the extension point " + iconfigurationElementName + "." + attributeName + " " + e; + } +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/BadNameExtensionException.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/BadNameExtensionException.java index 5f8f522bc2b..49a07ce9a2e 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/BadNameExtensionException.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/BadNameExtensionException.java @@ -1,70 +1,70 @@ -/*****************************************************************************
- * Copyright (c) 2008 CEA LIST.
- *
- *
- * 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:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.extension;
-
-/**
- * Exception thrown when a bad name is encountered in extension processing.
- *
- * @author dumoulin
- * @author schnekenburger
- */
-public class BadNameExtensionException extends ExtensionException {
-
- /**
- * serial version UID
- *
- * @generated
- */
- private static final long serialVersionUID = -2063118856033217385L;
-
- /**
- * Creates a simple BadNameExtensionException
- */
- public BadNameExtensionException() {
- }
-
- /**
- * Creates a BadNameExtensionException with a specific message.
- *
- * @param message
- * the message of the exception
- */
- public BadNameExtensionException(String message) {
- super(message);
- }
-
- /**
- * Creates a BadNameExtensionException with a specific cause.
- *
- * @param cause
- * the cause of the exception
- */
- public BadNameExtensionException(Throwable cause) {
- super(cause);
- }
-
- /**
- * Creates a BadNameExtensionException with a specific cause and a specific
- * message.
- *
- * @param message
- * the message of the exception
- * @param cause
- * the cause of the exception
- */
- public BadNameExtensionException(String message, Throwable cause) {
- super(message, cause);
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2008 CEA LIST. + * + * + * 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: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.extension; + +/** + * Exception thrown when a bad name is encountered in extension processing. + * + * @author dumoulin + * @author schnekenburger + */ +public class BadNameExtensionException extends ExtensionException { + + /** + * serial version UID + * + * @generated + */ + private static final long serialVersionUID = -2063118856033217385L; + + /** + * Creates a simple BadNameExtensionException + */ + public BadNameExtensionException() { + } + + /** + * Creates a BadNameExtensionException with a specific message. + * + * @param message + * the message of the exception + */ + public BadNameExtensionException(String message) { + super(message); + } + + /** + * Creates a BadNameExtensionException with a specific cause. + * + * @param cause + * the cause of the exception + */ + public BadNameExtensionException(Throwable cause) { + super(cause); + } + + /** + * Creates a BadNameExtensionException with a specific cause and a specific + * message. + * + * @param message + * the message of the exception + * @param cause + * the cause of the exception + */ + public BadNameExtensionException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/ExtensionException.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/ExtensionException.java index 586c9d3b1c5..e18cd7db143 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/ExtensionException.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/ExtensionException.java @@ -1,86 +1,86 @@ -/*****************************************************************************
- * Copyright (c) 2008 CEA LIST.
- *
- *
- * 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:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.extension;
-
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.papyrus.infra.core.editor.BackboneException;
-
-/**
- * Base class for extension exceptions
- *
- * @author dumoulin
- * @author schnekenburger
- */
-public class ExtensionException extends BackboneException {
-
- /**
- * serial version UID
- *
- * @generated
- */
- private static final long serialVersionUID = -9144153309491137046L;
-
- /**
- * Creates a simple ExtensionException.
- */
- public ExtensionException() {
- }
-
- /**
- * Creates a ExtensionException with a specific message.
- *
- * @param message
- * the message of the exception
- */
- public ExtensionException(String message) {
- super(message);
- }
-
- /**
- * Creates a ExtensionException with a specific cause.
- *
- * @param cause
- * the cause of the exception
- */
- public ExtensionException(Throwable cause) {
- super(cause);
-
- }
-
- /**
- * Creates a ExtensionException with a specific cause and a specific
- * message.
- *
- * @param message
- * the message of the exception
- * @param cause
- * the cause of the exception
- */
- public ExtensionException(String message, Throwable cause) {
- super(message, cause);
- }
-
- /**
- * Return the name of the plugin and extension declaring the extension.
- *
- * @param element
- * the configuration element corresponding to the extension
- * @return a string containing the name of the plugin and the name of the
- * extension
- */
- protected static String declaringExtensionToString(IConfigurationElement element) {
- return "plugin:" + element.getContributor().getName() + " extension:" + element.getName();
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2008 CEA LIST. + * + * + * 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: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.extension; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.papyrus.infra.core.editor.BackboneException; + +/** + * Base class for extension exceptions + * + * @author dumoulin + * @author schnekenburger + */ +public class ExtensionException extends BackboneException { + + /** + * serial version UID + * + * @generated + */ + private static final long serialVersionUID = -9144153309491137046L; + + /** + * Creates a simple ExtensionException. + */ + public ExtensionException() { + } + + /** + * Creates a ExtensionException with a specific message. + * + * @param message + * the message of the exception + */ + public ExtensionException(String message) { + super(message); + } + + /** + * Creates a ExtensionException with a specific cause. + * + * @param cause + * the cause of the exception + */ + public ExtensionException(Throwable cause) { + super(cause); + + } + + /** + * Creates a ExtensionException with a specific cause and a specific + * message. + * + * @param message + * the message of the exception + * @param cause + * the cause of the exception + */ + public ExtensionException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Return the name of the plugin and extension declaring the extension. + * + * @param element + * the configuration element corresponding to the extension + * @return a string containing the name of the plugin and the name of the + * extension + */ + protected static String declaringExtensionToString(IConfigurationElement element) { + return "plugin:" + element.getContributor().getName() + " extension:" + element.getName(); + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/NotFoundException.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/NotFoundException.java index 6bf20ef22b8..1cde1a0dacf 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/NotFoundException.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/extension/NotFoundException.java @@ -1,70 +1,70 @@ -/*****************************************************************************
- * Copyright (c) 2008 CEA LIST.
- *
- *
- * 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:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.extension;
-
-/**
- * Exception thrown when something is not found when parsing a configuration
- * element.
- *
- * @author dumoulin
- * @author schnekenburger
- */
-public class NotFoundException extends ExtensionException {
-
- /**
- * serial version UID
- *
- * @generated
- */
- private static final long serialVersionUID = -130754574538610199L;
-
- /**
- * Creates a simple NotFoundException.
- */
- public NotFoundException() {
- }
-
- /**
- * Creates a NotFoundException with a specific message.
- *
- * @param message
- * the message of the exception
- */
- public NotFoundException(String message) {
- super(message);
- }
-
- /**
- * Creates a NotFoundException with a specific cause.
- *
- * @param cause
- * the cause of the exception
- */
- public NotFoundException(Throwable cause) {
- super(cause);
- }
-
- /**
- * Creates a NotFoundException with a specific cause and a specific message.
- *
- * @param message
- * the message of the exception
- * @param cause
- * the cause of the exception
- */
- public NotFoundException(String message, Throwable cause) {
- super(message, cause);
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2008 CEA LIST. + * + * + * 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: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.extension; + +/** + * Exception thrown when something is not found when parsing a configuration + * element. + * + * @author dumoulin + * @author schnekenburger + */ +public class NotFoundException extends ExtensionException { + + /** + * serial version UID + * + * @generated + */ + private static final long serialVersionUID = -130754574538610199L; + + /** + * Creates a simple NotFoundException. + */ + public NotFoundException() { + } + + /** + * Creates a NotFoundException with a specific message. + * + * @param message + * the message of the exception + */ + public NotFoundException(String message) { + super(message); + } + + /** + * Creates a NotFoundException with a specific cause. + * + * @param cause + * the cause of the exception + */ + public NotFoundException(Throwable cause) { + super(cause); + } + + /** + * Creates a NotFoundException with a specific cause and a specific message. + * + * @param message + * the message of the exception + * @param cause + * the cause of the exception + */ + public NotFoundException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/listenerservice/IPapyrusListener.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/listenerservice/IPapyrusListener.java index 1c9a135c620..a8916bd52d0 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/listenerservice/IPapyrusListener.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/listenerservice/IPapyrusListener.java @@ -1,30 +1,30 @@ -/*******************************************************************************
- * Copyright (c) 2008 CEA LIST.
- * 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:
- * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
- *******************************************************************************/
-package org.eclipse.papyrus.infra.core.listenerservice;
-
-import org.eclipse.emf.common.notify.Notification;
-
-/**
- * This interface is a listener that will listen directly all events in papyrus:
- * uml. It will be very useful for external plug-in.
- *
- * An implementation may be an adapter.
- */
-public interface IPapyrusListener {
-
- /**
- * Notifies that a change to some feature has occurred.
- *
- * @param notification
- * - a description of the change.
- **/
- public void notifyChanged(Notification notification);
-}
+/******************************************************************************* + * Copyright (c) 2008 CEA LIST. + * 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: + * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation + *******************************************************************************/ +package org.eclipse.papyrus.infra.core.listenerservice; + +import org.eclipse.emf.common.notify.Notification; + +/** + * This interface is a listener that will listen directly all events in papyrus: + * uml. It will be very useful for external plug-in. + * + * An implementation may be an adapter. + */ +public interface IPapyrusListener { + + /** + * Notifies that a change to some feature has occurred. + * + * @param notification + * - a description of the change. + **/ + public void notifyChanged(Notification notification); +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/IFillableModelSetQueryAdapter.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/IFillableModelSetQueryAdapter.java index 84b17d16b0a..68358c77367 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/IFillableModelSetQueryAdapter.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/IFillableModelSetQueryAdapter.java @@ -1,39 +1,39 @@ -/*****************************************************************************
- * Copyright (c) 2011 Atos.
- *
- *
- * 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:
- * Tristan FAURE tristan.faure@atos.net - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.modelsetquery;
-
-import java.util.HashSet;
-
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EObject;
-
-public interface IFillableModelSetQueryAdapter extends IModelSetQueryAdapter {
- /**
- * This method provides a way for user to force first entries in the cache.
- * The list of element must be a HashSet to optimize the performances
- *
- * @param type
- * @param list
- */
- void addEntriesInCache(EClassifier type, HashSet<EObject> list);
-
- /**
- * Determines if the cache already contain this EClassifier
- *
- * @param type
- * , the desired type
- * @return true if the cache already compute this entry
- */
- boolean isAlreadyComputed(EClassifier type);
-}
+/***************************************************************************** + * Copyright (c) 2011 Atos. + * + * + * 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: + * Tristan FAURE tristan.faure@atos.net - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.modelsetquery; + +import java.util.HashSet; + +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EObject; + +public interface IFillableModelSetQueryAdapter extends IModelSetQueryAdapter { + /** + * This method provides a way for user to force first entries in the cache. + * The list of element must be a HashSet to optimize the performances + * + * @param type + * @param list + */ + void addEntriesInCache(EClassifier type, HashSet<EObject> list); + + /** + * Determines if the cache already contain this EClassifier + * + * @param type + * , the desired type + * @return true if the cache already compute this entry + */ + boolean isAlreadyComputed(EClassifier type); +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/IModelSetQueryAdapter.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/IModelSetQueryAdapter.java index d05f3a31d38..a222104f7b7 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/IModelSetQueryAdapter.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/IModelSetQueryAdapter.java @@ -1,39 +1,39 @@ -/*****************************************************************************
- * Copyright (c) 2010 Atos Origin.
- *
- *
- * 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:
- * Tristan FAURE tristan.faure@atosorigin.com - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.modelsetquery;
-
-import java.util.Collection;
-
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EObject;
-
-/**
- * interface to manage services to return objects from type
- *
- * @author tfaure
- *
- */
-public interface IModelSetQueryAdapter {
-
- /**
- * Return all the objects of type type
- *
- * @param object
- * , the object to start the search
- * @param type
- * , the type searched
- * @return the list of the instance of type
- */
- Collection<EObject> getReachableObjectsOfType(EObject object, EClassifier type);
-}
+/***************************************************************************** + * Copyright (c) 2010 Atos Origin. + * + * + * 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: + * Tristan FAURE tristan.faure@atosorigin.com - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.modelsetquery; + +import java.util.Collection; + +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EObject; + +/** + * interface to manage services to return objects from type + * + * @author tfaure + * + */ +public interface IModelSetQueryAdapter { + + /** + * Return all the objects of type type + * + * @param object + * , the object to start the search + * @param type + * , the type searched + * @return the list of the instance of type + */ + Collection<EObject> getReachableObjectsOfType(EObject object, EClassifier type); +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/ModelSetQuery.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/ModelSetQuery.java index 6c219a66be4..16a1b3b9368 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/ModelSetQuery.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/ModelSetQuery.java @@ -1,86 +1,86 @@ -/*****************************************************************************
- * Copyright (c) 2010 Atos Origin.
- *
- *
- * 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:
- * Emilien Perico (Atos Origin) emilien.perico@atosorigin.com - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.modelsetquery;
-
-
-import java.util.Collection;
-
-import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.common.notify.Notifier;
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.papyrus.infra.core.modelsetquery.impl.ModelSetQueryAdapterSimple;
-
-/**
- * The Class ModelSetQuery provides service to get objects of specified type
- * using cache mechanism
- */
-public class ModelSetQuery {
-
- /**
- * Return all the objects of specified type
- *
- * @param eobjectInModelSet
- * , the object from which to search starts
- * @param type
- * , the searched type
- * @return the list of the instance of specified type
- */
- public static Collection<EObject> getObjectsOfType(EObject eobjectInModelSet, EClassifier type) {
- IModelSetQueryAdapter adapter = getExistingTypeCacheAdapter(eobjectInModelSet);
- return adapter.getReachableObjectsOfType(eobjectInModelSet, type);
- }
-
- /**
- * Searches the adapter list of the given Notifier for a TypeCacheAdapter.
- * If not found, returns null.
- *
- * @param notifier
- * the notifier to search
- * @return the TypeCacheAdapter if found or a simple ITypeCacheAdapter which
- * calls default method
- */
- public static IModelSetQueryAdapter getExistingTypeCacheAdapter(Notifier notifier) {
- if (notifier == null) {
- return ModelSetQueryAdapterSimple.getSimpleTypeCacheAdapter();
- }
- for (Adapter adapter : notifier.eAdapters()) {
- if (adapter instanceof IModelSetQueryAdapter) {
- return (IModelSetQueryAdapter) adapter;
- }
- }
- if (notifier instanceof EObject) {
- EObject object = (EObject) notifier;
- IModelSetQueryAdapter typeCacheAdapter = getExistingTypeCacheAdapter(object.eResource());
- if (typeCacheAdapter instanceof Adapter) {
- object.eAdapters().add((Adapter) typeCacheAdapter);
- }
- if (typeCacheAdapter != null) {
- return typeCacheAdapter;
- }
- } else if (notifier instanceof Resource) {
- Resource resource = (Resource) notifier;
- IModelSetQueryAdapter typeCacheAdapter = getExistingTypeCacheAdapter(resource.getResourceSet());
- if (typeCacheAdapter != null) {
- if (typeCacheAdapter instanceof Adapter) {
- resource.eAdapters().add((Adapter) typeCacheAdapter);
- }
- return typeCacheAdapter;
- }
- }
- return ModelSetQueryAdapterSimple.getSimpleTypeCacheAdapter();
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2010 Atos Origin. + * + * + * 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: + * Emilien Perico (Atos Origin) emilien.perico@atosorigin.com - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.modelsetquery; + + +import java.util.Collection; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrus.infra.core.modelsetquery.impl.ModelSetQueryAdapterSimple; + +/** + * The Class ModelSetQuery provides service to get objects of specified type + * using cache mechanism + */ +public class ModelSetQuery { + + /** + * Return all the objects of specified type + * + * @param eobjectInModelSet + * , the object from which to search starts + * @param type + * , the searched type + * @return the list of the instance of specified type + */ + public static Collection<EObject> getObjectsOfType(EObject eobjectInModelSet, EClassifier type) { + IModelSetQueryAdapter adapter = getExistingTypeCacheAdapter(eobjectInModelSet); + return adapter.getReachableObjectsOfType(eobjectInModelSet, type); + } + + /** + * Searches the adapter list of the given Notifier for a TypeCacheAdapter. + * If not found, returns null. + * + * @param notifier + * the notifier to search + * @return the TypeCacheAdapter if found or a simple ITypeCacheAdapter which + * calls default method + */ + public static IModelSetQueryAdapter getExistingTypeCacheAdapter(Notifier notifier) { + if (notifier == null) { + return ModelSetQueryAdapterSimple.getSimpleTypeCacheAdapter(); + } + for (Adapter adapter : notifier.eAdapters()) { + if (adapter instanceof IModelSetQueryAdapter) { + return (IModelSetQueryAdapter) adapter; + } + } + if (notifier instanceof EObject) { + EObject object = (EObject) notifier; + IModelSetQueryAdapter typeCacheAdapter = getExistingTypeCacheAdapter(object.eResource()); + if (typeCacheAdapter instanceof Adapter) { + object.eAdapters().add((Adapter) typeCacheAdapter); + } + if (typeCacheAdapter != null) { + return typeCacheAdapter; + } + } else if (notifier instanceof Resource) { + Resource resource = (Resource) notifier; + IModelSetQueryAdapter typeCacheAdapter = getExistingTypeCacheAdapter(resource.getResourceSet()); + if (typeCacheAdapter != null) { + if (typeCacheAdapter instanceof Adapter) { + resource.eAdapters().add((Adapter) typeCacheAdapter); + } + return typeCacheAdapter; + } + } + return ModelSetQueryAdapterSimple.getSimpleTypeCacheAdapter(); + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryAdapterSimple.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryAdapterSimple.java index 7c9f771e05a..6c4c6040f71 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryAdapterSimple.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryAdapterSimple.java @@ -1,32 +1,32 @@ -package org.eclipse.papyrus.infra.core.modelsetquery.impl;
-
-import java.util.Collection;
-
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.edit.provider.ItemPropertyDescriptor;
-import org.eclipse.papyrus.infra.core.modelsetquery.IModelSetQueryAdapter;
-
-/**
- * This implementation uses ItemPropertyDescriptor class to resolve objects
- * from type
- *
- * @author tfaure
- */
-public class ModelSetQueryAdapterSimple implements IModelSetQueryAdapter {
- /**
- * This cache adapter is only used if the caller don't use correctly
- * TypeCacheAdapter. With the simple cache adapter performance are not good
- * but a result is still returned
- */
- private static ModelSetQueryAdapterSimple simpleCacheAdapter = new ModelSetQueryAdapterSimple();
-
- public static IModelSetQueryAdapter getSimpleTypeCacheAdapter() {
- return simpleCacheAdapter;
- }
-
- @Override
- public Collection<EObject> getReachableObjectsOfType(EObject object, EClassifier type) {
- return ItemPropertyDescriptor.getReachableObjectsOfType(object, type);
- }
-}
+package org.eclipse.papyrus.infra.core.modelsetquery.impl; + +import java.util.Collection; + +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.edit.provider.ItemPropertyDescriptor; +import org.eclipse.papyrus.infra.core.modelsetquery.IModelSetQueryAdapter; + +/** + * This implementation uses ItemPropertyDescriptor class to resolve objects + * from type + * + * @author tfaure + */ +public class ModelSetQueryAdapterSimple implements IModelSetQueryAdapter { + /** + * This cache adapter is only used if the caller don't use correctly + * TypeCacheAdapter. With the simple cache adapter performance are not good + * but a result is still returned + */ + private static ModelSetQueryAdapterSimple simpleCacheAdapter = new ModelSetQueryAdapterSimple(); + + public static IModelSetQueryAdapter getSimpleTypeCacheAdapter() { + return simpleCacheAdapter; + } + + @Override + public Collection<EObject> getReachableObjectsOfType(EObject object, EClassifier type) { + return ItemPropertyDescriptor.getReachableObjectsOfType(object, type); + } +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryAdapterSizeMatters.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryAdapterSizeMatters.java index 1eec11a2f7c..015bfdf913d 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryAdapterSizeMatters.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryAdapterSizeMatters.java @@ -1,174 +1,174 @@ -/*****************************************************************************
- * Copyright (c) 2010 Atos Origin.
- *
- *
- * 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:
- * Tristan FAURE tristan.faure@atosorigin.com - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.modelsetquery.impl;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-
-import org.eclipse.emf.common.notify.Notifier;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.util.EContentAdapter;
-import org.eclipse.papyrus.infra.core.modelsetquery.IFillableModelSetQueryAdapter;
-
-/**
- * This cache creates a map associating EClasses to all the corresponding
- * This implementation takes less space but it is less performant for get and put methods
- * instances
- *
- * @author Tristan Faure
- */
-public class ModelSetQueryAdapterSizeMatters extends EContentAdapter implements IFillableModelSetQueryAdapter {
-
- /**
- * The cache of elements
- */
- private Map<EClassifier, Collection<EObject>> cache = Collections.synchronizedMap(new IdentityHashMap<EClassifier, Collection<EObject>>());
- private Map<EClassifier, Collection<EClassifier>> subTypes = Collections.synchronizedMap(new IdentityHashMap<EClassifier, Collection<EClassifier>>());
-
-
- public ModelSetQueryAdapterSizeMatters() {
- super();
- }
-
- @Override
- protected void addAdapter(Notifier notifier) {
- super.addAdapter(notifier);
- if (notifier instanceof EObject) {
- EObject eobject = (EObject) notifier;
- addObjectInCache(eobject);
- }
- }
-
- @Override
- protected void removeAdapter(Notifier notifier) {
- super.removeAdapter(notifier);
- if (notifier instanceof EObject) {
- EObject eobject = (EObject) notifier;
- removeObjectFromCache(eobject);
- }
- }
-
- private void addObjectInCache(EObject newObj) {
- putObjectInCache(newObj);
- }
-
- private void putObjectInCache(EObject newObj) {
- putObjectInMap(newObj.eClass(), newObj);
- addSubTypes(newObj.eClass());
- }
-
- private void addSubTypes(EClass eClassifier) {
- for (EClass superType : eClassifier.getESuperTypes()) {
- addSubType(superType, eClassifier);
- addSubTypes(superType);
- }
- }
-
- protected void addSubType(EClass superType, EClassifier eClassifier) {
- Collection<EClassifier> result = subTypes.get(superType);
- if (result == null) {
- result = new HashSet<EClassifier>();
- subTypes.put(superType, result);
- }
- result.add(eClassifier);
- }
-
- private void putObjectInMap(EClassifier eClassifier, EObject obj) {
- Collection<EObject> result = cache.get(eClassifier);
- if (result == null) {
- result = new HashSet<EObject>();
- cache.put(eClassifier, result);
- }
- result.add(obj);
- }
-
- private void removeObjectFromCache(EObject newObj) {
- EClass eClass = newObj.eClass();
- removeObjectFromCache(eClass, newObj);
- }
-
- private void removeObjectFromCache(EClassifier eClassifier, EObject newObj) {
- Collection<EObject> listOfClassifiers = cache.get(eClassifier);
- if (listOfClassifiers != null) {
- listOfClassifiers.remove(newObj);
- if (listOfClassifiers.isEmpty()) {
- cache.remove(eClassifier);
- }
- }
- }
-
- @Override
- public Collection<EObject> getReachableObjectsOfType(EObject object, EClassifier type) {
- Set<EObject> buffer = new HashSet<EObject>();
- Set<EClassifier> alreadyComputed = new HashSet<EClassifier>();
- Stack<EClassifier> types = new Stack<EClassifier>();
- types.push(type);
- while (!types.isEmpty()) {
- EClassifier top = types.pop();
- alreadyComputed.add(top);
- // add instances to the buffer
- Collection<EObject> c = cache.get(top);
- if (c != null) {
- buffer.addAll(c);
- }
- // compute sub types
- Collection<EClassifier> c2 = subTypes.get(top);
- if (c2 != null) {
- for (EClassifier eClassifier : c2) {
- if (eClassifier != null && !alreadyComputed.contains(eClassifier)) {
- types.add(eClassifier);
- }
- }
- }
-
- }
- return buffer;
- }
-
- public void dispose() {
- cache.clear();
- subTypes.clear();
- cache = null;
- subTypes = null;
- }
-
- /**
- * This method provides a way for user to force first entries in the cache.
- * The list of element must be a HashSet to optimize the performances
- *
- * @param type
- * @param list
- */
- @Override
- public void addEntriesInCache(EClassifier type, HashSet<EObject> list) {
- for (EObject e : list) {
- addObjectInCache(e);
- }
- }
-
- @Override
- public boolean isAlreadyComputed(EClassifier type) {
- return cache.containsKey(type);
- }
-
-
-
-}
+/***************************************************************************** + * Copyright (c) 2010 Atos Origin. + * + * + * 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: + * Tristan FAURE tristan.faure@atosorigin.com - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.modelsetquery.impl; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.IdentityHashMap; +import java.util.Map; +import java.util.Set; +import java.util.Stack; + +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EContentAdapter; +import org.eclipse.papyrus.infra.core.modelsetquery.IFillableModelSetQueryAdapter; + +/** + * This cache creates a map associating EClasses to all the corresponding + * This implementation takes less space but it is less performant for get and put methods + * instances + * + * @author Tristan Faure + */ +public class ModelSetQueryAdapterSizeMatters extends EContentAdapter implements IFillableModelSetQueryAdapter { + + /** + * The cache of elements + */ + private Map<EClassifier, Collection<EObject>> cache = Collections.synchronizedMap(new IdentityHashMap<EClassifier, Collection<EObject>>()); + private Map<EClassifier, Collection<EClassifier>> subTypes = Collections.synchronizedMap(new IdentityHashMap<EClassifier, Collection<EClassifier>>()); + + + public ModelSetQueryAdapterSizeMatters() { + super(); + } + + @Override + protected void addAdapter(Notifier notifier) { + super.addAdapter(notifier); + if (notifier instanceof EObject) { + EObject eobject = (EObject) notifier; + addObjectInCache(eobject); + } + } + + @Override + protected void removeAdapter(Notifier notifier) { + super.removeAdapter(notifier); + if (notifier instanceof EObject) { + EObject eobject = (EObject) notifier; + removeObjectFromCache(eobject); + } + } + + private void addObjectInCache(EObject newObj) { + putObjectInCache(newObj); + } + + private void putObjectInCache(EObject newObj) { + putObjectInMap(newObj.eClass(), newObj); + addSubTypes(newObj.eClass()); + } + + private void addSubTypes(EClass eClassifier) { + for (EClass superType : eClassifier.getESuperTypes()) { + addSubType(superType, eClassifier); + addSubTypes(superType); + } + } + + protected void addSubType(EClass superType, EClassifier eClassifier) { + Collection<EClassifier> result = subTypes.get(superType); + if (result == null) { + result = new HashSet<EClassifier>(); + subTypes.put(superType, result); + } + result.add(eClassifier); + } + + private void putObjectInMap(EClassifier eClassifier, EObject obj) { + Collection<EObject> result = cache.get(eClassifier); + if (result == null) { + result = new HashSet<EObject>(); + cache.put(eClassifier, result); + } + result.add(obj); + } + + private void removeObjectFromCache(EObject newObj) { + EClass eClass = newObj.eClass(); + removeObjectFromCache(eClass, newObj); + } + + private void removeObjectFromCache(EClassifier eClassifier, EObject newObj) { + Collection<EObject> listOfClassifiers = cache.get(eClassifier); + if (listOfClassifiers != null) { + listOfClassifiers.remove(newObj); + if (listOfClassifiers.isEmpty()) { + cache.remove(eClassifier); + } + } + } + + @Override + public Collection<EObject> getReachableObjectsOfType(EObject object, EClassifier type) { + Set<EObject> buffer = new HashSet<EObject>(); + Set<EClassifier> alreadyComputed = new HashSet<EClassifier>(); + Stack<EClassifier> types = new Stack<EClassifier>(); + types.push(type); + while (!types.isEmpty()) { + EClassifier top = types.pop(); + alreadyComputed.add(top); + // add instances to the buffer + Collection<EObject> c = cache.get(top); + if (c != null) { + buffer.addAll(c); + } + // compute sub types + Collection<EClassifier> c2 = subTypes.get(top); + if (c2 != null) { + for (EClassifier eClassifier : c2) { + if (eClassifier != null && !alreadyComputed.contains(eClassifier)) { + types.add(eClassifier); + } + } + } + + } + return buffer; + } + + public void dispose() { + cache.clear(); + subTypes.clear(); + cache = null; + subTypes = null; + } + + /** + * This method provides a way for user to force first entries in the cache. + * The list of element must be a HashSet to optimize the performances + * + * @param type + * @param list + */ + @Override + public void addEntriesInCache(EClassifier type, HashSet<EObject> list) { + for (EObject e : list) { + addObjectInCache(e); + } + } + + @Override + public boolean isAlreadyComputed(EClassifier type) { + return cache.containsKey(type); + } + + + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryAdapterTimeMatters.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryAdapterTimeMatters.java index 53e20365439..c5c9b2be951 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryAdapterTimeMatters.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryAdapterTimeMatters.java @@ -1,131 +1,131 @@ -/*****************************************************************************
- * Copyright (c) 2010 Atos Origin.
- *
- *
- * 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:
- * Tristan FAURE tristan.faure@atosorigin.com - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.modelsetquery.impl;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Map;
-
-import org.eclipse.emf.common.notify.Notifier;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.util.EContentAdapter;
-import org.eclipse.emf.edit.provider.ItemPropertyDescriptor;
-import org.eclipse.papyrus.infra.core.modelsetquery.IFillableModelSetQueryAdapter;
-
-/**
- * This cache creates a map associating EClasses to all the corresponding
- * This implementation takes more space but it is more performant for get and put methods
- * instances
- *
- * @author Tristan Faure
- */
-public class ModelSetQueryAdapterTimeMatters extends EContentAdapter implements IFillableModelSetQueryAdapter {
-
- /**
- * The cache of elements
- */
- private Map<EClassifier, Collection<EObject>> cache = Collections.synchronizedMap(new IdentityHashMap<EClassifier, Collection<EObject>>());
-
- public ModelSetQueryAdapterTimeMatters() {
- super();
- }
-
- @Override
- protected void addAdapter(Notifier notifier) {
- super.addAdapter(notifier);
- if (notifier instanceof EObject) {
- EObject eobject = (EObject) notifier;
- addObjectInCache(eobject);
- }
- }
-
- @Override
- protected void removeAdapter(Notifier notifier) {
- super.removeAdapter(notifier);
- if (notifier instanceof EObject) {
- EObject eobject = (EObject) notifier;
- removeObjectFromCache(eobject);
- }
- }
-
- private void addObjectInCache(EObject newObj) {
- EClass eClass = newObj.eClass();
- putObjectInCache(eClass, newObj);
- for (EClass eSuperClass : eClass.getEAllSuperTypes()) {
- putObjectInCache(eSuperClass, newObj);
- }
- }
-
- private void putObjectInCache(EClassifier eClassifier, EObject newObj) {
- Collection<EObject> listOfClassifiers = cache.get(eClassifier);
- if (listOfClassifiers == null) {
- listOfClassifiers = new HashSet<EObject>();
- cache.put(eClassifier, listOfClassifiers);
- }
- if (listOfClassifiers != null) {
- listOfClassifiers.add(newObj);
- }
- }
-
- private void removeObjectFromCache(EObject newObj) {
- EClass eClass = newObj.eClass();
- removeObjectFromCache(eClass, newObj);
- for (EClass eSuperClass : eClass.getEAllSuperTypes()) {
- removeObjectFromCache(eSuperClass, newObj);
- }
- }
-
- private void removeObjectFromCache(EClassifier eClassifier, EObject newObj) {
- Collection<EObject> listOfClassifiers = cache.get(eClassifier);
- if (listOfClassifiers != null) {
- listOfClassifiers.remove(newObj);
- }
- }
-
- @Override
- public Collection<EObject> getReachableObjectsOfType(EObject object, EClassifier type) {
- if (!cache.containsKey(type)) {
- cache.put(type, new HashSet<EObject>(ItemPropertyDescriptor.getReachableObjectsOfType(object, type)));
- }
- return cache.get(type);
- }
-
- public void dispose() {
- cache.clear();
- cache = null;
- }
-
- /**
- * This method provides a way for user to force first entries in the cache.
- * The list of element must be a HashSet to optimize the performances
- *
- * @param type
- * @param list
- */
- @Override
- public void addEntriesInCache(EClassifier type, HashSet<EObject> list) {
- for (EObject e : list) {
- addObjectInCache(e);
- }
- }
-
- @Override
- public boolean isAlreadyComputed(EClassifier type) {
- return cache.containsKey(type);
- }
-}
+/***************************************************************************** + * Copyright (c) 2010 Atos Origin. + * + * + * 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: + * Tristan FAURE tristan.faure@atosorigin.com - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.modelsetquery.impl; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.IdentityHashMap; +import java.util.Map; + +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EContentAdapter; +import org.eclipse.emf.edit.provider.ItemPropertyDescriptor; +import org.eclipse.papyrus.infra.core.modelsetquery.IFillableModelSetQueryAdapter; + +/** + * This cache creates a map associating EClasses to all the corresponding + * This implementation takes more space but it is more performant for get and put methods + * instances + * + * @author Tristan Faure + */ +public class ModelSetQueryAdapterTimeMatters extends EContentAdapter implements IFillableModelSetQueryAdapter { + + /** + * The cache of elements + */ + private Map<EClassifier, Collection<EObject>> cache = Collections.synchronizedMap(new IdentityHashMap<EClassifier, Collection<EObject>>()); + + public ModelSetQueryAdapterTimeMatters() { + super(); + } + + @Override + protected void addAdapter(Notifier notifier) { + super.addAdapter(notifier); + if (notifier instanceof EObject) { + EObject eobject = (EObject) notifier; + addObjectInCache(eobject); + } + } + + @Override + protected void removeAdapter(Notifier notifier) { + super.removeAdapter(notifier); + if (notifier instanceof EObject) { + EObject eobject = (EObject) notifier; + removeObjectFromCache(eobject); + } + } + + private void addObjectInCache(EObject newObj) { + EClass eClass = newObj.eClass(); + putObjectInCache(eClass, newObj); + for (EClass eSuperClass : eClass.getEAllSuperTypes()) { + putObjectInCache(eSuperClass, newObj); + } + } + + private void putObjectInCache(EClassifier eClassifier, EObject newObj) { + Collection<EObject> listOfClassifiers = cache.get(eClassifier); + if (listOfClassifiers == null) { + listOfClassifiers = new HashSet<EObject>(); + cache.put(eClassifier, listOfClassifiers); + } + if (listOfClassifiers != null) { + listOfClassifiers.add(newObj); + } + } + + private void removeObjectFromCache(EObject newObj) { + EClass eClass = newObj.eClass(); + removeObjectFromCache(eClass, newObj); + for (EClass eSuperClass : eClass.getEAllSuperTypes()) { + removeObjectFromCache(eSuperClass, newObj); + } + } + + private void removeObjectFromCache(EClassifier eClassifier, EObject newObj) { + Collection<EObject> listOfClassifiers = cache.get(eClassifier); + if (listOfClassifiers != null) { + listOfClassifiers.remove(newObj); + } + } + + @Override + public Collection<EObject> getReachableObjectsOfType(EObject object, EClassifier type) { + if (!cache.containsKey(type)) { + cache.put(type, new HashSet<EObject>(ItemPropertyDescriptor.getReachableObjectsOfType(object, type))); + } + return cache.get(type); + } + + public void dispose() { + cache.clear(); + cache = null; + } + + /** + * This method provides a way for user to force first entries in the cache. + * The list of element must be a HashSet to optimize the performances + * + * @param type + * @param list + */ + @Override + public void addEntriesInCache(EClassifier type, HashSet<EObject> list) { + for (EObject e : list) { + addObjectInCache(e); + } + } + + @Override + public boolean isAlreadyComputed(EClassifier type) { + return cache.containsKey(type); + } +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryInitializer.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryInitializer.java index 3970e674ff6..823d4a7037e 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryInitializer.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/modelsetquery/impl/ModelSetQueryInitializer.java @@ -1,76 +1,76 @@ -/*****************************************************************************
- * Copyright (c) 2010 CEA LIST.
- *
- *
- * 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
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.modelsetquery.impl;
-
-import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.papyrus.infra.core.modelsetquery.IModelSetQueryAdapter;
-import org.eclipse.papyrus.infra.core.resource.IModelSetSnippet;
-import org.eclipse.papyrus.infra.core.resource.ModelSet;
-
-/**
- * This snippet take in charge the initialization of the TypeCache. The snippet
- * is attached to the {@link ModelSet} (in the extensions), and called right
- * after ModelsManager is initialized.
- *
- * @author cedric dumoulin
- *
- */
-public class ModelSetQueryInitializer implements IModelSetSnippet {
-
- /**
- * The type cache adapter used to reference elements from a type
- */
- private IModelSetQueryAdapter modelQueryAdapter;
-
- /**
- * @see org.eclipse.papyrus.resource.IModelSetSnippet#start(org.eclipse.papyrus.infra.core.resource.ModelSet)
- *
- * @param modelsManager
- */
- @Override
- public void start(ModelSet modelsManager) {
- EList<Adapter> eAdapters = modelsManager.eAdapters();
- boolean found = false;
- for (Adapter adapter : eAdapters) {
- if (adapter instanceof IModelSetQueryAdapter) {
- found = true;
- modelQueryAdapter = (IModelSetQueryAdapter) adapter;
- }
- }
- if (!found) {
- modelQueryAdapter = createDefaultIModelSetQueryAdapter();
- if (modelQueryAdapter instanceof Adapter) {
- eAdapters.add((Adapter) modelQueryAdapter);
- }
- }
-
- }
-
- public static IModelSetQueryAdapter createDefaultIModelSetQueryAdapter() {
- // for big models size matters TODO change the implementation to provide options
- return new ModelSetQueryAdapterSizeMatters();
- }
-
- /**
- * @see org.eclipse.papyrus.resource.IModelSetSnippet#dispose(org.eclipse.papyrus.infra.core.resource.ModelSet)
- *
- * @param modelsManager
- */
- @Override
- public void dispose(ModelSet modelsManager) {
- if (modelQueryAdapter instanceof Adapter) {
- modelsManager.eAdapters().remove(modelQueryAdapter);
- }
-
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2010 CEA LIST. + * + * + * 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 + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.modelsetquery.impl; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.util.EList; +import org.eclipse.papyrus.infra.core.modelsetquery.IModelSetQueryAdapter; +import org.eclipse.papyrus.infra.core.resource.IModelSetSnippet; +import org.eclipse.papyrus.infra.core.resource.ModelSet; + +/** + * This snippet take in charge the initialization of the TypeCache. The snippet + * is attached to the {@link ModelSet} (in the extensions), and called right + * after ModelsManager is initialized. + * + * @author cedric dumoulin + * + */ +public class ModelSetQueryInitializer implements IModelSetSnippet { + + /** + * The type cache adapter used to reference elements from a type + */ + private IModelSetQueryAdapter modelQueryAdapter; + + /** + * @see org.eclipse.papyrus.resource.IModelSetSnippet#start(org.eclipse.papyrus.infra.core.resource.ModelSet) + * + * @param modelsManager + */ + @Override + public void start(ModelSet modelsManager) { + EList<Adapter> eAdapters = modelsManager.eAdapters(); + boolean found = false; + for (Adapter adapter : eAdapters) { + if (adapter instanceof IModelSetQueryAdapter) { + found = true; + modelQueryAdapter = (IModelSetQueryAdapter) adapter; + } + } + if (!found) { + modelQueryAdapter = createDefaultIModelSetQueryAdapter(); + if (modelQueryAdapter instanceof Adapter) { + eAdapters.add((Adapter) modelQueryAdapter); + } + } + + } + + public static IModelSetQueryAdapter createDefaultIModelSetQueryAdapter() { + // for big models size matters TODO change the implementation to provide options + return new ModelSetQueryAdapterSizeMatters(); + } + + /** + * @see org.eclipse.papyrus.resource.IModelSetSnippet#dispose(org.eclipse.papyrus.infra.core.resource.ModelSet) + * + * @param modelsManager + */ + @Override + public void dispose(ModelSet modelsManager) { + if (modelQueryAdapter instanceof Adapter) { + modelsManager.eAdapters().remove(modelQueryAdapter); + } + + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/AbstractDynamicModel.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/AbstractDynamicModel.java index fcecfdd5e32..1ec47845c53 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/AbstractDynamicModel.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/AbstractDynamicModel.java @@ -1,101 +1,101 @@ -/*****************************************************************************
- * Copyright (c) 2010, 2015 LIFL, CEA LIST, Christian W. Damus, 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:
- * LIFL - Initial API and implementation
- * Christian W. Damus - bug 481149
- *
- *****************************************************************************/
-
-package org.eclipse.papyrus.infra.core.resource;
-
-import java.io.IOException;
-
-import org.eclipse.core.internal.resources.ResourceException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.emf.ecore.EObject;
-
-/**
- * Base class for models that can be created dynamically. Such models do not need to exist when others models are loaded.
- * If the model is missing, it will be created.
- * Furthermore, if the model is empty, it will not be saved.
- *
- *
- * @author cedric dumoulin
- *
- * @param T
- * Type of the roots of the model.
- */
-public abstract class AbstractDynamicModel<T extends EObject> extends AbstractBaseModel {
-
-
- /**
- *
- * Constructor.
- *
- * @param modelKind
- */
- public AbstractDynamicModel() {
- super();
- }
-
- /**
- * Load the model if it exist, or create a new one if it doesn't exist.
- *
- * @param fullPathWithoutExtension
- */
- @SuppressWarnings("restriction")
- @Override
- public void loadModel(IPath fullPathWithoutExtension) {
-
- // Try to load the model. It this fail, create a model.
- try {
- // Try to load the model
- super.loadModel(fullPathWithoutExtension);
- return;
- } catch (RuntimeException e) {
-
- // Check if the exception come from an non existing resource.
- if (!(e.getCause() instanceof ResourceException)) {
- throw e;
- }
- }
- // The resource do not exist, crate it.
- createModel(fullPathWithoutExtension);
-
- // call registered snippets
- startSnippets();
- }
-
- /**
- * Save the model if it contains something.
- *
- * @see org.eclipse.papyrus.infra.core.resource.AbstractBaseModel#saveModel()
- *
- * @throws IOException
- */
- @Override
- public void saveModel() throws IOException {
-
- if (getResource().getContents().size() <= 0) {
- return;
- }
-
- // Do the save
- super.saveModel();
- }
-
- /**
- * Add a root to this model.
- *
- * @param root
- */
- public void addModelRoot(T root) {
- getResource().getContents().add(root);
- }
-}
+/***************************************************************************** + * Copyright (c) 2010, 2015 LIFL, CEA LIST, Christian W. Damus, 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: + * LIFL - Initial API and implementation + * Christian W. Damus - bug 481149 + * + *****************************************************************************/ + +package org.eclipse.papyrus.infra.core.resource; + +import java.io.IOException; + +import org.eclipse.core.internal.resources.ResourceException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.emf.ecore.EObject; + +/** + * Base class for models that can be created dynamically. Such models do not need to exist when others models are loaded. + * If the model is missing, it will be created. + * Furthermore, if the model is empty, it will not be saved. + * + * + * @author cedric dumoulin + * + * @param T + * Type of the roots of the model. + */ +public abstract class AbstractDynamicModel<T extends EObject> extends AbstractBaseModel { + + + /** + * + * Constructor. + * + * @param modelKind + */ + public AbstractDynamicModel() { + super(); + } + + /** + * Load the model if it exist, or create a new one if it doesn't exist. + * + * @param fullPathWithoutExtension + */ + @SuppressWarnings("restriction") + @Override + public void loadModel(IPath fullPathWithoutExtension) { + + // Try to load the model. It this fail, create a model. + try { + // Try to load the model + super.loadModel(fullPathWithoutExtension); + return; + } catch (RuntimeException e) { + + // Check if the exception come from an non existing resource. + if (!(e.getCause() instanceof ResourceException)) { + throw e; + } + } + // The resource do not exist, crate it. + createModel(fullPathWithoutExtension); + + // call registered snippets + startSnippets(); + } + + /** + * Save the model if it contains something. + * + * @see org.eclipse.papyrus.infra.core.resource.AbstractBaseModel#saveModel() + * + * @throws IOException + */ + @Override + public void saveModel() throws IOException { + + if (getResource().getContents().size() <= 0) { + return; + } + + // Do the save + super.saveModel(); + } + + /** + * Add a root to this model. + * + * @param root + */ + public void addModelRoot(T root) { + getResource().getContents().add(root); + } +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/AbstractModelWithSharedResource.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/AbstractModelWithSharedResource.java index b78f34bf6d1..88b5faaa62c 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/AbstractModelWithSharedResource.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/AbstractModelWithSharedResource.java @@ -1,261 +1,261 @@ -/*****************************************************************************
- * Copyright (c) 2011, 2016 LIFL, CEA LIST, Christian W. Damus, 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:
- * LIFL - Initial API and implementation
- * Christian W. Damus - bugs 485220, 496299
- * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Bug 496905
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.resource;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.papyrus.infra.core.Activator;
-
-/**
- * Base class for models sharing a common {@link Resource}. To share a common {@link Resource}, one of the model should be Master, while the other are
- * slaves. The Master is the one performing the save operation. All the model
- * should use the same file extension. So, {@link #getModelFileExtension()} should return the same value for all models.
- *
- * @author cedric dumoulin
- *
- * @param T
- * Type of the roots of the model.
- */
-public abstract class AbstractModelWithSharedResource<T extends EObject> extends EMFLogicalModel {
-
- /**
- * Possible type for this model: master or slave
- */
- public enum ModelKind {
- master, slave
- }
-
- /**
- * Model kind.
- *
- * @since 3.0
- */
- protected ModelKind modelKind;
-
- /**
- *
- * Constructor.
- *
- * @param modelKind
- */
- public AbstractModelWithSharedResource(ModelKind modelKind) {
- this.modelKind = modelKind;
- }
-
- /**
- * By default, we are a slave. Constructor.
- *
- * @param modelKind
- */
- public AbstractModelWithSharedResource() {
- this.modelKind = ModelKind.slave;
- }
-
- /**
- * Attach the model to its resource if this is not already done.
- */
- @Override
- public void loadModel(URI uriWithoutExtension) {
- try {
- // Look for the resource
- lookupResource(uriWithoutExtension);
-
- // Check if model is loaded.
- if (resourceIsSet()) {
- configureResource(resource);
- startSnippets();
- return;
- }
- // model is not loaded, do it.
- super.loadModel(uriWithoutExtension);
- } catch (Exception ex) {
- if (modelKind == ModelKind.master) {
- Activator.log.error(ex);
- }
- }
- }
-
- /**
- * Create the model if this is not already done.
- */
- @Override
- public void createModel(URI uri) {
- try {
- // Look for the resource
- lookupResource(uri);
-
- // Check if model is loaded.
- if (resourceIsSet()) {
- configureResource(resource);
- return;
- }
- super.createModel(uri);
- } catch (Exception ex) {
- if (modelKind == ModelKind.master) {
- Activator.log.error(ex);
- }
- }
- }
-
- /**
- * Lookup for the resource in the resourceSet.
- *
- * @param uri
- * the URI (without extension) of the resource to look for
- */
- private void lookupResource(URI uriWithoutExtension) {
-
- // Compute model URI
- resourceURI = uriWithoutExtension.appendFileExtension(getModelFileExtension());
-
- resource = getResourceSet().getResource(resourceURI, false);
-
- }
-
- /**
- * Do nothing as we are slave. The Resource is save by the master model.
- *
- * @see org.eclipse.papyrus.infra.core.resource.AbstractBaseModel#saveModel()
- *
- * @throws IOException
- */
- @Override
- public void saveModel() throws IOException {
-
- // Do nothing if we are a slave
- if (modelKind == ModelKind.slave) {
- return;
- }
-
- // Do the save
- super.saveModel();
- }
-
- @Override
- public void saveCopy(IPath targetPathWithoutExtension, Map<Object, Object> targetMap) {
- // Do nothing if we are a slave
- if (modelKind == ModelKind.slave) {
- return;
- }
-
- // Do the save
- super.saveCopy(targetPathWithoutExtension, targetMap);
- }
-
-
- /**
- * Get the root of this model. Lookup in the associated {@link Resource} for
- * the root.
- *
- * @return The root of the model, or null if no root exist.
- */
- @SuppressWarnings("unchecked")
- public T getModelRoot() {
- Resource resource = getResource();
- if (resource == null) {
- return null;
- }
-
- for (EObject object : resource.getContents()) {
-
- if (isModelRoot(object)) {
- return (T) object;
- }
- }
-
- // Not found
- return null;
- }
-
- /**
- * Get the roots of this model. Lookup in the associated {@link Resource} for the roots.
- *
- * @return A list containing the roots of the model. The list is empty if
- * there is no root.
- */
- @SuppressWarnings("unchecked")
- public List<T> getModelRoots() {
-
- List<T> roots = new ArrayList<>();
-
- for (EObject object : getResource().getContents()) {
- if (isModelRoot(object)) {
- roots.add((T) object);
- }
- }
-
- return roots;
- }
-
- @Override
- public Iterable<? extends EObject> getRootElements() {
- return getModelRoots();
- }
-
- /**
- * @see org.eclipse.papyrus.infra.core.resource.EMFLogicalModel#isModelFor(java.lang.Object)
- *
- * @param element
- * @return
- */
- @Override
- public boolean isModelFor(Object element) {
- if (modelKind == ModelKind.slave) {
- // I'm not the main model for this resource/object
- return false;
- }
- return super.isModelFor(element);
- }
-
- /**
- * Return true if the provided object is a root of the model, false
- * otherwise. This method should be implemented by subclasses.
- *
- * @param object
- * @return
- */
- protected abstract boolean isModelRoot(EObject object);
-
- /**
- * Add a root to this model.
- *
- * @param root
- */
- public void addModelRoot(T root) {
- getResource().getContents().add(root);
- }
-
- @Override
- protected Map<Object, Object> getSaveOptions() {
- if (modelKind == ModelKind.master) {
- return super.getSaveOptions();
- } else {
- return Collections.emptyMap();
- }
- }
-
- @Override
- protected boolean isSupportedRoot(EObject object) {
- return isModelRoot(object);
- }
-}
+/***************************************************************************** + * Copyright (c) 2011, 2016 LIFL, CEA LIST, Christian W. Damus, 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: + * LIFL - Initial API and implementation + * Christian W. Damus - bugs 485220, 496299 + * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Bug 496905 + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.resource; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.papyrus.infra.core.Activator; + +/** + * Base class for models sharing a common {@link Resource}. To share a common {@link Resource}, one of the model should be Master, while the other are + * slaves. The Master is the one performing the save operation. All the model + * should use the same file extension. So, {@link #getModelFileExtension()} should return the same value for all models. + * + * @author cedric dumoulin + * + * @param T + * Type of the roots of the model. + */ +public abstract class AbstractModelWithSharedResource<T extends EObject> extends EMFLogicalModel { + + /** + * Possible type for this model: master or slave + */ + public enum ModelKind { + master, slave + } + + /** + * Model kind. + * + * @since 3.0 + */ + protected ModelKind modelKind; + + /** + * + * Constructor. + * + * @param modelKind + */ + public AbstractModelWithSharedResource(ModelKind modelKind) { + this.modelKind = modelKind; + } + + /** + * By default, we are a slave. Constructor. + * + * @param modelKind + */ + public AbstractModelWithSharedResource() { + this.modelKind = ModelKind.slave; + } + + /** + * Attach the model to its resource if this is not already done. + */ + @Override + public void loadModel(URI uriWithoutExtension) { + try { + // Look for the resource + lookupResource(uriWithoutExtension); + + // Check if model is loaded. + if (resourceIsSet()) { + configureResource(resource); + startSnippets(); + return; + } + // model is not loaded, do it. + super.loadModel(uriWithoutExtension); + } catch (Exception ex) { + if (modelKind == ModelKind.master) { + Activator.log.error(ex); + } + } + } + + /** + * Create the model if this is not already done. + */ + @Override + public void createModel(URI uri) { + try { + // Look for the resource + lookupResource(uri); + + // Check if model is loaded. + if (resourceIsSet()) { + configureResource(resource); + return; + } + super.createModel(uri); + } catch (Exception ex) { + if (modelKind == ModelKind.master) { + Activator.log.error(ex); + } + } + } + + /** + * Lookup for the resource in the resourceSet. + * + * @param uri + * the URI (without extension) of the resource to look for + */ + private void lookupResource(URI uriWithoutExtension) { + + // Compute model URI + resourceURI = uriWithoutExtension.appendFileExtension(getModelFileExtension()); + + resource = getResourceSet().getResource(resourceURI, false); + + } + + /** + * Do nothing as we are slave. The Resource is save by the master model. + * + * @see org.eclipse.papyrus.infra.core.resource.AbstractBaseModel#saveModel() + * + * @throws IOException + */ + @Override + public void saveModel() throws IOException { + + // Do nothing if we are a slave + if (modelKind == ModelKind.slave) { + return; + } + + // Do the save + super.saveModel(); + } + + @Override + public void saveCopy(IPath targetPathWithoutExtension, Map<Object, Object> targetMap) { + // Do nothing if we are a slave + if (modelKind == ModelKind.slave) { + return; + } + + // Do the save + super.saveCopy(targetPathWithoutExtension, targetMap); + } + + + /** + * Get the root of this model. Lookup in the associated {@link Resource} for + * the root. + * + * @return The root of the model, or null if no root exist. + */ + @SuppressWarnings("unchecked") + public T getModelRoot() { + Resource resource = getResource(); + if (resource == null) { + return null; + } + + for (EObject object : resource.getContents()) { + + if (isModelRoot(object)) { + return (T) object; + } + } + + // Not found + return null; + } + + /** + * Get the roots of this model. Lookup in the associated {@link Resource} for the roots. + * + * @return A list containing the roots of the model. The list is empty if + * there is no root. + */ + @SuppressWarnings("unchecked") + public List<T> getModelRoots() { + + List<T> roots = new ArrayList<>(); + + for (EObject object : getResource().getContents()) { + if (isModelRoot(object)) { + roots.add((T) object); + } + } + + return roots; + } + + @Override + public Iterable<? extends EObject> getRootElements() { + return getModelRoots(); + } + + /** + * @see org.eclipse.papyrus.infra.core.resource.EMFLogicalModel#isModelFor(java.lang.Object) + * + * @param element + * @return + */ + @Override + public boolean isModelFor(Object element) { + if (modelKind == ModelKind.slave) { + // I'm not the main model for this resource/object + return false; + } + return super.isModelFor(element); + } + + /** + * Return true if the provided object is a root of the model, false + * otherwise. This method should be implemented by subclasses. + * + * @param object + * @return + */ + protected abstract boolean isModelRoot(EObject object); + + /** + * Add a root to this model. + * + * @param root + */ + public void addModelRoot(T root) { + getResource().getContents().add(root); + } + + @Override + protected Map<Object, Object> getSaveOptions() { + if (modelKind == ModelKind.master) { + return super.getSaveOptions(); + } else { + return Collections.emptyMap(); + } + } + + @Override + protected boolean isSupportedRoot(EObject object) { + return isModelRoot(object); + } +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/AdjunctResourceModelSnippet.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/AdjunctResourceModelSnippet.java index baf04915476..dd2bd982217 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/AdjunctResourceModelSnippet.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/AdjunctResourceModelSnippet.java @@ -1,121 +1,121 @@ -/*****************************************************************************
- * Copyright (c) 2016 Christian W. Damus 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:
- * Christian W. Damus - Initial API and implementation
- * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Bug 496905
- *
- *****************************************************************************/
-
-package org.eclipse.papyrus.infra.core.resource;
-
-import java.util.Collections;
-
-import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.ecore.resource.URIConverter;
-import org.eclipse.papyrus.infra.core.Activator;
-
-/**
- * An {@link IModel} snippet that loads the model's corresponding resource
- * whenever a "primary" semantic resource is loaded that has a resource
- * corresponding to it that is managed by the {@code IModel}.
- *
- * @since 2.1
- */
-public class AdjunctResourceModelSnippet implements IModelSnippet {
- private EMFLogicalModel model;
- private Adapter adapter;
-
- /**
- * Initializes me.
- */
- public AdjunctResourceModelSnippet() {
- super();
- }
-
-
- @Override
- public void start(IModel startingModel) {
- if (startingModel instanceof EMFLogicalModel) {
- model = (EMFLogicalModel) startingModel;
-
- adapter = new ResourceAdapter() {
- @Override
- protected void handleResourceLoaded(Resource resource) {
- maybeLoadAdjunctResource(resource);
- }
- };
-
- model.getModelManager().eAdapters().add(adapter);
- }
- }
-
- @Override
- public void dispose(IModel stoppingModel) {
- if ((stoppingModel == model) && (adapter != null)) {
- model.getModelManager().eAdapters().remove(adapter);
- adapter = null;
- model = null;
- }
- }
-
- void maybeLoadAdjunctResource(Resource resource) {
- // If the parameter resource is the model's own kind of resource,
- // then there is nothing to do
- if ((model != null) && !model.isRelatedResource(resource)) {
- URI adjunctURI = resource.getURI().trimFileExtension().appendFileExtension(model.getModelFileExtension());
- ResourceSet resourceSet = resource.getResourceSet();
-
- boolean adjunctAlreadyLoaded = false;
- for (Resource loadedResource : resourceSet.getResources()) {
- if (loadedResource.getURI().equals(adjunctURI)) {
- adjunctAlreadyLoaded = true;
- break;
- }
- }
-
- if (!adjunctAlreadyLoaded && (resourceSet.getURIConverter() != null)) {
- URIConverter converter = resourceSet.getURIConverter();
-
- // If the di resource associated to the parameter resource exists,
- // then load it
- if (converter.exists(adjunctURI, Collections.emptyMap())) {
- // Best effort load. This must not interfere with other
- // resource set operations
- loadResource(model, resourceSet, adjunctURI);
- }
- }
- }
- }
-
- /**
- * This allows to load the model.
- *
- * @param model
- * The {@link EMFLogicalModel}.
- * @param resourceSet
- * The resource set.
- * @param adjunctURI
- * The adjunct URI.
- *
- * @since 3.0
- */
- protected void loadResource(final EMFLogicalModel model, final ResourceSet resourceSet, final URI adjunctURI) {
- try {
- resourceSet.getResource(adjunctURI, true);
- } catch (final Exception e) {
- Activator.log.error(
- String.format("Failed to load %s resource", model.getModelFileExtension()), //$NON-NLS-1$
- e);
- }
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2016 Christian W. Damus 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: + * Christian W. Damus - Initial API and implementation + * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Bug 496905 + * + *****************************************************************************/ + +package org.eclipse.papyrus.infra.core.resource; + +import java.util.Collections; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.URIConverter; +import org.eclipse.papyrus.infra.core.Activator; + +/** + * An {@link IModel} snippet that loads the model's corresponding resource + * whenever a "primary" semantic resource is loaded that has a resource + * corresponding to it that is managed by the {@code IModel}. + * + * @since 2.1 + */ +public class AdjunctResourceModelSnippet implements IModelSnippet { + private EMFLogicalModel model; + private Adapter adapter; + + /** + * Initializes me. + */ + public AdjunctResourceModelSnippet() { + super(); + } + + + @Override + public void start(IModel startingModel) { + if (startingModel instanceof EMFLogicalModel) { + model = (EMFLogicalModel) startingModel; + + adapter = new ResourceAdapter() { + @Override + protected void handleResourceLoaded(Resource resource) { + maybeLoadAdjunctResource(resource); + } + }; + + model.getModelManager().eAdapters().add(adapter); + } + } + + @Override + public void dispose(IModel stoppingModel) { + if ((stoppingModel == model) && (adapter != null)) { + model.getModelManager().eAdapters().remove(adapter); + adapter = null; + model = null; + } + } + + void maybeLoadAdjunctResource(Resource resource) { + // If the parameter resource is the model's own kind of resource, + // then there is nothing to do + if ((model != null) && !model.isRelatedResource(resource)) { + URI adjunctURI = resource.getURI().trimFileExtension().appendFileExtension(model.getModelFileExtension()); + ResourceSet resourceSet = resource.getResourceSet(); + + boolean adjunctAlreadyLoaded = false; + for (Resource loadedResource : resourceSet.getResources()) { + if (loadedResource.getURI().equals(adjunctURI)) { + adjunctAlreadyLoaded = true; + break; + } + } + + if (!adjunctAlreadyLoaded && (resourceSet.getURIConverter() != null)) { + URIConverter converter = resourceSet.getURIConverter(); + + // If the di resource associated to the parameter resource exists, + // then load it + if (converter.exists(adjunctURI, Collections.emptyMap())) { + // Best effort load. This must not interfere with other + // resource set operations + loadResource(model, resourceSet, adjunctURI); + } + } + } + } + + /** + * This allows to load the model. + * + * @param model + * The {@link EMFLogicalModel}. + * @param resourceSet + * The resource set. + * @param adjunctURI + * The adjunct URI. + * + * @since 3.0 + */ + protected void loadResource(final EMFLogicalModel model, final ResourceSet resourceSet, final URI adjunctURI) { + try { + resourceSet.getResource(adjunctURI, true); + } catch (final Exception e) { + Activator.log.error( + String.format("Failed to load %s resource", model.getModelFileExtension()), //$NON-NLS-1$ + e); + } + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/BadArgumentExcetion.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/BadArgumentExcetion.java index 970c23130cc..59f719aa29e 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/BadArgumentExcetion.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/BadArgumentExcetion.java @@ -1,80 +1,80 @@ -/*****************************************************************************
- * Copyright (c) 2014 Cedric Dumoulin.
- *
- *
- * 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:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-
-package org.eclipse.papyrus.infra.core.resource;
-
-
-/**
- * Exception thrown when an argument is invalid.
- *
- * @author cedric dumoulin
- *
- */
-public class BadArgumentExcetion extends Exception {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor.
- *
- */
- public BadArgumentExcetion() {
- super();
- }
-
- /**
- * Constructor.
- *
- * @param message
- */
- public BadArgumentExcetion(String message) {
- super(message);
- }
-
- /**
- * Constructor.
- *
- * @param cause
- */
- public BadArgumentExcetion(Throwable cause) {
- super(cause);
- }
-
- /**
- * Constructor.
- *
- * @param message
- * @param cause
- */
- public BadArgumentExcetion(String message, Throwable cause) {
- super(message, cause);
- }
-
- /**
- * Constructor.
- *
- * @param message
- * @param cause
- * @param enableSuppression
- * @param writableStackTrace
- * Remove temporarily (because of incompatibility with current Java version)
- */
- // public BadArgumentExcetion(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
- // super(message, cause, enableSuppression, writableStackTrace);
- // }
-
-}
+/***************************************************************************** + * Copyright (c) 2014 Cedric Dumoulin. + * + * + * 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: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.infra.core.resource; + + +/** + * Exception thrown when an argument is invalid. + * + * @author cedric dumoulin + * + */ +public class BadArgumentExcetion extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Constructor. + * + */ + public BadArgumentExcetion() { + super(); + } + + /** + * Constructor. + * + * @param message + */ + public BadArgumentExcetion(String message) { + super(message); + } + + /** + * Constructor. + * + * @param cause + */ + public BadArgumentExcetion(Throwable cause) { + super(cause); + } + + /** + * Constructor. + * + * @param message + * @param cause + */ + public BadArgumentExcetion(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructor. + * + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + * Remove temporarily (because of incompatibility with current Java version) + */ + // public BadArgumentExcetion(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + // super(message, cause, enableSuppression, writableStackTrace); + // } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/BadStateException.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/BadStateException.java index 768e2dce73b..eda278978f4 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/BadStateException.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/BadStateException.java @@ -1,60 +1,60 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.resource;
-
-/**
- * Exception thrown when a method is called while the object state is not ready
- * for this call.
- *
- * @author cedric dumoulin
- *
- */
-public class BadStateException extends Exception {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor.
- *
- */
- public BadStateException() {
- super();
-
- }
-
- /**
- * Constructor.
- *
- * @param message
- * @param cause
- */
- public BadStateException(String message, Throwable cause) {
- super(message, cause);
-
- }
-
- /**
- * Constructor.
- *
- * @param message
- */
- public BadStateException(String message) {
- super(message);
-
- }
-
- /**
- * Constructor.
- *
- * @param cause
- */
- public BadStateException(Throwable cause) {
- super(cause);
-
- }
-
-}
+/** + * + */ +package org.eclipse.papyrus.infra.core.resource; + +/** + * Exception thrown when a method is called while the object state is not ready + * for this call. + * + * @author cedric dumoulin + * + */ +public class BadStateException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Constructor. + * + */ + public BadStateException() { + super(); + + } + + /** + * Constructor. + * + * @param message + * @param cause + */ + public BadStateException(String message, Throwable cause) { + super(message, cause); + + } + + /** + * Constructor. + * + * @param message + */ + public BadStateException(String message) { + super(message); + + } + + /** + * Constructor. + * + * @param cause + */ + public BadStateException(Throwable cause) { + super(cause); + + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/EditingDomainServiceFactory.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/EditingDomainServiceFactory.java index f93b9be657a..0615e418654 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/EditingDomainServiceFactory.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/EditingDomainServiceFactory.java @@ -1,63 +1,63 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.resource;
-
-import org.eclipse.papyrus.infra.core.services.IServiceFactory;
-import org.eclipse.papyrus.infra.core.services.ServiceException;
-import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
-
-/**
- * A service factory starting the EditingDomain service.
- *
- * @author cedric dumoulin
- *
- */
-public class EditingDomainServiceFactory implements IServiceFactory {
-
- /**
- * The associated ModelSet. This service depends on the ModelSet service.
- * So, we can get it in the init.
- */
- private ModelSet modelSet;
-
- /**
- * @see org.eclipse.papyrus.infra.core.services.IService#init(org.eclipse.papyrus.infra.core.services.ServicesRegistry)
- *
- * @param servicesRegistry
- * @throws ServiceException
- */
- @Override
- public void init(ServicesRegistry servicesRegistry) throws ServiceException {
- modelSet = servicesRegistry.getService(ModelSet.class);
- }
-
- /**
- * @see org.eclipse.papyrus.infra.core.services.IService#startService()
- *
- * @throws ServiceException
- */
- @Override
- public void startService() throws ServiceException {
- }
-
- /**
- * @see org.eclipse.papyrus.infra.core.services.IService#disposeService()
- *
- * @throws ServiceException
- */
- @Override
- public void disposeService() throws ServiceException {
- }
-
- /**
- * @see org.eclipse.papyrus.infra.core.services.IServiceFactory#createServiceInstance()
- *
- * @return
- */
- @Override
- public Object createServiceInstance() {
- return modelSet.getTransactionalEditingDomain();
- }
-
-}
+/** + * + */ +package org.eclipse.papyrus.infra.core.resource; + +import org.eclipse.papyrus.infra.core.services.IServiceFactory; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.services.ServicesRegistry; + +/** + * A service factory starting the EditingDomain service. + * + * @author cedric dumoulin + * + */ +public class EditingDomainServiceFactory implements IServiceFactory { + + /** + * The associated ModelSet. This service depends on the ModelSet service. + * So, we can get it in the init. + */ + private ModelSet modelSet; + + /** + * @see org.eclipse.papyrus.infra.core.services.IService#init(org.eclipse.papyrus.infra.core.services.ServicesRegistry) + * + * @param servicesRegistry + * @throws ServiceException + */ + @Override + public void init(ServicesRegistry servicesRegistry) throws ServiceException { + modelSet = servicesRegistry.getService(ModelSet.class); + } + + /** + * @see org.eclipse.papyrus.infra.core.services.IService#startService() + * + * @throws ServiceException + */ + @Override + public void startService() throws ServiceException { + } + + /** + * @see org.eclipse.papyrus.infra.core.services.IService#disposeService() + * + * @throws ServiceException + */ + @Override + public void disposeService() throws ServiceException { + } + + /** + * @see org.eclipse.papyrus.infra.core.services.IServiceFactory#createServiceInstance() + * + * @return + */ + @Override + public Object createServiceInstance() { + return modelSet.getTransactionalEditingDomain(); + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IModelSetSnippet.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IModelSetSnippet.java index 9dde759af22..dd258c084a3 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IModelSetSnippet.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IModelSetSnippet.java @@ -1,32 +1,32 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.resource;
-
-/**
- * A model snippet can be used to add code that should do some stuff on a
- * modelsManager. A ModelSnippet is attached to a modelsManager, and is called
- * after modelsManager is started and just before it is disposed.
- *
- *
- * @author cedric dumoulin
- *
- */
-public interface IModelSetSnippet {
-
- /**
- * Called right after the model is started.
- *
- * @param modelsManager
- * The modelsManager that is starting
- */
- public void start(ModelSet modelsManager);
-
- /**
- * Called just before the model is disposed or unloaded.
- *
- * @param modelsManager
- * The modelsManager that is starting
- */
- public void dispose(ModelSet modelsManager);
-}
+/** + * + */ +package org.eclipse.papyrus.infra.core.resource; + +/** + * A model snippet can be used to add code that should do some stuff on a + * modelsManager. A ModelSnippet is attached to a modelsManager, and is called + * after modelsManager is started and just before it is disposed. + * + * + * @author cedric dumoulin + * + */ +public interface IModelSetSnippet { + + /** + * Called right after the model is started. + * + * @param modelsManager + * The modelsManager that is starting + */ + public void start(ModelSet modelsManager); + + /** + * Called just before the model is disposed or unloaded. + * + * @param modelsManager + * The modelsManager that is starting + */ + public void dispose(ModelSet modelsManager); +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IModelSnippet.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IModelSnippet.java index 6b714ea499d..ee1acc31263 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IModelSnippet.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IModelSnippet.java @@ -1,32 +1,32 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.resource;
-
-/**
- * A model snippet can be used to add code that should do some stuff on a model.
- * A ModelSnippet is attached to a model, and is called after model starting and
- * when model is disposed.
- *
- *
- * @author cedric dumoulin
- *
- */
-public interface IModelSnippet {
-
- /**
- * Called right after the model is started.
- *
- * @param startingModel
- * The model that is starting
- */
- public void start(IModel startingModel);
-
- /**
- * Called just before the model is disposed or unloaded.
- *
- * @param stoppingModel
- * The model that is starting
- */
- public void dispose(IModel stoppingModel);
-}
+/** + * + */ +package org.eclipse.papyrus.infra.core.resource; + +/** + * A model snippet can be used to add code that should do some stuff on a model. + * A ModelSnippet is attached to a model, and is called after model starting and + * when model is disposed. + * + * + * @author cedric dumoulin + * + */ +public interface IModelSnippet { + + /** + * Called right after the model is started. + * + * @param startingModel + * The model that is starting + */ + public void start(IModel startingModel); + + /** + * Called just before the model is disposed or unloaded. + * + * @param stoppingModel + * The model that is starting + */ + public void dispose(IModel stoppingModel); +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IReadOnlyHandler.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IReadOnlyHandler.java index c45f85bc471..009e53a5a8f 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IReadOnlyHandler.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IReadOnlyHandler.java @@ -1,89 +1,89 @@ -/*****************************************************************************
- * Copyright (c) 2011, 2014 Atos Origin, CEA, 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:
- * Mathieu Velten (Atos Origin) mathieu.velten@atosorigin.com - Initial API and implementation
- * Christian W. Damus (CEA) - bug 429826
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.resource;
-
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.edit.domain.EditingDomain;
-
-import com.google.common.base.Optional;
-
-/**
- * A pluggable handler determining whether a resource is "read only" (not writable). Implementations
- * of this interface, if they do not implement {@link IReadOnlyHandler2}, implicitly determine
- * read-only-ness according to the {@linkplain ReadOnlyAxis#PERMISSION permission axis}.
- *
- * @see IReadOnlyHandler2
- * @see ReadOnlyAxis#PERMISSION
- */
-public interface IReadOnlyHandler {
-
- /**
- * Queries whether any of the resources identified by the given URIs is
- * read-only.
- *
- * @param uris
- * the URIs about which read-only-ness is to be determined
- *
- * @return {@link Optional#absent() absent} if I do not know whether any of
- * the URIs is read-only or a {@link Optional#isPresent() present} boolean indicating whether any definitively is or they all
- * definitively are not read-only
- */
- Optional<Boolean> anyReadOnly(URI[] uris);
-
- /**
- * Attempt to ensure that the resources identified by the given URIs are
- * writable.
- *
- * @param uris
- * the URIs of resources to make writable (not all are
- * necessarily read-only)
- *
- * @return {@link Optional#absent() absent} if I do not know how to make
- * these resources writable and the next provider should be given a
- * chance, or a {@link Optional#isPresent() present} boolean
- * indicating that I made the resources writable ({@code true}) or
- * they cannot be made writable ({@code false})
- */
- Optional<Boolean> makeWritable(URI[] uris);
-
- /**
- * Queries whether an {@code eObject} is individually read-only in a given
- * editing domain, if it is in a resource that supports object-level
- * read/write permissions.
- *
- * @param eObject
- * an element in some model resource
- *
- * @return {@link Optional#absent() absent} if I do not know whether the {@code eObject} is read-only or a {@link Optional#isPresent()
- * present} boolean indicating whether it definitively is or is not
- * read-only
- */
- Optional<Boolean> isReadOnly(EObject eObject);
-
- /**
- * Attempt to ensure that the given {@code eObject} is writable.
- *
- * @param eObject
- * a {@linkplain #isReadOnly(EObject, EditingDomain) read-only} element in some model resource
- *
- * @return {@link Optional#absent() absent} if I do not know how to make
- * this object writable and the next provider should be given a
- * chance, or a {@link Optional#isPresent() present} boolean
- * indicating that I made it writable ({@code true}) or it cannot be
- * made writable ({@code false})
- */
- Optional<Boolean> makeWritable(EObject eObject);
-}
+/***************************************************************************** + * Copyright (c) 2011, 2014 Atos Origin, CEA, 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: + * Mathieu Velten (Atos Origin) mathieu.velten@atosorigin.com - Initial API and implementation + * Christian W. Damus (CEA) - bug 429826 + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.resource; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.edit.domain.EditingDomain; + +import com.google.common.base.Optional; + +/** + * A pluggable handler determining whether a resource is "read only" (not writable). Implementations + * of this interface, if they do not implement {@link IReadOnlyHandler2}, implicitly determine + * read-only-ness according to the {@linkplain ReadOnlyAxis#PERMISSION permission axis}. + * + * @see IReadOnlyHandler2 + * @see ReadOnlyAxis#PERMISSION + */ +public interface IReadOnlyHandler { + + /** + * Queries whether any of the resources identified by the given URIs is + * read-only. + * + * @param uris + * the URIs about which read-only-ness is to be determined + * + * @return {@link Optional#absent() absent} if I do not know whether any of + * the URIs is read-only or a {@link Optional#isPresent() present} boolean indicating whether any definitively is or they all + * definitively are not read-only + */ + Optional<Boolean> anyReadOnly(URI[] uris); + + /** + * Attempt to ensure that the resources identified by the given URIs are + * writable. + * + * @param uris + * the URIs of resources to make writable (not all are + * necessarily read-only) + * + * @return {@link Optional#absent() absent} if I do not know how to make + * these resources writable and the next provider should be given a + * chance, or a {@link Optional#isPresent() present} boolean + * indicating that I made the resources writable ({@code true}) or + * they cannot be made writable ({@code false}) + */ + Optional<Boolean> makeWritable(URI[] uris); + + /** + * Queries whether an {@code eObject} is individually read-only in a given + * editing domain, if it is in a resource that supports object-level + * read/write permissions. + * + * @param eObject + * an element in some model resource + * + * @return {@link Optional#absent() absent} if I do not know whether the {@code eObject} is read-only or a {@link Optional#isPresent() + * present} boolean indicating whether it definitively is or is not + * read-only + */ + Optional<Boolean> isReadOnly(EObject eObject); + + /** + * Attempt to ensure that the given {@code eObject} is writable. + * + * @param eObject + * a {@linkplain #isReadOnly(EObject, EditingDomain) read-only} element in some model resource + * + * @return {@link Optional#absent() absent} if I do not know how to make + * this object writable and the next provider should be given a + * chance, or a {@link Optional#isPresent() present} boolean + * indicating that I made it writable ({@code true}) or it cannot be + * made writable ({@code false}) + */ + Optional<Boolean> makeWritable(EObject eObject); +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ITransactionalEditingDomainProvider.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ITransactionalEditingDomainProvider.java index b3e76221a2f..e12bd61d008 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ITransactionalEditingDomainProvider.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ITransactionalEditingDomainProvider.java @@ -1,29 +1,29 @@ -/*****************************************************************************
- * Copyright (c) 2011-2012 Atos.
- *
- *
- * 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:
- * Mathieu Velten mathieu.velten@atos.net - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.resource;
-
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.transaction.TransactionalEditingDomain;
-
-/**
- * Classes implementing this interface can provide a way to create editing domain to Papyrus
- * environment. The provider registered on the transactionalEditingDomainProvider extension point
- * with the higher priority will be used by Papyrus to create Editing Domain.
- *
- * @author mvelten
- *
- */
-public interface ITransactionalEditingDomainProvider {
- TransactionalEditingDomain createTransactionalEditingDomain(ResourceSet resourceSet);
-}
+/***************************************************************************** + * Copyright (c) 2011-2012 Atos. + * + * + * 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: + * Mathieu Velten mathieu.velten@atos.net - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.resource; + +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.transaction.TransactionalEditingDomain; + +/** + * Classes implementing this interface can provide a way to create editing domain to Papyrus + * environment. The provider registered on the transactionalEditingDomainProvider extension point + * with the higher priority will be used by Papyrus to create Editing Domain. + * + * @author mvelten + * + */ +public interface ITransactionalEditingDomainProvider { + TransactionalEditingDomain createTransactionalEditingDomain(ResourceSet resourceSet); +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IVersionableModel.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IVersionableModel.java index 5a12d3ea9ea..9343a3d54e3 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IVersionableModel.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IVersionableModel.java @@ -1,30 +1,30 @@ -/*****************************************************************************
- * Copyright (c) 2013 CEA LIST.
- *
- * 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:
- * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.resource;
-
-import java.util.Map;
-
-import org.eclipse.core.runtime.IPath;
-
-
-public interface IVersionableModel extends IModel {
-
- /**
- * Saves a copy of this model to the specified path. The model itself
- * shouldn't be modified in the operation
- *
- * @param targetWithoutExtension
- */
- public void saveCopy(IPath targetPathWithoutExtension, Map<Object, Object> targetMap);
-
- public void fillTargetMap(IPath targetPathWithoutExtension, Map<Object, Object> targetMap);
-}
+/***************************************************************************** + * Copyright (c) 2013 CEA LIST. + * + * 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: + * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.resource; + +import java.util.Map; + +import org.eclipse.core.runtime.IPath; + + +public interface IVersionableModel extends IModel { + + /** + * Saves a copy of this model to the specified path. The model itself + * shouldn't be modified in the operation + * + * @param targetWithoutExtension + */ + public void saveCopy(IPath targetPathWithoutExtension, Map<Object, Object> targetMap); + + public void fillTargetMap(IPath targetPathWithoutExtension, Map<Object, Object> targetMap); +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelException.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelException.java index 5d48fb6576c..aa2e986df94 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelException.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelException.java @@ -1,54 +1,54 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.resource;
-
-/**
- * Root exception for this package.
- *
- * @author cedric dumoulin
- *
- */
-public class ModelException extends Exception {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor.
- *
- */
- public ModelException() {
- }
-
- /**
- * Constructor.
- *
- * @param message
- */
- public ModelException(String message) {
- super(message);
- }
-
- /**
- * Constructor.
- *
- * @param cause
- */
- public ModelException(Throwable cause) {
- super(cause);
- }
-
- /**
- * Constructor.
- *
- * @param message
- * @param cause
- */
- public ModelException(String message, Throwable cause) {
- super(message, cause);
- }
-
-}
+/** + * + */ +package org.eclipse.papyrus.infra.core.resource; + +/** + * Root exception for this package. + * + * @author cedric dumoulin + * + */ +public class ModelException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Constructor. + * + */ + public ModelException() { + } + + /** + * Constructor. + * + * @param message + */ + public ModelException(String message) { + super(message); + } + + /** + * Constructor. + * + * @param cause + */ + public ModelException(Throwable cause) { + super(cause); + } + + /** + * Constructor. + * + * @param message + * @param cause + */ + public ModelException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelIdentifiers.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelIdentifiers.java index 5cfbce8cc3e..f6c37fda022 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelIdentifiers.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelIdentifiers.java @@ -1,28 +1,28 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.resource;
-
-import java.util.ArrayList;
-
-/**
- * A collection of Identifiers identifying Models.
- *
- * @author cedric dumoulin
- *
- */
-public class ModelIdentifiers extends ArrayList<String> {
-
- public ModelIdentifiers(String... modelIdentifiers) {
-
- for (String identifier : modelIdentifiers) {
- add(identifier);
- }
- }
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
-}
+/** + * + */ +package org.eclipse.papyrus.infra.core.resource; + +import java.util.ArrayList; + +/** + * A collection of Identifiers identifying Models. + * + * @author cedric dumoulin + * + */ +public class ModelIdentifiers extends ArrayList<String> { + + public ModelIdentifiers(String... modelIdentifiers) { + + for (String identifier : modelIdentifiers) { + add(identifier); + } + } + + /** + * + */ + private static final long serialVersionUID = 1L; + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelMultiException.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelMultiException.java index b29a244d0ad..edb2a97721b 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelMultiException.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelMultiException.java @@ -1,140 +1,140 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.resource;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * An exception encapsulating multiple exceptions. This exception is thrown when
- * an operation performed on several Models fails on one or more of these
- * models. The exception contains all the exceptions encoutered while opertating
- * on models.
- *
- * @author cedric dumoulin
- *
- */
-public class ModelMultiException extends ModelException {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * List of encountered exceptions.
- */
- List<Throwable> encounteredExceptions = new ArrayList<Throwable>();
-
- /**
- * List of identifiers corresponding to exceptions.
- */
- List<Object> encounteredModels = new ArrayList<Object>();
-
- /**
- * @return the encounteredExceptions
- */
- public List<Throwable> getExceptions() {
- return encounteredExceptions;
- }
-
- /**
- * Constructor.
- *
- */
- public ModelMultiException() {
- super("Multiple exceptions");
- }
-
- /**
- * Constructor.
- *
- * @param message
- */
- public ModelMultiException(String message) {
- super(message);
- }
-
- /**
- * Return the first exception.
- *
- * @see java.lang.Throwable#getCause()
- *
- * @return
- */
- @Override
- public Throwable getCause() {
- return (encounteredExceptions.size() > 0 ? encounteredExceptions.get(0) : null);
- }
-
- /**
- * Return the message if any, or the message of the first exception.
- *
- * @see java.lang.Throwable#getMessage()
- *
- * @return
- */
- @Override
- public String getMessage() {
-
- StringBuffer buffer = new StringBuffer();
-
- String message = super.getMessage();
- if (message != null) {
- buffer.append(message).append('\n');
- }
-
- buffer.append("----- exceptions : ----------\n");
- for (int i = 0; i < encounteredExceptions.size(); i++) {
- Throwable exception = encounteredExceptions.get(i);
- Object identifierMsg = encounteredModels.get(i);
-
- if (identifierMsg != null) {
- buffer.append(identifierMsg.toString()).append(" : ");
- }
- String msg = exception.getMessage();
- if (msg != null) {
- buffer.append(msg).append('\n');
- }
- }
- buffer.append("----------------------------- \n");
-
- return buffer.toString();
- // // Check for first exception
- // if( encounteredExceptions.size() > 1)
- // return encounteredExceptions.get(0).getMessage();
- //
- // // default
- // return null;
- }
-
- /**
- * Add an exception to the list of exceptions.
- *
- * @param exception
- */
- public void addException(Throwable exception) {
- addException("unknown", exception);
- }
-
- /**
- * Add an exception to the list of exceptions. Also record the corresponding
- * model identifier if any.
- *
- * @param exception
- */
- public void addException(Object identifier, Throwable exception) {
- encounteredExceptions.add(exception);
- encounteredModels.add(identifier);
- }
-
- /**
- * Return true if this MultiExceptions contains nested exceptions.
- *
- * @return
- */
- public boolean isNotEmpty() {
- return encounteredExceptions.size() != 0;
- }
-}
+/** + * + */ +package org.eclipse.papyrus.infra.core.resource; + +import java.util.ArrayList; +import java.util.List; + +/** + * An exception encapsulating multiple exceptions. This exception is thrown when + * an operation performed on several Models fails on one or more of these + * models. The exception contains all the exceptions encoutered while opertating + * on models. + * + * @author cedric dumoulin + * + */ +public class ModelMultiException extends ModelException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * List of encountered exceptions. + */ + List<Throwable> encounteredExceptions = new ArrayList<Throwable>(); + + /** + * List of identifiers corresponding to exceptions. + */ + List<Object> encounteredModels = new ArrayList<Object>(); + + /** + * @return the encounteredExceptions + */ + public List<Throwable> getExceptions() { + return encounteredExceptions; + } + + /** + * Constructor. + * + */ + public ModelMultiException() { + super("Multiple exceptions"); + } + + /** + * Constructor. + * + * @param message + */ + public ModelMultiException(String message) { + super(message); + } + + /** + * Return the first exception. + * + * @see java.lang.Throwable#getCause() + * + * @return + */ + @Override + public Throwable getCause() { + return (encounteredExceptions.size() > 0 ? encounteredExceptions.get(0) : null); + } + + /** + * Return the message if any, or the message of the first exception. + * + * @see java.lang.Throwable#getMessage() + * + * @return + */ + @Override + public String getMessage() { + + StringBuffer buffer = new StringBuffer(); + + String message = super.getMessage(); + if (message != null) { + buffer.append(message).append('\n'); + } + + buffer.append("----- exceptions : ----------\n"); + for (int i = 0; i < encounteredExceptions.size(); i++) { + Throwable exception = encounteredExceptions.get(i); + Object identifierMsg = encounteredModels.get(i); + + if (identifierMsg != null) { + buffer.append(identifierMsg.toString()).append(" : "); + } + String msg = exception.getMessage(); + if (msg != null) { + buffer.append(msg).append('\n'); + } + } + buffer.append("----------------------------- \n"); + + return buffer.toString(); + // // Check for first exception + // if( encounteredExceptions.size() > 1) + // return encounteredExceptions.get(0).getMessage(); + // + // // default + // return null; + } + + /** + * Add an exception to the list of exceptions. + * + * @param exception + */ + public void addException(Throwable exception) { + addException("unknown", exception); + } + + /** + * Add an exception to the list of exceptions. Also record the corresponding + * model identifier if any. + * + * @param exception + */ + public void addException(Object identifier, Throwable exception) { + encounteredExceptions.add(exception); + encounteredModels.add(identifier); + } + + /** + * Return true if this MultiExceptions contains nested exceptions. + * + * @return + */ + public boolean isNotEmpty() { + return encounteredExceptions.size() != 0; + } +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelSet.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelSet.java index 44cc5e9eefa..9a81de681d0 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelSet.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelSet.java @@ -1,1326 +1,1326 @@ -/*****************************************************************************
- * Copyright (c) 2008, 2016 CEA LIST, Christian W. Damus, 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:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- * Emilien Perico emilien.perico@atosorigin.com - manage loading strategies
- * Christian W. Damus (CEA) - manage models by URI, not IFile (CDO)
- * Christian W. Damus (CEA) - Support read-only state at object level (CDO)
- * Christian W. Damus (CEA) - Refactoring of Create Model Wizard (CDO)
- * Christian W. Damus (CEA LIST) - Controlled resources in CDO repositories
- * Christian W. Damus (CEA) - bugs 429826, 432813, 437052
- * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Bug 436952
- * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Bug 436998
- * Christian W. Damus - bugs 436998, 468030, 485220
- * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Bug 496905
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.resource;
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.core.filesystem.EFS;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
-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.util.EList;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.common.util.WrappedException;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.emf.ecore.xmi.XMLResource;
-import org.eclipse.emf.edit.domain.EditingDomain;
-import org.eclipse.emf.transaction.TransactionalEditingDomain;
-import org.eclipse.emf.transaction.impl.EditingDomainManager;
-import org.eclipse.papyrus.infra.core.Activator;
-import org.eclipse.papyrus.infra.core.editor.ModelSetServiceFactory;
-import org.eclipse.papyrus.infra.core.language.ILanguage;
-import org.eclipse.papyrus.infra.core.language.ILanguageService;
-import org.eclipse.papyrus.infra.core.resource.additional.AdditionalResourcesModel;
-import org.eclipse.papyrus.infra.core.utils.ServiceUtils;
-import org.eclipse.papyrus.infra.tools.util.PlatformHelper;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-
-/**
- * This class is used to manage a set of {@link IModel}.
- *
- * <h2>>Usage</h2>
- * <ul>
- * <li>First, register associated model. A loader can be used.</li>
- * <li>Second, call load() or create()</li>
- * <li>Then, it is possible to get associated models</li>
- * <li>Finally, call save()</li>
- * </ul>
- *
- * Please note that indirectly referenced models are loaded on demand. If a
- * model contains a cross reference towards another model (e.g. an import in
- * case of UML) the referenced resource does not appear initially in the set.
- * However, it is added once the referenced model is resolved.
- *
- * TODO Modify ModelSetSnippet in order to inform them of model addition.
- *
- * @author cedric dumoulin
- *
- */
-public class ModelSet extends ResourceSetImpl {
-
- /**
- * Id use to register the EditinDomain into the registry
- */
- public static final String PAPYRUS_EDITING_DOMAIN_ID = "org.eclipse.papyrus.SharedEditingDomainID";
-
- /** The associated IModels. */
- protected Map<String, IModel> models = new HashMap<String, IModel>();
-
- /** The snippets. */
- protected ModelSetSnippetList snippets = new ModelSetSnippetList();
-
- protected AdditionalResourcesModel additional = new AdditionalResourcesModel();
-
- /**
- * The associated EditingDomain.
- */
- protected TransactionalEditingDomain transactionalEditingDomain;
-
- /**
- * The URI, without extension, used for action on models.
- */
- protected URI uriWithoutExtension;
-
- protected Adapter modificationTrackingAdapter;
-
- protected IReadOnlyHandler2 roHandler;
-
- /**
- * URI pointing to resource on which back end should be deleted on save
- * One example of use is empty uncontrolled resources
- */
- protected Set<URI> toDeleteOnSave = new HashSet<URI>();
-
- /** list of listeners of resources to know if the resource are loaded or not */
- protected ArrayList<IResourceLoadStateListener> resourceLoadStateListeners;
-
- /** map of resource loaded in the resource set, with resource as the key and a boolean indicating if the resource is loaded or not has the valuer */
- protected Map<Resource, Boolean> resourcesToLoadState = new HashMap<Resource, Boolean>();
-
- private List<ILanguage> languages;
-
- /**
- *
- * Constructor.
- *
- */
- public ModelSet() {
- registerModel(additional);
- setTrackingModification(true);
-
- getLoadOptions().put(XMLResource.OPTION_DEFER_ATTACHMENT, true);
- getLoadOptions().put(XMLResource.OPTION_DEFER_IDREF_RESOLUTION, true);
- getLoadOptions().put(XMLResource.OPTION_LAX_FEATURE_PROCESSING, Boolean.TRUE);
- getLoadOptions().put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE);
- getLoadOptions().put(XMLResource.OPTION_USE_PACKAGE_NS_URI_AS_LOCATION, Boolean.FALSE);
-
- this.eAdapters.add(new ResourceAddRemoveTracker());
- }
-
- /**
- * Register the specified model under its associated key. The key is defined
- * in the model itself. It is usually the model type from
- * (ModelPackage.eCONTENT_TYPE).
- *
- * @param model
- * the model
- */
- public void registerModel(IModel model) {
- IModel existing = models.get(model.getIdentifier());
- if ((existing == null) || existing.getClass().isAssignableFrom(model.getClass().getSuperclass())) {
- // only add this model if it is the first instance for its identifier
- // or it's an instance of a subclass
- doRegisterModel(model);
- }
- }
-
- protected void doRegisterModel(IModel model) {
- models.put(model.getIdentifier(), model);
- model.init(this);
- }
-
- /**
- * Get a model by its key. TODO throw an exception if not found.
- *
- * @param key
- * the key
- * @return the model
- */
- public IModel getModel(String key) {
- return models.get(key);
- }
-
- /**
- * Get a model by its key. TODO throw an exception if not found.
- *
- * @param key
- * the key
- * @return the model
- * @throws NotFoundException
- * If no model is registered under the key.
- */
- public IModel getModelChecked(String key) throws NotFoundException {
- IModel model = models.get(key);
- if (model == null) {
- throw new NotFoundException("Can't find model for identifier '" + key + "'.");
- }
-
- return model;
- }
-
- @Override
- public Resource createResource(URI uri, String contentType) {
- return setResourceOptions(super.createResource(uri, contentType));
- }
-
- @Override
- public Resource getResource(URI uri, boolean loadOnDemand) throws WrappedException {
- if (uri.hasFragment()) {
- Activator.log.warn("Invalid Resource URI: resource URIs cannot contain a fragment"); //$NON-NLS-1$
- uri = uri.trimFragment(); // Fix and continue
- }
- Resource r = null;
- try {
- r = super.getResource(uri, loadOnDemand);
- } catch (WrappedException e) {
- // Activator.log.error(e);
- if (ModelUtils.isDegradedModeAllowed(e.getCause())) {
- try {
- r = super.getResource(uri, false);
- } catch (WrappedException ee) {
- throw ee;
- }
- } else {
- // don't log, but throw error again, bug 405047 - [core] FileNotFoundException during MARTE profile loads
- throw e;
- }
- }
-
- return r != null && r.isLoaded() ? r : setResourceOptions(r);
- }
-
- @Override
- protected void handleDemandLoadException(Resource resource, IOException exception) throws RuntimeException {
- super.handleDemandLoadException(resource, exception);
- }
-
- public void setTrackingModification(boolean isTrackingModification) {
- boolean oldIsTrackingModification = modificationTrackingAdapter != null;
-
- if (oldIsTrackingModification != isTrackingModification) {
- if (isTrackingModification) {
- modificationTrackingAdapter = createModificationTrackingAdapter();
- this.eAdapters().add(modificationTrackingAdapter);
- } else {
- Adapter oldModificationTrackingAdapter = modificationTrackingAdapter;
- modificationTrackingAdapter = null;
- this.eAdapters().remove(oldModificationTrackingAdapter);
- }
- }
- }
-
- protected Adapter createModificationTrackingAdapter() {
- return new ProxyModificationTrackingAdapter();
- }
-
- public boolean isTrackingModification() {
- return modificationTrackingAdapter != null;
- }
-
- /**
- * Queries whether a {@code resource} managed by me is either known to be or assumed to be needing to be saved.
- * Generally this is true for resources that have been modified since the last save and that are saveable
- * (not read-only and correctly and completely loaded in the first place).
- *
- * @param resource
- * a resource that I manage
- *
- * @return whether the {@code resource} currently needs to be saved
- */
- public boolean shouldSave(Resource resource) {
- boolean result;
-
- if (getTransactionalEditingDomain().isReadOnly(resource) || ModelUtils.resourceFailedOnLoad(resource)) {
- result = false;
- } else if (!getURIConverter().exists(resource.getURI(), null)) {
- // If the resource needs to be created, it needs to be saved
- result = true;
- } else if (modificationTrackingAdapter instanceof ProxyModificationTrackingAdapter) {
- result = ((ProxyModificationTrackingAdapter) modificationTrackingAdapter).shouldSave(resource);
- } else if (modificationTrackingAdapter != null) {
- result = !resource.isTrackingModification() || resource.isModified();
- } else {
- // Assume that the resource is modified since the last save
- result = true;
- }
-
- return result;
- }
-
- /**
- * @deprecated please use {@link #getAssociatedResource(EObject, String, boolean)} instead
- *
- * @param modelElement
- * @param associatedResourceExtension
- * @return
- */
- @Deprecated
- public Resource getAssociatedResource(EObject modelElement, String associatedResourceExtension) {
- return getAssociatedResource(modelElement, associatedResourceExtension, true);
- }
-
- /**
- * @deprecated please use {@link #getAssociatedResource(Resource, String, boolean)} instead
- *
- * @param modelResource
- * @param associatedResourceExtension
- * @return
- */
- @Deprecated
- public Resource getAssociatedResource(Resource modelResource, String associatedResourceExtension) {
- return getAssociatedResource(modelResource, associatedResourceExtension, true);
- }
-
- /**
- * Retrieve and load the associated resource which have the given extension.
- *
- * @param modelElement
- * @param associatedResourceExtension
- * @param loadOnDemand
- * same as for getResource
- * @return
- */
- public Resource getAssociatedResource(EObject modelElement, String associatedResourceExtension, boolean loadOnDemand) {
- if (modelElement != null) {
- return getAssociatedResource(modelElement.eResource(), associatedResourceExtension, loadOnDemand);
- }
- return null;
- }
-
- /**
- * Retrieve and load the associated resource which have the given extension.
- *
- * @param modelResource
- * @param associatedResourceExtension
- * @param loadOnDemand
- * same as for getResource
- * @return
- */
- public Resource getAssociatedResource(Resource modelResource, String associatedResourceExtension, boolean loadOnDemand) {
- Resource r = null;
- if (modelResource != null) {
- URI trimmedModelURI = modelResource.getURI().trimFileExtension();
- r = getResource(trimmedModelURI.appendFileExtension(associatedResourceExtension), loadOnDemand);
- }
- return r;
- }
-
- /**
- * This method is called by getResource, createResource and demandLoad before returning
- * the resource to the caller so we can set options on the resource.
- *
- * @param r
- * , can be null
- * @return the same resource for convenience
- */
- protected Resource setResourceOptions(Resource r) {
-
- for (IModel model : models.values()) {
- if (model instanceof IEMFModel) {
- ((IEMFModel) model).handle(r);
- }
- }
-
- if (r != null && isTrackingModification() && !r.isTrackingModification()) {
- r.setTrackingModification(true);
- }
- return r;
- }
-
- @Override
- protected void demandLoad(Resource resource) throws IOException {
- // perf optimization : call setResourceOptions before the loading of the resource to avoid
- // going through the whole objects tree when setting the tracking modification
- super.demandLoad(setResourceOptions(resource));
- }
-
- /**
- * Create the transactional editing domain.
- *
- * @return the transactional editing domain
- */
- public synchronized TransactionalEditingDomain getTransactionalEditingDomain() {
- transactionalEditingDomain = TransactionalEditingDomainManager.getTransactionalEditingDomain(this);
-
- if (transactionalEditingDomain == null) {
- transactionalEditingDomain = TransactionalEditingDomainManager.createTransactionalEditingDomain(this);
- // register the id for lifecyle events the id is set by the registry
- EditingDomainManager.getInstance().configureListeners(PAPYRUS_EDITING_DOMAIN_ID, transactionalEditingDomain);
- }
- return transactionalEditingDomain;
- }
-
- /**
- * @return the filenameWithoutExtension
- *
- * @deprecated Use the {@link #getURIWithoutExtension()} API, instead.
- */
- @Deprecated
- public IPath getFilenameWithoutExtension() {
- IPath result = null;
-
- if (uriWithoutExtension != null) {
- if (uriWithoutExtension.isPlatformResource()) {
- result = new Path(uriWithoutExtension.toPlatformString(true));
- } else {
- throw new IllegalStateException("URI is not a platform:/resource URI");
- }
- }
-
- return result;
- }
-
- public URI getURIWithoutExtension() {
- return uriWithoutExtension;
- }
-
- /**
- * @return the filenameWithoutExtension
- * @throws BadStateException
- */
- protected URI getURIWithoutExtensionChecked() throws BadStateException {
- if (uriWithoutExtension == null) {
- throw new BadStateException("Path should be set prior calling any operations.");
- }
-
- return uriWithoutExtension;
- }
-
- /**
- * @param filenameWithoutExtension
- * the filenameWithoutExtension to set
- */
- protected void setURIWithoutExtension(URI uriWithoutExtension) {
- this.uriWithoutExtension = uriWithoutExtension;
- }
-
- /**
- * Create all the associated models. This creates the models, regardless if
- * they already exist.
- *
- * @param newFile
- * The file from which path is extracted to create the new
- * resources
- *
- * @deprecated Use the {@link #createModels(URI)} API, instead.
- */
- @Deprecated
- public void createsModels(IFile newFile) {
- createModels(createURI(newFile));
- }
-
- /**
- * Create all the associated models. This creates the models, regardless if
- * they already exist.
- *
- * @param newFile
- * The file from which path is extracted to create the new
- * resources
- */
- public void createModels(URI newURI) {
-
- // Set the URI, without extension.
- setURIWithoutExtension(newURI.trimFileExtension());
-
- // Walk all registered models
- for (IModel model : models.values()) {
- model.createModel(uriWithoutExtension);
- }
-
- // call snippets to allow them to do their stuff
- snippets.performStart(this);
- }
-
- /**
- * Create the model specified by the identifiers. Other models are
- * untouched, unless they are sharing something with specified models.
- *
- * This creates the models, regardless if they already exist.
- *
- * @param newFile
- * The file from which path is extracted to create the new
- * resources
- */
- public void createsModels(ModelIdentifiers modelIdentifiers) {
-
- // Walk all registered models
- for (String modelId : modelIdentifiers) {
- IModel model = getModel(modelId);
-
- // Load models using the default path
- model.createModel(uriWithoutExtension);
- }
-
- // call snippets to allow them to do their stuff
- // snippets.modelsAdded(modelIdentifiers);
- }
-
- /**
- * Load only the specified model. ModelSetSnippets are not called. Model is
- * loaded using the ModelSet Path.
- *
- * @param modelIdentifier
- * the model identifier
- * @param file
- * the file
- * @return the i model
- * @throws BadStateException
- * If the global path is not specified.
- * @returns The loaded model.
- */
- public IModel loadModel(String modelIdentifier) throws BadStateException {
-
- IModel model = getModel(modelIdentifier);
- model.loadModel(getURIWithoutExtensionChecked());
-
- return model;
- }
-
- /**
- * Import only the specified model. ModelSetSnippets are not called.
- *
- * @param modelIdentifier
- * the model identifier
- * @param file
- * the file
- * @return the i model
- * @throws ModelException
- * @returns The loaded model.
- * @deprecated Use {@link #importModel(ModelIdentifier, IFile)}
- */
- @Deprecated
- public IModel loadModel(String modelIdentifier, IFile file) throws ModelException {
-
- importModels(new ModelIdentifiers(modelIdentifier), file);
-
- return getModel(modelIdentifier);
- }
-
- /**
- * Load all the associated models from a handle on one of the associated
- * file.
- *
- * @param file
- * The file to load (no matter the extension)
- * @deprecated Use the {@link #loadModels(URI)} API, instead.
- */
- @Deprecated
- public void loadModels(IFile file) throws ModelMultiException {
- loadModels(createURI(file));
- }
-
- protected URI createURI(IFile file) {
- return URI.createPlatformResourceURI(file.getFullPath().toString(), true);
- }
-
- /**
- * Load all the associated models from a URI identifying one of the associated
- * files.
- *
- * @param uri
- * The URI to load (no matter the extension)
- */
- public void loadModels(URI uri) throws ModelMultiException {
-
- // Get the file name, without extension.
- uriWithoutExtension = uri.trimFileExtension();
-
- installLanguages();
-
- ModelMultiException exceptions = null;
- List<IModel> orderedModelsForLoading = getOrderedModelsForLoading();
-
- // Walk all registered models
- for (IModel model : orderedModelsForLoading) {
- // Try to load each model. Catch exceptions in order to load other
- // models.
- try {
- model.loadModel(uriWithoutExtension);
- } catch (Exception e) {
- // Record the exception
- if (exceptions == null) {
-
- exceptions = new ModelMultiException("Problems encountered while loading one of the models.");
- }
- exceptions.addException(model.getIdentifier(), e);
- }
- }
-
- // call snippets to allow them to do their stuff
- snippets.performStart(this);
-
- // Report exceptions if any
- if (exceptions != null) {
- throw exceptions;
- }
- }
-
- /**
- * Returns the models to be loaded, in order according to their dependencies
- *
- * @return the models to be loaded, in order according to their dependencies
- */
- protected List<IModel> getOrderedModelsForLoading() {
- return ModelUtils.getOrderedModelsForLoading(models);
- }
-
- /**
- * Import specified models into the ModelSet. The models are imported using
- * the specified IFile. After import, the models are associated with the
- * ModelSet Path.
- *
- * @param modelIdentifiers
- * The model to import from the specified IFile.
- * @param file
- * The IFile used to import the model.
- * @throws ModelException
- * If an error occur during import.
- *
- * @deprecated Use the {@link #importModels(ModelIdentifiers, URI)} API, instead
- */
- @Deprecated
- public void importModels(ModelIdentifiers modelIdentifiers, IFile file) throws ModelException {
-
- importModels(modelIdentifiers, createURI(file));
- }
-
- /**
- * Import specified models into the ModelSet. The models are imported using
- * the specified IFile. After import, the models are associated with the
- * ModelSet Path.
- *
- * @param modelIdentifiers
- * The model to import from the specified IFile.
- * @param uri
- * The URI used to import the model.
- * @throws ModelException
- * If an error occur during import.
- */
- public void importModels(ModelIdentifiers modelIdentifiers, URI uri) throws ModelException {
-
- if (uri != null) {
- URI toImport = uri.trimFileExtension();
- // Walk all registered models
- for (String modelId : modelIdentifiers) {
- IModel model = getModel(modelId);
-
- // Load models using the default path
- model.importModel(toImport);
-
- model.setModelURI(uriWithoutExtension);
- }
- } else {
- throw new ModelException("URI used to import the model is null");
- }
- }
-
- /**
- * Import only the specified model. ModelSetSnippets are not called. An
- * import can be performed after model are loaded. Normally, it should not
- * be done before a model is loaded.
- *
- * @param modelIdentifier
- * the model identifier
- * @param file
- * the file
- * @throws ModelException
- * @returns The loaded model.
- *
- * @deprecated Use the {@link #importModel(String, URI)} API, instead.
- */
- @Deprecated
- public IModel importModel(String modelIdentifier, IFile file) throws ModelException {
-
- return importModel(modelIdentifier, createURI(file));
- }
-
- /**
- * Import only the specified model. ModelSetSnippets are not called. An
- * import can be performed after model are loaded. Normally, it should not
- * be done before a model is loaded.
- *
- * @param modelIdentifier
- * the model identifier
- * @param file
- * the file
- * @throws ModelException
- * @returns The loaded model.
- */
- public IModel importModel(String modelIdentifier, URI uri) throws ModelException {
-
- importModels(new ModelIdentifiers(modelIdentifier), uri);
-
- return getModel(modelIdentifier);
- }
-
- /**
- * Create models that are not already created or loaded.
- */
- public void createMissingModels() throws ModelException {
- throw new UnsupportedOperationException("Not yet implemented"); // TODO
-
- }
-
- /**
- * Load models that are not already created or loaded.
- */
- public void loadMissingModels() throws ModelException {
- throw new UnsupportedOperationException("Not yet implemented"); // TODO
-
- }
-
- /**
- * Save the resources.
- *
- * @param monitor
- * The monitor.
- * @throws IOException
- * IO Error.
- */
- public void save(IProgressMonitor monitor) throws IOException {
-
- // Initialize monitor with the number of models
- Collection<IModel> modelList = models.values();
- monitor.beginTask("Saving resources", modelList.size());
-
- IReadOnlyHandler2 roHandler = getReadOnlyHandler();
- if (isTrackingModification() && (roHandler != null)) {
- Set<URI> roUris = new HashSet<URI>();
- for (IModel model : modelList) {
- Set<URI> uris = model.getModifiedURIs();
- for (URI u : uris) {
- Optional<Boolean> res = (roHandler.anyReadOnly(ReadOnlyAxis.permissionAxes(), new URI[] { u }));
- if (res.isPresent() && res.get()) {
- roUris.add(u);
- }
- }
- }
-
- for (URI u : getResourcesToDeleteOnSave()) {
- Optional<Boolean> res = roHandler.anyReadOnly(ReadOnlyAxis.permissionAxes(), new URI[] { u });
- if (res.isPresent() && res.get()) {
- roUris.add(u);
- }
- }
-
- if (!roUris.isEmpty()) {
- Optional<Boolean> authorizeSave = roHandler.makeWritable(ReadOnlyAxis.permissionAxes(), roUris.toArray(new URI[roUris.size()]));
-
- if (authorizeSave.isPresent() && !authorizeSave.get()) {
- monitor.done();
- // FIXME: In Kepler M6, it seems that it is sometimes possible to modify the readOnly StandardL3 profile.
- // This doesn't have any consequence, but prevents the save action. We'd better not throw an exception here.
- // throw new IOException("Some modified resources are read-only : the model can't be saved");
- }
- }
- }
-
- // Clean Model set of deleted resources
- cleanModelSet();
-
- try {
- // Walk all registered models
- for (IModel model : modelList) {
- try {
- if (!(model instanceof AdditionalResourcesModel)) {
-
- // Bug 436952, 4436998 : Clean referenced resources by models
- model.cleanModel(getResourcesToDeleteOnSave());
-
- model.saveModel();
- monitor.worked(1);
- }
- } catch (Exception ex) {
- // If an exception occurs, we should not prevent other models from being saved.
- // This would probably make things even worse. Catch and log.
- Activator.log.error(ex);
- }
- }
- try {
- additional.cleanModel(getResourcesToDeleteOnSave());
- additional.saveModel();
- } catch (Exception ex) {
- Activator.log.error(ex);
- }
-
- // Delete resource back end to delete on save
- handleResourcesToDelete();
- } finally {
- monitor.done();
- }
- }
-
-
-
- /**
- * Clean model set.
- */
- protected void cleanModelSet() {
-
- // Get referenced resources by Model Set
- Iterator<Resource> resourcesIterator = getResources().iterator();
- while (resourcesIterator.hasNext()) {
- Resource nextResource = resourcesIterator.next();
-
- // Verify if the resource can be unreferenced
- if (getResourcesToDeleteOnSave().contains(nextResource.getURI())) {
- resourcesIterator.remove();
- }
-
- }
- }
-
-
-
- /**
- * @return {@link ModelSet#toDeleteOnSave}
- */
- public Set<URI> getResourcesToDeleteOnSave() {
- return toDeleteOnSave;
- }
-
- /**
- * Delete resources pointed by {@link #getResourcesToDeleteOnSave()} set.
- */
- protected void handleResourcesToDelete() {
- Iterator<URI> uriIterator = getResourcesToDeleteOnSave().iterator();
- while (uriIterator.hasNext()) {
- URI uri = uriIterator.next();
-
- if (validateDeleteResource(uri)) {
-
- if (deleteResource(uri)) {
- uriIterator.remove();
- }
- }
- }
- }
-
- protected boolean validateDeleteResource(URI uri) {
- boolean result = true;
-
- Resource resource = getResource(uri, false);
- if (resource != null) {
- String warMessage = "The resource " + resource.getURI().lastSegment() + " was about to deleted but was still contained in the resource set. The will not be deleted";
- Activator.log.warn(warMessage);
-
- result = false;
- }
-
- return result;
- }
-
- /**
- * This allows to delete a resource from the uri.
- *
- * @param uri
- * The uri of the resource to delete.
- * @return <code>true</code> if the resource is deleted, <code>false</code> otherwise.
- * @since 3.0
- */
- public boolean deleteResource(final URI uri) {
- boolean result = false;
-
- try {
- getURIConverter().delete(uri, null);
- result = true;
- } catch (IOException e) {
- Activator.log.error(e);
-
- // hope it's a file that we can delete from the workspace!
- IFile file = getFile(uri);
- if (file != null && file.exists()) {
- try {
- file.delete(true, new NullProgressMonitor());
- result = true;
- } catch (CoreException e2) {
- Activator.log.error(e2);
- }
- }
- }
-
- return result;
- }
-
- /**
- * Finds the file corresponding to the specified URI, using a URI converter
- * if necessary (and provided) to normalize it.
- *
- * @param uri
- * a URI
- * @param converter
- * an optional URI converter (may be <code>null</code>)
- *
- * @return the file, if available in the workspace
- */
- protected IFile getFile(URI uri) {
- IFile result = null;
- if (uri.isPlatformPlugin()) {
- /* resource with platform plug-in URI could not be in the workspace */
- return result;
- } else if (uri.isPlatformResource()) {
- IPath path = new Path(uri.toPlatformString(true));
- result = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
- } else if (uri.isFile() && !uri.isRelative()) {
- result = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(uri.toFileString()));
- } else {
- // normalize, to see whether may we can resolve it this time
- if (uriConverter != null) {
- URI normalized = uriConverter.normalize(uri);
- if (!uri.equals(normalized)) {
- // recurse on the new URI
- result = getFile(normalized);
- }
- }
- }
- if ((result == null) && !uri.isRelative()) {
- try {
- java.net.URI location = new java.net.URI(uri.toString());
- if (hasRegisteredEFS(location)) {
- IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(new java.net.URI(uri.toString()));
- if (files.length > 0) {
- // set the result to be the first file found
- result = files[0];
- }
- }
- } catch (URISyntaxException e) {
- // won't get this because EMF provides a well-formed URI
- }
- }
- return result;
- }
-
- protected boolean hasRegisteredEFS(java.net.URI location) {
- try {
- if (EFS.getStore(location) != null) {
- return true;
- }
- } catch (CoreException ex) {
- return false;
- }
- return false;
- }
-
- /**
- * The resources are already loaded, but we want to save them under another
- * name.
- *
- * @param path
- * the path
- * @throws IOException
- * Signals that an I/O exception has occurred.
- *
- * @deprecated Use the {@link #saveAs(URI)} API, instead.
- */
- @Deprecated
- public void saveAs(IPath path) throws IOException {
- saveAs(URI.createPlatformResourceURI(path.toString(), true));
- }
-
- /**
- * The resources are already loaded, but we want to save them under another
- * name.
- *
- * @param path
- * the path
- * @throws IOException
- * Signals that an I/O exception has occurred.
- */
- public void saveAs(URI uri) throws IOException {
-
- EcoreUtil.resolveAll(this); // Save will not be consistent if we don't load all related resources first
-
- // Get the file name, without extension.
- URI newUriWithoutExtension = uri.trimFileExtension();
-
- // Walk all registered models
- for (IModel model : models.values()) {
- model.setModelURI(newUriWithoutExtension);
- }
-
- this.uriWithoutExtension = newUriWithoutExtension;
-
- // Save with new paths
- save(new NullProgressMonitor());
- }
-
- /**
- * Unload all the resources. Do not disguard associated models.
- */
- public void unload() {
- // call snippets to allow them to do their stuff
- snippets.performDispose(this);
- snippets.clear();
-
-
- // FIXME RS: handle the unload ordering as indicated in the model extension point
- // Walk all registered models
- for (IModel model : models.values()) {
- if (!(model instanceof AdditionalResourcesModel)) {
- model.unload();
- }
- }
- additional.unload();
-
- // Unload remaining resources
- for (Iterator<Resource> iter = getResources().iterator(); iter.hasNext();) {
- iter.next().unload();
- iter.remove();
- }
-
- uninstallLanguages();
-
- // Clear the package registry (it may contain dynamic profile EPackages that we don't
- // want to leak in BasicExtendedMetaData instances attached to static EPackages)
- // Works around EMF bug 433108
- EPackage.Registry packageRegistry = getPackageRegistry();
- if (packageRegistry != null) {
- packageRegistry.clear();
- }
-
- // Dispose Editing Domain
- if (transactionalEditingDomain != null) {
- transactionalEditingDomain.dispose();
- transactionalEditingDomain = null;
- }
- // Detach associated factories
- if (adapterFactories != null) {
- adapterFactories.clear();
- }
- EList<Adapter> adapters = eAdapters();
- if (adapters != null) {
- adapters.clear();
- }
- }
-
- public IReadOnlyHandler2 getReadOnlyHandler() {
- if (roHandler == null) {
- EditingDomain editingDomain = getTransactionalEditingDomain();
- Object handler = PlatformHelper.getAdapter(editingDomain, IReadOnlyHandler.class);
- if (handler instanceof IReadOnlyHandler2) {
- roHandler = (IReadOnlyHandler2) handler;
- } else if (handler instanceof IReadOnlyHandler) {
- roHandler = AbstractReadOnlyHandler.adapt((IReadOnlyHandler) handler, editingDomain);
- }
- }
- return roHandler;
- }
-
- /**
- * Obtains my internal API adapter.
- *
- * @return my internal API adapter
- */
- public Internal getInternal() {
- return new Internal() {
-
- @Override
- public void setPrimaryModelResourceURI(URI uri) {
- setURIWithoutExtension(uri.trimFileExtension());
- }
-
- @Override
- public void registerModel(IModel model, boolean force) {
- if (force) {
- doRegisterModel(model);
- } else {
- ModelSet.this.registerModel(model);
- }
- }
- };
- }
-
- /**
- * Add a {@link IModelSetSnippet}. A snippet allows to add code that will
- * perform additional operations on the ModelSet.
- *
- * @param snippet
- * The snippet to add.
- */
- public void addModelSetSnippet(IModelSetSnippet snippet) {
- snippets.add(snippet);
- }
-
- /**
- * A list of {@link IModelSetSnippet}.
- *
- * Used by Models to maintain their list of Snippets.
- *
- * @author cedric dumoulin
- *
- */
- public class ModelSetSnippetList extends ArrayList<IModelSetSnippet> {
-
- /** The Constant serialVersionUID. */
- private static final long serialVersionUID = 1L;
-
- /**
- * Call the start method on all registered snippets.
- *
- * @param modelsManager
- * The model that is starting
- */
- public void performStart(ModelSet modelsManager) {
- for (IModelSetSnippet snippet : this) {
- snippet.start(modelsManager);
- }
- }
-
- /**
- * Call the start method on all registered snippets.
- *
- * @param modelsManager
- * The model that is stopping
- */
- public void performDispose(ModelSet modelsManager) {
- for (IModelSetSnippet snippet : this) {
- snippet.dispose(modelsManager);
- }
-
- }
- }
-
- /**
- * Internal API for manipulation of {@link ModelSet}s.
- */
- public static interface Internal {
-
- /**
- * Sets the {@link ModelSet}'s primary resource URI.
- *
- * @param uri
- * the URI
- *
- * @see ModelSet#createModels(URI)
- * @see ModelSet#saveAs(URI)
- */
- void setPrimaryModelResourceURI(URI uri);
-
- /**
- * Register a model with the option to force it (in case a more specific
- * implementation of the model is already registered).
- *
- * @param model
- * a model to register
- * @param force
- * whether to force the registration
- */
- void registerModel(IModel model, boolean force);
- }
-
- /**
- *
- * @param target
- */
- public void saveCopy(IPath targetPathWithoutExtension) {
- List<IVersionableModel> versionableModels = new LinkedList<IVersionableModel>();
-
- Map<Object, Object> targetMap = new HashMap<Object, Object>();
-
- for (IModel model : models.values()) {
- if (model instanceof IVersionableModel) {
- IVersionableModel versionable = (IVersionableModel) model;
- versionable.fillTargetMap(targetPathWithoutExtension, targetMap);
- versionableModels.add(versionable);
- }
- }
-
- for (IVersionableModel model : versionableModels) {
- model.saveCopy(targetPathWithoutExtension, targetMap);
- }
- }
-
- public boolean addResourceLoadStateListener(IResourceLoadStateListener listener) {
- return resourceLoadStateListeners.add(listener);
- }
-
- public boolean removeResourceLoadStateListener(IResourceLoadStateListener listener) {
- return resourceLoadStateListeners.remove(listener);
- }
-
- public void notifyResourceLoadState(Resource resource, boolean newState) {
- if (resourceLoadStateListeners != null) {
- for (IResourceLoadStateListener listener : resourceLoadStateListeners) {
- try {
- listener.notifyLoadStateChanged(resource, newState);
- } catch (Throwable e) {
- Activator.log.error(e);
- }
- }
- }
- }
-
- public boolean isUserModelResource(URI uri) {
- return uri.isPlatformResource() || uri.isFile();
- }
-
- public class ResourceAddRemoveTracker implements Adapter {
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void notifyChanged(Notification notification) {
- // if notification = add, add many or remove/remove many resource(s) to list of resources, process..
- if (RESOURCE_SET__RESOURCES == notification.getFeatureID(ResourceSet.class)) {
- switch (notification.getEventType()) {
- case Notification.ADD:
- Object object = notification.getNewValue();
- if (object instanceof Resource) {
- resourcesToLoadState.put(((Resource) object), ((Resource) object).isLoaded());
- }
- break;
- case Notification.REMOVE:
- object = notification.getOldValue();
- if (object instanceof Resource) {
- resourcesToLoadState.remove((object));
- }
- break;
- case Notification.ADD_MANY:
-
- break;
-
- case Notification.REMOVE_MANY:
-
- break;
-
- default:
- // nothing to do
- break;
- }
-
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Notifier getTarget() {
- return ModelSet.this;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setTarget(Notifier newTarget) {
- // nothing here
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean isAdapterForType(Object type) {
- return false;
- }
-
- }
-
- /**
- * Returns the IModel which handles the specified element, if any
- *
- * @param container
- * @return
- */
- public IModel getModelFor(Object element) {
- for (IModel model : models.values()) {
- if (model.isModelFor(element)) {
- return model;
- }
- }
- return null;
- }
-
- protected void installLanguages() {
- ILanguageService languageService = ServiceUtils.getInstance().getService(ILanguageService.class, ModelSetServiceFactory.getServiceRegistry(this), null);
- if (languageService != null) {
- languages = Lists.newArrayList(languageService.getLanguages(getURIWithoutExtension(), false));
-
- for (ILanguage next : languages) {
- try {
- next.install(this);
- } catch (Exception e) {
- Activator.log.error("Uncaught exception in installation of language " + next, e); //$NON-NLS-1$
- }
- }
- }
- }
-
- protected void uninstallLanguages() {
- if (languages != null) {
- for (ILanguage next : Lists.reverse(languages)) {
- try {
- next.uninstall(this);
- } catch (Exception e) {
- Activator.log.error("Uncaught exception in uninstallation of language " + next, e); //$NON-NLS-1$
- }
- }
-
- languages.clear();
- }
- }
-
- /**
- * Obtains the model that should persist an {@code object}.
- *
- * @param object
- * an object to be persisted as a new root of a managed EMF {@code Resource}
- *
- * @return the model that is best suited to persist the {@code object}, or {@code null} if none
- * @since 2.0
- */
- public IEMFModel getModelToPersist(EObject object) {
- return models.values().stream()
- .filter(IEMFModel.class::isInstance)
- .map(IEMFModel.class::cast)
- .filter(m -> m.canPersist(object))
- .findFirst()
- .orElse(null);
- }
-}
+/***************************************************************************** + * Copyright (c) 2008, 2016 CEA LIST, Christian W. Damus, 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: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * Emilien Perico emilien.perico@atosorigin.com - manage loading strategies + * Christian W. Damus (CEA) - manage models by URI, not IFile (CDO) + * Christian W. Damus (CEA) - Support read-only state at object level (CDO) + * Christian W. Damus (CEA) - Refactoring of Create Model Wizard (CDO) + * Christian W. Damus (CEA LIST) - Controlled resources in CDO repositories + * Christian W. Damus (CEA) - bugs 429826, 432813, 437052 + * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Bug 436952 + * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Bug 436998 + * Christian W. Damus - bugs 436998, 468030, 485220 + * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Bug 496905 + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.resource; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +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.util.EList; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.common.util.WrappedException; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.xmi.XMLResource; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.emf.transaction.impl.EditingDomainManager; +import org.eclipse.papyrus.infra.core.Activator; +import org.eclipse.papyrus.infra.core.editor.ModelSetServiceFactory; +import org.eclipse.papyrus.infra.core.language.ILanguage; +import org.eclipse.papyrus.infra.core.language.ILanguageService; +import org.eclipse.papyrus.infra.core.resource.additional.AdditionalResourcesModel; +import org.eclipse.papyrus.infra.core.utils.ServiceUtils; +import org.eclipse.papyrus.infra.tools.util.PlatformHelper; + +import com.google.common.base.Optional; +import com.google.common.collect.Lists; + +/** + * This class is used to manage a set of {@link IModel}. + * + * <h2>>Usage</h2> + * <ul> + * <li>First, register associated model. A loader can be used.</li> + * <li>Second, call load() or create()</li> + * <li>Then, it is possible to get associated models</li> + * <li>Finally, call save()</li> + * </ul> + * + * Please note that indirectly referenced models are loaded on demand. If a + * model contains a cross reference towards another model (e.g. an import in + * case of UML) the referenced resource does not appear initially in the set. + * However, it is added once the referenced model is resolved. + * + * TODO Modify ModelSetSnippet in order to inform them of model addition. + * + * @author cedric dumoulin + * + */ +public class ModelSet extends ResourceSetImpl { + + /** + * Id use to register the EditinDomain into the registry + */ + public static final String PAPYRUS_EDITING_DOMAIN_ID = "org.eclipse.papyrus.SharedEditingDomainID"; + + /** The associated IModels. */ + protected Map<String, IModel> models = new HashMap<String, IModel>(); + + /** The snippets. */ + protected ModelSetSnippetList snippets = new ModelSetSnippetList(); + + protected AdditionalResourcesModel additional = new AdditionalResourcesModel(); + + /** + * The associated EditingDomain. + */ + protected TransactionalEditingDomain transactionalEditingDomain; + + /** + * The URI, without extension, used for action on models. + */ + protected URI uriWithoutExtension; + + protected Adapter modificationTrackingAdapter; + + protected IReadOnlyHandler2 roHandler; + + /** + * URI pointing to resource on which back end should be deleted on save + * One example of use is empty uncontrolled resources + */ + protected Set<URI> toDeleteOnSave = new HashSet<URI>(); + + /** list of listeners of resources to know if the resource are loaded or not */ + protected ArrayList<IResourceLoadStateListener> resourceLoadStateListeners; + + /** map of resource loaded in the resource set, with resource as the key and a boolean indicating if the resource is loaded or not has the valuer */ + protected Map<Resource, Boolean> resourcesToLoadState = new HashMap<Resource, Boolean>(); + + private List<ILanguage> languages; + + /** + * + * Constructor. + * + */ + public ModelSet() { + registerModel(additional); + setTrackingModification(true); + + getLoadOptions().put(XMLResource.OPTION_DEFER_ATTACHMENT, true); + getLoadOptions().put(XMLResource.OPTION_DEFER_IDREF_RESOLUTION, true); + getLoadOptions().put(XMLResource.OPTION_LAX_FEATURE_PROCESSING, Boolean.TRUE); + getLoadOptions().put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE); + getLoadOptions().put(XMLResource.OPTION_USE_PACKAGE_NS_URI_AS_LOCATION, Boolean.FALSE); + + this.eAdapters.add(new ResourceAddRemoveTracker()); + } + + /** + * Register the specified model under its associated key. The key is defined + * in the model itself. It is usually the model type from + * (ModelPackage.eCONTENT_TYPE). + * + * @param model + * the model + */ + public void registerModel(IModel model) { + IModel existing = models.get(model.getIdentifier()); + if ((existing == null) || existing.getClass().isAssignableFrom(model.getClass().getSuperclass())) { + // only add this model if it is the first instance for its identifier + // or it's an instance of a subclass + doRegisterModel(model); + } + } + + protected void doRegisterModel(IModel model) { + models.put(model.getIdentifier(), model); + model.init(this); + } + + /** + * Get a model by its key. TODO throw an exception if not found. + * + * @param key + * the key + * @return the model + */ + public IModel getModel(String key) { + return models.get(key); + } + + /** + * Get a model by its key. TODO throw an exception if not found. + * + * @param key + * the key + * @return the model + * @throws NotFoundException + * If no model is registered under the key. + */ + public IModel getModelChecked(String key) throws NotFoundException { + IModel model = models.get(key); + if (model == null) { + throw new NotFoundException("Can't find model for identifier '" + key + "'."); + } + + return model; + } + + @Override + public Resource createResource(URI uri, String contentType) { + return setResourceOptions(super.createResource(uri, contentType)); + } + + @Override + public Resource getResource(URI uri, boolean loadOnDemand) throws WrappedException { + if (uri.hasFragment()) { + Activator.log.warn("Invalid Resource URI: resource URIs cannot contain a fragment"); //$NON-NLS-1$ + uri = uri.trimFragment(); // Fix and continue + } + Resource r = null; + try { + r = super.getResource(uri, loadOnDemand); + } catch (WrappedException e) { + // Activator.log.error(e); + if (ModelUtils.isDegradedModeAllowed(e.getCause())) { + try { + r = super.getResource(uri, false); + } catch (WrappedException ee) { + throw ee; + } + } else { + // don't log, but throw error again, bug 405047 - [core] FileNotFoundException during MARTE profile loads + throw e; + } + } + + return r != null && r.isLoaded() ? r : setResourceOptions(r); + } + + @Override + protected void handleDemandLoadException(Resource resource, IOException exception) throws RuntimeException { + super.handleDemandLoadException(resource, exception); + } + + public void setTrackingModification(boolean isTrackingModification) { + boolean oldIsTrackingModification = modificationTrackingAdapter != null; + + if (oldIsTrackingModification != isTrackingModification) { + if (isTrackingModification) { + modificationTrackingAdapter = createModificationTrackingAdapter(); + this.eAdapters().add(modificationTrackingAdapter); + } else { + Adapter oldModificationTrackingAdapter = modificationTrackingAdapter; + modificationTrackingAdapter = null; + this.eAdapters().remove(oldModificationTrackingAdapter); + } + } + } + + protected Adapter createModificationTrackingAdapter() { + return new ProxyModificationTrackingAdapter(); + } + + public boolean isTrackingModification() { + return modificationTrackingAdapter != null; + } + + /** + * Queries whether a {@code resource} managed by me is either known to be or assumed to be needing to be saved. + * Generally this is true for resources that have been modified since the last save and that are saveable + * (not read-only and correctly and completely loaded in the first place). + * + * @param resource + * a resource that I manage + * + * @return whether the {@code resource} currently needs to be saved + */ + public boolean shouldSave(Resource resource) { + boolean result; + + if (getTransactionalEditingDomain().isReadOnly(resource) || ModelUtils.resourceFailedOnLoad(resource)) { + result = false; + } else if (!getURIConverter().exists(resource.getURI(), null)) { + // If the resource needs to be created, it needs to be saved + result = true; + } else if (modificationTrackingAdapter instanceof ProxyModificationTrackingAdapter) { + result = ((ProxyModificationTrackingAdapter) modificationTrackingAdapter).shouldSave(resource); + } else if (modificationTrackingAdapter != null) { + result = !resource.isTrackingModification() || resource.isModified(); + } else { + // Assume that the resource is modified since the last save + result = true; + } + + return result; + } + + /** + * @deprecated please use {@link #getAssociatedResource(EObject, String, boolean)} instead + * + * @param modelElement + * @param associatedResourceExtension + * @return + */ + @Deprecated + public Resource getAssociatedResource(EObject modelElement, String associatedResourceExtension) { + return getAssociatedResource(modelElement, associatedResourceExtension, true); + } + + /** + * @deprecated please use {@link #getAssociatedResource(Resource, String, boolean)} instead + * + * @param modelResource + * @param associatedResourceExtension + * @return + */ + @Deprecated + public Resource getAssociatedResource(Resource modelResource, String associatedResourceExtension) { + return getAssociatedResource(modelResource, associatedResourceExtension, true); + } + + /** + * Retrieve and load the associated resource which have the given extension. + * + * @param modelElement + * @param associatedResourceExtension + * @param loadOnDemand + * same as for getResource + * @return + */ + public Resource getAssociatedResource(EObject modelElement, String associatedResourceExtension, boolean loadOnDemand) { + if (modelElement != null) { + return getAssociatedResource(modelElement.eResource(), associatedResourceExtension, loadOnDemand); + } + return null; + } + + /** + * Retrieve and load the associated resource which have the given extension. + * + * @param modelResource + * @param associatedResourceExtension + * @param loadOnDemand + * same as for getResource + * @return + */ + public Resource getAssociatedResource(Resource modelResource, String associatedResourceExtension, boolean loadOnDemand) { + Resource r = null; + if (modelResource != null) { + URI trimmedModelURI = modelResource.getURI().trimFileExtension(); + r = getResource(trimmedModelURI.appendFileExtension(associatedResourceExtension), loadOnDemand); + } + return r; + } + + /** + * This method is called by getResource, createResource and demandLoad before returning + * the resource to the caller so we can set options on the resource. + * + * @param r + * , can be null + * @return the same resource for convenience + */ + protected Resource setResourceOptions(Resource r) { + + for (IModel model : models.values()) { + if (model instanceof IEMFModel) { + ((IEMFModel) model).handle(r); + } + } + + if (r != null && isTrackingModification() && !r.isTrackingModification()) { + r.setTrackingModification(true); + } + return r; + } + + @Override + protected void demandLoad(Resource resource) throws IOException { + // perf optimization : call setResourceOptions before the loading of the resource to avoid + // going through the whole objects tree when setting the tracking modification + super.demandLoad(setResourceOptions(resource)); + } + + /** + * Create the transactional editing domain. + * + * @return the transactional editing domain + */ + public synchronized TransactionalEditingDomain getTransactionalEditingDomain() { + transactionalEditingDomain = TransactionalEditingDomainManager.getTransactionalEditingDomain(this); + + if (transactionalEditingDomain == null) { + transactionalEditingDomain = TransactionalEditingDomainManager.createTransactionalEditingDomain(this); + // register the id for lifecyle events the id is set by the registry + EditingDomainManager.getInstance().configureListeners(PAPYRUS_EDITING_DOMAIN_ID, transactionalEditingDomain); + } + return transactionalEditingDomain; + } + + /** + * @return the filenameWithoutExtension + * + * @deprecated Use the {@link #getURIWithoutExtension()} API, instead. + */ + @Deprecated + public IPath getFilenameWithoutExtension() { + IPath result = null; + + if (uriWithoutExtension != null) { + if (uriWithoutExtension.isPlatformResource()) { + result = new Path(uriWithoutExtension.toPlatformString(true)); + } else { + throw new IllegalStateException("URI is not a platform:/resource URI"); + } + } + + return result; + } + + public URI getURIWithoutExtension() { + return uriWithoutExtension; + } + + /** + * @return the filenameWithoutExtension + * @throws BadStateException + */ + protected URI getURIWithoutExtensionChecked() throws BadStateException { + if (uriWithoutExtension == null) { + throw new BadStateException("Path should be set prior calling any operations."); + } + + return uriWithoutExtension; + } + + /** + * @param filenameWithoutExtension + * the filenameWithoutExtension to set + */ + protected void setURIWithoutExtension(URI uriWithoutExtension) { + this.uriWithoutExtension = uriWithoutExtension; + } + + /** + * Create all the associated models. This creates the models, regardless if + * they already exist. + * + * @param newFile + * The file from which path is extracted to create the new + * resources + * + * @deprecated Use the {@link #createModels(URI)} API, instead. + */ + @Deprecated + public void createsModels(IFile newFile) { + createModels(createURI(newFile)); + } + + /** + * Create all the associated models. This creates the models, regardless if + * they already exist. + * + * @param newFile + * The file from which path is extracted to create the new + * resources + */ + public void createModels(URI newURI) { + + // Set the URI, without extension. + setURIWithoutExtension(newURI.trimFileExtension()); + + // Walk all registered models + for (IModel model : models.values()) { + model.createModel(uriWithoutExtension); + } + + // call snippets to allow them to do their stuff + snippets.performStart(this); + } + + /** + * Create the model specified by the identifiers. Other models are + * untouched, unless they are sharing something with specified models. + * + * This creates the models, regardless if they already exist. + * + * @param newFile + * The file from which path is extracted to create the new + * resources + */ + public void createsModels(ModelIdentifiers modelIdentifiers) { + + // Walk all registered models + for (String modelId : modelIdentifiers) { + IModel model = getModel(modelId); + + // Load models using the default path + model.createModel(uriWithoutExtension); + } + + // call snippets to allow them to do their stuff + // snippets.modelsAdded(modelIdentifiers); + } + + /** + * Load only the specified model. ModelSetSnippets are not called. Model is + * loaded using the ModelSet Path. + * + * @param modelIdentifier + * the model identifier + * @param file + * the file + * @return the i model + * @throws BadStateException + * If the global path is not specified. + * @returns The loaded model. + */ + public IModel loadModel(String modelIdentifier) throws BadStateException { + + IModel model = getModel(modelIdentifier); + model.loadModel(getURIWithoutExtensionChecked()); + + return model; + } + + /** + * Import only the specified model. ModelSetSnippets are not called. + * + * @param modelIdentifier + * the model identifier + * @param file + * the file + * @return the i model + * @throws ModelException + * @returns The loaded model. + * @deprecated Use {@link #importModel(ModelIdentifier, IFile)} + */ + @Deprecated + public IModel loadModel(String modelIdentifier, IFile file) throws ModelException { + + importModels(new ModelIdentifiers(modelIdentifier), file); + + return getModel(modelIdentifier); + } + + /** + * Load all the associated models from a handle on one of the associated + * file. + * + * @param file + * The file to load (no matter the extension) + * @deprecated Use the {@link #loadModels(URI)} API, instead. + */ + @Deprecated + public void loadModels(IFile file) throws ModelMultiException { + loadModels(createURI(file)); + } + + protected URI createURI(IFile file) { + return URI.createPlatformResourceURI(file.getFullPath().toString(), true); + } + + /** + * Load all the associated models from a URI identifying one of the associated + * files. + * + * @param uri + * The URI to load (no matter the extension) + */ + public void loadModels(URI uri) throws ModelMultiException { + + // Get the file name, without extension. + uriWithoutExtension = uri.trimFileExtension(); + + installLanguages(); + + ModelMultiException exceptions = null; + List<IModel> orderedModelsForLoading = getOrderedModelsForLoading(); + + // Walk all registered models + for (IModel model : orderedModelsForLoading) { + // Try to load each model. Catch exceptions in order to load other + // models. + try { + model.loadModel(uriWithoutExtension); + } catch (Exception e) { + // Record the exception + if (exceptions == null) { + + exceptions = new ModelMultiException("Problems encountered while loading one of the models."); + } + exceptions.addException(model.getIdentifier(), e); + } + } + + // call snippets to allow them to do their stuff + snippets.performStart(this); + + // Report exceptions if any + if (exceptions != null) { + throw exceptions; + } + } + + /** + * Returns the models to be loaded, in order according to their dependencies + * + * @return the models to be loaded, in order according to their dependencies + */ + protected List<IModel> getOrderedModelsForLoading() { + return ModelUtils.getOrderedModelsForLoading(models); + } + + /** + * Import specified models into the ModelSet. The models are imported using + * the specified IFile. After import, the models are associated with the + * ModelSet Path. + * + * @param modelIdentifiers + * The model to import from the specified IFile. + * @param file + * The IFile used to import the model. + * @throws ModelException + * If an error occur during import. + * + * @deprecated Use the {@link #importModels(ModelIdentifiers, URI)} API, instead + */ + @Deprecated + public void importModels(ModelIdentifiers modelIdentifiers, IFile file) throws ModelException { + + importModels(modelIdentifiers, createURI(file)); + } + + /** + * Import specified models into the ModelSet. The models are imported using + * the specified IFile. After import, the models are associated with the + * ModelSet Path. + * + * @param modelIdentifiers + * The model to import from the specified IFile. + * @param uri + * The URI used to import the model. + * @throws ModelException + * If an error occur during import. + */ + public void importModels(ModelIdentifiers modelIdentifiers, URI uri) throws ModelException { + + if (uri != null) { + URI toImport = uri.trimFileExtension(); + // Walk all registered models + for (String modelId : modelIdentifiers) { + IModel model = getModel(modelId); + + // Load models using the default path + model.importModel(toImport); + + model.setModelURI(uriWithoutExtension); + } + } else { + throw new ModelException("URI used to import the model is null"); + } + } + + /** + * Import only the specified model. ModelSetSnippets are not called. An + * import can be performed after model are loaded. Normally, it should not + * be done before a model is loaded. + * + * @param modelIdentifier + * the model identifier + * @param file + * the file + * @throws ModelException + * @returns The loaded model. + * + * @deprecated Use the {@link #importModel(String, URI)} API, instead. + */ + @Deprecated + public IModel importModel(String modelIdentifier, IFile file) throws ModelException { + + return importModel(modelIdentifier, createURI(file)); + } + + /** + * Import only the specified model. ModelSetSnippets are not called. An + * import can be performed after model are loaded. Normally, it should not + * be done before a model is loaded. + * + * @param modelIdentifier + * the model identifier + * @param file + * the file + * @throws ModelException + * @returns The loaded model. + */ + public IModel importModel(String modelIdentifier, URI uri) throws ModelException { + + importModels(new ModelIdentifiers(modelIdentifier), uri); + + return getModel(modelIdentifier); + } + + /** + * Create models that are not already created or loaded. + */ + public void createMissingModels() throws ModelException { + throw new UnsupportedOperationException("Not yet implemented"); // TODO + + } + + /** + * Load models that are not already created or loaded. + */ + public void loadMissingModels() throws ModelException { + throw new UnsupportedOperationException("Not yet implemented"); // TODO + + } + + /** + * Save the resources. + * + * @param monitor + * The monitor. + * @throws IOException + * IO Error. + */ + public void save(IProgressMonitor monitor) throws IOException { + + // Initialize monitor with the number of models + Collection<IModel> modelList = models.values(); + monitor.beginTask("Saving resources", modelList.size()); + + IReadOnlyHandler2 roHandler = getReadOnlyHandler(); + if (isTrackingModification() && (roHandler != null)) { + Set<URI> roUris = new HashSet<URI>(); + for (IModel model : modelList) { + Set<URI> uris = model.getModifiedURIs(); + for (URI u : uris) { + Optional<Boolean> res = (roHandler.anyReadOnly(ReadOnlyAxis.permissionAxes(), new URI[] { u })); + if (res.isPresent() && res.get()) { + roUris.add(u); + } + } + } + + for (URI u : getResourcesToDeleteOnSave()) { + Optional<Boolean> res = roHandler.anyReadOnly(ReadOnlyAxis.permissionAxes(), new URI[] { u }); + if (res.isPresent() && res.get()) { + roUris.add(u); + } + } + + if (!roUris.isEmpty()) { + Optional<Boolean> authorizeSave = roHandler.makeWritable(ReadOnlyAxis.permissionAxes(), roUris.toArray(new URI[roUris.size()])); + + if (authorizeSave.isPresent() && !authorizeSave.get()) { + monitor.done(); + // FIXME: In Kepler M6, it seems that it is sometimes possible to modify the readOnly StandardL3 profile. + // This doesn't have any consequence, but prevents the save action. We'd better not throw an exception here. + // throw new IOException("Some modified resources are read-only : the model can't be saved"); + } + } + } + + // Clean Model set of deleted resources + cleanModelSet(); + + try { + // Walk all registered models + for (IModel model : modelList) { + try { + if (!(model instanceof AdditionalResourcesModel)) { + + // Bug 436952, 4436998 : Clean referenced resources by models + model.cleanModel(getResourcesToDeleteOnSave()); + + model.saveModel(); + monitor.worked(1); + } + } catch (Exception ex) { + // If an exception occurs, we should not prevent other models from being saved. + // This would probably make things even worse. Catch and log. + Activator.log.error(ex); + } + } + try { + additional.cleanModel(getResourcesToDeleteOnSave()); + additional.saveModel(); + } catch (Exception ex) { + Activator.log.error(ex); + } + + // Delete resource back end to delete on save + handleResourcesToDelete(); + } finally { + monitor.done(); + } + } + + + + /** + * Clean model set. + */ + protected void cleanModelSet() { + + // Get referenced resources by Model Set + Iterator<Resource> resourcesIterator = getResources().iterator(); + while (resourcesIterator.hasNext()) { + Resource nextResource = resourcesIterator.next(); + + // Verify if the resource can be unreferenced + if (getResourcesToDeleteOnSave().contains(nextResource.getURI())) { + resourcesIterator.remove(); + } + + } + } + + + + /** + * @return {@link ModelSet#toDeleteOnSave} + */ + public Set<URI> getResourcesToDeleteOnSave() { + return toDeleteOnSave; + } + + /** + * Delete resources pointed by {@link #getResourcesToDeleteOnSave()} set. + */ + protected void handleResourcesToDelete() { + Iterator<URI> uriIterator = getResourcesToDeleteOnSave().iterator(); + while (uriIterator.hasNext()) { + URI uri = uriIterator.next(); + + if (validateDeleteResource(uri)) { + + if (deleteResource(uri)) { + uriIterator.remove(); + } + } + } + } + + protected boolean validateDeleteResource(URI uri) { + boolean result = true; + + Resource resource = getResource(uri, false); + if (resource != null) { + String warMessage = "The resource " + resource.getURI().lastSegment() + " was about to deleted but was still contained in the resource set. The will not be deleted"; + Activator.log.warn(warMessage); + + result = false; + } + + return result; + } + + /** + * This allows to delete a resource from the uri. + * + * @param uri + * The uri of the resource to delete. + * @return <code>true</code> if the resource is deleted, <code>false</code> otherwise. + * @since 3.0 + */ + public boolean deleteResource(final URI uri) { + boolean result = false; + + try { + getURIConverter().delete(uri, null); + result = true; + } catch (IOException e) { + Activator.log.error(e); + + // hope it's a file that we can delete from the workspace! + IFile file = getFile(uri); + if (file != null && file.exists()) { + try { + file.delete(true, new NullProgressMonitor()); + result = true; + } catch (CoreException e2) { + Activator.log.error(e2); + } + } + } + + return result; + } + + /** + * Finds the file corresponding to the specified URI, using a URI converter + * if necessary (and provided) to normalize it. + * + * @param uri + * a URI + * @param converter + * an optional URI converter (may be <code>null</code>) + * + * @return the file, if available in the workspace + */ + protected IFile getFile(URI uri) { + IFile result = null; + if (uri.isPlatformPlugin()) { + /* resource with platform plug-in URI could not be in the workspace */ + return result; + } else if (uri.isPlatformResource()) { + IPath path = new Path(uri.toPlatformString(true)); + result = ResourcesPlugin.getWorkspace().getRoot().getFile(path); + } else if (uri.isFile() && !uri.isRelative()) { + result = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(uri.toFileString())); + } else { + // normalize, to see whether may we can resolve it this time + if (uriConverter != null) { + URI normalized = uriConverter.normalize(uri); + if (!uri.equals(normalized)) { + // recurse on the new URI + result = getFile(normalized); + } + } + } + if ((result == null) && !uri.isRelative()) { + try { + java.net.URI location = new java.net.URI(uri.toString()); + if (hasRegisteredEFS(location)) { + IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(new java.net.URI(uri.toString())); + if (files.length > 0) { + // set the result to be the first file found + result = files[0]; + } + } + } catch (URISyntaxException e) { + // won't get this because EMF provides a well-formed URI + } + } + return result; + } + + protected boolean hasRegisteredEFS(java.net.URI location) { + try { + if (EFS.getStore(location) != null) { + return true; + } + } catch (CoreException ex) { + return false; + } + return false; + } + + /** + * The resources are already loaded, but we want to save them under another + * name. + * + * @param path + * the path + * @throws IOException + * Signals that an I/O exception has occurred. + * + * @deprecated Use the {@link #saveAs(URI)} API, instead. + */ + @Deprecated + public void saveAs(IPath path) throws IOException { + saveAs(URI.createPlatformResourceURI(path.toString(), true)); + } + + /** + * The resources are already loaded, but we want to save them under another + * name. + * + * @param path + * the path + * @throws IOException + * Signals that an I/O exception has occurred. + */ + public void saveAs(URI uri) throws IOException { + + EcoreUtil.resolveAll(this); // Save will not be consistent if we don't load all related resources first + + // Get the file name, without extension. + URI newUriWithoutExtension = uri.trimFileExtension(); + + // Walk all registered models + for (IModel model : models.values()) { + model.setModelURI(newUriWithoutExtension); + } + + this.uriWithoutExtension = newUriWithoutExtension; + + // Save with new paths + save(new NullProgressMonitor()); + } + + /** + * Unload all the resources. Do not disguard associated models. + */ + public void unload() { + // call snippets to allow them to do their stuff + snippets.performDispose(this); + snippets.clear(); + + + // FIXME RS: handle the unload ordering as indicated in the model extension point + // Walk all registered models + for (IModel model : models.values()) { + if (!(model instanceof AdditionalResourcesModel)) { + model.unload(); + } + } + additional.unload(); + + // Unload remaining resources + for (Iterator<Resource> iter = getResources().iterator(); iter.hasNext();) { + iter.next().unload(); + iter.remove(); + } + + uninstallLanguages(); + + // Clear the package registry (it may contain dynamic profile EPackages that we don't + // want to leak in BasicExtendedMetaData instances attached to static EPackages) + // Works around EMF bug 433108 + EPackage.Registry packageRegistry = getPackageRegistry(); + if (packageRegistry != null) { + packageRegistry.clear(); + } + + // Dispose Editing Domain + if (transactionalEditingDomain != null) { + transactionalEditingDomain.dispose(); + transactionalEditingDomain = null; + } + // Detach associated factories + if (adapterFactories != null) { + adapterFactories.clear(); + } + EList<Adapter> adapters = eAdapters(); + if (adapters != null) { + adapters.clear(); + } + } + + public IReadOnlyHandler2 getReadOnlyHandler() { + if (roHandler == null) { + EditingDomain editingDomain = getTransactionalEditingDomain(); + Object handler = PlatformHelper.getAdapter(editingDomain, IReadOnlyHandler.class); + if (handler instanceof IReadOnlyHandler2) { + roHandler = (IReadOnlyHandler2) handler; + } else if (handler instanceof IReadOnlyHandler) { + roHandler = AbstractReadOnlyHandler.adapt((IReadOnlyHandler) handler, editingDomain); + } + } + return roHandler; + } + + /** + * Obtains my internal API adapter. + * + * @return my internal API adapter + */ + public Internal getInternal() { + return new Internal() { + + @Override + public void setPrimaryModelResourceURI(URI uri) { + setURIWithoutExtension(uri.trimFileExtension()); + } + + @Override + public void registerModel(IModel model, boolean force) { + if (force) { + doRegisterModel(model); + } else { + ModelSet.this.registerModel(model); + } + } + }; + } + + /** + * Add a {@link IModelSetSnippet}. A snippet allows to add code that will + * perform additional operations on the ModelSet. + * + * @param snippet + * The snippet to add. + */ + public void addModelSetSnippet(IModelSetSnippet snippet) { + snippets.add(snippet); + } + + /** + * A list of {@link IModelSetSnippet}. + * + * Used by Models to maintain their list of Snippets. + * + * @author cedric dumoulin + * + */ + public class ModelSetSnippetList extends ArrayList<IModelSetSnippet> { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Call the start method on all registered snippets. + * + * @param modelsManager + * The model that is starting + */ + public void performStart(ModelSet modelsManager) { + for (IModelSetSnippet snippet : this) { + snippet.start(modelsManager); + } + } + + /** + * Call the start method on all registered snippets. + * + * @param modelsManager + * The model that is stopping + */ + public void performDispose(ModelSet modelsManager) { + for (IModelSetSnippet snippet : this) { + snippet.dispose(modelsManager); + } + + } + } + + /** + * Internal API for manipulation of {@link ModelSet}s. + */ + public static interface Internal { + + /** + * Sets the {@link ModelSet}'s primary resource URI. + * + * @param uri + * the URI + * + * @see ModelSet#createModels(URI) + * @see ModelSet#saveAs(URI) + */ + void setPrimaryModelResourceURI(URI uri); + + /** + * Register a model with the option to force it (in case a more specific + * implementation of the model is already registered). + * + * @param model + * a model to register + * @param force + * whether to force the registration + */ + void registerModel(IModel model, boolean force); + } + + /** + * + * @param target + */ + public void saveCopy(IPath targetPathWithoutExtension) { + List<IVersionableModel> versionableModels = new LinkedList<IVersionableModel>(); + + Map<Object, Object> targetMap = new HashMap<Object, Object>(); + + for (IModel model : models.values()) { + if (model instanceof IVersionableModel) { + IVersionableModel versionable = (IVersionableModel) model; + versionable.fillTargetMap(targetPathWithoutExtension, targetMap); + versionableModels.add(versionable); + } + } + + for (IVersionableModel model : versionableModels) { + model.saveCopy(targetPathWithoutExtension, targetMap); + } + } + + public boolean addResourceLoadStateListener(IResourceLoadStateListener listener) { + return resourceLoadStateListeners.add(listener); + } + + public boolean removeResourceLoadStateListener(IResourceLoadStateListener listener) { + return resourceLoadStateListeners.remove(listener); + } + + public void notifyResourceLoadState(Resource resource, boolean newState) { + if (resourceLoadStateListeners != null) { + for (IResourceLoadStateListener listener : resourceLoadStateListeners) { + try { + listener.notifyLoadStateChanged(resource, newState); + } catch (Throwable e) { + Activator.log.error(e); + } + } + } + } + + public boolean isUserModelResource(URI uri) { + return uri.isPlatformResource() || uri.isFile(); + } + + public class ResourceAddRemoveTracker implements Adapter { + + /** + * {@inheritDoc} + */ + @Override + public void notifyChanged(Notification notification) { + // if notification = add, add many or remove/remove many resource(s) to list of resources, process.. + if (RESOURCE_SET__RESOURCES == notification.getFeatureID(ResourceSet.class)) { + switch (notification.getEventType()) { + case Notification.ADD: + Object object = notification.getNewValue(); + if (object instanceof Resource) { + resourcesToLoadState.put(((Resource) object), ((Resource) object).isLoaded()); + } + break; + case Notification.REMOVE: + object = notification.getOldValue(); + if (object instanceof Resource) { + resourcesToLoadState.remove((object)); + } + break; + case Notification.ADD_MANY: + + break; + + case Notification.REMOVE_MANY: + + break; + + default: + // nothing to do + break; + } + + } + } + + /** + * {@inheritDoc} + */ + @Override + public Notifier getTarget() { + return ModelSet.this; + } + + /** + * {@inheritDoc} + */ + @Override + public void setTarget(Notifier newTarget) { + // nothing here + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isAdapterForType(Object type) { + return false; + } + + } + + /** + * Returns the IModel which handles the specified element, if any + * + * @param container + * @return + */ + public IModel getModelFor(Object element) { + for (IModel model : models.values()) { + if (model.isModelFor(element)) { + return model; + } + } + return null; + } + + protected void installLanguages() { + ILanguageService languageService = ServiceUtils.getInstance().getService(ILanguageService.class, ModelSetServiceFactory.getServiceRegistry(this), null); + if (languageService != null) { + languages = Lists.newArrayList(languageService.getLanguages(getURIWithoutExtension(), false)); + + for (ILanguage next : languages) { + try { + next.install(this); + } catch (Exception e) { + Activator.log.error("Uncaught exception in installation of language " + next, e); //$NON-NLS-1$ + } + } + } + } + + protected void uninstallLanguages() { + if (languages != null) { + for (ILanguage next : Lists.reverse(languages)) { + try { + next.uninstall(this); + } catch (Exception e) { + Activator.log.error("Uncaught exception in uninstallation of language " + next, e); //$NON-NLS-1$ + } + } + + languages.clear(); + } + } + + /** + * Obtains the model that should persist an {@code object}. + * + * @param object + * an object to be persisted as a new root of a managed EMF {@code Resource} + * + * @return the model that is best suited to persist the {@code object}, or {@code null} if none + * @since 2.0 + */ + public IEMFModel getModelToPersist(EObject object) { + return models.values().stream() + .filter(IEMFModel.class::isInstance) + .map(IEMFModel.class::cast) + .filter(m -> m.canPersist(object)) + .findFirst() + .orElse(null); + } +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelSnippetList.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelSnippetList.java index 8a441880c38..0de42e58def 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelSnippetList.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/ModelSnippetList.java @@ -1,47 +1,47 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.resource;
-
-import java.util.ArrayList;
-
-/**
- * A list of {@link IModelSnippet}.
- *
- * Used by Models to maintain their list of Snippets.
- *
- * @author cedric dumoulin
- *
- */
-public class ModelSnippetList extends ArrayList<IModelSnippet> {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Call the start method on all registered snippets.
- *
- * @param model
- * The model that is starting
- */
- public void performStart(IModel model) {
- for (IModelSnippet snippet : this) {
- snippet.start(model);
- }
- }
-
- /**
- * Call the start method on all registered snippets.
- *
- * @param model
- * The model that is stopping
- */
- public void performDispose(IModel model) {
- for (IModelSnippet snippet : this) {
- snippet.dispose(model);
- }
-
- }
-}
+/** + * + */ +package org.eclipse.papyrus.infra.core.resource; + +import java.util.ArrayList; + +/** + * A list of {@link IModelSnippet}. + * + * Used by Models to maintain their list of Snippets. + * + * @author cedric dumoulin + * + */ +public class ModelSnippetList extends ArrayList<IModelSnippet> { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Call the start method on all registered snippets. + * + * @param model + * The model that is starting + */ + public void performStart(IModel model) { + for (IModelSnippet snippet : this) { + snippet.start(model); + } + } + + /** + * Call the start method on all registered snippets. + * + * @param model + * The model that is stopping + */ + public void performDispose(IModel model) { + for (IModelSnippet snippet : this) { + snippet.dispose(model); + } + + } +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/NotFoundException.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/NotFoundException.java index e616c138b9c..e5d9e20ece3 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/NotFoundException.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/NotFoundException.java @@ -1,54 +1,54 @@ -/**
- *
- */
-package org.eclipse.papyrus.infra.core.resource;
-
-/**
- * Exception indicating that something is not found.
- *
- * @author cedric dumoulin
- *
- */
-public class NotFoundException extends ModelException {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor.
- *
- */
- public NotFoundException() {
- }
-
- /**
- * Constructor.
- *
- * @param message
- */
- public NotFoundException(String message) {
- super(message);
- }
-
- /**
- * Constructor.
- *
- * @param cause
- */
- public NotFoundException(Throwable cause) {
- super(cause);
- }
-
- /**
- * Constructor.
- *
- * @param message
- * @param cause
- */
- public NotFoundException(String message, Throwable cause) {
- super(message, cause);
- }
-
-}
+/** + * + */ +package org.eclipse.papyrus.infra.core.resource; + +/** + * Exception indicating that something is not found. + * + * @author cedric dumoulin + * + */ +public class NotFoundException extends ModelException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Constructor. + * + */ + public NotFoundException() { + } + + /** + * Constructor. + * + * @param message + */ + public NotFoundException(String message) { + super(message); + } + + /** + * Constructor. + * + * @param cause + */ + public NotFoundException(Throwable cause) { + super(cause); + } + + /** + * Constructor. + * + * @param message + * @param cause + */ + public NotFoundException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/PapyrusProjectScope.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/PapyrusProjectScope.java index 5efef5e01e3..0d01ac4530e 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/PapyrusProjectScope.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/PapyrusProjectScope.java @@ -1,142 +1,142 @@ -/*****************************************************************************
- * Copyright (c) 2016, 2017 CEA LIST, Christian W. Damus, 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:
- * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Initial API and implementation
- * Christian W. Damus - bug 528343
- *
- *****************************************************************************/
-
-package org.eclipse.papyrus.infra.core.resource;
-
-import java.util.Objects;
-
-import org.eclipse.core.internal.preferences.AbstractScope;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.core.runtime.preferences.IEclipsePreferences;
-
-/**
- * This papyrus scope for the papyrus project preference store.
- * This need to manage the preference for the papyrus project with the papyrus project name (to retrieve the correct name).
- *
- * @since 3.0
- */
-@SuppressWarnings("restriction")
-public class PapyrusProjectScope extends AbstractScope {
-
- /**
- * String constant (value of <code>"papyrusProject"</code>) used for the scope name for this preference scope.
- */
- public static final String SCOPE = "papyrusProject"; //$NON-NLS-1$
-
- /**
- * The papyrus project name.
- */
- private final String papyrusProjectName;
-
- /**
- * The context project.
- */
- private final IProject context;
-
- /**
- * Cached hash code.
- */
- private int hash = 0;
-
- /**
- * Constructor.
- *
- * @param project
- * The project.
- * @param papyrusProjectName
- * The name of the '.di' file.
- */
- public PapyrusProjectScope(final IProject project, final String papyrusProjectName) {
- this.context = project;
- this.papyrusProjectName = papyrusProjectName;
- }
-
- /**
- * Default path hierarchy for nodes is /<scope>/<qualifier>.
- *
- * @param qualifier
- * The qualifier.
- * @return The path hierarchy.
- */
- @Override
- public IEclipsePreferences getNode(final String qualifier) {
- if (qualifier == null)
- throw new IllegalArgumentException();
- final StringBuilder node = new StringBuilder(context.getName());
- node.append("/"); //$NON-NLS-1$
- node.append(papyrusProjectName);
- return (IEclipsePreferences) Platform.getPreferencesService().getRootNode().node(SCOPE).node(node.toString()).node(qualifier);
- }
-
- /**
- * The papyrus scope name.
- *
- * @return The papyrus scope name.
- */
- @Override
- public String getName() {
- return SCOPE;
- }
-
- /**
- * The location of the scope.
- *
- * @return The location of the scope.
- */
- @Override
- public IPath getLocation() {
- // This must not be save
- return null;
- }
-
- /**
- * This allows to determinate if the object in parameter is equals to the current.
- *
- * @param obj
- * The object to compare.
- * @return <code>true</code> if this is equals, <code>false</code> otherwise.
- */
- @Override
- public boolean equals(final Object obj) {
- if (this == obj)
- return true;
- if (!(obj instanceof PapyrusProjectScope))
- return false;
- if (!super.equals(obj))
- return false;
- PapyrusProjectScope other = (PapyrusProjectScope) obj;
- return context.equals(other.context) && papyrusProjectName.equals(other.papyrusProjectName);
- }
-
- /**
- * This allows to define the int hash code.
- *
- * @return The int representing the hascode.
- */
- @Override
- public int hashCode() {
- if (hash == 0) {
- int h = super.hashCode();
- h = 37 * h + Objects.hashCode(context);
- h = 37 * h + Objects.hashCode(papyrusProjectName);
-
- hash = h;
- }
-
- return hash;
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2016, 2017 CEA LIST, Christian W. Damus, 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: + * Nicolas FAUVERGUE (ALL4TEC) nicolas.fauvergue@all4tec.net - Initial API and implementation + * Christian W. Damus - bug 528343 + * + *****************************************************************************/ + +package org.eclipse.papyrus.infra.core.resource; + +import java.util.Objects; + +import org.eclipse.core.internal.preferences.AbstractScope; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; + +/** + * This papyrus scope for the papyrus project preference store. + * This need to manage the preference for the papyrus project with the papyrus project name (to retrieve the correct name). + * + * @since 3.0 + */ +@SuppressWarnings("restriction") +public class PapyrusProjectScope extends AbstractScope { + + /** + * String constant (value of <code>"papyrusProject"</code>) used for the scope name for this preference scope. + */ + public static final String SCOPE = "papyrusProject"; //$NON-NLS-1$ + + /** + * The papyrus project name. + */ + private final String papyrusProjectName; + + /** + * The context project. + */ + private final IProject context; + + /** + * Cached hash code. + */ + private int hash = 0; + + /** + * Constructor. + * + * @param project + * The project. + * @param papyrusProjectName + * The name of the '.di' file. + */ + public PapyrusProjectScope(final IProject project, final String papyrusProjectName) { + this.context = project; + this.papyrusProjectName = papyrusProjectName; + } + + /** + * Default path hierarchy for nodes is /<scope>/<qualifier>. + * + * @param qualifier + * The qualifier. + * @return The path hierarchy. + */ + @Override + public IEclipsePreferences getNode(final String qualifier) { + if (qualifier == null) + throw new IllegalArgumentException(); + final StringBuilder node = new StringBuilder(context.getName()); + node.append("/"); //$NON-NLS-1$ + node.append(papyrusProjectName); + return (IEclipsePreferences) Platform.getPreferencesService().getRootNode().node(SCOPE).node(node.toString()).node(qualifier); + } + + /** + * The papyrus scope name. + * + * @return The papyrus scope name. + */ + @Override + public String getName() { + return SCOPE; + } + + /** + * The location of the scope. + * + * @return The location of the scope. + */ + @Override + public IPath getLocation() { + // This must not be save + return null; + } + + /** + * This allows to determinate if the object in parameter is equals to the current. + * + * @param obj + * The object to compare. + * @return <code>true</code> if this is equals, <code>false</code> otherwise. + */ + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (!(obj instanceof PapyrusProjectScope)) + return false; + if (!super.equals(obj)) + return false; + PapyrusProjectScope other = (PapyrusProjectScope) obj; + return context.equals(other.context) && papyrusProjectName.equals(other.papyrusProjectName); + } + + /** + * This allows to define the int hash code. + * + * @return The int representing the hascode. + */ + @Override + public int hashCode() { + if (hash == 0) { + int h = super.hashCode(); + h = 37 * h + Objects.hashCode(context); + h = 37 * h + Objects.hashCode(papyrusProjectName); + + hash = h; + } + + return hash; + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/TransactionalEditingDomainManager.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/TransactionalEditingDomainManager.java index f0c53ef82e2..1830668951b 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/TransactionalEditingDomainManager.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/TransactionalEditingDomainManager.java @@ -1,114 +1,114 @@ -/*****************************************************************************
- * Copyright (c) 2011, 2014 Atos, CEA, 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:
- * Mathieu Velten mathieu.velten@atos.net - Initial API and implementation
- * Christian W. Damus (CEA) - bug 402525
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.resource;
-
-import java.util.Collections;
-import java.util.LinkedList;
-
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
-import org.eclipse.emf.transaction.TransactionalEditingDomain;
-import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl;
-import org.eclipse.emf.workspace.WorkspaceEditingDomainFactory;
-
-/**
- * Manager used to read transactionalEditingDomainProvider extension point
- * and providing an helper method to create an Editing Domain.
- *
- * @author mvelten
- *
- */
-public class TransactionalEditingDomainManager {
-
- protected static final ITransactionalEditingDomainProvider[] orderedProvidersArray;
-
- protected static class ProviderPriorityPair implements Comparable<ProviderPriorityPair> {
-
- public ITransactionalEditingDomainProvider provider;
-
- public int priority;
-
- @Override
- public int compareTo(ProviderPriorityPair o) {
- if (o.priority > priority) {
- return 1;
- } else if (o.priority < priority) {
- return -1;
- } else {
- return 0;
- }
- }
- }
-
- static {
- IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.papyrus.infra.core", "transactionalEditingDomainProvider");
-
- LinkedList<ProviderPriorityPair> providerPriorityPairs = new LinkedList<ProviderPriorityPair>();
-
- for (IConfigurationElement elem : configElements) {
- if ("transactionalEditingDomainProvider".equals(elem.getName())) {
- try {
- ProviderPriorityPair providerPriorityPair = new ProviderPriorityPair();
- providerPriorityPair.provider = (ITransactionalEditingDomainProvider) elem.createExecutableExtension("class");
- providerPriorityPair.priority = Integer.parseInt(elem.getAttribute("priority"));
-
- providerPriorityPairs.add(providerPriorityPair);
- } catch (Exception e) {
- }
- }
- }
-
- Collections.sort(providerPriorityPairs);
-
- orderedProvidersArray = new ITransactionalEditingDomainProvider[providerPriorityPairs.size()];
-
- for (int i = 0; i < orderedProvidersArray.length; i++) {
- orderedProvidersArray[i] = providerPriorityPairs.get(i).provider;
- }
- }
-
- /**
- * Create an Editing Domain using the registered provider with the highest priority.
- *
- * @param resourceSet
- * @return
- */
- public static TransactionalEditingDomain createTransactionalEditingDomain(ResourceSet resourceSet) {
- for (ITransactionalEditingDomainProvider provider : orderedProvidersArray) {
- TransactionalEditingDomain ed = provider.createTransactionalEditingDomain(resourceSet);
- if (ed != null) {
- return ed;
- }
- }
- return createDefaultTransactionalEditingDomain(resourceSet);
- }
-
- public static TransactionalEditingDomain createDefaultTransactionalEditingDomain(ResourceSet resourceSet) {
- // NotifyingWorkspaceCommandStack stack = new NotifyingWorkspaceCommandStack(CheckedOperationHistory.getInstance());
- // stack.setResourceUndoContextPolicy(IResourceUndoContextPolicy.DEFAULT);
-
- NestingTransactionalCommandStack stack = new NestingTransactionalCommandStack();
- TransactionalEditingDomain result = new TransactionalEditingDomainImpl(new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE), stack, resourceSet);
-
- WorkspaceEditingDomainFactory.INSTANCE.mapResourceSet(result);
-
- return result;
- }
-
- public static TransactionalEditingDomain getTransactionalEditingDomain(ResourceSet resourceSet) {
- return WorkspaceEditingDomainFactory.INSTANCE.getEditingDomain(resourceSet);
- }
-}
+/***************************************************************************** + * Copyright (c) 2011, 2014 Atos, CEA, 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: + * Mathieu Velten mathieu.velten@atos.net - Initial API and implementation + * Christian W. Damus (CEA) - bug 402525 + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.resource; + +import java.util.Collections; +import java.util.LinkedList; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.Platform; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.edit.provider.ComposedAdapterFactory; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl; +import org.eclipse.emf.workspace.WorkspaceEditingDomainFactory; + +/** + * Manager used to read transactionalEditingDomainProvider extension point + * and providing an helper method to create an Editing Domain. + * + * @author mvelten + * + */ +public class TransactionalEditingDomainManager { + + protected static final ITransactionalEditingDomainProvider[] orderedProvidersArray; + + protected static class ProviderPriorityPair implements Comparable<ProviderPriorityPair> { + + public ITransactionalEditingDomainProvider provider; + + public int priority; + + @Override + public int compareTo(ProviderPriorityPair o) { + if (o.priority > priority) { + return 1; + } else if (o.priority < priority) { + return -1; + } else { + return 0; + } + } + } + + static { + IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.papyrus.infra.core", "transactionalEditingDomainProvider"); + + LinkedList<ProviderPriorityPair> providerPriorityPairs = new LinkedList<ProviderPriorityPair>(); + + for (IConfigurationElement elem : configElements) { + if ("transactionalEditingDomainProvider".equals(elem.getName())) { + try { + ProviderPriorityPair providerPriorityPair = new ProviderPriorityPair(); + providerPriorityPair.provider = (ITransactionalEditingDomainProvider) elem.createExecutableExtension("class"); + providerPriorityPair.priority = Integer.parseInt(elem.getAttribute("priority")); + + providerPriorityPairs.add(providerPriorityPair); + } catch (Exception e) { + } + } + } + + Collections.sort(providerPriorityPairs); + + orderedProvidersArray = new ITransactionalEditingDomainProvider[providerPriorityPairs.size()]; + + for (int i = 0; i < orderedProvidersArray.length; i++) { + orderedProvidersArray[i] = providerPriorityPairs.get(i).provider; + } + } + + /** + * Create an Editing Domain using the registered provider with the highest priority. + * + * @param resourceSet + * @return + */ + public static TransactionalEditingDomain createTransactionalEditingDomain(ResourceSet resourceSet) { + for (ITransactionalEditingDomainProvider provider : orderedProvidersArray) { + TransactionalEditingDomain ed = provider.createTransactionalEditingDomain(resourceSet); + if (ed != null) { + return ed; + } + } + return createDefaultTransactionalEditingDomain(resourceSet); + } + + public static TransactionalEditingDomain createDefaultTransactionalEditingDomain(ResourceSet resourceSet) { + // NotifyingWorkspaceCommandStack stack = new NotifyingWorkspaceCommandStack(CheckedOperationHistory.getInstance()); + // stack.setResourceUndoContextPolicy(IResourceUndoContextPolicy.DEFAULT); + + NestingTransactionalCommandStack stack = new NestingTransactionalCommandStack(); + TransactionalEditingDomain result = new TransactionalEditingDomainImpl(new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE), stack, resourceSet); + + WorkspaceEditingDomainFactory.INSTANCE.mapResourceSet(result); + + return result; + } + + public static TransactionalEditingDomain getTransactionalEditingDomain(ResourceSet resourceSet) { + return WorkspaceEditingDomainFactory.INSTANCE.getEditingDomain(resourceSet); + } +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/services/ServicesRegistry.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/services/ServicesRegistry.java index d04a519dc7b..bbe41b2cfcf 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/services/ServicesRegistry.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/services/ServicesRegistry.java @@ -1,1134 +1,1134 @@ -/*****************************************************************************
- * Copyright (c) 2011, 2015 LIFL, CEA, Christian W. Damus, 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:
- * LIFL - Initial API and implementation
- * Christian W. Damus (CEA) - bug 431953 (fix start-up of selective services to require only their dependencies)
- * Christian W. Damus - bug 468030
- */
-package org.eclipse.papyrus.infra.core.services;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Logger;
-
-import org.eclipse.papyrus.infra.core.Activator;
-import org.eclipse.papyrus.infra.core.services.ServiceDescriptor.ServiceTypeKind;
-import org.eclipse.papyrus.infra.core.services.internal.LazyStartupEntry;
-import org.eclipse.papyrus.infra.core.services.internal.PojoServiceEntry;
-import org.eclipse.papyrus.infra.core.services.internal.ServiceAdapterEntry;
-import org.eclipse.papyrus.infra.core.services.internal.ServiceEntry;
-import org.eclipse.papyrus.infra.core.services.internal.ServiceFactoryEntry;
-import org.eclipse.papyrus.infra.core.services.internal.ServiceStartupEntry;
-import org.eclipse.papyrus.infra.core.services.internal.ServiceTypeEntry;
-import org.eclipse.papyrus.infra.core.services.internal.StartStartupEntry;
-import org.eclipse.papyrus.infra.core.utils.AdapterUtils;
-
-/**
- * A registry of services. This registry allows to get a service by its
- * identifier. The identifier is generally the classname of the service.
- * Services can be added using the Eclipse extension mechanism (if you use {@link ExtensionServicesRegistry}). <br>
- * A Service is a class providing operations. The ServiceRegistry is used to
- * share objects (i.e. services) between nested editors and also the core main
- * editor.
- *
- * <br>
- * In this implementation, services should be added to the registry before the
- * call to createServices(). If a service is added after the call, it will not
- * be started (except if it is a lazy service). <br>
- * A typical usage is:
- *
- * <pre>
- * <code>
- * ServicesRegistry serviceRegistry = new ServiceRegistry();
- * // Add your services
- * serviceRegistry.add( ...);
- * serviceRegistry.add( ...);
- *
- * // start the services
- * serviceRegistry.startRegistry();
- *
- * // Retrieve a service
- * myService = serviceRegistry.getService( serviceKey );
- * </code>
- * </pre>
- *
- * It is possible to register new services after the serviceRegistry has been
- * started. In this case, you need to start them explicitly if they are of type
- * ServiceStartKind.STARTUP.
- *
- * <pre>
- * <code>
- * // Add your new services
- * serviceRegistry.add( key1, ...);
- * serviceRegistry.add( key2, ...);
- *
- * // start the new services
- * serviceRegistry.startRegistry(key1, key2);
- * </code>
- * </pre>
- *
- * <ul>
- * <li></li>
- * <li></li>
- * </ul>
- *
- * @author cedric dumoulin
- *
- *
- */
-public class ServicesRegistry {
-
- /**
- * Log object
- *
- * @deprecated Use {@link Activator#log} instead
- */
- // @unused
- @Deprecated
- protected Logger log = Logger.getLogger(getClass().getName());
-
- /**
- * Map of existing services.
- */
- // private Map<Object, AbstractServiceEntry> services;
-
- /**
- * A Map of services added to the register (thow the addXxx() methods), but
- * not yet registered. They will be registered after a call to startXxx().
- */
- private Map<String, ServiceStartupEntry> addedServices = new HashMap<String, ServiceStartupEntry>();
-
- /**
- * Map of services registered with a name.
- */
- private Map<String, ServiceStartupEntry> namedServices = new HashMap<String, ServiceStartupEntry>();
-
- /**
- * Map of services registered without a name (anonymous). Such services
- * can't be retrieved.
- */
- private List<ServiceStartupEntry> anonymousServices = new ArrayList<ServiceStartupEntry>();
-
- /**
- * Constructor.
- */
- public ServicesRegistry() {
- }
-
- /**
- * Add a service by its ServiceDescriptor.
- *
- * @param serviceDescriptor
- * Descriptor describing the service.
- * @throws ServiceException
- * If an error occurs while initializing service.
- */
- public void add(ServiceDescriptor serviceDescriptor) {
- // Check if the service already exist.
- ServiceStartupEntry service = addedServices.get(serviceDescriptor.getKey());
- if (service != null) {
- if (service.getDescriptor().getPriority() > serviceDescriptor.getPriority()) {
- return;
- } else if (service.getDescriptor().getPriority() == serviceDescriptor.getPriority()) {
- Activator.log.warn("Two services with same priority (" + serviceDescriptor.getPriority() + ") are declared under key '" + service.getDescriptor().getKey() + "'. Keep the first encountered only. (bundles: "
- + service.getDescriptor().getClassBundleID() + ", " + serviceDescriptor.getClassBundleID() + ")");
- }
- }
-
- // Compute the service type entry
- ServiceTypeEntry serviceTypeEntry;
- ServiceTypeKind typeKind = serviceDescriptor.getServiceTypeKind();
- if (typeKind == ServiceTypeKind.service) {
- serviceTypeEntry = new ServiceEntry(serviceDescriptor);
- } else if (typeKind == ServiceTypeKind.serviceFactory) {
- serviceTypeEntry = new ServiceFactoryEntry(serviceDescriptor);
- } else {
- serviceTypeEntry = new PojoServiceEntry(serviceDescriptor);
- }
-
- // Create the entry
- ServiceStartupEntry serviceEntry;
- if (serviceDescriptor.isStartAtStartup()) {
- serviceEntry = new StartStartupEntry(serviceTypeEntry);
- } else {
- serviceEntry = new LazyStartupEntry(serviceTypeEntry, this);
- }
- // Add the entry
- addedServices.put(serviceDescriptor.getKey(), serviceEntry);
- }
-
- /**
- * Add a service. The descriptor will be created.
- *
- * @param key
- * Service key
- * @param priority
- * service priority
- * @param serviceInstance
- * The instance of the service
- */
- public void add(String key, int priority, IService serviceInstance) {
- add(key, priority, serviceInstance, ServiceStartKind.STARTUP);
- }
-
- /**
- * Add a service. The descriptor will be created.
- *
- * @param key
- * Service key
- * @param priority
- * service priority
- * @param serviceInstance
- * The instance of the service
- */
- public void add(Class<?> key, int priority, IService serviceInstance) {
- add(key.getName(), priority, serviceInstance, ServiceStartKind.STARTUP);
- }
-
- /**
- * Add a service. The descriptor will be created.
- *
- * @param key
- * Service key
- * @param priority
- * service priority
- * @param serviceInstance
- * The instance of the service
- */
- public void add(String key, int priority, IService serviceInstance, ServiceStartKind startKind) {
- // Check if the service already exist.
- ServiceStartupEntry service = addedServices.get(key);
- if (service != null) {
- if (service.getDescriptor().getPriority() > priority) {
- return;
- } else if (service.getDescriptor().getPriority() == priority) {
- Activator.log.warn("Two services with same priority (" + priority + ") are declared under key '" + service.getDescriptor().getKey() + "'. Keep the first encountered only.");
- }
- }
-
- // Create descriptor and add service.
- ServiceDescriptor descriptor = new ServiceDescriptor(key, serviceInstance.getClass().getName(), startKind, priority);
-
- if (startKind == ServiceStartKind.STARTUP) {
- addedServices.put(key, new StartStartupEntry(new ServiceEntry(descriptor, serviceInstance)));
- } else {
- addedServices.put(key, new LazyStartupEntry(new ServiceEntry(descriptor, serviceInstance), this));
- }
- }
-
- /**
- * Add a service. The descriptor will be created.
- *
- * @param key
- * Service key Class used as key. The classname is used as key.
- * @param priority
- * service priority
- * @param serviceInstance
- * The instance of the service
- */
- public void add(Class<?> key, int priority, IService serviceInstance, ServiceStartKind startKind) {
-
- add(key.getName(), priority, serviceInstance, startKind);
- }
-
- /**
- * Add an already instanciated pojo (Plain Old Java Object) as Service. The
- * descriptor will be created. No life cycle methods are called on the
- * service.
- *
- * @param key
- * Service key
- * @param priority
- * service priority
- * @param serviceInstance
- * The instance of the service
- */
- public void add(Class<?> key, int priority, Object serviceInstance) {
- add(key, priority, serviceInstance, ServiceStartKind.STARTUP);
- }
-
- /**
- * Add an already instanciated pojo (Plain Old Java Object) as Service. The
- * descriptor will be created. No life cycle methods are called on the
- * service.
- *
- * @param key
- * Service key
- * @param priority
- * service priority
- * @param serviceInstance
- * The instance of the service
- * @param startKind
- *
- */
- public void add(String key, int priority, Object serviceInstance, ServiceStartKind startKind) {
- // If the service instance is actually an IService, register it thus to enable the lifecycle hooks
- if (serviceInstance instanceof IService) {
- add(key, priority, (IService) serviceInstance, startKind);
- }
-
- // Check if the service already exist.
- ServiceStartupEntry service = addedServices.get(key);
- if (service != null) {
- if (service.getDescriptor().getPriority() > priority) {
- return;
- } else if (service.getDescriptor().getPriority() == priority) {
- Activator.log.warn("Two services with same priority (" + priority + ") are declared under key '" + service.getDescriptor().getKey() + "'. Keep the first encountered only.");
- }
- }
-
- // Create descriptor and add service.
- ServiceDescriptor descriptor = new ServiceDescriptor(key, serviceInstance.getClass().getName(), startKind, priority);
- ServiceTypeEntry type;
- ServiceStartupEntry entry;
-
- // If the instance is a service or has an adapter for the service protocol, register that
- IService serviceAdapter = AdapterUtils.adapt(serviceInstance, IService.class, null);
- if (serviceAdapter != null) {
- type = new ServiceAdapterEntry(descriptor, serviceInstance, serviceAdapter);
- } else {
- type = new PojoServiceEntry(descriptor, serviceInstance);
- }
-
- switch (startKind) {
- case STARTUP:
- entry = new StartStartupEntry(type);
- break;
- case LAZY:
- entry = new LazyStartupEntry(type, this);
- break;
- default:
- throw new IllegalArgumentException("Unrecognized startKind: " + startKind);
- }
-
- addedServices.put(key, entry);
- }
-
- /**
- * Add an already instanciated pojo (Plain Old Java Object) as Service. The
- * descriptor will be created. No life cycle methods are called on the
- * service.
- *
- * @param key
- * Service key Class used as key. The classname is used as key.
- * @param priority
- * service priority
- * @param serviceInstance
- * The instance of the service
- * @param startKind
- *
- */
- public void add(Class<?> key, int priority, Object serviceInstance, ServiceStartKind startKind) {
-
- add(key.getName(), priority, serviceInstance, startKind);
- }
-
- /**
- * Remove the specified service from the registry.
- *
- * @param key
- */
- public void remove(ServiceDescriptor serviceDescriptor) throws ServiceException {
- remove(serviceDescriptor.getKey());
- }
-
- /**
- * Remove the specified service from the registry.
- *
- * @param key
- */
- public void remove(Object key) throws ServiceException {
- ServiceStartupEntry service = namedServices.remove(key);
- if (service == null) {
- return;
- }
-
- // Stop the service
- service.disposeService();
- }
-
- /**
- * Get the requested service by its key. The key is usually the classname of
- * the service.
- *
- * @param serviceClass
- * @return
- * @throws ServiceException
- * If servive can't be started
- */
- public Object getService(Object key) throws ServiceException {
- ServiceStartupEntry service = namedServices.get(key);
- if (service == null) {
- // throw an exception.
- // If added, say it.
- service = addedServices.get(key);
- if (service != null) {
- throw new BadStateException("Registry should be started before.", service.getState(), service.getDescriptor());
- } else {
- throw new ServiceNotFoundException("No service registered under '" + key + "'");
- }
- }
-
- return service.getServiceInstance();
- }
-
- /**
- * Get the requested service by its class (the service has to be registered
- * by its class object).
- *
- * @param key
- * The service class.
- * @return The service.
- * @throws ServiceException
- * If service can't be started
- */
- @SuppressWarnings("unchecked")
- public <S> S getService(Class<S> key) throws ServiceException {
-
- String realKey = key.getName();
- ServiceStartupEntry service = namedServices.get(realKey);
-
- if (service == null) {
- // throw an exception.
- // If added, say it.
- service = addedServices.get(realKey);
- if (service != null) {
- throw new BadStateException("Registry should be started before.", service.getState(), service.getDescriptor());
- } else {
- throw new ServiceNotFoundException("No service registered under '" + key + "'");
- }
- }
-
- return (S) service.getServiceInstance();
- }
-
- /**
- * Return true if the service is instantiated. Return false otherwise.
- *
- * @return
- */
- public boolean isStarted(Object key) throws ServiceNotFoundException {
- ServiceStartupEntry service = namedServices.get(key);
- if (service == null) {
- throw new ServiceNotFoundException("No service registered under '" + key + "'");
- }
-
- return service.isStarted();
- }
-
- /**
- * Return the state of the specified service.
- *
- * @return
- */
- public ServiceState serviceState(Object key) throws ServiceNotFoundException {
- ServiceStartupEntry service = namedServices.get(key);
- if (service == null) {
- throw new ServiceNotFoundException("No service registered under '" + key + "'");
- }
-
- return service.getState();
- }
-
- /**
- * Start the registry. Start all services marked as start = STARTUP are
- * started. All services are first created, then initialized and finally
- * started. If an error occur on a service during one of this step, the
- * service is removed from the registry and and the error is logged.
- *
- * @throws ServiceMultiException
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- public void startRegistry() throws ServiceMultiException {
- // Create an object to collect errors if any.
- ServiceMultiException errors = new ServiceMultiException();
-
- // Build the lookup maps
- LookupMap map = new LookupMap(addedServices, namedServices);
-
- // Check if all dependencies exist.
- try {
- checkDependencies(addedServices.values(), map);
- } catch (ServiceMultiException ex) {
- for (Throwable t : ex.getExceptions()) {
- errors.addException(t);
- }
- }
-
- // Get all roots : LAZY and START
- Collection<ServiceStartupEntry> roots = getServiceRoots(addedServices.values(), map);
- // showServices(" Roots:", roots);
- // Detect cycles
- checkCycle(roots, map);
- // Retain only services with startupkind = START
- roots = retainsToStartServices(roots);
- //
- List<ServiceStartupEntry> toStart = buildTopologicalListOfServicesToStart(roots, map);
-
- if (Activator.log.isDebugEnabled()) {
- showServices(" Services to start:", toStart);
- }
-
- createServices(toStart, errors);
- // Register all new services : lazy and start
- registerServices(addedServices.values());
- initServices(toStart, errors);
- startServices(toStart, errors);
-
- // Report errors if any
- if (errors.getExceptions().size() > 0) {
- throw errors;
- }
-
- }
-
- /**
- * Start the specified services, and their required services. The specifies
- * services should be in the addServices or already registered. Start all
- * services marked as start = STARTUP . All eligible services are first
- * created, then initialized and finally started. If an error occur on a
- * service during one of this step, the service is removed from the registry
- * and and the error is logged.
- *
- * @param serviceKeys
- * Keys of services to start.
- * @throws ServiceMultiException
- * @throws ServiceNotFoundException
- * If a service can't be retrieved by its key.
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- public void startServices(List<String> serviceKeys) throws ServiceMultiException, ServiceNotFoundException {
-
- // Build the lookup maps
- LookupMap map = new LookupMap(addedServices, namedServices);
-
- // Get the services
- List<ServiceStartupEntry> services = keysToServices(serviceKeys, map);
-
- // Start them
- startServices(services, map);
- }
-
- /**
- * Same as {@link #startServices(List)}, but with an array as input.
- *
- * @see #startServices(List)
- *
- * @param serviceKeys
- * Keys of services to start.
- * @throws ServiceMultiException
- * @throws ServiceNotFoundException
- * If a service can't be retrieved by its key.
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- public void startServices(String... serviceKeys) throws ServiceMultiException, ServiceNotFoundException {
-
- List<String> serviceKeysList = Arrays.asList(serviceKeys);
- startServices(serviceKeysList);
- }
-
- /**
- * Start the specified services, and their required services. The specifies
- * services should be in the addServices or already registered. Start all
- * services marked as start = STARTUP . All eligible services are first
- * created, then initialized and finally started. If an error occur on a
- * service during one of this step, the service is removed from the registry
- * and and the error is logged.
- *
- * @param serviceKeys
- * Keys of services to start. Keys will be translated to the
- * classname.
- * @throws ServiceMultiException
- * @throws ServiceNotFoundException
- * If a service can't be retrieved by its key.
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- public void startServicesByClassKeys(List<Class<?>> serviceKeys) throws ServiceMultiException, ServiceNotFoundException {
-
- // Build the lookup maps
- LookupMap map = new LookupMap(addedServices, namedServices);
-
- // Get the services
- List<ServiceStartupEntry> services = classKeysToServices(serviceKeys, map);
-
- // Start them
- startServices(services, map);
- }
-
- /**
- * Same as {@link #startServicesByClassKeys(List)}, but with an array as
- * input.
- *
- * @see #startServices(List)
- *
- * @param serviceKeys
- * Keys of services to start.
- * @throws ServiceMultiException
- * @throws ServiceNotFoundException
- * If a service can't be retrieved by its key.
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- public void startServicesByClassKeys(Class<?>... serviceKeys) throws ServiceMultiException, ServiceNotFoundException {
-
- List<Class<?>> serviceKeysList = Arrays.asList(serviceKeys);
- startServicesByClassKeys(serviceKeysList);
- }
-
- /**
- * Start the specified services, and their required services. The specifies
- * services should be in the specified map. The map is also used to resolves
- * dependencies. Start all services marked as start = STARTUP . All eligible
- * services are first created, then initialized and finally started. If an
- * error occur on a service during one of this step, the service is removed
- * from the registry and and the error is logged.
- *
- * @param services
- * Services to start
- * @param map
- * a table of (key, service) used to get a service by its key.
- * @throws ServiceMultiException
- * If a service can't be started.
- */
- private void startServices(List<ServiceStartupEntry> services, LookupMap map) throws ServiceMultiException {
- // Create an object to collect errors if any.
- ServiceMultiException errors = new ServiceMultiException();
-
- // Check if all dependencies exist.
- try {
- checkDependencies(services, map);
- } catch (ServiceMultiException ex) {
- for (Throwable t : ex.getExceptions()) {
- errors.addException(t);
- }
- }
-
- // Get all roots : LAZY and START
- Collection<ServiceStartupEntry> roots = getServiceRoots(services, map);
- if (Activator.log.isDebugEnabled()) {
- showServices(" Roots:", roots);
- }
- // Detect cycles
- checkCycle(roots, map);
- // Retain only services with state == REGISTERED
- roots = retainUnstartedServices(roots);
- //
- List<ServiceStartupEntry> toStart = buildTopologicalListOfServicesToStart(roots, map);
-
- // Remove already started services
- toStart = retainUnstartedServices(toStart);
-
- // if( log.isLoggable(Level.FINE))
- // {
- showServices(" Services to start:", toStart);
- // }
-
- createServices(toStart, errors);
- // Register all started services
- registerServices(toStart);
- initServices(toStart, errors);
- startServices(toStart, errors);
-
- // Report errors if any
- if (errors.getExceptions().size() > 0) {
- throw errors;
- }
- }
-
- /**
- * Return a list of services from a list of services keys.
- *
- * @param serviceKeys
- * @param map
- * @return
- * @throws ServiceNotFoundException
- * If a service can't be retrieved by its key.
- */
- private List<ServiceStartupEntry> keysToServices(List<String> serviceKeys, LookupMap map) throws ServiceNotFoundException {
-
- List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>(serviceKeys.size());
-
- for (String key : serviceKeys) {
- result.add(map.getChecked(key));
- }
- return result;
- }
-
- /**
- * Return a list of services from a list of services keys.
- *
- * @param serviceKeys
- * @param map
- * @return
- * @throws ServiceNotFoundException
- * If a service can't be retrieved by its key.
- */
- private List<ServiceStartupEntry> classKeysToServices(List<Class<?>> serviceKeys, LookupMap map) throws ServiceNotFoundException {
-
- List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>(serviceKeys.size());
-
- for (Class<?> key : serviceKeys) {
- result.add(map.getChecked(key.getName()));
- }
- return result;
- }
-
- /**
- * Print the services. For debug purpose
- *
- * @param roots
- */
- private void showServices(String message, Collection<ServiceStartupEntry> roots) {
- StringBuffer buffer = new StringBuffer();
- buffer.append("--------------------------\n");
- buffer.append(message);
- buffer.append("\n");
- for (ServiceStartupEntry service : roots) {
- buffer.append(" ");
- buffer.append(service.getDescriptor().toString());
- buffer.append("\n");
- }
- buffer.append("--------- done -----------\n");
- Activator.log.debug(buffer.toString());
- }
-
- /**
- * Check if all dependencies exist. Throw an error if a declared dependency
- * has no corresponding service.
- *
- * @param services
- * Services to check
- * @param map
- * Map of services by keys.
- * @throws ServiceMultiException
- */
- private void checkDependencies(Collection<ServiceStartupEntry> services, LookupMap map) throws ServiceMultiException {
-
- ServiceMultiException errors = new ServiceMultiException();
-
- // Walk each service and check if its required services exist.
- for (ServiceStartupEntry service : services) {
- ServiceDescriptor desc = service.getDescriptor();
-
- // Check each required service
- for (String key : desc.getRequiredServiceKeys()) {
-
- // Check if service can be found
- try {
- map.getChecked(key);
- } catch (ServiceNotFoundException e) {
- errors.addException(desc.getKey(), e);
- }
- }
- }
-
- // Throw errors if any
- if (errors.getExceptions().size() > 0) {
- throw errors;
- }
- }
-
- /**
- * Retains only the services that should be started. Retains only services
- * with startupkind = START and state == REGISTERED
- *
- * @param services
- * Collection to filter
- * @return a new Collection containing the services to start.
- */
- private List<ServiceStartupEntry> retainsToStartServices(Collection<ServiceStartupEntry> services) {
-
- List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>();
- for (ServiceStartupEntry service : services) {
- ServiceDescriptor desc = service.getDescriptor();
- if (service.getState() == ServiceState.registered && desc.isStartAtStartup()) {
- result.add(service);
- }
- }
-
- return result;
- }
-
- /**
- * Retains the services that are not yet started. Retains only services with state == REGISTERED
- *
- * @param services
- * Collection to filter
- * @return a new Collection containing the registered services
- */
- private List<ServiceStartupEntry> retainUnstartedServices(Collection<ServiceStartupEntry> services) {
- List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>(services.size());
- for (ServiceStartupEntry service : services) {
- if (service.getState() == ServiceState.registered) {
- result.add(service);
- }
- }
-
- return result;
- }
-
- /**
- * Check for cycles. Throws an exception if a cycle is discovered. Each root
- * is checked to see if it contains a cycle.
- *
- * @param roots
- * @param map
- */
- private void checkCycle(Collection<ServiceStartupEntry> roots, LookupMap map) {
-
-
- }
-
- /**
- * Build a list of services to start, in the topological order (right
- * order). The required services are placed before the dependent services in
- * the list. Services already started are disguarded.
- *
- * @param roots
- * @param map
- * Map used to resolve the entry by their key.
- * @return
- */
- private List<ServiceStartupEntry> buildTopologicalListOfServicesToStart(Collection<ServiceStartupEntry> roots, LookupMap map) {
-
- List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>();
-
- // Each root represent a graph. Walk the root and its child in the list,
- // in the right order.
- for (ServiceStartupEntry root : roots) {
- walkGraphDepthFirst(result, root, map);
- }
-
- return result;
- }
-
- /**
- * Add recursively the provided node, and then its direct children.
- *
- * @param result
- * The list where the node are added
- * @param node
- * The node to add
- * @param map
- */
- private void walkGraphDepthFirst(List<ServiceStartupEntry> result, ServiceStartupEntry node, LookupMap map) {
-
- // Do not add already added or started node.
- if (result.contains(node) || node.isStarted()) {
- return;
- }
-
- // add direct child
- for (String serviceKey : node.getDescriptor().getRequiredServiceKeys()) {
- try {
- ServiceStartupEntry child = map.getChecked(serviceKey);
- walkGraphDepthFirst(result, child, map);
- } catch (ServiceNotFoundException e) {
- // Do nothing, we have already reported the problems with
- // checkServices;
- }
- }
-
- // Now add the node
- result.add(node);
- }
-
- /**
- * Create a List of the root services. The roots are services that are not
- * required by any service.
- *
- * @param addedServices
- * A collection from which roots are required. The collection is
- * unmodified.
- * @param map
- * @return
- */
- private Collection<ServiceStartupEntry> getServiceRoots(Collection<ServiceStartupEntry> addedServices, LookupMap keyServiceMap) {
-
- // Create a copy of the list of services
- Collection<ServiceStartupEntry> services = new ArrayList<ServiceStartupEntry>(addedServices);
-
- List<ServiceStartupEntry> allRequired = new ArrayList<ServiceStartupEntry>();
-
- // The roots are services that are not required by any service.
- // Build a list of the services required by all other services.
- for (ServiceStartupEntry service : services) {
- // Add each child to the list of required
- for (String serviceKey : service.getDescriptor().getRequiredServiceKeys()) {
- try {
-
- ServiceStartupEntry child = keyServiceMap.getChecked(serviceKey);
- allRequired.add(child);
- } catch (ServiceNotFoundException e) {
- // Do nothing, we have already reported the problems with
- // checkServices;
- }
- }
-
- }
-
- // Roots are those that are not required.
- // So it is the original list minus the required.
- services.removeAll(allRequired);
-
- return services;
- }
-
- /**
- * Dispose all services.
- *
- * @throws ServiceMultiException
- */
- public void disposeRegistry() throws ServiceMultiException {
-
- // List of keys of service in error.
- ServiceMultiException errors = new ServiceMultiException();
- disposeServices(namedServices.values(), errors);
- disposeServices(anonymousServices, errors);
-
- // Clean up properties to help GC
- addedServices.clear();
- anonymousServices.clear();
- namedServices.clear();
-
- // Report errors if any
- if (errors.getExceptions().size() > 0) {
- throw errors;
- }
- }
-
- /**
- * Create all services provided in the list
- *
- * @param toStart
- * List of services to create.
- * @param errors
- * Exception to collect errors.
- *
- * @throws ServiceMultiException
- * If an error occure during the creation
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- private void createServices(List<ServiceStartupEntry> toStart, ServiceMultiException errors) {
-
- // Loop on all services
- for (ServiceStartupEntry serviceEntry : toStart) {
- try {
-
- serviceEntry.createService();
- } catch (ServiceException e) {
- // Do not log the exception, as it is thrown. It may already be caught and logged by the caller.
- // log.log(Level.SEVERE, "Can't create service '" + serviceEntry + "'", e);
- errors.addException(serviceEntry.getDescriptor().getKey(), e);
- }
- }
-
- }
-
- /**
- * Register all services provided in the list. After this operation,
- * services are available thru {@link #getService(Class)}.
- *
- * @param toStart
- * List of services to register.
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- private void registerServices(Collection<ServiceStartupEntry> toStart) {
-
- // Loop on all services
- for (ServiceStartupEntry serviceEntry : toStart) {
- ServiceDescriptor desc = serviceEntry.getDescriptor();
- if (desc.isAnonymous()) {
- anonymousServices.add(serviceEntry);
- } else {
- namedServices.put(desc.getKey(), serviceEntry);
- }
- }
- }
-
- /**
- * Init all services provided in the list
- *
- * @param toStart
- * List of services to init.
- * @param errors
- *
- * @throws ServiceMultiException
- * If an error occure during the process
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- private void initServices(List<ServiceStartupEntry> toStart, ServiceMultiException errors) {
-
- // Loop on all services
- for (ServiceStartupEntry serviceEntry : toStart) {
- try {
-
- serviceEntry.initService(this);
- } catch (ServiceException e) {
- // Do not log the exception, as it is thrown. It may already be caught and logged by the caller.
- // log.log(Level.SEVERE, "Can't initialize service '" + serviceEntry + "'", e);
- errors.addException(serviceEntry.getDescriptor().getKey(), e);
- }
- }
-
- }
-
- /**
- * Init all services provided in the list
- *
- * @param toStart
- * List of services to init.
- * @param errors
- *
- * @throws ServiceMultiException
- * If an error occure during the process
- *
- * @throws ServiceException
- * If a service can't be started.
- */
- private void startServices(List<ServiceStartupEntry> toStart, ServiceMultiException errors) {
-
- // Loop on all services
- for (ServiceStartupEntry serviceEntry : toStart) {
- try {
-
- serviceEntry.startService();
- } catch (ServiceException e) {
- // Do not log the exception, as it is thrown. It may already be caught and logged by the caller.
- // log.log(Level.SEVERE, "Can't start service '" + serviceEntry + "'", e);
- errors.addException(serviceEntry.getDescriptor().getKey(), e);
- }
- }
-
- }
-
- /**
- * Dispose all started services.
- * Services are disposed in creation reverse order
- *
- * @throws ServiceMultiException
- *
- * @throws ServiceException
- * If a service can't be disposed.
- */
- private void disposeServices(Collection<ServiceStartupEntry> services, ServiceMultiException errors) {
-
- // Dispose services
- for (ServiceStartupEntry serviceEntry : services) {
- try {
- serviceEntry.disposeService();
- } catch (Exception ex) {
- // Do not log the exception, as it is thrown. It may already be caught and logged by the caller.
- // log.log(Level.SEVERE, "Can't dispose service'" + serviceEntry.getDescriptor().getKey() + "'", ex);
- errors.addException(serviceEntry.getDescriptor(), ex);
- }
- }
- }
-
- /**
- * This class represents a union of two maps of <String,
- * ServiceStartupEntry>. It provide specific methods to retrieve a {@link ServiceStartupEntry} by its key.
- *
- * @author cedric dumoulin
- *
- */
- private class LookupMap {
-
- Map<String, ServiceStartupEntry> map1;
-
- Map<String, ServiceStartupEntry> map2;
-
- /**
- *
- * Constructor. Build a union of two maps.
- *
- * @param map1
- * @param map2
- */
- public LookupMap(Map<String, ServiceStartupEntry> map1, Map<String, ServiceStartupEntry> map2) {
- this.map1 = map1;
- this.map2 = map2;
- }
-
- /**
- *
- * Constructor. Build a union of one map (sic).
- *
- * @param map
- */
- @SuppressWarnings("unused")
- public LookupMap(Map<String, ServiceStartupEntry> map) {
- this(map, null);
- }
-
- /**
- * Get a service by its key.
- *
- * @param key
- * @return the service or null if not found.
- */
- @SuppressWarnings("unused")
- public ServiceStartupEntry get(String key) {
-
- ServiceStartupEntry res = map1.get(key);
- if (res != null) {
- return res;
- }
- if (map2 != null) {
- res = map2.get(key);
- }
-
- return res;
- }
-
- /**
- * Get a service by its key.
- *
- * @param key
- * @return The requested service.
- * @throws ServiceNotFoundException
- * if the service can't be found.
- */
- public ServiceStartupEntry getChecked(String key) throws ServiceNotFoundException {
-
- ServiceStartupEntry res = map1.get(key);
- if (res != null) {
- return res;
- }
- if (map2 != null) {
- res = map2.get(key);
- }
- if (res != null) {
- return res;
- }
-
- throw new ServiceNotFoundException("No service found under key '" + key.toString() + "'");
- }
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2011, 2015 LIFL, CEA, Christian W. Damus, 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: + * LIFL - Initial API and implementation + * Christian W. Damus (CEA) - bug 431953 (fix start-up of selective services to require only their dependencies) + * Christian W. Damus - bug 468030 + */ +package org.eclipse.papyrus.infra.core.services; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +import org.eclipse.papyrus.infra.core.Activator; +import org.eclipse.papyrus.infra.core.services.ServiceDescriptor.ServiceTypeKind; +import org.eclipse.papyrus.infra.core.services.internal.LazyStartupEntry; +import org.eclipse.papyrus.infra.core.services.internal.PojoServiceEntry; +import org.eclipse.papyrus.infra.core.services.internal.ServiceAdapterEntry; +import org.eclipse.papyrus.infra.core.services.internal.ServiceEntry; +import org.eclipse.papyrus.infra.core.services.internal.ServiceFactoryEntry; +import org.eclipse.papyrus.infra.core.services.internal.ServiceStartupEntry; +import org.eclipse.papyrus.infra.core.services.internal.ServiceTypeEntry; +import org.eclipse.papyrus.infra.core.services.internal.StartStartupEntry; +import org.eclipse.papyrus.infra.core.utils.AdapterUtils; + +/** + * A registry of services. This registry allows to get a service by its + * identifier. The identifier is generally the classname of the service. + * Services can be added using the Eclipse extension mechanism (if you use {@link ExtensionServicesRegistry}). <br> + * A Service is a class providing operations. The ServiceRegistry is used to + * share objects (i.e. services) between nested editors and also the core main + * editor. + * + * <br> + * In this implementation, services should be added to the registry before the + * call to createServices(). If a service is added after the call, it will not + * be started (except if it is a lazy service). <br> + * A typical usage is: + * + * <pre> + * <code> + * ServicesRegistry serviceRegistry = new ServiceRegistry(); + * // Add your services + * serviceRegistry.add( ...); + * serviceRegistry.add( ...); + * + * // start the services + * serviceRegistry.startRegistry(); + * + * // Retrieve a service + * myService = serviceRegistry.getService( serviceKey ); + * </code> + * </pre> + * + * It is possible to register new services after the serviceRegistry has been + * started. In this case, you need to start them explicitly if they are of type + * ServiceStartKind.STARTUP. + * + * <pre> + * <code> + * // Add your new services + * serviceRegistry.add( key1, ...); + * serviceRegistry.add( key2, ...); + * + * // start the new services + * serviceRegistry.startRegistry(key1, key2); + * </code> + * </pre> + * + * <ul> + * <li></li> + * <li></li> + * </ul> + * + * @author cedric dumoulin + * + * + */ +public class ServicesRegistry { + + /** + * Log object + * + * @deprecated Use {@link Activator#log} instead + */ + // @unused + @Deprecated + protected Logger log = Logger.getLogger(getClass().getName()); + + /** + * Map of existing services. + */ + // private Map<Object, AbstractServiceEntry> services; + + /** + * A Map of services added to the register (thow the addXxx() methods), but + * not yet registered. They will be registered after a call to startXxx(). + */ + private Map<String, ServiceStartupEntry> addedServices = new HashMap<String, ServiceStartupEntry>(); + + /** + * Map of services registered with a name. + */ + private Map<String, ServiceStartupEntry> namedServices = new HashMap<String, ServiceStartupEntry>(); + + /** + * Map of services registered without a name (anonymous). Such services + * can't be retrieved. + */ + private List<ServiceStartupEntry> anonymousServices = new ArrayList<ServiceStartupEntry>(); + + /** + * Constructor. + */ + public ServicesRegistry() { + } + + /** + * Add a service by its ServiceDescriptor. + * + * @param serviceDescriptor + * Descriptor describing the service. + * @throws ServiceException + * If an error occurs while initializing service. + */ + public void add(ServiceDescriptor serviceDescriptor) { + // Check if the service already exist. + ServiceStartupEntry service = addedServices.get(serviceDescriptor.getKey()); + if (service != null) { + if (service.getDescriptor().getPriority() > serviceDescriptor.getPriority()) { + return; + } else if (service.getDescriptor().getPriority() == serviceDescriptor.getPriority()) { + Activator.log.warn("Two services with same priority (" + serviceDescriptor.getPriority() + ") are declared under key '" + service.getDescriptor().getKey() + "'. Keep the first encountered only. (bundles: " + + service.getDescriptor().getClassBundleID() + ", " + serviceDescriptor.getClassBundleID() + ")"); + } + } + + // Compute the service type entry + ServiceTypeEntry serviceTypeEntry; + ServiceTypeKind typeKind = serviceDescriptor.getServiceTypeKind(); + if (typeKind == ServiceTypeKind.service) { + serviceTypeEntry = new ServiceEntry(serviceDescriptor); + } else if (typeKind == ServiceTypeKind.serviceFactory) { + serviceTypeEntry = new ServiceFactoryEntry(serviceDescriptor); + } else { + serviceTypeEntry = new PojoServiceEntry(serviceDescriptor); + } + + // Create the entry + ServiceStartupEntry serviceEntry; + if (serviceDescriptor.isStartAtStartup()) { + serviceEntry = new StartStartupEntry(serviceTypeEntry); + } else { + serviceEntry = new LazyStartupEntry(serviceTypeEntry, this); + } + // Add the entry + addedServices.put(serviceDescriptor.getKey(), serviceEntry); + } + + /** + * Add a service. The descriptor will be created. + * + * @param key + * Service key + * @param priority + * service priority + * @param serviceInstance + * The instance of the service + */ + public void add(String key, int priority, IService serviceInstance) { + add(key, priority, serviceInstance, ServiceStartKind.STARTUP); + } + + /** + * Add a service. The descriptor will be created. + * + * @param key + * Service key + * @param priority + * service priority + * @param serviceInstance + * The instance of the service + */ + public void add(Class<?> key, int priority, IService serviceInstance) { + add(key.getName(), priority, serviceInstance, ServiceStartKind.STARTUP); + } + + /** + * Add a service. The descriptor will be created. + * + * @param key + * Service key + * @param priority + * service priority + * @param serviceInstance + * The instance of the service + */ + public void add(String key, int priority, IService serviceInstance, ServiceStartKind startKind) { + // Check if the service already exist. + ServiceStartupEntry service = addedServices.get(key); + if (service != null) { + if (service.getDescriptor().getPriority() > priority) { + return; + } else if (service.getDescriptor().getPriority() == priority) { + Activator.log.warn("Two services with same priority (" + priority + ") are declared under key '" + service.getDescriptor().getKey() + "'. Keep the first encountered only."); + } + } + + // Create descriptor and add service. + ServiceDescriptor descriptor = new ServiceDescriptor(key, serviceInstance.getClass().getName(), startKind, priority); + + if (startKind == ServiceStartKind.STARTUP) { + addedServices.put(key, new StartStartupEntry(new ServiceEntry(descriptor, serviceInstance))); + } else { + addedServices.put(key, new LazyStartupEntry(new ServiceEntry(descriptor, serviceInstance), this)); + } + } + + /** + * Add a service. The descriptor will be created. + * + * @param key + * Service key Class used as key. The classname is used as key. + * @param priority + * service priority + * @param serviceInstance + * The instance of the service + */ + public void add(Class<?> key, int priority, IService serviceInstance, ServiceStartKind startKind) { + + add(key.getName(), priority, serviceInstance, startKind); + } + + /** + * Add an already instanciated pojo (Plain Old Java Object) as Service. The + * descriptor will be created. No life cycle methods are called on the + * service. + * + * @param key + * Service key + * @param priority + * service priority + * @param serviceInstance + * The instance of the service + */ + public void add(Class<?> key, int priority, Object serviceInstance) { + add(key, priority, serviceInstance, ServiceStartKind.STARTUP); + } + + /** + * Add an already instanciated pojo (Plain Old Java Object) as Service. The + * descriptor will be created. No life cycle methods are called on the + * service. + * + * @param key + * Service key + * @param priority + * service priority + * @param serviceInstance + * The instance of the service + * @param startKind + * + */ + public void add(String key, int priority, Object serviceInstance, ServiceStartKind startKind) { + // If the service instance is actually an IService, register it thus to enable the lifecycle hooks + if (serviceInstance instanceof IService) { + add(key, priority, (IService) serviceInstance, startKind); + } + + // Check if the service already exist. + ServiceStartupEntry service = addedServices.get(key); + if (service != null) { + if (service.getDescriptor().getPriority() > priority) { + return; + } else if (service.getDescriptor().getPriority() == priority) { + Activator.log.warn("Two services with same priority (" + priority + ") are declared under key '" + service.getDescriptor().getKey() + "'. Keep the first encountered only."); + } + } + + // Create descriptor and add service. + ServiceDescriptor descriptor = new ServiceDescriptor(key, serviceInstance.getClass().getName(), startKind, priority); + ServiceTypeEntry type; + ServiceStartupEntry entry; + + // If the instance is a service or has an adapter for the service protocol, register that + IService serviceAdapter = AdapterUtils.adapt(serviceInstance, IService.class, null); + if (serviceAdapter != null) { + type = new ServiceAdapterEntry(descriptor, serviceInstance, serviceAdapter); + } else { + type = new PojoServiceEntry(descriptor, serviceInstance); + } + + switch (startKind) { + case STARTUP: + entry = new StartStartupEntry(type); + break; + case LAZY: + entry = new LazyStartupEntry(type, this); + break; + default: + throw new IllegalArgumentException("Unrecognized startKind: " + startKind); + } + + addedServices.put(key, entry); + } + + /** + * Add an already instanciated pojo (Plain Old Java Object) as Service. The + * descriptor will be created. No life cycle methods are called on the + * service. + * + * @param key + * Service key Class used as key. The classname is used as key. + * @param priority + * service priority + * @param serviceInstance + * The instance of the service + * @param startKind + * + */ + public void add(Class<?> key, int priority, Object serviceInstance, ServiceStartKind startKind) { + + add(key.getName(), priority, serviceInstance, startKind); + } + + /** + * Remove the specified service from the registry. + * + * @param key + */ + public void remove(ServiceDescriptor serviceDescriptor) throws ServiceException { + remove(serviceDescriptor.getKey()); + } + + /** + * Remove the specified service from the registry. + * + * @param key + */ + public void remove(Object key) throws ServiceException { + ServiceStartupEntry service = namedServices.remove(key); + if (service == null) { + return; + } + + // Stop the service + service.disposeService(); + } + + /** + * Get the requested service by its key. The key is usually the classname of + * the service. + * + * @param serviceClass + * @return + * @throws ServiceException + * If servive can't be started + */ + public Object getService(Object key) throws ServiceException { + ServiceStartupEntry service = namedServices.get(key); + if (service == null) { + // throw an exception. + // If added, say it. + service = addedServices.get(key); + if (service != null) { + throw new BadStateException("Registry should be started before.", service.getState(), service.getDescriptor()); + } else { + throw new ServiceNotFoundException("No service registered under '" + key + "'"); + } + } + + return service.getServiceInstance(); + } + + /** + * Get the requested service by its class (the service has to be registered + * by its class object). + * + * @param key + * The service class. + * @return The service. + * @throws ServiceException + * If service can't be started + */ + @SuppressWarnings("unchecked") + public <S> S getService(Class<S> key) throws ServiceException { + + String realKey = key.getName(); + ServiceStartupEntry service = namedServices.get(realKey); + + if (service == null) { + // throw an exception. + // If added, say it. + service = addedServices.get(realKey); + if (service != null) { + throw new BadStateException("Registry should be started before.", service.getState(), service.getDescriptor()); + } else { + throw new ServiceNotFoundException("No service registered under '" + key + "'"); + } + } + + return (S) service.getServiceInstance(); + } + + /** + * Return true if the service is instantiated. Return false otherwise. + * + * @return + */ + public boolean isStarted(Object key) throws ServiceNotFoundException { + ServiceStartupEntry service = namedServices.get(key); + if (service == null) { + throw new ServiceNotFoundException("No service registered under '" + key + "'"); + } + + return service.isStarted(); + } + + /** + * Return the state of the specified service. + * + * @return + */ + public ServiceState serviceState(Object key) throws ServiceNotFoundException { + ServiceStartupEntry service = namedServices.get(key); + if (service == null) { + throw new ServiceNotFoundException("No service registered under '" + key + "'"); + } + + return service.getState(); + } + + /** + * Start the registry. Start all services marked as start = STARTUP are + * started. All services are first created, then initialized and finally + * started. If an error occur on a service during one of this step, the + * service is removed from the registry and and the error is logged. + * + * @throws ServiceMultiException + * + * @throws ServiceException + * If a service can't be started. + */ + public void startRegistry() throws ServiceMultiException { + // Create an object to collect errors if any. + ServiceMultiException errors = new ServiceMultiException(); + + // Build the lookup maps + LookupMap map = new LookupMap(addedServices, namedServices); + + // Check if all dependencies exist. + try { + checkDependencies(addedServices.values(), map); + } catch (ServiceMultiException ex) { + for (Throwable t : ex.getExceptions()) { + errors.addException(t); + } + } + + // Get all roots : LAZY and START + Collection<ServiceStartupEntry> roots = getServiceRoots(addedServices.values(), map); + // showServices(" Roots:", roots); + // Detect cycles + checkCycle(roots, map); + // Retain only services with startupkind = START + roots = retainsToStartServices(roots); + // + List<ServiceStartupEntry> toStart = buildTopologicalListOfServicesToStart(roots, map); + + if (Activator.log.isDebugEnabled()) { + showServices(" Services to start:", toStart); + } + + createServices(toStart, errors); + // Register all new services : lazy and start + registerServices(addedServices.values()); + initServices(toStart, errors); + startServices(toStart, errors); + + // Report errors if any + if (errors.getExceptions().size() > 0) { + throw errors; + } + + } + + /** + * Start the specified services, and their required services. The specifies + * services should be in the addServices or already registered. Start all + * services marked as start = STARTUP . All eligible services are first + * created, then initialized and finally started. If an error occur on a + * service during one of this step, the service is removed from the registry + * and and the error is logged. + * + * @param serviceKeys + * Keys of services to start. + * @throws ServiceMultiException + * @throws ServiceNotFoundException + * If a service can't be retrieved by its key. + * + * @throws ServiceException + * If a service can't be started. + */ + public void startServices(List<String> serviceKeys) throws ServiceMultiException, ServiceNotFoundException { + + // Build the lookup maps + LookupMap map = new LookupMap(addedServices, namedServices); + + // Get the services + List<ServiceStartupEntry> services = keysToServices(serviceKeys, map); + + // Start them + startServices(services, map); + } + + /** + * Same as {@link #startServices(List)}, but with an array as input. + * + * @see #startServices(List) + * + * @param serviceKeys + * Keys of services to start. + * @throws ServiceMultiException + * @throws ServiceNotFoundException + * If a service can't be retrieved by its key. + * + * @throws ServiceException + * If a service can't be started. + */ + public void startServices(String... serviceKeys) throws ServiceMultiException, ServiceNotFoundException { + + List<String> serviceKeysList = Arrays.asList(serviceKeys); + startServices(serviceKeysList); + } + + /** + * Start the specified services, and their required services. The specifies + * services should be in the addServices or already registered. Start all + * services marked as start = STARTUP . All eligible services are first + * created, then initialized and finally started. If an error occur on a + * service during one of this step, the service is removed from the registry + * and and the error is logged. + * + * @param serviceKeys + * Keys of services to start. Keys will be translated to the + * classname. + * @throws ServiceMultiException + * @throws ServiceNotFoundException + * If a service can't be retrieved by its key. + * + * @throws ServiceException + * If a service can't be started. + */ + public void startServicesByClassKeys(List<Class<?>> serviceKeys) throws ServiceMultiException, ServiceNotFoundException { + + // Build the lookup maps + LookupMap map = new LookupMap(addedServices, namedServices); + + // Get the services + List<ServiceStartupEntry> services = classKeysToServices(serviceKeys, map); + + // Start them + startServices(services, map); + } + + /** + * Same as {@link #startServicesByClassKeys(List)}, but with an array as + * input. + * + * @see #startServices(List) + * + * @param serviceKeys + * Keys of services to start. + * @throws ServiceMultiException + * @throws ServiceNotFoundException + * If a service can't be retrieved by its key. + * + * @throws ServiceException + * If a service can't be started. + */ + public void startServicesByClassKeys(Class<?>... serviceKeys) throws ServiceMultiException, ServiceNotFoundException { + + List<Class<?>> serviceKeysList = Arrays.asList(serviceKeys); + startServicesByClassKeys(serviceKeysList); + } + + /** + * Start the specified services, and their required services. The specifies + * services should be in the specified map. The map is also used to resolves + * dependencies. Start all services marked as start = STARTUP . All eligible + * services are first created, then initialized and finally started. If an + * error occur on a service during one of this step, the service is removed + * from the registry and and the error is logged. + * + * @param services + * Services to start + * @param map + * a table of (key, service) used to get a service by its key. + * @throws ServiceMultiException + * If a service can't be started. + */ + private void startServices(List<ServiceStartupEntry> services, LookupMap map) throws ServiceMultiException { + // Create an object to collect errors if any. + ServiceMultiException errors = new ServiceMultiException(); + + // Check if all dependencies exist. + try { + checkDependencies(services, map); + } catch (ServiceMultiException ex) { + for (Throwable t : ex.getExceptions()) { + errors.addException(t); + } + } + + // Get all roots : LAZY and START + Collection<ServiceStartupEntry> roots = getServiceRoots(services, map); + if (Activator.log.isDebugEnabled()) { + showServices(" Roots:", roots); + } + // Detect cycles + checkCycle(roots, map); + // Retain only services with state == REGISTERED + roots = retainUnstartedServices(roots); + // + List<ServiceStartupEntry> toStart = buildTopologicalListOfServicesToStart(roots, map); + + // Remove already started services + toStart = retainUnstartedServices(toStart); + + // if( log.isLoggable(Level.FINE)) + // { + showServices(" Services to start:", toStart); + // } + + createServices(toStart, errors); + // Register all started services + registerServices(toStart); + initServices(toStart, errors); + startServices(toStart, errors); + + // Report errors if any + if (errors.getExceptions().size() > 0) { + throw errors; + } + } + + /** + * Return a list of services from a list of services keys. + * + * @param serviceKeys + * @param map + * @return + * @throws ServiceNotFoundException + * If a service can't be retrieved by its key. + */ + private List<ServiceStartupEntry> keysToServices(List<String> serviceKeys, LookupMap map) throws ServiceNotFoundException { + + List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>(serviceKeys.size()); + + for (String key : serviceKeys) { + result.add(map.getChecked(key)); + } + return result; + } + + /** + * Return a list of services from a list of services keys. + * + * @param serviceKeys + * @param map + * @return + * @throws ServiceNotFoundException + * If a service can't be retrieved by its key. + */ + private List<ServiceStartupEntry> classKeysToServices(List<Class<?>> serviceKeys, LookupMap map) throws ServiceNotFoundException { + + List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>(serviceKeys.size()); + + for (Class<?> key : serviceKeys) { + result.add(map.getChecked(key.getName())); + } + return result; + } + + /** + * Print the services. For debug purpose + * + * @param roots + */ + private void showServices(String message, Collection<ServiceStartupEntry> roots) { + StringBuffer buffer = new StringBuffer(); + buffer.append("--------------------------\n"); + buffer.append(message); + buffer.append("\n"); + for (ServiceStartupEntry service : roots) { + buffer.append(" "); + buffer.append(service.getDescriptor().toString()); + buffer.append("\n"); + } + buffer.append("--------- done -----------\n"); + Activator.log.debug(buffer.toString()); + } + + /** + * Check if all dependencies exist. Throw an error if a declared dependency + * has no corresponding service. + * + * @param services + * Services to check + * @param map + * Map of services by keys. + * @throws ServiceMultiException + */ + private void checkDependencies(Collection<ServiceStartupEntry> services, LookupMap map) throws ServiceMultiException { + + ServiceMultiException errors = new ServiceMultiException(); + + // Walk each service and check if its required services exist. + for (ServiceStartupEntry service : services) { + ServiceDescriptor desc = service.getDescriptor(); + + // Check each required service + for (String key : desc.getRequiredServiceKeys()) { + + // Check if service can be found + try { + map.getChecked(key); + } catch (ServiceNotFoundException e) { + errors.addException(desc.getKey(), e); + } + } + } + + // Throw errors if any + if (errors.getExceptions().size() > 0) { + throw errors; + } + } + + /** + * Retains only the services that should be started. Retains only services + * with startupkind = START and state == REGISTERED + * + * @param services + * Collection to filter + * @return a new Collection containing the services to start. + */ + private List<ServiceStartupEntry> retainsToStartServices(Collection<ServiceStartupEntry> services) { + + List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>(); + for (ServiceStartupEntry service : services) { + ServiceDescriptor desc = service.getDescriptor(); + if (service.getState() == ServiceState.registered && desc.isStartAtStartup()) { + result.add(service); + } + } + + return result; + } + + /** + * Retains the services that are not yet started. Retains only services with state == REGISTERED + * + * @param services + * Collection to filter + * @return a new Collection containing the registered services + */ + private List<ServiceStartupEntry> retainUnstartedServices(Collection<ServiceStartupEntry> services) { + List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>(services.size()); + for (ServiceStartupEntry service : services) { + if (service.getState() == ServiceState.registered) { + result.add(service); + } + } + + return result; + } + + /** + * Check for cycles. Throws an exception if a cycle is discovered. Each root + * is checked to see if it contains a cycle. + * + * @param roots + * @param map + */ + private void checkCycle(Collection<ServiceStartupEntry> roots, LookupMap map) { + + + } + + /** + * Build a list of services to start, in the topological order (right + * order). The required services are placed before the dependent services in + * the list. Services already started are disguarded. + * + * @param roots + * @param map + * Map used to resolve the entry by their key. + * @return + */ + private List<ServiceStartupEntry> buildTopologicalListOfServicesToStart(Collection<ServiceStartupEntry> roots, LookupMap map) { + + List<ServiceStartupEntry> result = new ArrayList<ServiceStartupEntry>(); + + // Each root represent a graph. Walk the root and its child in the list, + // in the right order. + for (ServiceStartupEntry root : roots) { + walkGraphDepthFirst(result, root, map); + } + + return result; + } + + /** + * Add recursively the provided node, and then its direct children. + * + * @param result + * The list where the node are added + * @param node + * The node to add + * @param map + */ + private void walkGraphDepthFirst(List<ServiceStartupEntry> result, ServiceStartupEntry node, LookupMap map) { + + // Do not add already added or started node. + if (result.contains(node) || node.isStarted()) { + return; + } + + // add direct child + for (String serviceKey : node.getDescriptor().getRequiredServiceKeys()) { + try { + ServiceStartupEntry child = map.getChecked(serviceKey); + walkGraphDepthFirst(result, child, map); + } catch (ServiceNotFoundException e) { + // Do nothing, we have already reported the problems with + // checkServices; + } + } + + // Now add the node + result.add(node); + } + + /** + * Create a List of the root services. The roots are services that are not + * required by any service. + * + * @param addedServices + * A collection from which roots are required. The collection is + * unmodified. + * @param map + * @return + */ + private Collection<ServiceStartupEntry> getServiceRoots(Collection<ServiceStartupEntry> addedServices, LookupMap keyServiceMap) { + + // Create a copy of the list of services + Collection<ServiceStartupEntry> services = new ArrayList<ServiceStartupEntry>(addedServices); + + List<ServiceStartupEntry> allRequired = new ArrayList<ServiceStartupEntry>(); + + // The roots are services that are not required by any service. + // Build a list of the services required by all other services. + for (ServiceStartupEntry service : services) { + // Add each child to the list of required + for (String serviceKey : service.getDescriptor().getRequiredServiceKeys()) { + try { + + ServiceStartupEntry child = keyServiceMap.getChecked(serviceKey); + allRequired.add(child); + } catch (ServiceNotFoundException e) { + // Do nothing, we have already reported the problems with + // checkServices; + } + } + + } + + // Roots are those that are not required. + // So it is the original list minus the required. + services.removeAll(allRequired); + + return services; + } + + /** + * Dispose all services. + * + * @throws ServiceMultiException + */ + public void disposeRegistry() throws ServiceMultiException { + + // List of keys of service in error. + ServiceMultiException errors = new ServiceMultiException(); + disposeServices(namedServices.values(), errors); + disposeServices(anonymousServices, errors); + + // Clean up properties to help GC + addedServices.clear(); + anonymousServices.clear(); + namedServices.clear(); + + // Report errors if any + if (errors.getExceptions().size() > 0) { + throw errors; + } + } + + /** + * Create all services provided in the list + * + * @param toStart + * List of services to create. + * @param errors + * Exception to collect errors. + * + * @throws ServiceMultiException + * If an error occure during the creation + * + * @throws ServiceException + * If a service can't be started. + */ + private void createServices(List<ServiceStartupEntry> toStart, ServiceMultiException errors) { + + // Loop on all services + for (ServiceStartupEntry serviceEntry : toStart) { + try { + + serviceEntry.createService(); + } catch (ServiceException e) { + // Do not log the exception, as it is thrown. It may already be caught and logged by the caller. + // log.log(Level.SEVERE, "Can't create service '" + serviceEntry + "'", e); + errors.addException(serviceEntry.getDescriptor().getKey(), e); + } + } + + } + + /** + * Register all services provided in the list. After this operation, + * services are available thru {@link #getService(Class)}. + * + * @param toStart + * List of services to register. + * + * @throws ServiceException + * If a service can't be started. + */ + private void registerServices(Collection<ServiceStartupEntry> toStart) { + + // Loop on all services + for (ServiceStartupEntry serviceEntry : toStart) { + ServiceDescriptor desc = serviceEntry.getDescriptor(); + if (desc.isAnonymous()) { + anonymousServices.add(serviceEntry); + } else { + namedServices.put(desc.getKey(), serviceEntry); + } + } + } + + /** + * Init all services provided in the list + * + * @param toStart + * List of services to init. + * @param errors + * + * @throws ServiceMultiException + * If an error occure during the process + * + * @throws ServiceException + * If a service can't be started. + */ + private void initServices(List<ServiceStartupEntry> toStart, ServiceMultiException errors) { + + // Loop on all services + for (ServiceStartupEntry serviceEntry : toStart) { + try { + + serviceEntry.initService(this); + } catch (ServiceException e) { + // Do not log the exception, as it is thrown. It may already be caught and logged by the caller. + // log.log(Level.SEVERE, "Can't initialize service '" + serviceEntry + "'", e); + errors.addException(serviceEntry.getDescriptor().getKey(), e); + } + } + + } + + /** + * Init all services provided in the list + * + * @param toStart + * List of services to init. + * @param errors + * + * @throws ServiceMultiException + * If an error occure during the process + * + * @throws ServiceException + * If a service can't be started. + */ + private void startServices(List<ServiceStartupEntry> toStart, ServiceMultiException errors) { + + // Loop on all services + for (ServiceStartupEntry serviceEntry : toStart) { + try { + + serviceEntry.startService(); + } catch (ServiceException e) { + // Do not log the exception, as it is thrown. It may already be caught and logged by the caller. + // log.log(Level.SEVERE, "Can't start service '" + serviceEntry + "'", e); + errors.addException(serviceEntry.getDescriptor().getKey(), e); + } + } + + } + + /** + * Dispose all started services. + * Services are disposed in creation reverse order + * + * @throws ServiceMultiException + * + * @throws ServiceException + * If a service can't be disposed. + */ + private void disposeServices(Collection<ServiceStartupEntry> services, ServiceMultiException errors) { + + // Dispose services + for (ServiceStartupEntry serviceEntry : services) { + try { + serviceEntry.disposeService(); + } catch (Exception ex) { + // Do not log the exception, as it is thrown. It may already be caught and logged by the caller. + // log.log(Level.SEVERE, "Can't dispose service'" + serviceEntry.getDescriptor().getKey() + "'", ex); + errors.addException(serviceEntry.getDescriptor(), ex); + } + } + } + + /** + * This class represents a union of two maps of <String, + * ServiceStartupEntry>. It provide specific methods to retrieve a {@link ServiceStartupEntry} by its key. + * + * @author cedric dumoulin + * + */ + private class LookupMap { + + Map<String, ServiceStartupEntry> map1; + + Map<String, ServiceStartupEntry> map2; + + /** + * + * Constructor. Build a union of two maps. + * + * @param map1 + * @param map2 + */ + public LookupMap(Map<String, ServiceStartupEntry> map1, Map<String, ServiceStartupEntry> map2) { + this.map1 = map1; + this.map2 = map2; + } + + /** + * + * Constructor. Build a union of one map (sic). + * + * @param map + */ + @SuppressWarnings("unused") + public LookupMap(Map<String, ServiceStartupEntry> map) { + this(map, null); + } + + /** + * Get a service by its key. + * + * @param key + * @return the service or null if not found. + */ + @SuppressWarnings("unused") + public ServiceStartupEntry get(String key) { + + ServiceStartupEntry res = map1.get(key); + if (res != null) { + return res; + } + if (map2 != null) { + res = map2.get(key); + } + + return res; + } + + /** + * Get a service by its key. + * + * @param key + * @return The requested service. + * @throws ServiceNotFoundException + * if the service can't be found. + */ + public ServiceStartupEntry getChecked(String key) throws ServiceNotFoundException { + + ServiceStartupEntry res = map1.get(key); + if (res != null) { + return res; + } + if (map2 != null) { + res = map2.get(key); + } + if (res != null) { + return res; + } + + throw new ServiceNotFoundException("No service found under key '" + key.toString() + "'"); + } + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/services/internal/ErrorServiceTypeEntry.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/services/internal/ErrorServiceTypeEntry.java index 99e10e95d6a..634748456d6 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/services/internal/ErrorServiceTypeEntry.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/services/internal/ErrorServiceTypeEntry.java @@ -1,104 +1,104 @@ -/*****************************************************************************
- * Copyright (c) CEA LIST.
- *
- *
- * 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:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.services.internal;
-
-import org.eclipse.papyrus.infra.core.services.BadStateException;
-import org.eclipse.papyrus.infra.core.services.ServiceDescriptor;
-import org.eclipse.papyrus.infra.core.services.ServiceException;
-import org.eclipse.papyrus.infra.core.services.ServiceState;
-import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
-
-/**
- * A service entry used for faulty services. In this implementation, methods do
- * nothings or throw an error.
- *
- *
- * @author cedric dumoulin
- *
- */
-public class ErrorServiceTypeEntry extends ServiceTypeEntry {
-
-
- /**
- *
- * Constructor.
- *
- * @param descriptor
- */
- public ErrorServiceTypeEntry(ServiceDescriptor descriptor) {
- super(descriptor);
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.core.services.internal.ServiceTypeEntry#getServiceInstance()
- *
- * @return
- * @throws ServiceException
- */
- @Override
- public Object getServiceInstance() throws ServiceException {
- throw new BadStateException("Service has not started.", ServiceState.error, serviceDescriptor); //$NON-NLS-1$
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.core.services.internal.ServiceTypeEntry#createService()
- *
- * @throws ServiceException
- */
- @Override
- public void createService() throws ServiceException {
- // do nothing
-
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.core.services.internal.ServiceTypeEntry#initService(ServicesRegistry)
- *
- * @param servicesRegistry
- * @throws ServiceException
- */
- @Override
- public void initService(ServicesRegistry servicesRegistry) throws ServiceException {
- // do nothing
-
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.core.services.internal.ServiceTypeEntry#startService()
- *
- * @throws ServiceException
- */
- @Override
- public void startService() throws ServiceException {
- // do nothing
-
- }
-
- /**
- *
- * @see org.eclipse.papyrus.infra.core.services.internal.ServiceTypeEntry#disposeService()
- *
- * @throws ServiceException
- */
- @Override
- public void disposeService() throws ServiceException {
- // do nothing
-
- }
-
-}
+/***************************************************************************** + * Copyright (c) CEA LIST. + * + * + * 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: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.services.internal; + +import org.eclipse.papyrus.infra.core.services.BadStateException; +import org.eclipse.papyrus.infra.core.services.ServiceDescriptor; +import org.eclipse.papyrus.infra.core.services.ServiceException; +import org.eclipse.papyrus.infra.core.services.ServiceState; +import org.eclipse.papyrus.infra.core.services.ServicesRegistry; + +/** + * A service entry used for faulty services. In this implementation, methods do + * nothings or throw an error. + * + * + * @author cedric dumoulin + * + */ +public class ErrorServiceTypeEntry extends ServiceTypeEntry { + + + /** + * + * Constructor. + * + * @param descriptor + */ + public ErrorServiceTypeEntry(ServiceDescriptor descriptor) { + super(descriptor); + } + + /** + * + * @see org.eclipse.papyrus.infra.core.services.internal.ServiceTypeEntry#getServiceInstance() + * + * @return + * @throws ServiceException + */ + @Override + public Object getServiceInstance() throws ServiceException { + throw new BadStateException("Service has not started.", ServiceState.error, serviceDescriptor); //$NON-NLS-1$ + } + + /** + * + * @see org.eclipse.papyrus.infra.core.services.internal.ServiceTypeEntry#createService() + * + * @throws ServiceException + */ + @Override + public void createService() throws ServiceException { + // do nothing + + } + + /** + * + * @see org.eclipse.papyrus.infra.core.services.internal.ServiceTypeEntry#initService(ServicesRegistry) + * + * @param servicesRegistry + * @throws ServiceException + */ + @Override + public void initService(ServicesRegistry servicesRegistry) throws ServiceException { + // do nothing + + } + + /** + * + * @see org.eclipse.papyrus.infra.core.services.internal.ServiceTypeEntry#startService() + * + * @throws ServiceException + */ + @Override + public void startService() throws ServiceException { + // do nothing + + } + + /** + * + * @see org.eclipse.papyrus.infra.core.services.internal.ServiceTypeEntry#disposeService() + * + * @throws ServiceException + */ + @Override + public void disposeService() throws ServiceException { + // do nothing + + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/DiResourceSet.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/DiResourceSet.java index eaf5335d14f..b4a21af1f54 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/DiResourceSet.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/DiResourceSet.java @@ -1,43 +1,43 @@ -/*****************************************************************************
- * Copyright (c) 2008, 2016 CEA LIST, Christian W. Damus, 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:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- * Christian W. Damus - bug 485220
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.utils;
-
-import org.eclipse.papyrus.infra.core.resource.ModelSet;
-import org.eclipse.papyrus.infra.core.resource.ModelsReader;
-
-/**
- * ResourceSet Manager for UML and DI files, and also other loaded models.
- *
- * @author Cedric dumoulin
- * @author <a href="mailto:jerome.benois@obeo.fr">Jerome Benois</a>
- * @author <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a>
- *
- * @deprecated Use ModelSet instead.
- */
-@Deprecated
-public class DiResourceSet extends ModelSet {
-
- /**
- *
- * Constructor.
- *
- */
- public DiResourceSet() {
- super();
- // Register declared models
- ModelsReader reader = new ModelsReader();
- reader.readModel(this);
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2008, 2016 CEA LIST, Christian W. Damus, 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: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * Christian W. Damus - bug 485220 + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.utils; + +import org.eclipse.papyrus.infra.core.resource.ModelSet; +import org.eclipse.papyrus.infra.core.resource.ModelsReader; + +/** + * ResourceSet Manager for UML and DI files, and also other loaded models. + * + * @author Cedric dumoulin + * @author <a href="mailto:jerome.benois@obeo.fr">Jerome Benois</a> + * @author <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a> + * + * @deprecated Use ModelSet instead. + */ +@Deprecated +public class DiResourceSet extends ModelSet { + + /** + * + * Constructor. + * + */ + public DiResourceSet() { + super(); + // Register declared models + ModelsReader reader = new ModelsReader(); + reader.readModel(this); + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/EMFHelper.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/EMFHelper.java index 350c20b074d..a8f5860fb1a 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/EMFHelper.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/EMFHelper.java @@ -1,65 +1,65 @@ -/*****************************************************************************
- * Copyright (c) 2010, 2014 CEA LIST 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:
- * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
- * Christian W. Damus (CEA) - filter out EObjects that are Resources (CDO)
- * Christian W. Damus (CEA) - Support read-only state at object level (CDO)
- * Christian W. Damus (CEA) - bug 426732
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.utils;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EStructuralFeature.Setting;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
-
-/**
- * @deprecated Please use {@link org.eclipse.papyrus.infra.emf.utils.EMFHelper} instead
- * (which inherit this one) for architectural reason.
- */
-@Deprecated
-public class EMFHelper {
-
- /**
- * Gets the usages.
- *
- * @param source
- * the source
- *
- * @return the usages or null if there is no usages
- */
- public static Collection<Setting> getUsages(EObject source) {
- if (source == null) {
- return Collections.emptyList();
- }
-
- ECrossReferenceAdapter crossReferencer = ECrossReferenceAdapter.getCrossReferenceAdapter(source);
- if (crossReferencer == null) {
- // try to register a cross referencer at the highest level
- crossReferencer = new ECrossReferenceAdapter();
- Resource resource = source.eResource();
- if (resource != null) {
- if (resource.getResourceSet() != null) {
- resource.getResourceSet().eAdapters().add(crossReferencer);
- } else {
- resource.eAdapters().add(crossReferencer);
- }
- } else {
- source.eAdapters().add(crossReferencer);
- }
- }
-
- return crossReferencer.getInverseReferences(source, false);
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2010, 2014 CEA LIST 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: + * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation + * Christian W. Damus (CEA) - filter out EObjects that are Resources (CDO) + * Christian W. Damus (CEA) - Support read-only state at object level (CDO) + * Christian W. Damus (CEA) - bug 426732 + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.utils; + +import java.util.Collection; +import java.util.Collections; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature.Setting; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; + +/** + * @deprecated Please use {@link org.eclipse.papyrus.infra.emf.utils.EMFHelper} instead + * (which inherit this one) for architectural reason. + */ +@Deprecated +public class EMFHelper { + + /** + * Gets the usages. + * + * @param source + * the source + * + * @return the usages or null if there is no usages + */ + public static Collection<Setting> getUsages(EObject source) { + if (source == null) { + return Collections.emptyList(); + } + + ECrossReferenceAdapter crossReferencer = ECrossReferenceAdapter.getCrossReferenceAdapter(source); + if (crossReferencer == null) { + // try to register a cross referencer at the highest level + crossReferencer = new ECrossReferenceAdapter(); + Resource resource = source.eResource(); + if (resource != null) { + if (resource.getResourceSet() != null) { + resource.getResourceSet().eAdapters().add(crossReferencer); + } else { + resource.eAdapters().add(crossReferencer); + } + } else { + source.eAdapters().add(crossReferencer); + } + } + + return crossReferencer.getInverseReferences(source, false); + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/EditorNameInitializer.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/EditorNameInitializer.java index 1eca74aecb9..6f4344e3ce8 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/EditorNameInitializer.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/EditorNameInitializer.java @@ -1,81 +1,81 @@ -/*****************************************************************************
- * Copyright (c) 2012 CEA LIST.
- *
- *
- * 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:
- * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.utils;
-
-import java.util.Collection;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.EStructuralFeature.Setting;
-import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
-
-/**
- *
- * This class provides useful method to get an unused name for a new editor
- *
- */
-public class EditorNameInitializer {
-
- private EditorNameInitializer() {
- // to prenvent instanciation
- }
-
- /**
- *
- * @param editorModelEClass
- * the eclass of the model of the editor
- * @param nameFeature
- * the feature name
- * @param wantedNameWithoutIndex
- * the wantedname for the new editor
- * @param context
- * the context of the editor
- * @return
- * the name for this editor
- */
- public static final String getNameWithIncrement(final EClass editorModelEClass, final EStructuralFeature nameFeature, final String wantedNameWithoutIndex, final EObject context) {
- // a set of the existing index for the wantedName
- final SortedSet<Integer> existingIndex = new TreeSet<Integer>();
- final ECrossReferenceAdapter crossRef = ECrossReferenceAdapter.getCrossReferenceAdapter(context);
- final Collection<Setting> crossReference = crossRef.getNonNavigableInverseReferences(context, true);
- for (final Setting set : crossReference) {
- final EObject eobject = set.getEObject();
- if (eobject.eClass() == editorModelEClass) {
- if (nameFeature != null) {
- final Object currentName = eobject.eGet(nameFeature);
- if (currentName instanceof String) {
- final String aName = (String) currentName;
- if (aName.contains(wantedNameWithoutIndex)) {
- final String lastChars = aName.substring(wantedNameWithoutIndex.length(), aName.length());
- try {
- final Integer value = Integer.parseInt(lastChars);
- existingIndex.add(value);
- } catch (final Exception e) {
- // nothing to do
- }
- }
- }
- }
- }
- }
- int index = 0;
- if (!existingIndex.isEmpty()) {
- index = existingIndex.last().intValue() + 1;
- }
- return wantedNameWithoutIndex + String.valueOf(index);
- }
-}
+/***************************************************************************** + * Copyright (c) 2012 CEA LIST. + * + * + * 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: + * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.utils; + +import java.util.Collection; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.EStructuralFeature.Setting; +import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; + +/** + * + * This class provides useful method to get an unused name for a new editor + * + */ +public class EditorNameInitializer { + + private EditorNameInitializer() { + // to prenvent instanciation + } + + /** + * + * @param editorModelEClass + * the eclass of the model of the editor + * @param nameFeature + * the feature name + * @param wantedNameWithoutIndex + * the wantedname for the new editor + * @param context + * the context of the editor + * @return + * the name for this editor + */ + public static final String getNameWithIncrement(final EClass editorModelEClass, final EStructuralFeature nameFeature, final String wantedNameWithoutIndex, final EObject context) { + // a set of the existing index for the wantedName + final SortedSet<Integer> existingIndex = new TreeSet<Integer>(); + final ECrossReferenceAdapter crossRef = ECrossReferenceAdapter.getCrossReferenceAdapter(context); + final Collection<Setting> crossReference = crossRef.getNonNavigableInverseReferences(context, true); + for (final Setting set : crossReference) { + final EObject eobject = set.getEObject(); + if (eobject.eClass() == editorModelEClass) { + if (nameFeature != null) { + final Object currentName = eobject.eGet(nameFeature); + if (currentName instanceof String) { + final String aName = (String) currentName; + if (aName.contains(wantedNameWithoutIndex)) { + final String lastChars = aName.substring(wantedNameWithoutIndex.length(), aName.length()); + try { + final Integer value = Integer.parseInt(lastChars); + existingIndex.add(value); + } catch (final Exception e) { + // nothing to do + } + } + } + } + } + } + int index = 0; + if (!existingIndex.isEmpty()) { + index = existingIndex.last().intValue() + 1; + } + return wantedNameWithoutIndex + String.valueOf(index); + } +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/FilteredCollectionView.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/FilteredCollectionView.java index b4a7c58b8ee..8c337816b1a 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/FilteredCollectionView.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/FilteredCollectionView.java @@ -1,220 +1,220 @@ -/*****************************************************************************
- * Copyright (c) 2008 CEA LIST.
- *
- *
- * 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:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.utils;
-
-import java.util.AbstractCollection;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * A unmodifiable view on a specified list. The view filters the original list
- * according to the provided filter.
- */
-public class FilteredCollectionView<T> extends AbstractCollection<T> implements Collection<T> {
-
- /** The original collection */
- private Collection<T> list;
-
- /** The filter for the view */
- private IFilter filter;
-
- /**
- * The cached size. Compute only once, so change in the underlying
- * collection is not reflected
- */
- private int size = -1;
-
- /**
- * Creates a new FilteredCollectionView.
- *
- * @param list
- * the list to filter
- * @param filter
- * the filter for the view
- */
- public FilteredCollectionView(Collection<T> list, IFilter filter) {
- this.list = list;
- this.filter = filter;
- }
-
- /**
- * Sets the value of the list property.
- *
- * @param aList
- * the new value of the list property
- */
- public void setBackupCollection(Collection<T> aList) {
- list = aList;
- }
-
- /**
- * Sets the value of the filter property.
- *
- * @param aFilter
- * the new value of the filter property
- */
- public void setFilter(IFilter aFilter) {
- filter = aFilter;
- }
-
- /**
- * Returns the value of the filter property.
- *
- * @return the new value of the filter property
- */
- public IFilter getFilter() {
- return filter;
- }
-
- /**
- * The size of the filtered list.
- *
- * @return the number of elements in the filtered list
- */
- @Override
- public int size() {
- if (size == -1) { // compute the size
- size = 0;
- Iterator<T> i = iterator();
- while (i.hasNext()) {
- size++;
- i.next();
- }
- }
- return size;
- }
-
- /**
- * Return true if the filteredCollection contains the object.
- *
- * @see java.util.AbstractCollection#contains(java.lang.Object)
- * @param o
- * @return
- *
- */
- @Override
- public boolean contains(Object o) {
- return list.contains(o);
- }
-
- /**
- * remove the object. Throw an UnsupportedOperationException, as the
- * FilteredCollection is ReadOnly.
- *
- * @see java.util.AbstractCollection#remove(java.lang.Object)
- * @param o
- * @return
- *
- */
- @Override
- public boolean remove(Object o) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Return the value to be returned by the iterator.next() method. This
- * method can be overloaded by subclasses in order to return another value
- * than the objects belonging to the underlying list.
- *
- * @param ele
- * The iterated object. This is the object iterated inside the
- * underlying list.
- * @return
- */
- protected T returnedValue(T ele) {
- return ele;
- }
-
- /**
- * listIterator.
- *
- * @return ListIterator
- */
- @Override
- public Iterator<T> iterator() {
- return new FilteredIterator();
- }
-
- /**
- * Iterator other the filtered collection
- */
- private class FilteredIterator implements Iterator<T> {
-
- /** the next object */
- T next;
-
- /** The original list iterator */
- Iterator<T> listIterator;
-
- /**
- * Creates a new FilteredIterator
- */
- public FilteredIterator() {
- listIterator = list.iterator();
- next = nextFilteredObject();
- }
-
- /**
- * Unsupported operation, as this is just a view of a list.
- */
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Returns the next object of the list, when filter is applied
- *
- * @return
- */
- protected T nextFilteredObject() {
- while (listIterator.hasNext()) {
- T ele = listIterator.next();
- if (filter.isAllowed(ele)) {
- return returnedValue(ele);
- }
- } // end loop
- return null;
- }
-
- /**
- * hasNext.
- *
- * @return boolean
- */
- @Override
- public boolean hasNext() {
- return next != null;
- }
-
- /**
- * Compute the next field (null or next value), and return the previous
- * value of the next field.
- *
- * @return Object
- */
- @Override
- public T next() {
- if (next == null) {
- throw new NoSuchElementException();
- }
- T ele = next;
- next = nextFilteredObject();
- return ele;
- }
-
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2008 CEA LIST. + * + * + * 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: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.utils; + +import java.util.AbstractCollection; +import java.util.Collection; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * A unmodifiable view on a specified list. The view filters the original list + * according to the provided filter. + */ +public class FilteredCollectionView<T> extends AbstractCollection<T> implements Collection<T> { + + /** The original collection */ + private Collection<T> list; + + /** The filter for the view */ + private IFilter filter; + + /** + * The cached size. Compute only once, so change in the underlying + * collection is not reflected + */ + private int size = -1; + + /** + * Creates a new FilteredCollectionView. + * + * @param list + * the list to filter + * @param filter + * the filter for the view + */ + public FilteredCollectionView(Collection<T> list, IFilter filter) { + this.list = list; + this.filter = filter; + } + + /** + * Sets the value of the list property. + * + * @param aList + * the new value of the list property + */ + public void setBackupCollection(Collection<T> aList) { + list = aList; + } + + /** + * Sets the value of the filter property. + * + * @param aFilter + * the new value of the filter property + */ + public void setFilter(IFilter aFilter) { + filter = aFilter; + } + + /** + * Returns the value of the filter property. + * + * @return the new value of the filter property + */ + public IFilter getFilter() { + return filter; + } + + /** + * The size of the filtered list. + * + * @return the number of elements in the filtered list + */ + @Override + public int size() { + if (size == -1) { // compute the size + size = 0; + Iterator<T> i = iterator(); + while (i.hasNext()) { + size++; + i.next(); + } + } + return size; + } + + /** + * Return true if the filteredCollection contains the object. + * + * @see java.util.AbstractCollection#contains(java.lang.Object) + * @param o + * @return + * + */ + @Override + public boolean contains(Object o) { + return list.contains(o); + } + + /** + * remove the object. Throw an UnsupportedOperationException, as the + * FilteredCollection is ReadOnly. + * + * @see java.util.AbstractCollection#remove(java.lang.Object) + * @param o + * @return + * + */ + @Override + public boolean remove(Object o) { + throw new UnsupportedOperationException(); + } + + /** + * Return the value to be returned by the iterator.next() method. This + * method can be overloaded by subclasses in order to return another value + * than the objects belonging to the underlying list. + * + * @param ele + * The iterated object. This is the object iterated inside the + * underlying list. + * @return + */ + protected T returnedValue(T ele) { + return ele; + } + + /** + * listIterator. + * + * @return ListIterator + */ + @Override + public Iterator<T> iterator() { + return new FilteredIterator(); + } + + /** + * Iterator other the filtered collection + */ + private class FilteredIterator implements Iterator<T> { + + /** the next object */ + T next; + + /** The original list iterator */ + Iterator<T> listIterator; + + /** + * Creates a new FilteredIterator + */ + public FilteredIterator() { + listIterator = list.iterator(); + next = nextFilteredObject(); + } + + /** + * Unsupported operation, as this is just a view of a list. + */ + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + /** + * Returns the next object of the list, when filter is applied + * + * @return + */ + protected T nextFilteredObject() { + while (listIterator.hasNext()) { + T ele = listIterator.next(); + if (filter.isAllowed(ele)) { + return returnedValue(ele); + } + } // end loop + return null; + } + + /** + * hasNext. + * + * @return boolean + */ + @Override + public boolean hasNext() { + return next != null; + } + + /** + * Compute the next field (null or next value), and return the previous + * value of the next field. + * + * @return Object + */ + @Override + public T next() { + if (next == null) { + throw new NoSuchElementException(); + } + T ele = next; + next = nextFilteredObject(); + return ele; + } + + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/FilteredCollectionViewFromIterator.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/FilteredCollectionViewFromIterator.java index 1c1548e93e9..3382fc2bb69 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/FilteredCollectionViewFromIterator.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/FilteredCollectionViewFromIterator.java @@ -1,258 +1,258 @@ -/*****************************************************************************
- * Copyright (c) 2008 CEA LIST.
- *
- *
- * 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:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-//Source file: H:\\temp\\generated\\modTransf\\util\\FilteredListView.java
-package org.eclipse.papyrus.infra.core.utils;
-
-import java.util.AbstractCollection;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * A unmodifiable view on a specified list from its iterator. The view filters
- * the original list according to the provided filter.
- *
- * @param <E>
- * the type of objects in the filtered collection
- */
-public class FilteredCollectionViewFromIterator<E> extends AbstractCollection<E> implements Collection<E> {
-
- /**
- * The iterator provider linked to the backup list.
- */
- private IteratorProvider<E> iter;
-
- /**
- *
- */
- private IFilter filter;
-
- /**
- * The cached size. Compute only once, so change in the underlying
- * collection is not reflected
- */
- private int size = -1;
-
- /**
- *
- *
- * @param filter
- * @param list
- * *
- * @param iter
- */
- public FilteredCollectionViewFromIterator(IteratorProvider<E> iter, IFilter filter) {
- this.iter = iter;
- this.filter = filter;
- }
-
- /**
- * Sets the value of the list property.
- *
- * @param iter
- * the new value of the list property
- */
- public void setBackupCollection(IteratorProvider<E> iter) {
- this.iter = iter;
- }
-
- /**
- *
- *
- * @return
- */
- Iterator<E> getBackupIterator() {
- return iter.iterator();
- }
-
- /**
- * Sets the value of the filter property.
- *
- * @param aFilter
- * the new value of the filter property
- */
- public void setFilter(IFilter aFilter) {
- filter = aFilter;
- }
-
- /**
- * Sets the value of the filter property.
- *
- * @return the new value of the filter property
- */
- public IFilter getFilter() {
- return filter;
- }
-
- /**
- * size.
- *
- * @return int
- */
- @Override
- public int size() {
- if (size == -1) { // compute the size
- size = 0;
- Iterator<E> i = iterator();
- while (i.hasNext()) {
- size++;
- i.next();
- }
- }
- return size;
- }
-
- /**
- * Removes a single instance of the specified element from this collection,
- * if it is present (optional operation). More formally, removes an element <tt>e</tt> such that <tt>(o==null ? e==null :
- * o.equals(e))</tt>, if the collection contains one or more such elements.
- * Returns <tt>true</tt> if the collection contained the specified element
- * (or equivalently, if the collection changed as a result of the call).
- * <p>
- *
- * This implementation call the remove method on the underlying collection.
- * <p>
- *
- * @param o
- * element to be removed from this collection, if present.
- *
- * @return <tt>true</tt> if the collection contained the specified element.
- *
- * @throws UnsupportedOperationException
- * if the <tt>remove</tt> method is not supported by this
- * collection.
- */
- @Override
- public boolean remove(Object o) {
- // return list.remove(o);
- throw new UnsupportedOperationException();
- }
-
- /**
- * Return the value to be returned by the iterator.next() method. This
- * method can be overloaded by subclasses in order to return another value
- * than the objects belonging to the underlying list.
- *
- * @param ele
- * The iterated object. This is the object iterated inside the
- * underlying list.
- *
- * @return
- */
- protected E returnedValue(E ele) {
- return ele;
- }
-
- /**
- * listIterator.
- *
- * @param index
- * int
- *
- * @return ListIterator
- */
- @Override
- public Iterator<E> iterator() {
- return new FilteredIterator();
- }
-
- /**
- *
- */
- private class FilteredIterator implements Iterator<E> {
-
- /**
- *
- */
- E next;
-
- /**
- *
- */
- Iterator<E> listIterator;
-
- /**
- *
- */
- public FilteredIterator() {
- listIterator = getBackupIterator();
- next = nextFilteredObject();
- }
-
- /**
- * remove.
- */
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
-
- /**
- *
- *
- * @return
- */
- protected E nextFilteredObject() {
- while (listIterator.hasNext()) {
- E ele = listIterator.next();
- if (filter.isAllowed(ele)) {
- return returnedValue(ele);
- }
- } // end loop
- return null;
- }
-
- /**
- * hasNext.
- *
- * @return boolean
- */
- @Override
- public boolean hasNext() {
- return next != null;
- }
-
- /**
- * Compute the next field (null or next value), and return the previous
- * value of the next field.
- *
- * @return Object
- */
- @Override
- public E next() {
- if (next == null) {
- throw new NoSuchElementException();
- }
- E ele = next;
- next = nextFilteredObject();
- return ele;
- }
-
- }
-
- /**
- * Inner class. Provide an iterator used internally in the unmodifiable
- * collection view..
- */
- public interface IteratorProvider<E> {
-
- /**
- * provide a new iterator over the list.
- *
- * @return
- */
- Iterator<E> iterator();
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2008 CEA LIST. + * + * + * 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: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ +//Source file: H:\\temp\\generated\\modTransf\\util\\FilteredListView.java +package org.eclipse.papyrus.infra.core.utils; + +import java.util.AbstractCollection; +import java.util.Collection; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * A unmodifiable view on a specified list from its iterator. The view filters + * the original list according to the provided filter. + * + * @param <E> + * the type of objects in the filtered collection + */ +public class FilteredCollectionViewFromIterator<E> extends AbstractCollection<E> implements Collection<E> { + + /** + * The iterator provider linked to the backup list. + */ + private IteratorProvider<E> iter; + + /** + * + */ + private IFilter filter; + + /** + * The cached size. Compute only once, so change in the underlying + * collection is not reflected + */ + private int size = -1; + + /** + * + * + * @param filter + * @param list + * * + * @param iter + */ + public FilteredCollectionViewFromIterator(IteratorProvider<E> iter, IFilter filter) { + this.iter = iter; + this.filter = filter; + } + + /** + * Sets the value of the list property. + * + * @param iter + * the new value of the list property + */ + public void setBackupCollection(IteratorProvider<E> iter) { + this.iter = iter; + } + + /** + * + * + * @return + */ + Iterator<E> getBackupIterator() { + return iter.iterator(); + } + + /** + * Sets the value of the filter property. + * + * @param aFilter + * the new value of the filter property + */ + public void setFilter(IFilter aFilter) { + filter = aFilter; + } + + /** + * Sets the value of the filter property. + * + * @return the new value of the filter property + */ + public IFilter getFilter() { + return filter; + } + + /** + * size. + * + * @return int + */ + @Override + public int size() { + if (size == -1) { // compute the size + size = 0; + Iterator<E> i = iterator(); + while (i.hasNext()) { + size++; + i.next(); + } + } + return size; + } + + /** + * Removes a single instance of the specified element from this collection, + * if it is present (optional operation). More formally, removes an element <tt>e</tt> such that <tt>(o==null ? e==null : + * o.equals(e))</tt>, if the collection contains one or more such elements. + * Returns <tt>true</tt> if the collection contained the specified element + * (or equivalently, if the collection changed as a result of the call). + * <p> + * + * This implementation call the remove method on the underlying collection. + * <p> + * + * @param o + * element to be removed from this collection, if present. + * + * @return <tt>true</tt> if the collection contained the specified element. + * + * @throws UnsupportedOperationException + * if the <tt>remove</tt> method is not supported by this + * collection. + */ + @Override + public boolean remove(Object o) { + // return list.remove(o); + throw new UnsupportedOperationException(); + } + + /** + * Return the value to be returned by the iterator.next() method. This + * method can be overloaded by subclasses in order to return another value + * than the objects belonging to the underlying list. + * + * @param ele + * The iterated object. This is the object iterated inside the + * underlying list. + * + * @return + */ + protected E returnedValue(E ele) { + return ele; + } + + /** + * listIterator. + * + * @param index + * int + * + * @return ListIterator + */ + @Override + public Iterator<E> iterator() { + return new FilteredIterator(); + } + + /** + * + */ + private class FilteredIterator implements Iterator<E> { + + /** + * + */ + E next; + + /** + * + */ + Iterator<E> listIterator; + + /** + * + */ + public FilteredIterator() { + listIterator = getBackupIterator(); + next = nextFilteredObject(); + } + + /** + * remove. + */ + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + /** + * + * + * @return + */ + protected E nextFilteredObject() { + while (listIterator.hasNext()) { + E ele = listIterator.next(); + if (filter.isAllowed(ele)) { + return returnedValue(ele); + } + } // end loop + return null; + } + + /** + * hasNext. + * + * @return boolean + */ + @Override + public boolean hasNext() { + return next != null; + } + + /** + * Compute the next field (null or next value), and return the previous + * value of the next field. + * + * @return Object + */ + @Override + public E next() { + if (next == null) { + throw new NoSuchElementException(); + } + E ele = next; + next = nextFilteredObject(); + return ele; + } + + } + + /** + * Inner class. Provide an iterator used internally in the unmodifiable + * collection view.. + */ + public interface IteratorProvider<E> { + + /** + * provide a new iterator over the list. + * + * @return + */ + Iterator<E> iterator(); + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/FilteredListView.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/FilteredListView.java index 52ba6ced0eb..2836252dd6a 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/FilteredListView.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/FilteredListView.java @@ -1,385 +1,385 @@ -/*****************************************************************************
- * Copyright (c) 2008 CEA LIST.
- *
- *
- * 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:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.utils;
-
-import java.util.AbstractSequentialList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.NoSuchElementException;
-
-/**
- * A unmodifiable view on a specified list. The view filters the original list
- * according to the provided filter.
- */
-public class FilteredListView extends AbstractSequentialList<Object> implements List<Object> {
-
- /**
- *
- */
- private List<Object> list;
-
- /**
- *
- */
- private IFilter filter;
-
- /**
- * The cached size. Copute only once, so change in the underlying collection
- * is not reflected
- */
- private int size = -1;
-
- /**
- *
- *
- * @param filter
- * @param list
- */
- public FilteredListView(List<Object> list, IFilter filter) {
- this.list = list;
- this.filter = filter;
- }
-
- /**
- * Sets the value of the list property.
- *
- * @param aList
- * the new value of the list property
- */
- public void setBackupList(List aList) {
- list = aList;
- }
-
- /**
- * Sets the value of the filter property.
- *
- * @param aFilter
- * the new value of the filter property
- */
- public void setFilter(IFilter aFilter) {
- filter = aFilter;
- }
-
- /**
- * size.
- *
- * @return int
- */
- @Override
- public int size() {
- if (size == -1) { // compute the size
- size = 0;
- Iterator<Object> i = iterator();
- while (i.hasNext()) {
- size++;
- i.next();
- }
- }
- return size;
- }
-
- /**
- * Returns <tt>true</tt> if this collection contains the specified element.
- * More formally, returns <tt>true</tt> if and only if this collection
- * contains at least one element <tt>e</tt> such that <tt>(o==null ? e==null : o.equals(e))</tt>.
- * <p>
- *
- * @param o
- * object to be checked for containment in this collection.
- *
- * @return <tt>true</tt> if this collection contains the specified element.
- */
- @Override
- public boolean contains(Object o) {
- return list.contains(o);
- }
-
- /**
- * Removes a single instance of the specified element from this collection,
- * if it is present (optional operation). More formally, removes an element <tt>e</tt> such that <tt>(o==null ? e==null :
- * o.equals(e))</tt>, if the collection contains one or more such elements.
- * Returns <tt>true</tt> if the collection contained the specified element
- * (or equivalently, if the collection changed as a result of the call).
- * <p>
- *
- * This implementation call the remove method on the underlying collection.
- * <p>
- *
- * @param o
- * element to be removed from this collection, if present.
- *
- * @return <tt>true</tt> if the collection contained the specified element.
- *
- * @throws UnsupportedOperationException
- * if the <tt>remove</tt> method is not supported by this
- * collection.
- */
- @Override
- public boolean remove(Object o) {
- // return list.remove(o);
- throw new UnsupportedOperationException();
- }
-
- /**
- * listIterator.
- *
- * @param index
- * int
- *
- * @return ListIterator
- */
- @Override
- public ListIterator<Object> listIterator(int index) {
- return new FilteredListIterator(index);
- }
-
- /**
- *
- */
- private class FilteredListIterator implements ListIterator<Object> {
-
- /**
- *
- */
- Object current;
-
- /**
- *
- */
- Object next;
-
- /**
- *
- */
- Object previous;
-
- /**
- * Index of the current element (last returned) in the backup list.
- */
- int currentIndex;
-
- /**
- *
- */
- int previousIndex;
-
- /**
- *
- */
- int nextIndex;
-
- /**
- * Index of the last returned element.
- */
- int eleIndex = -1;
-
- /**
- * Index of the boundary.
- */
- int index = 0;
-
- /**
- *
- */
- ListIterator<Object> listIterator;
-
- /**
- *
- *
- * @param index
- */
- FilteredListIterator(int index) {
- listIterator = list.listIterator(0);
- nextIndex = -1;
- next = nextFilteredObject();
-
- previous = null;
- previousIndex = -1;
- current = next;
- currentIndex = 0;
-
- // Go to the specified index
- while (hasNext() && (nextIndex() < index)) {
- next();
- }
- }
-
- /**
- *
- *
- * @return
- */
- protected Object nextFilteredObject() {
- while (listIterator.hasNext()) {
-
- int curIndex = listIterator.nextIndex(); // This is the current
- // index in the list
- Object ele = listIterator.next();
- if (filter.isAllowed(ele) && (curIndex > nextIndex)) {
- nextIndex = curIndex;
- return ele;
- }
- } // end loop
- return null;
- }
-
- /**
- *
- *
- * @return
- */
- protected Object previousFilteredObject() {
- while (listIterator.hasPrevious()) {
- int curIndex = listIterator.previousIndex(); // This is the
- // current index
- // in the list
- Object ele = listIterator.previous();
- if (filter.isAllowed(ele) && (curIndex < previousIndex)) {
- previousIndex = curIndex;
- return ele;
- }
- } // end loop
- return null;
- }
-
- /**
- * /** nextIndex.
- *
- * @return int
- */
- @Override
- public int nextIndex() {
- return index;
- }
-
- /**
- * previousIndex.
- *
- * @return int
- */
- @Override
- public int previousIndex() {
- return index - 1;
- }
-
- /**
- * remove.
- */
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
-
- /**
- * hasNext.
- *
- * @return boolean
- */
- @Override
- public boolean hasNext() {
- return next != null;
- }
-
- /**
- * hasPrevious.
- *
- * @return boolean
- */
- @Override
- public boolean hasPrevious() {
- return previous != null;
- }
-
- /**
- * next.
- *
- * @return Object
- */
- @Override
- public Object next() {
- if (next == null) {
- throw new NoSuchElementException();
- }
-
- if (index > eleIndex) { // previous was up, continue
- previous = current;
- previousIndex = currentIndex;
- current = next;
- currentIndex = nextIndex;
- next = nextFilteredObject();
-
- index++;
- eleIndex++;
- return current;
- } else { // previous was down, turn back
- index++;
- return current;
- }
- }
-
- /**
- * previous.
- *
- * @return Object
- */
- @Override
- public Object previous() {
- if (previous == null) {
- throw new NoSuchElementException();
- }
-
- if (index > eleIndex) { // previous was up, turn back
- index--;
- return current;
- } else { // previuos was done, continue
- next = current;
- nextIndex = currentIndex;
- current = previous;
- currentIndex = previousIndex;
- previous = previousFilteredObject();
-
- index--;
- eleIndex--;
- return current;
-
- }
-
- }
-
- /**
- * add.
- *
- * @param o
- * Object
- */
- @Override
- public void add(Object o) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * set.
- *
- * @param o
- * Object
- */
- @Override
- public void set(Object o) {
- throw new UnsupportedOperationException();
- }
-
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2008 CEA LIST. + * + * + * 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: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.utils; + +import java.util.AbstractSequentialList; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.NoSuchElementException; + +/** + * A unmodifiable view on a specified list. The view filters the original list + * according to the provided filter. + */ +public class FilteredListView extends AbstractSequentialList<Object> implements List<Object> { + + /** + * + */ + private List<Object> list; + + /** + * + */ + private IFilter filter; + + /** + * The cached size. Copute only once, so change in the underlying collection + * is not reflected + */ + private int size = -1; + + /** + * + * + * @param filter + * @param list + */ + public FilteredListView(List<Object> list, IFilter filter) { + this.list = list; + this.filter = filter; + } + + /** + * Sets the value of the list property. + * + * @param aList + * the new value of the list property + */ + public void setBackupList(List aList) { + list = aList; + } + + /** + * Sets the value of the filter property. + * + * @param aFilter + * the new value of the filter property + */ + public void setFilter(IFilter aFilter) { + filter = aFilter; + } + + /** + * size. + * + * @return int + */ + @Override + public int size() { + if (size == -1) { // compute the size + size = 0; + Iterator<Object> i = iterator(); + while (i.hasNext()) { + size++; + i.next(); + } + } + return size; + } + + /** + * Returns <tt>true</tt> if this collection contains the specified element. + * More formally, returns <tt>true</tt> if and only if this collection + * contains at least one element <tt>e</tt> such that <tt>(o==null ? e==null : o.equals(e))</tt>. + * <p> + * + * @param o + * object to be checked for containment in this collection. + * + * @return <tt>true</tt> if this collection contains the specified element. + */ + @Override + public boolean contains(Object o) { + return list.contains(o); + } + + /** + * Removes a single instance of the specified element from this collection, + * if it is present (optional operation). More formally, removes an element <tt>e</tt> such that <tt>(o==null ? e==null : + * o.equals(e))</tt>, if the collection contains one or more such elements. + * Returns <tt>true</tt> if the collection contained the specified element + * (or equivalently, if the collection changed as a result of the call). + * <p> + * + * This implementation call the remove method on the underlying collection. + * <p> + * + * @param o + * element to be removed from this collection, if present. + * + * @return <tt>true</tt> if the collection contained the specified element. + * + * @throws UnsupportedOperationException + * if the <tt>remove</tt> method is not supported by this + * collection. + */ + @Override + public boolean remove(Object o) { + // return list.remove(o); + throw new UnsupportedOperationException(); + } + + /** + * listIterator. + * + * @param index + * int + * + * @return ListIterator + */ + @Override + public ListIterator<Object> listIterator(int index) { + return new FilteredListIterator(index); + } + + /** + * + */ + private class FilteredListIterator implements ListIterator<Object> { + + /** + * + */ + Object current; + + /** + * + */ + Object next; + + /** + * + */ + Object previous; + + /** + * Index of the current element (last returned) in the backup list. + */ + int currentIndex; + + /** + * + */ + int previousIndex; + + /** + * + */ + int nextIndex; + + /** + * Index of the last returned element. + */ + int eleIndex = -1; + + /** + * Index of the boundary. + */ + int index = 0; + + /** + * + */ + ListIterator<Object> listIterator; + + /** + * + * + * @param index + */ + FilteredListIterator(int index) { + listIterator = list.listIterator(0); + nextIndex = -1; + next = nextFilteredObject(); + + previous = null; + previousIndex = -1; + current = next; + currentIndex = 0; + + // Go to the specified index + while (hasNext() && (nextIndex() < index)) { + next(); + } + } + + /** + * + * + * @return + */ + protected Object nextFilteredObject() { + while (listIterator.hasNext()) { + + int curIndex = listIterator.nextIndex(); // This is the current + // index in the list + Object ele = listIterator.next(); + if (filter.isAllowed(ele) && (curIndex > nextIndex)) { + nextIndex = curIndex; + return ele; + } + } // end loop + return null; + } + + /** + * + * + * @return + */ + protected Object previousFilteredObject() { + while (listIterator.hasPrevious()) { + int curIndex = listIterator.previousIndex(); // This is the + // current index + // in the list + Object ele = listIterator.previous(); + if (filter.isAllowed(ele) && (curIndex < previousIndex)) { + previousIndex = curIndex; + return ele; + } + } // end loop + return null; + } + + /** + * /** nextIndex. + * + * @return int + */ + @Override + public int nextIndex() { + return index; + } + + /** + * previousIndex. + * + * @return int + */ + @Override + public int previousIndex() { + return index - 1; + } + + /** + * remove. + */ + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + /** + * hasNext. + * + * @return boolean + */ + @Override + public boolean hasNext() { + return next != null; + } + + /** + * hasPrevious. + * + * @return boolean + */ + @Override + public boolean hasPrevious() { + return previous != null; + } + + /** + * next. + * + * @return Object + */ + @Override + public Object next() { + if (next == null) { + throw new NoSuchElementException(); + } + + if (index > eleIndex) { // previous was up, continue + previous = current; + previousIndex = currentIndex; + current = next; + currentIndex = nextIndex; + next = nextFilteredObject(); + + index++; + eleIndex++; + return current; + } else { // previous was down, turn back + index++; + return current; + } + } + + /** + * previous. + * + * @return Object + */ + @Override + public Object previous() { + if (previous == null) { + throw new NoSuchElementException(); + } + + if (index > eleIndex) { // previous was up, turn back + index--; + return current; + } else { // previuos was done, continue + next = current; + nextIndex = currentIndex; + current = previous; + currentIndex = previousIndex; + previous = previousFilteredObject(); + + index--; + eleIndex--; + return current; + + } + + } + + /** + * add. + * + * @param o + * Object + */ + @Override + public void add(Object o) { + throw new UnsupportedOperationException(); + } + + /** + * set. + * + * @param o + * Object + */ + @Override + public void set(Object o) { + throw new UnsupportedOperationException(); + } + + } + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/IDebugChannel.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/IDebugChannel.java index fdfbd74072c..7c1e8462a6f 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/IDebugChannel.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/IDebugChannel.java @@ -1,30 +1,30 @@ -/*******************************************************************************
- * Copyright (c) 2008 CEA LIST.
- * 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:
- * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
- *******************************************************************************/
-package org.eclipse.papyrus.infra.core.utils;
-
-/**
- * This interface contains all channels to trace papyrus
- *
- * @author Patrick Tessier
- */
-public interface IDebugChannel {
-
- /**
- * constant used to trace the core running
- */
- public static final String PAPYRUS_CORE = "org.eclipse.papyrus.infra.core/debug/core";
-
- /**
- * constant used to trace the loading of extension point
- */
- public static final String PAPYRUS_EXTENSIONPOINT_LOADING = "org.eclipse.papyrus.infra.core/debug/extensionpoint";
-
-}
+/******************************************************************************* + * Copyright (c) 2008 CEA LIST. + * 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: + * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation + *******************************************************************************/ +package org.eclipse.papyrus.infra.core.utils; + +/** + * This interface contains all channels to trace papyrus + * + * @author Patrick Tessier + */ +public interface IDebugChannel { + + /** + * constant used to trace the core running + */ + public static final String PAPYRUS_CORE = "org.eclipse.papyrus.infra.core/debug/core"; + + /** + * constant used to trace the loading of extension point + */ + public static final String PAPYRUS_EXTENSIONPOINT_LOADING = "org.eclipse.papyrus.infra.core/debug/extensionpoint"; + +} diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/IFilter.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/IFilter.java index 5a8a7329c33..4c9b67e4476 100644 --- a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/IFilter.java +++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/utils/IFilter.java @@ -1,30 +1,30 @@ -/*****************************************************************************
- * Copyright (c) 2008 CEA LIST.
- *
- *
- * 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:
- * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.core.utils;
-
-/**
- * A filter.
- */
-public interface IFilter {
-
- /**
- * Is the specified object allowed ? Return true if the filter allow this
- * object. Return false if the filter doesn't allows the object.
- *
- * @param object
- *
- * @return boolean
- */
- public boolean isAllowed(Object object);
-}
+/***************************************************************************** + * Copyright (c) 2008 CEA LIST. + * + * + * 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: + * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.infra.core.utils; + +/** + * A filter. + */ +public interface IFilter { + + /** + * Is the specified object allowed ? Return true if the filter allow this + * object. Return false if the filter doesn't allows the object. + * + * @param object + * + * @return boolean + */ + public boolean isAllowed(Object object); +} |