diff options
author | Quentin Le Menez | 2017-11-23 16:01:02 +0000 |
---|---|---|
committer | Quentin Le Menez | 2017-12-22 11:03:11 +0000 |
commit | ba7ed2a3bcea1819b70c50f822694519fa915beb (patch) | |
tree | ca6ee533cdf368cbef52f8d05b5ae2a76f8aee18 /layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus | |
parent | e99862e1dc1881c570ad724bba4bc6b0b07ed069 (diff) | |
download | org.eclipse.papyrus.incubation-ba7ed2a3bcea1819b70c50f822694519fa915beb.tar.gz org.eclipse.papyrus.incubation-ba7ed2a3bcea1819b70c50f822694519fa915beb.tar.xz org.eclipse.papyrus.incubation-ba7ed2a3bcea1819b70c50f822694519fa915beb.zip |
Bug 529135 - [Layers] Test to regenerate the model code
- still needed a lot of manual fixing, may have overlooked stuff
Change-Id: I6c6435488a04939eddb659d87538e713e6282e39
Signed-off-by: Quentin Le Menez <quentin.lemenez@cea.fr>
Diffstat (limited to 'layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus')
35 files changed, 4070 insertions, 0 deletions
diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/Activator.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/Activator.java new file mode 100755 index 0000000..0d635da --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/Activator.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model; + +import org.eclipse.core.runtime.Plugin; +import org.eclipse.papyrus.infra.core.log.LogHelper; +import org.osgi.framework.BundleContext; + +public class Activator extends Plugin { + + private static BundleContext context; + + /** Logging helper */ + public static LogHelper log; + + static BundleContext getContext() { + return context; + } + + // TODO and the ID ? + + /* + * (non-Javadoc) + * + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + // register the login helper + log = new LogHelper(this); + } + + /* + * (non-Javadoc) + * + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/BadStateException.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/BadStateException.java new file mode 100755 index 0000000..94f00f7 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/BadStateException.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model; + + +/** + * @author cedric dumoulin + * + */ +public class BadStateException extends LayersException { + + /** + * + */ + private static final long serialVersionUID = -5674451388263111557L; + + /** + * Constructor. + * + */ + public BadStateException() { + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param message + */ + public BadStateException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param cause + */ + public BadStateException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param message + * @param cause + */ + public BadStateException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/InstanciationException.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/InstanciationException.java new file mode 100755 index 0000000..3e4b4a0 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/InstanciationException.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model; + + +/** + * @author dumoulin + * + */ +public class InstanciationException extends LayersException { + + /** + * + */ + private static final long serialVersionUID = 2070317356365033045L; + + /** + * Constructor. + * + */ + public InstanciationException() { + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param message + */ + public InstanciationException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param cause + */ + public InstanciationException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param message + * @param cause + */ + public InstanciationException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/LayersException.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/LayersException.java new file mode 100755 index 0000000..81e3d57 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/LayersException.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model; + + +/** + * @author dumoulin + * + */ +public class LayersException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Constructor. + * + */ + public LayersException() { + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param message + */ + public LayersException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param cause + */ + public LayersException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param message + * @param cause + */ + public LayersException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + // public LayersException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + // super(message, cause, enableSuppression, writableStackTrace); + // // TODO Auto-generated constructor stub + // } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/NotFoundException.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/NotFoundException.java new file mode 100755 index 0000000..43e8063 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/NotFoundException.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model; + + +/** + * @author dumoulin + * + */ +public class NotFoundException extends LayersException { + + /** + * + */ + private static final long serialVersionUID = 2070317356365033045L; + + /** + * Constructor. + * + */ + public NotFoundException() { + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param message + */ + public NotFoundException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param cause + */ + public NotFoundException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * Constructor. + * + * @param message + * @param cause + */ + public NotFoundException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/PropertyValueFactory.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/PropertyValueFactory.java new file mode 100755 index 0000000..8770d6c --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/PropertyValueFactory.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.osgi.framework.Bundle; + + +/** + * @author cedric dumoulin + * + */ +public class PropertyValueFactory { + + /** + * Constructor. + * + */ + public PropertyValueFactory() { + // TODO Auto-generated constructor stub + } + + /** + * Create an instance of the specified class, located in the specified plugin. + * + * @param pluginId + * @param classname + * @return + * @throws ClassNotFoundException + * @throws IllegalAccessException + * @throws InstantiationException + */ + public Object newInstance(String pluginId, String classname) throws ClassNotFoundException, InstantiationException, IllegalAccessException { + + + Class<?> classType = loadClass(pluginId, classname); + + return classType.newInstance(); + } + + /** + * Load requested class from the current classloader. If not found, try to get it from the + * specified plugin. + * + * @param declaringID + * @param className + * @return + * @throws ClassNotFoundException + */ + public Class<?> loadClass(String declaringID, String className) throws ClassNotFoundException { + Class<?> factoryClass; + try { + factoryClass = Class.forName(className); + } catch (ClassNotFoundException e) { + // try another way + try { + Bundle bundle = Platform.getBundle(declaringID); + factoryClass = bundle.loadClass(className); + } catch (ClassNotFoundException e1) { + throw new ClassNotFoundException("Can't find class " + className + + "in plugin " + declaringID, e1); + } catch (NullPointerException e1) { + throw new ClassNotFoundException("Can't find plugin " + declaringID, e1); + } + } + return factoryClass; + + } + + /** + * Create an instance of the specified model concept. + * + * @param nsURI + * @param propertyName + * @return + * @throws ClassNotFoundException + * @throws InstantiationException + * @throws IllegalAccessException + */ + public EObject newEClassInstance(String nsURI, String propertyName) throws ClassNotFoundException { + + + + EPackage modelPackage = EPackage.Registry.INSTANCE.getEPackage(nsURI); + if (modelPackage == null) { + throw new ClassNotFoundException("Can't get EPAckage for model '" + nsURI + "'"); + } + + EClass classifier = (EClass) modelPackage.getEClassifier(propertyName); + if (classifier == null) { + throw new ClassNotFoundException("Can't get classifier '" + propertyName + "' in model '" + nsURI + "'"); + } + + return modelPackage.getEFactoryInstance().create(classifier); + } + + public Object getEObjectPropertyValue(EObject eObject, String propertyName) { + return eObject.eGet(eObject.eClass().getEStructuralFeature(propertyName)); + } + + public void setEObjectPropertyValue(EObject eObject, String propertyName, Object value) { + eObject.eSet(eObject.eClass().getEStructuralFeature(propertyName), value); + } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/command/ComputePropertyValueCommand.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/command/ComputePropertyValueCommand.java new file mode 100755 index 0000000..d2ef20c --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/command/ComputePropertyValueCommand.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.command; + +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.LayersException; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStack; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.TypeInstance; + + +/** + * This command is used to compute a property value in {@link LayersStack}. + * The effective computation is done when the {@link #getValue()} method is called. + * + * + * @author cedric dumoulin + * + */ +public interface ComputePropertyValueCommand { + + + /** + * Execute the command and return the computed value. + * Compute the value of the Property, and return it. + * + * @return The computed value of the Property. + * @throws LayersException + * If something goes wrong + */ + public TypeInstance getCmdValue() throws LayersException; + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/exprmatcher/ExpressionMatcher.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/exprmatcher/ExpressionMatcher.java new file mode 100755 index 0000000..aa8ef88 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/exprmatcher/ExpressionMatcher.java @@ -0,0 +1,416 @@ +/***************************************************************************** + * Copyright (c) 2013 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.internal.infra.gmfdiag.layers.model.exprmatcher; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.query.conditions.eobjects.EObjectCondition; +import org.eclipse.emf.query.ocl.conditions.BooleanOCLCondition; +import org.eclipse.emf.query.statements.FROM; +import org.eclipse.emf.query.statements.IQueryResult; +import org.eclipse.emf.query.statements.SELECT; +import org.eclipse.emf.query.statements.WHERE; +import org.eclipse.gmf.runtime.notation.NotationPackage; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.ocl.ParserException; +import org.eclipse.ocl.ecore.OCL; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.LayersException; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.util.Collections3; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.util.ObservableListView; + +/** + * This class evaluate its associated expression against the associated models. + * It provide a list of elements matching the expression in the model. + * The list of matching elements is synchronized by the matcher. The list can be provided at construction + * time. The ExpressinMatcher takes care to minimize the number of write to the underlying list of matching elements. + * Usually, there is two writes (see {@link Collections3#resetListTo(Collection, Collection)}. <br> + * It is possible to be inform of changes in the underlying list by wrapping it in an {@link ObservableListView}. + * + * + * @author cedric dumoulin + * + */ +public class ExpressionMatcher implements IValueChangedEventListener { + + protected String expression = ""; + + /** + * List of element matching the expression. + * This class maintains the list. + */ + protected List<View> matchingElements; + + /** + * List of element used as starting point for search. + */ + protected List<EObject> searchRoots; + + /** + * OCL Condition computed from the expr. + */ + protected EObjectCondition condition; + protected OCL ocl; + + + /** + * + * Constructor. + * + */ + public ExpressionMatcher() { + this.expression = ""; + this.searchRoots = Collections.emptyList(); + // init matchingElements + matchingElements = new ArrayList<View>(); + } + + /** + * + * Constructor. + * + * @param searchRoots + * @throws LayersException + */ + public ExpressionMatcher(List<View> matchingElementsList) { + this.expression = ""; + this.searchRoots = Collections.emptyList(); + // init matchingElements + matchingElements = matchingElementsList; + } + + /** + * + * Constructor. + * + * @param searchRoots + * @throws LayersException + */ + // public ExpressionMatcher(List<EObject> searchRoots) { + // this.expression = ""; + // setSearchRoots(searchRoots); + // // init matchingElements + // matchingElements = new ObservableListView<View>(new ArrayList<View>()); + // } + + /** + * + * Constructor. + * + * @param searchRoot + * @throws LayersException + */ + public ExpressionMatcher(EObject searchRoot) { + this.expression = ""; + setSearchRoots(Collections.singletonList(searchRoot)); + // init matchingElements + matchingElements = new ArrayList<View>(); + } + + /** + * Constructor. + * + * @param expression + * @param searchRoots + * @throws LayersException + * If the Condition can't be computed from the expression. + */ + public ExpressionMatcher(String expression, List<EObject> searchRoots) throws LayersException { + this.searchRoots = searchRoots; + matchingElements = new ArrayList<View>(); + + // compute expr + setExpression(expression); + } + + /** + * Constructor. + * + * @param expression + * @param searchRoots + * @throws LayersException + * If the Condition can't be computed from the expression. + */ + public ExpressionMatcher(String expression, List<View> matchingElementsList, List<EObject> searchRoots) throws LayersException { + this.searchRoots = searchRoots; + matchingElements = matchingElementsList; + + // compute expr + setExpression(expression); + } + + /** + * Constructor. + * + * @param expression + * @param searchRoots + * @throws LayersException + * If the Condition can't be computed from the expression. + */ + public ExpressionMatcher(String expression, EObject searchRoot) throws LayersException { + this(expression, Collections.singletonList(searchRoot)); + } + + /** + * Constructor. + * + * @param expression + * @param searchRoots + * @throws LayersException + * If the Condition can't be computed from the expression. + */ + public ExpressionMatcher(String expression, List<View> matchingElementsList, EObject searchRoot) throws LayersException { + this(expression, matchingElementsList, Collections.singletonList(searchRoot)); + } + + /** + * Compute the condition from the expr. + */ + private void computeCondition() throws LayersException { + // silently fails if the expr is not set. + if (getExpression() == null || getExpression().length() == 0) { + return; + } + + if (ocl == null) { + ocl = OCL.newInstance(); + } + // Create the condition + try { + // If the 3rd args is null, this is a context free condition. + + condition = new BooleanOCLCondition<EClassifier, EClass, EObject>( + ocl.getEnvironment(), + // "self.oclIsKindOf(Shape)", + // "self.oclIsKindOf(Shape) and self.oclAsType(Shape).visible = true", + // "self.oclAsType(Shape).visible = true", + getExpression(), + NotationPackage.Literals.VIEW + // null + ); + } catch (ParserException e) { + // TODO Auto-generated catch block + condition = null; + throw new LayersException("Can't parse expression : " + e.getMessage(), e); + } + + } + + /** + * Recompute the matching elements. + * This lead to firing Events (added and removed) + */ + public void refreshMatchingElements() { + + + if (condition == null) { + // If the condition is not set, the list should be empty + if (!getMatchingElements().isEmpty()) { + resetMatchingElements(Collections.EMPTY_LIST); + } + return; + } + + // Create the OCL statement + SELECT statement = new SELECT(SELECT.UNBOUNDED, false, + new FROM(getSearchRoots()), new WHERE(condition), + new NullProgressMonitor()); + + // Execute the OCL statement + IQueryResult results = statement.execute(); + + /** + * Reset the matching elements with the new result. + */ + resetMatchingElements(results); + } + + /** + * Reset the {@link #matchingElements} and let it contain the specified collection. + * This fire added and removed events. + * + * @param results + */ + @SuppressWarnings("unchecked") + private void resetMatchingElements(Collection<?> newElements) { + + Collections3.resetListTo(matchingElements, (Collection<View>) newElements); + // matchingElements.resetTo((Collection<View>)newElements); + + // // Compute views to add + // // This are views in the newElements, but not in the actual list of matchingElement + // // viewsToAdd = results - getViews() + // List<View> viewsToAdd = new ArrayList<View>(); + // for( Object o : newElements ) { + // View v = (View)o; + // if( !getMatchingElements().contains(v)) { + // viewsToAdd.add(v); + // } + // } + // + // // Compute views to remove + // // Their is two ways to compute it: + // // - viewsToremove = diagramViews - results + // // - or viewsToremove = getViews() - result + // // Use the cheaper one. + // // The computed viewsToRemove list contains also views that are not in the layer, + // // But this is cheaper than checking for the existence. + // + // // List<View> viewsToRemove = new ArrayList<View>(); + // // for( View v : (views.size()<getViews().size()?views:getViews()) ) { + // // if( !results.contains(v)) { + // // viewsToRemove.add(v); + // // } + // // } + // + // // Do operations + // getMatchingElements().retainAll(newElements); + // // getViews().removeAll(viewsToRemove); + // getMatchingElements().addAll(viewsToAdd); + + } + + /** + * @return the expression + */ + public String getExpression() { + return expression; + } + + + /** + * @param expression + * the expression to set + * @throws LayersException + * If the Condition can't be computed from the expression. + */ + public void setExpression(String expression) throws LayersException { + + if (expression == null || expression.length() == 0) { + // standardize noop expr + expression = ""; + } + if (expression.equals(this.expression)) { + return; + } + + this.expression = expression; + + computeCondition(); + refreshMatchingElements(); + } + + + /** + * @return the matchingElements + */ + public List<View> getMatchingElements() { + return matchingElements; + } + + + /** + * @return the searchRoots + */ + public List<EObject> getSearchRoots() { + return searchRoots; + } + + /** + * + * @param searchRoots + */ + public void setSearchRoots(List<EObject> searchRoots) { + + // Remove any existing observers + removeSearchRootsObservers(); + + if (searchRoots == null) { + searchRoots = Collections.emptyList(); + } + this.searchRoots = searchRoots; + // add observers on roots changes + addSearchRootsObservers(); + + // Do not refresh. Let user do it. + } + + /** + * + * @param searchRoots + */ + public void setSearchRoots(EObject searchRoot) { + if (searchRoot == null) { + // Remove any existing observers + removeSearchRootsObservers(); + searchRoots = Collections.emptyList(); + return; + } + + setSearchRoots(Collections.singletonList(searchRoot)); + } + + /** + * Observes all searchRoots for changes. If a change occurs, refresh the matching elements. + * + */ + protected void addSearchRootsObservers() { + + if (searchRoots == null) { + return; + } + + + for (EObject root : searchRoots) { + ValueChangedEventNotifier notifier = ValueChangedEventNotifierFactory.instance.adapt(root); + notifier.addEventListener(this); + } + } + + /** + * Observes all searchRoots for changes. If a change occurs, refresh the matching elements. + * + */ + protected void removeSearchRootsObservers() { + + if (searchRoots == null) { + return; + } + + for (EObject root : searchRoots) { + ValueChangedEventNotifier notifier = ValueChangedEventNotifierFactory.instance.adapt(root); + notifier.removeEventListener(this); + } + } + + /** + * Called when a value change in one of the elements of the observed roots. + * + * @param msg + */ + @Override + public void valueChanged(Notification msg) { + refreshMatchingElements(); + } + + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/exprmatcher/IValueChangedEventListener.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/exprmatcher/IValueChangedEventListener.java new file mode 100755 index 0000000..96cfbca --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/exprmatcher/IValueChangedEventListener.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.exprmatcher; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EObject; + + +/** + * Class implementing this interface can listen to event from EObject. + * This class is used by {@link ExpressionMatcher} to be informed when it need to be refreshed. + * + * @author cedric dumoulin + * + */ +public interface IValueChangedEventListener { + + /** + * Called by events when a property is changed in a {@link EObject} + * + * @param msg + */ + public void valueChanged(Notification msg); + + + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/exprmatcher/ValueChangedEventNotifier.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/exprmatcher/ValueChangedEventNotifier.java new file mode 100755 index 0000000..f07f347 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/exprmatcher/ValueChangedEventNotifier.java @@ -0,0 +1,336 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.exprmatcher; + +import static org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.Activator.log; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EContentAdapter; +import org.eclipse.gmf.runtime.notation.Diagram; +import org.eclipse.gmf.runtime.notation.NotationPackage; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStack; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStackApplication; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.notifier.LayersTreeEventNotifier; +import org.eclipse.uml2.uml.NamedElement; +import org.eclipse.uml2.uml.UMLPackage; + + +/** + * An EMF {@link Adapter} listening on uml::NamedElement properties changes. + * + * This class listen to a {@link NamedElement} and send following events to listeners: + * <ul> + * <li>valueChanged</li> + * </ul> + * + * @author cedric dumoulin + * + */ +public class ValueChangedEventNotifier extends EContentAdapter { + + boolean isDisposed = false; + + /** + * List of listener to notify. + */ + protected List<IValueChangedEventListener> listeners = new ArrayList<IValueChangedEventListener>(); + + /** + * Something happen on the tree of object + * + * @see org.eclipse.emf.ecore.util.EContentAdapter#notifyChanged(org.eclipse.emf.common.notify.Notification) + * + * @param msg + */ + @Override + public void notifyChanged(Notification notification) { + + // Self atttach + super.notifyChanged(notification); + + // Take into account the domain hierarchy found from the notation. + + // Now, filter + if (isDiagramRootView(notification)) { + fireValueChangedEvent(notification); + } else if (isUmlDomainElementChanged(notification)) { + fireValueChangedEvent(notification); + } + + + // // We are only interested in NamedElement (from newValue if set, or oldValue if removed) + // Object newValue = notification.getNewValue(); + // if( ! (newValue instanceof NamedElement || notification.getOldValue() instanceof NamedElement ) ) { + // return; + // } + // // Check diagram modification + // // There is 4 sources: View::persistedChildren and View::transientChildren + // // Diagram::persistedChildren and Diagram::transientChildren + // Object feature = notification.getFeature(); + // if( feature == UMLPackage.eINSTANCE.getNamedElement() + // || feature == NotationPackage.eINSTANCE.getView_TransientChildren() + // || feature == NotationPackage.eINSTANCE.getDiagram_PersistedEdges() + // || feature == NotationPackage.eINSTANCE.getDiagram_TransientEdges() ) { + // // LayerOperator::layers || LayersStack::layers + // // check the event type. + // switch(notification.getEventType()) { + // case Notification.SET: + // + // break; + // case Notification.ADD: + // // A view is added + // fireValueChangedEvent(notification); + // break; + // case Notification.REMOVE: + // // A layer is removed + // fireDiagramViewRemovedEvent(notification); + // break; + // } + // } + + }; + + /** + * Return true if the notification indicates a change in a uml element. + * + * @param notification + * @return + */ + private boolean isUmlDomainElementChanged(Notification notification) { + // Notifier should be the diagram + if (!(notification.getNotifier() instanceof NamedElement)) { + return false; + } + + Object feature = notification.getFeature(); + + if (feature == UMLPackage.eINSTANCE.getNamedElement_Name()) { + // check the event type. + switch (notification.getEventType()) { + case Notification.SET: + case Notification.ADD: + case Notification.REMOVE: + + return true; + } + } + return false; + } + + /** + * Return true if the notification indicates that a Diagram root view is modifified. + * + * @param notification + * @return + */ + private boolean isDiagramRootView(Notification notification) { + + // Notifier should be the diagram + if (!(notification.getNotifier() instanceof Diagram)) { + return false; + } + + Object feature = notification.getFeature(); + + if (feature == NotationPackage.eINSTANCE.getView_PersistedChildren() + || feature == NotationPackage.eINSTANCE.getView_TransientChildren() + || feature == NotationPackage.eINSTANCE.getDiagram_PersistedEdges() + || feature == NotationPackage.eINSTANCE.getDiagram_TransientEdges()) { + // LayerOperator::layers || LayersStack::layers + // check the event type. + switch (notification.getEventType()) { + case Notification.SET: + case Notification.ADD: + case Notification.REMOVE: + + return true; + } + } + return false; + } + + /** + * This Adapter is for {@link LayersTreeEventNotifier}. + * + * @see org.eclipse.emf.common.notify.impl.AdapterImpl#isAdapterForType(java.lang.Object) + * + * @param type + * @return + */ + @Override + public boolean isAdapterForType(Object type) { + return type == ValueChangedEventNotifier.class; + } + + /** + * Constructor. + * + * @param layersModel + */ + public ValueChangedEventNotifier() { + } + + /** + * Dispose the synchronizer + */ + public void dispose() { + + if (isDisposed()) { + return; + } + + isDisposed = true; + listeners.clear(); + } + + /** + * Return true if the object is disposed. + * + * @return + */ + public boolean isDisposed() { + return isDisposed == true; + } + + /** + * Add the specified listener to the list of listener. + * Do not add it if the listener is already in the list. + * + * @param listener + */ + public void addEventListener(IValueChangedEventListener listener) { + + if (listener == null) { + return; + } + + // Check if exist + if (listeners.contains(listener)) { + return; + } + + listeners.add(listener); + } + + /** + * Remove the specified listener from the list of listeners. + * + * @param listener + */ + public void removeEventListener(IValueChangedEventListener listener) { + + listeners.remove(listener); + } + + /** + * Called by events when a {@link LayersStack} is added to the {@link LayersStackApplication} + * + * @param msg + */ + protected void fireValueChangedEvent(Notification msg) { + for (IValueChangedEventListener listener : listeners) { + listener.valueChanged(msg); + } + } + + /** + * Handle View::element hierarchy in the self adapt mechanism. + * Handles a notification by calling {@link #handleContainment handleContainment} for any containment-based notification. + */ + @Override + protected void selfAdapt(Notification notification) { + if (log.isDebugEnabled()) { + log.debug(this.getClass().getSimpleName() + ".selfAdapt(" + notification + ")"); + } + + if (notification.getFeature() == NotationPackage.eINSTANCE.getView_Element()) { + handleContainment(notification); + } else { + super.selfAdapt(notification); + } + } + + /** + * Handle View::element hierarchy in the self adapt mechanism. + * + * @see org.eclipse.emf.ecore.util.EContentAdapter#setTarget(org.eclipse.emf.ecore.EObject) + * + * @param target + */ + @Override + protected void setTarget(EObject target) { + if (log.isDebugEnabled()) { + log.debug(this.getClass().getSimpleName() + ".setTarget(" + target + ")"); + } + + // Handle the View::element tree + if (target instanceof View) { + EObject extraTarget = ((View) target).getElement(); + if (extraTarget != null) { + log.info(this.getClass().getSimpleName() + ".setExtraTarget(" + extraTarget + ")"); + // copied from org.eclipse.emf.ecore.util.EContentAdapter.setTarget(EObject) + // basicSetTarget(target); + // Add the extra object + addAdapter(extraTarget); + // Add the content of the extra object + // for (Iterator<? extends Notifier> i = resolve() ? + // extraTarget.eContents().iterator() : + // ((InternalEList<? extends Notifier>)extraTarget.eContents()).basicIterator(); + // i.hasNext(); ) + // { + // Notifier notifier = i.next(); + // addAdapter(notifier); + // } + + } + } + } + + /** + * Handle View::element hierarchy in the self adapt mechanism. + * + * @see org.eclipse.emf.ecore.util.EContentAdapter#unsetTarget(org.eclipse.emf.ecore.EObject) + * + * @param target + */ + @Override + protected void unsetTarget(EObject target) { + // TODO Auto-generated method stub + super.unsetTarget(target); + // Handle the View::element tree + if (target instanceof View) { + EObject extraTarget = ((View) target).getElement(); + if (extraTarget != null) { + // copied from org.eclipse.emf.ecore.util.EContentAdapter.setTarget(EObject) + // basicSetTarget(target); + // Remove the extra object + removeAdapter(extraTarget); + // Remove contents of the extra object + // for (Iterator<? extends Notifier> i = resolve() ? + // extraTarget.eContents().iterator() : + // ((InternalEList<? extends Notifier>)extraTarget.eContents()).basicIterator(); + // i.hasNext(); ) + // { + // Notifier notifier = i.next(); + // removeAdapter(notifier); + // } + + } + } + } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/exprmatcher/ValueChangedEventNotifierFactory.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/exprmatcher/ValueChangedEventNotifierFactory.java new file mode 100755 index 0000000..fb0f66c --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/exprmatcher/ValueChangedEventNotifierFactory.java @@ -0,0 +1,70 @@ +/***************************************************************************** + * Copyright (c) 2013 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.internal.infra.gmfdiag.layers.model.exprmatcher; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStack; + +/** + * Factory used to create a {@link ValueChangedEventNotifier}. + * The factory ensures that there is only one Notifier for a given {@link LayersStack}. + * + * @author cedric dumoulin + * + */ +public class ValueChangedEventNotifierFactory extends AdapterFactoryImpl { + + /** + * Global factory. + */ + static public ValueChangedEventNotifierFactory instance = new ValueChangedEventNotifierFactory(); + + /** + * Convenience method. + * + * @param target + * @return + */ + public ValueChangedEventNotifier adapt(Notifier target) { + return (ValueChangedEventNotifier) adapt(target, ValueChangedEventNotifier.class); + } + + /** + * + * @see org.eclipse.emf.common.notify.impl.AdapterFactoryImpl#createAdapter(org.eclipse.emf.common.notify.Notifier) + * + * @param target + * @return + */ + @Override + protected Adapter createAdapter(Notifier target) { + return new ValueChangedEventNotifier(); + } + + /** + * This Factory is for {@link ValueChangedEventNotifier}. + * + * @see org.eclipse.emf.common.notify.impl.AdapterFactoryImpl#isFactoryForType(java.lang.Object) + * + * @param type + * @return + */ + @Override + public boolean isFactoryForType(Object type) { + return type == ValueChangedEventNotifier.class; + } +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/layers/loaders/ILayerOperatorDescriptorRegistryLoader.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/layers/loaders/ILayerOperatorDescriptorRegistryLoader.java new file mode 100755 index 0000000..69a6805 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/layers/loaders/ILayerOperatorDescriptorRegistryLoader.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.loaders; + +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerOperatorDescriptorRegistry; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.PropertyRegistry; + + +/** + * Interface that a {@link LayerOperatorDescriptorRegistry} loader should implements. + * + * @author cedric dumoulin + * + */ +public interface ILayerOperatorDescriptorRegistryLoader { + + /** + * Load the specified registry. Initialize its Descriptors and its Operators. + * + * @param layerOperatorDescriptorRegistry + * @param propertyRegistry + */ + public void loadLayerOperatorDescriptorRegistry(LayerOperatorDescriptorRegistry descriptorRegistry, PropertyRegistry propertyRegistry); + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/layers/loaders/LayerOperatorDescriptorRegistryLoader.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/layers/loaders/LayerOperatorDescriptorRegistryLoader.java new file mode 100755 index 0000000..9f5522c --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/layers/loaders/LayerOperatorDescriptorRegistryLoader.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.loaders; + +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.NotFoundException; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.CustomPropertyOperator; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerOperatorDescriptor; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerOperatorDescriptorRegistry; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersFactory; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.PropertyRegistry; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.operators.BooleanAndOperator; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.operators.BooleanOrOperator; + + +/** + * Class used to load a {@link LayerOperatorDescriptorRegistry}. + * + * @author cedric dumoulin + * + * @deprecated use {@link RegistriesLoader} instead. + * + */ +@Deprecated +public class LayerOperatorDescriptorRegistryLoader implements ILayerOperatorDescriptorRegistryLoader { + + /** + * Load the specified registry. Initialize its Descriptors and its Operators. + * + * @param layerOperatorDescriptorRegistry + * @param propertyRegistry + */ + public void loadRegistryOld(LayerOperatorDescriptorRegistry descriptorRegistry, PropertyRegistry propertyRegistry) { + + // Custom operator declarations + // operatorName, operatorImplementationClass + String[] operatorDeclarations = new String[] { + "booleanOr", BooleanOrOperator.class.getName(), + "booleanAnd", BooleanAndOperator.class.getName(), + + }; + + // Load operators + for (int i = 0; i < operatorDeclarations.length; i += 2) { + CustomPropertyOperator operator = LayersFactory.eINSTANCE.createCustomPropertyOperator(); + operator.setName(operatorDeclarations[i]); + operator.setClassname(operatorDeclarations[i + 1]); + descriptorRegistry.addPropertyOperator(operator); + } + + // AndLayerStackOperatorDescriptor + // propertyName, operatorName + String[] andDescriptorDeclarations = new String[] { + "isVisible", "booleanAnd", + }; + + LayerOperatorDescriptor andDescriptor = LayersFactory.eINSTANCE.createAndStackedLayerOperatorDescriptor(); + descriptorRegistry.addLayerOperatorDescriptor(andDescriptor); + + // attach operator to layer and property + String descriptorName = andDescriptor.getName(); + for (int i = 0; i < andDescriptorDeclarations.length; i += 2) { + try { + descriptorRegistry.attachOperatorToDescriptor(propertyRegistry.getProperty(andDescriptorDeclarations[i]), andDescriptorDeclarations[i + 1], descriptorName); + } catch (NotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + // OrLayerStackOperatorDescriptor + // propertyName, operatorName + String[] orDescriptorDeclarations = new String[] { + "isVisible", "booleanOr", + }; + + LayerOperatorDescriptor orDescriptor = LayersFactory.eINSTANCE.createOrStackedLayerOperatorDescriptor(); + descriptorRegistry.addLayerOperatorDescriptor(orDescriptor); + + // attach operator to layer and property + descriptorName = orDescriptor.getName(); + for (int i = 0; i < orDescriptorDeclarations.length; i += 2) { + try { + descriptorRegistry.attachOperatorToDescriptor(propertyRegistry.getProperty(orDescriptorDeclarations[i]), orDescriptorDeclarations[i + 1], descriptorName); + } catch (NotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + /** + * @see org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.loaders.ILayerOperatorDescriptorRegistryLoader#loadLayerOperatorDescriptorRegistry(org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerOperatorDescriptorRegistry, + * org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.PropertyRegistry) + * + * @param descriptorRegistry + * @param propertyRegistry + */ + @Override + public void loadLayerOperatorDescriptorRegistry(LayerOperatorDescriptorRegistry descriptorRegistry, PropertyRegistry propertyRegistry) { + + createLayersConfigModel(); + + } + + /** + * Create a Model + */ + private void createLayersConfigModel() { + // TODO Auto-generated method stub + + } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/layers/loaders/LayersConfigModel.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/layers/loaders/LayersConfigModel.java new file mode 100755 index 0000000..8ec211a --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/layers/loaders/LayersConfigModel.java @@ -0,0 +1,259 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.loaders; + +import static org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.loaders.LayersConfigModelUtils.createFolder; +import static org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.loaders.LayersConfigModelUtils.createLayerOperatorConfig; +import static org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.loaders.LayersConfigModelUtils.createLayerOperatorsMultipleBinding; +import static org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.loaders.LayersConfigModelUtils.createOperatorBinding; +import static org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.loaders.LayersConfigModelUtils.createPropertyId; +import static org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.loaders.LayersConfigModelUtils.createPropertyOperatorConfig; +import static org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.loaders.LayersConfigModelUtils.createTypeConfig; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.common.util.TreeIterator; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersPackage; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.operators.BooleanAndOperator; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.operators.BooleanOrOperator; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.operators.FillAverageOperator; +import org.eclipse.papyrus.layers.configmodel.layersconfig.Folder; +import org.eclipse.papyrus.layers.configmodel.layersconfig.LayerOperatorConfig; +import org.eclipse.papyrus.layers.configmodel.layersconfig.LayerOperatorMultipleBinding; +import org.eclipse.papyrus.layers.configmodel.layersconfig.LayersconfigFactory; +import org.eclipse.papyrus.layers.configmodel.layersconfig.OperatorBinding; +import org.eclipse.papyrus.layers.configmodel.layersconfig.OperatorConfig; +import org.eclipse.papyrus.layers.configmodel.layersconfig.PropertyId; +import org.eclipse.papyrus.layers.configmodel.layersconfig.TypeConfig; + + +/** + * This class encapsulate an LayersConfig model. + * It provides a default instance initialized with a model. + * + * @author cedric dumoulin + * + */ +public class LayersConfigModel { + + /** + * The default instance used by all applications. + */ + static final protected LayersConfigModel instance; + + protected Resource resource; + + + + /** + * Create and initialize default instance. + */ + static { + instance = new LayersConfigModel(); + instance.initDefaultModel(); + } + + /** + * Constructor. + * + */ + public LayersConfigModel() { + createResourceAndRootFolder(); + } + + + /** + * @return the instance + */ + public static LayersConfigModel getInstance() { + return instance; + } + + /** + * Init the object with a default model. + */ + private void initDefaultModel() { + // Create model + Folder layeropFolder = createFolder(getRootFolder(), "layerOp"); + + LayerOperatorConfig stackedLayersOperatorConfig = createLayerOperatorConfig(layeropFolder, "stackedLayersOperator", LayersPackage.eINSTANCE.getStackedLayerOperatorDescriptor().getName()); + LayerOperatorConfig stackedLayersOperatorMinimunConfig = createLayerOperatorConfig(layeropFolder, "stackedLayersOperatorMinimum", LayersPackage.eINSTANCE.getStackedLayerOperatorDescriptor().getName()); + createLayerOperatorConfig(layeropFolder, "stackedLayersOperatorMaximum", LayersPackage.eINSTANCE.getStackedLayerOperatorDescriptor().getName()); + LayerOperatorConfig stackedLayersOperatorAverage = createLayerOperatorConfig(layeropFolder, "stackedLayersOperatorAverage", LayersPackage.eINSTANCE.getStackedLayerOperatorDescriptor().getName()); + + // Create Operators + Folder operatorFolder = createFolder(getRootFolder(), "operatorDesc"); + OperatorConfig operatorBooleanAnd = createPropertyOperatorConfig(operatorFolder, "operatorBooleanAnd", BooleanAndOperator.class.getName()); + OperatorConfig operatorBooleanOr = createPropertyOperatorConfig(operatorFolder, "operatorBooleanOr", BooleanOrOperator.class.getName()); + OperatorConfig operatorFillAverage = createPropertyOperatorConfig(operatorFolder, "operatorFillAverage", FillAverageOperator.class.getName()); + + + // Create basic types + Folder typeFolder = createFolder(getRootFolder(), "types"); + TypeConfig typeBoolean = createTypeConfig(typeFolder, "boolean"); + TypeConfig typeInt = createTypeConfig(typeFolder, "int"); + TypeConfig typeString = createTypeConfig(typeFolder, "String"); + TypeConfig typeFont = createTypeConfig(typeFolder, "Font"); + TypeConfig typeColor = createTypeConfig(typeFolder, "Color"); + TypeConfig typeFill = createTypeConfig(typeFolder, "Fill"); + TypeConfig typeLine = createTypeConfig(typeFolder, "Line"); + + // Create properties + Folder propertiesFolder = createFolder(getRootFolder(), "properties"); + // PropertyId propertyIsVisible = createPropertyId(propertiesFolder, "isVisible", typeBoolean); + // PropertyId propertyIsAbstract = createPropertyId(propertiesFolder, "isAbstract", typeBoolean); + // PropertyId propertyFill = createPropertyId(propertiesFolder, "fill", typeFill); + PropertyId propertyLine = createPropertyId(propertiesFolder, "line", typeLine); + PropertyId propertyFont = createPropertyId(propertiesFolder, "font", typeFont); + PropertyId propertyBgcolor = createPropertyId(propertiesFolder, "bgcolor", typeColor); + PropertyId propertyFgcolor = createPropertyId(propertiesFolder, "fgcolor", typeColor); + + PropertyId propertyCSS = createPropertyId(propertiesFolder, "css", typeString); + + // Bind operators to layers + Folder opBindingFolder = createFolder(getRootFolder(), "opBindings"); + + LayerOperatorMultipleBinding layerOpBindingsA = createLayerOperatorsMultipleBinding(opBindingFolder, stackedLayersOperatorConfig); + // createOperatorBinding(layerOpBindingsA, propertyIsVisible, operatorBooleanAnd); + // createOperatorBinding(layerOpBindingsA, propertyIsAbstract, operatorBooleanAnd); + // createOperatorBinding(layerOpBindingsA, propertyFill, operatorFillAverage); + + LayerOperatorMultipleBinding layerOpBindingsB = createLayerOperatorsMultipleBinding(opBindingFolder, stackedLayersOperatorMinimunConfig); + // createOperatorBinding(layerOpBindingsB, propertyIsVisible, operatorBooleanOr); + // createOperatorBinding(layerOpBindingsB, propertyIsAbstract, operatorBooleanOr); + // createOperatorBinding(layerOpBindingsB, propertyFill, operatorFillAverage); + + LayerOperatorMultipleBinding layerOpBindingsAverage = createLayerOperatorsMultipleBinding(opBindingFolder, stackedLayersOperatorAverage); + // createOperatorBinding(layerOpBindingsAverage, propertyIsVisible, operatorBooleanOr); + // createOperatorBinding(layerOpBindingsAverage, propertyIsAbstract, operatorBooleanOr); + // createOperatorBinding(layerOpBindingsAverage, propertyFill, operatorFillAverage); + + } + + /** + * Create the resource and add it the root folder. + * + * @return + */ + protected Folder createResourceAndRootFolder() { + // Create a resource set. + ResourceSet resourceSet = new ResourceSetImpl(); + + // Register the default resource factory -- only needed for stand-alone! + resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put( + Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl()); + + // Get the URI of the model file. + URI fileURI = URI.createURI("config.layersconfig"); + + // Create a resource for this file. + resource = resourceSet.createResource(fileURI); + Folder parent = LayersconfigFactory.eINSTANCE.createFolder(); + resource.getContents().add(parent); + return parent; + } + + + /** + * @return the resource + */ + public Resource getResource() { + return resource; + } + + /** + * Get the root folder of the model. + * There is always a root folder + * + * @return + */ + public Folder getRootFolder() { + return (Folder) getResource().getContents().get(0); + } + + /** + * Get all {@link LayerOperatorConfig} contained in the model. + * + * @return + */ + public List<LayerOperatorConfig> getAllLayerOperatorConfig() { + + List<LayerOperatorConfig> res = new ArrayList<LayerOperatorConfig>(); + + TreeIterator<EObject> iter = resource.getAllContents(); + while (iter.hasNext()) { + EObject obj = iter.next(); + if (obj instanceof LayerOperatorConfig) { + res.add((LayerOperatorConfig) obj); + } + } + return res; + } + + /** + * Get all object of the specified type contained in the model. + * + * @param type + * The expected type for objects + * + * @return A list of object with the specified type. + */ + @SuppressWarnings("unchecked") + public <T extends EObject> List<T> getAllOfType(Class<T> type) { + List<T> res = new ArrayList<T>(); + + TreeIterator<EObject> iter = resource.getAllContents(); + while (iter.hasNext()) { + EObject obj = iter.next(); + if (type.isInstance(obj)) { + res.add((T) obj); + } + } + return res; + } + + /** + * Get all operators config objects. + * + * @return + */ + public List<OperatorConfig> getAllOperatorConfig() { + + return getAllOfType(OperatorConfig.class); + } + + + /** + * Get all {@link OperatorBinding} declared in the model. + * + * @return + */ + public List<OperatorBinding> getAllOperatorBinding() { + return getAllOfType(OperatorBinding.class); + } + + + /** + * Initialize the provided model with some defs for tests. + * + * @param model + */ + private void initLayersConfigModel(LayersConfigModel model) { + + } +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/layers/loaders/LayersConfigModelUtils.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/layers/loaders/LayersConfigModelUtils.java new file mode 100755 index 0000000..e2032f3 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/layers/loaders/LayersConfigModelUtils.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.loaders; + +import org.eclipse.papyrus.layers.configmodel.layersconfig.Folder; +import org.eclipse.papyrus.layers.configmodel.layersconfig.LayerOperatorConfig; +import org.eclipse.papyrus.layers.configmodel.layersconfig.LayerOperatorMultipleBinding; +import org.eclipse.papyrus.layers.configmodel.layersconfig.LayersconfigFactory; +import org.eclipse.papyrus.layers.configmodel.layersconfig.OperatorBinding; +import org.eclipse.papyrus.layers.configmodel.layersconfig.OperatorConfig; +import org.eclipse.papyrus.layers.configmodel.layersconfig.PropertyId; +import org.eclipse.papyrus.layers.configmodel.layersconfig.TypeConfig; + + +/** + * Set of utility methods to create elements in a {@link LayersConfigModel}. + * + * @author cedric dumoulin + * + */ +public class LayersConfigModelUtils { + + /** + * Create a {@link Folder} element + * + * @param parent + * @param name + * @return + */ + static public Folder createFolder(Folder parent, String name) { + Folder folder = LayersconfigFactory.eINSTANCE.createFolder(); + folder.setName(name); + parent.getFolderElements().add(folder); + return folder; + } + + /** + * Create a {@link LayerOperatorConfig} element + * + * @param parent + * @param ID + * @param classname + * @return + */ + static public LayerOperatorConfig createLayerOperatorConfig(Folder parent, String ID, String classname) { + LayerOperatorConfig config = LayersconfigFactory.eINSTANCE.createLayerOperatorConfig(); + config.setName(ID); + config.setClassname(classname); + parent.getFolderElements().add(config); + return config; + } + + /** + * Create a {@link OperatorConfig} element + * + * @param parent + * @param ID + * @param classname + * @return + */ + static public OperatorConfig createPropertyOperatorConfig(Folder parent, String ID, String classname) { + OperatorConfig config = LayersconfigFactory.eINSTANCE.createOperatorConfig(); + config.setName(ID); + config.setClassname(classname); + parent.getFolderElements().add(config); + return config; + } + + /** + * + * @param owner + * @param layerOperator + * @return + */ + static public LayerOperatorMultipleBinding createLayerOperatorsMultipleBinding(Folder owner, LayerOperatorConfig layerOperator) { + LayerOperatorMultipleBinding config = LayersconfigFactory.eINSTANCE.createLayerOperatorMultipleBinding(); + config.setLayerOperatorConfig(layerOperator); + owner.getFolderElements().add(config); + return config; + } + + static public OperatorBinding createOperatorBinding(LayerOperatorMultipleBinding owner, PropertyId propertyId, OperatorConfig operatorConfig) { + OperatorBinding binding = LayersconfigFactory.eINSTANCE.createOperatorBinding(); + binding.setPropertyId(propertyId); + binding.setOperator(operatorConfig); + binding.setOwner(owner); + return binding; + } + + static public PropertyId createPropertyId(Folder parent, String ID, TypeConfig type) { + PropertyId propertyId = LayersconfigFactory.eINSTANCE.createPropertyId(); + propertyId.setName(ID); + propertyId.setType(type); + parent.getFolderElements().add(propertyId); + return propertyId; + } + + static public TypeConfig createTypeConfig(Folder parent, String ID) { + TypeConfig config = LayersconfigFactory.eINSTANCE.createTypeConfig(); + config.setName(ID); + parent.getFolderElements().add(config); + return config; + } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/layers/loaders/RegistriesLoader.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/layers/loaders/RegistriesLoader.java new file mode 100755 index 0000000..50c9bd1 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/layers/loaders/RegistriesLoader.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.loaders; + +import static org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.Activator.log; + +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.InstanciationException; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.NotFoundException; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerOperatorDescriptor; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerOperatorDescriptorRegistry; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.Property; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.PropertyOperator; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.PropertyRegistry; +import org.eclipse.papyrus.layers.configmodel.layersconfig.LayerOperatorConfig; +import org.eclipse.papyrus.layers.configmodel.layersconfig.OperatorBinding; +import org.eclipse.papyrus.layers.configmodel.layersconfig.OperatorConfig; + + +/** + * A loader used to load various Registries from a unique {@link LayersConfigModel}. + * + * @author cedric dumoulin + * + */ +public class RegistriesLoader implements ILayerOperatorDescriptorRegistryLoader { + + /** + * The model used to load the registries. + * + */ + protected LayersConfigModel model; + + /** + * Constructor. + * + * @param model + */ + public RegistriesLoader(LayersConfigModel model) { + this.model = model; + } + + /** + * Load the {@link LayerOperatorDescriptorRegistry} from the {@link LayersConfigModel}. + * + * @see org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.loaders.ILayerOperatorDescriptorRegistryLoader#loadLayerOperatorDescriptorRegistry(org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerOperatorDescriptorRegistry, + * org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.PropertyRegistry) + * + * @param descriptorRegistry + * @param propertyRegistry + */ + @Override + public void loadLayerOperatorDescriptorRegistry(LayerOperatorDescriptorRegistry descriptorRegistry, PropertyRegistry propertyRegistry) { + + // Load LayerOperators + for (LayerOperatorConfig layerOperatorConfig : model.getAllLayerOperatorConfig()) { + try { + LayerOperatorDescriptor descriptor = layerOperatorConfig.createLayersOperatorDescriptor(); + descriptorRegistry.addLayerOperatorDescriptor(descriptor); + } catch (InstanciationException e) { + log.error("LOG - " + this.getClass().getName() + " - " + e.getMessage(), e); + } + } + + // Load operators + for (OperatorConfig operatorConfig : model.getAllOperatorConfig()) { + try { + PropertyOperator operator = operatorConfig.createOperatorDescriptor(); + descriptorRegistry.addPropertyOperator(operator); + } catch (InstanciationException e) { + log.error("LOG - " + this.getClass().getName() + " - " + e.getMessage(), e); + } + + } + + // Populate LayerOperator with operators + for (OperatorBinding binding : model.getAllOperatorBinding()) { + try { + System.err.println("binding.getPropertyId().getName(): " + binding.getPropertyId().getName()); + Property property = propertyRegistry.getProperty(binding.getPropertyId().getName()); + String layerDescriptorName = binding.getLayerOperatorConfig().getName(); + String operatorName = binding.getOperator().getName(); + descriptorRegistry.attachOperatorToDescriptor(property, operatorName, layerDescriptorName); + } catch (NotFoundException e) { + log.error("LOG - " + this.getClass().getName() + " - " + e.getMessage(), e); + } + + } + + } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/DiagramViewChangedEventNotifier.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/DiagramViewChangedEventNotifier.java new file mode 100755 index 0000000..171c3ce --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/DiagramViewChangedEventNotifier.java @@ -0,0 +1,208 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.notifier; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.util.EContentAdapter; +import org.eclipse.gmf.runtime.notation.Diagram; +import org.eclipse.gmf.runtime.notation.NotationPackage; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStack; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStackApplication; + + +/** + * An EMF {@link Adapter} listening on notation::diagram::view added and removed. + * + * This class listen to a {@link Diagram} and send following events to listeners: + * <ul> + * <li>view removed</li> + * <li>view added</li> + * </ul> + * + * @author cedric dumoulin + * + */ +public class DiagramViewChangedEventNotifier extends EContentAdapter { + + boolean isDisposed = false; + + /** + * List of listener to notify. + */ + protected List<IDiagramViewEventListener> listeners = new ArrayList<IDiagramViewEventListener>(); + + /** + * Something happen on the tree of object + * + * @see org.eclipse.emf.ecore.util.EContentAdapter#notifyChanged(org.eclipse.emf.common.notify.Notification) + * + * @param msg + */ + @Override + public void notifyChanged(Notification notification) { + + // Self atttach + super.notifyChanged(notification); + + // We are only interested in views (from newValue if set, or oldValue if removed) + // TODO Use an appropriate filter / Predicate to filter views. + Object newValue = notification.getNewValue(); + if (!(newValue instanceof View || notification.getOldValue() instanceof View)) { + return; + } + // Check diagram modification + // There is 4 sources: View::persistedChildren and View::transientChildren + // Diagram::persistedChildren and Diagram::transientChildren + Object feature = notification.getFeature(); + if (feature == NotationPackage.eINSTANCE.getView_PersistedChildren() + || feature == NotationPackage.eINSTANCE.getView_TransientChildren() + || feature == NotationPackage.eINSTANCE.getDiagram_PersistedEdges() + || feature == NotationPackage.eINSTANCE.getDiagram_TransientEdges()) { + // LayerOperator::layers || LayersStack::layers + // check the event type. + switch (notification.getEventType()) { + case Notification.SET: + + break; + case Notification.ADD: + // A view is added + fireDiagramViewAddedEvent(notification); + break; + case Notification.REMOVE: + // A layer is removed + fireDiagramViewRemovedEvent(notification); + break; + } + } + + }; + + /** + * This Adapter is for {@link LayersTreeEventNotifier}. + * + * @see org.eclipse.emf.common.notify.impl.AdapterImpl#isAdapterForType(java.lang.Object) + * + * @param type + * @return + */ + @Override + public boolean isAdapterForType(Object type) { + return type == DiagramViewChangedEventNotifier.class; + } + + /** + * Constructor. + * + * @param layersModel + */ + public DiagramViewChangedEventNotifier() { + } + + /** + * Dispose the synchronizer + */ + public void dispose() { + + if (isDisposed()) { + return; + } + + isDisposed = true; + listeners.clear(); + } + + /** + * Return true if the object is disposed. + * + * @return + */ + public boolean isDisposed() { + return isDisposed == true; + } + + /** + * Add the specified listener to the list of listener. + * Do not add it if the listener is already in the list. + * + * @param listener + */ + public void addEventListener(IDiagramViewEventListener listener) { + + if (listener == null) { + return; + } + + // Check if exist + if (listeners.contains(listener)) { + return; + } + + listeners.add(listener); + } + + /** + * Remove the specified listener from the list of listeners. + * + * @param listener + */ + public void removeEventListener(IDiagramViewEventListener listener) { + + listeners.remove(listener); + } + + /** + * Called by events when a {@link LayersStack} is added to the {@link LayersStackApplication} + * + * @param msg + */ + protected void fireDiagramViewAddedEvent(Notification msg) { + for (IDiagramViewEventListener listener : listeners) { + listener.diagramViewAdded(msg); + } + } + + /** + * Called by events when a {@link LayersStack} is added to the {@link LayersStackApplication} + * + * @param msg + */ + protected void fireDiagramViewRemovedEvent(Notification msg) { + for (IDiagramViewEventListener listener : listeners) { + listener.diagramViewRemoved(msg); + } + } + + /** + * Get the removed diagram in case of diagramRemoved event + * + * @param msg + * @return + */ + public static View viewAddedEvent_getAddedView(Notification msg) { + return (View) msg.getNewValue(); + } + + /** + * Get the removed diagram in case of diagramRemoved event + * + * @param msg + * @return + */ + public static View viewAddedEvent_getRemovedView(Notification msg) { + return (View) msg.getOldValue(); + } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/DiagramViewChangedEventNotifierFactory.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/DiagramViewChangedEventNotifierFactory.java new file mode 100755 index 0000000..1f987ea --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/DiagramViewChangedEventNotifierFactory.java @@ -0,0 +1,70 @@ +/***************************************************************************** + * Copyright (c) 2013 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.internal.infra.gmfdiag.layers.model.notifier; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStack; + +/** + * Factory used to create a {@link DiagramViewChangedEventNotifier}. + * The factory ensures that there is only one Notifier for a given {@link LayersStack}. + * + * @author cedric dumoulin + * + */ +public class DiagramViewChangedEventNotifierFactory extends AdapterFactoryImpl { + + /** + * Global factory. + */ + static public DiagramViewChangedEventNotifierFactory instance = new DiagramViewChangedEventNotifierFactory(); + + /** + * Convenience method. + * + * @param target + * @return + */ + public DiagramViewChangedEventNotifier adapt(Notifier target) { + return (DiagramViewChangedEventNotifier) adapt(target, DiagramViewChangedEventNotifier.class); + } + + /** + * + * @see org.eclipse.emf.common.notify.impl.AdapterFactoryImpl#createAdapter(org.eclipse.emf.common.notify.Notifier) + * + * @param target + * @return + */ + @Override + protected Adapter createAdapter(Notifier target) { + return new DiagramViewChangedEventNotifier(); + } + + /** + * This Factory is for {@link DiagramViewChangedEventNotifier}. + * + * @see org.eclipse.emf.common.notify.impl.AdapterFactoryImpl#isFactoryForType(java.lang.Object) + * + * @param type + * @return + */ + @Override + public boolean isFactoryForType(Object type) { + return type == DiagramViewChangedEventNotifier.class; + } +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/DiagramViewEventNotifier.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/DiagramViewEventNotifier.java new file mode 100755 index 0000000..497dd16 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/DiagramViewEventNotifier.java @@ -0,0 +1,211 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.notifier; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.util.EContentAdapter; +import org.eclipse.gmf.runtime.notation.Diagram; +import org.eclipse.gmf.runtime.notation.NotationPackage; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStack; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStackApplication; + + +/** + * This class listen to a {@link Diagram} and send following events to listeners: + * <ul> + * <li>view removed</li> + * <li>view added</li> + * </ul> + * + * @author cedric dumoulin + * @deprecated use {@link DiagramViewChangedEventNotifier} instead. + */ +@Deprecated +public class DiagramViewEventNotifier { + + protected Diagram diagram; + + /** + * List of listener to notify. + */ + protected List<IDiagramViewEventListener> listeners = new ArrayList<IDiagramViewEventListener>(); + + protected Adapter diagramViewListener = new EContentAdapter() { + + /** + * Something happen on the tree of object + * + * @see org.eclipse.emf.ecore.util.EContentAdapter#notifyChanged(org.eclipse.emf.common.notify.Notification) + * + * @param msg + */ + @Override + public void notifyChanged(Notification notification) { + + // Self atttach + super.notifyChanged(notification); + + // We are only interested in views (from newValue if set, or oldValue if removed) + Object newValue = notification.getNewValue(); + if (!(newValue instanceof View || notification.getOldValue() instanceof View)) { + return; + } + // Check diagram modification + // There is 4 sources: View::persistedChildren and View::transientChildren + // Diagram::persistedChildren and Diagram::transientChildren + Object feature = notification.getFeature(); + if (feature == NotationPackage.eINSTANCE.getView_PersistedChildren() + || feature == NotationPackage.eINSTANCE.getView_TransientChildren() + || feature == NotationPackage.eINSTANCE.getDiagram_PersistedEdges() + || feature == NotationPackage.eINSTANCE.getDiagram_TransientEdges()) { + // LayerOperator::layers || LayersStack::layers + // check the event type. + switch (notification.getEventType()) { + case Notification.SET: + + break; + case Notification.ADD: + // A view is added + fireDiagramViewAddedEvent(notification); + break; + case Notification.REMOVE: + // A layer is removed + fireDiagramViewRemovedEvent(notification); + break; + } + } + } + + }; + + /** + * Constructor. + * + * @param layersModel + */ + public DiagramViewEventNotifier(Diagram diagram) { + this.diagram = diagram; + activate(); + } + + /** + * Activate the listeners. + * + */ + protected void activate() { + // Listen on diagram removed events + diagram.eAdapters().add(diagramViewListener); + } + + /** + * Deactivate listeners + */ + protected void deactivate() { + // Listen on diagram removed events + diagram.eAdapters().remove(diagramViewListener); + } + + /** + * Dispose the synchronizer + */ + public void dispose() { + // Deactivate listeners + deactivate(); + diagram = null; + } + + /** + * Return true if the object is disposed. + * + * @return + */ + public boolean isDisposed() { + return diagram == null; + } + + /** + * Add the specified listener to the list of listener. + * Do not add it if the listener is already in the list. + * + * @param listener + */ + public void addEventListener(IDiagramViewEventListener listener) { + + if (listener == null) { + return; + } + + // Check if exist + if (listeners.contains(listener)) { + return; + } + + listeners.add(listener); + } + + /** + * Remove the specified listener from the list of listeners. + * + * @param listener + */ + public void removeEventListener(IDiagramViewEventListener listener) { + + listeners.remove(listener); + } + + /** + * Called by events when a {@link LayersStack} is added to the {@link LayersStackApplication} + * + * @param msg + */ + protected void fireDiagramViewAddedEvent(Notification msg) { + for (IDiagramViewEventListener listener : listeners) { + listener.diagramViewAdded(msg); + } + } + + /** + * Called by events when a {@link LayersStack} is added to the {@link LayersStackApplication} + * + * @param msg + */ + protected void fireDiagramViewRemovedEvent(Notification msg) { + for (IDiagramViewEventListener listener : listeners) { + listener.diagramViewRemoved(msg); + } + } + + /** + * Get the removed diagram in case of diagramRemoved event + * + * @param msg + * @return + */ + public static View viewAddedEvent_getAddedView(Notification msg) { + return (View) msg.getNewValue(); + } + + /** + * Get the removed diagram in case of diagramRemoved event + * + * @param msg + * @return + */ + public static View viewAddedEvent_getRemovedView(Notification msg) { + return (View) msg.getOldValue(); + } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/IDiagramViewEventListener.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/IDiagramViewEventListener.java new file mode 100755 index 0000000..338d513 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/IDiagramViewEventListener.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.notifier; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.gmf.runtime.notation.Diagram; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStackApplication; + + +/** + * Class implementing this interface can listen to event from a {@link LayersStackApplication}. + * + * @author cedric dumoulin + * + */ +public interface IDiagramViewEventListener { + + /** + * Called by events when a {@link View} is added to the {@link Diagram} or one of its contained + * elements. + * + * @param msg + */ + public void diagramViewAdded(Notification msg); + + /** + * Called by events when a {@link View} is removed from the {@link Diagram} or one of its contained + * elements. + * + * @param msg + */ + public void diagramViewRemoved(Notification msg); + + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/ILayersTreeEventListener.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/ILayersTreeEventListener.java new file mode 100755 index 0000000..116f048 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/ILayersTreeEventListener.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.notifier; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerOperator; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStack; + + +/** + * Class implementing this interface can listen to event from a {@link LayersStack}. + * Interface for listeners whising to be informed of change in the Tree of Layers structure. <br> + * Listeners of such events should register themself to the notifier {@link LayersTreeEventNotifier}. <br> + * The following events are fired: + * <ul> + * <li>LayerAdded</li> + * <li>LayerRemoved</li> + * <li>LayerMoved</li> + * <li>LayerSet</li> + * </ul> + * + * @author cedric dumoulin + * + */ +public interface ILayersTreeEventListener { + + /** + * Method called when a layer is added to one layer. + * The event contains: the layer. + * + * @param notification + */ + public void layerAdded(Notification notification); + + /** + * Method called when a layer is removed from one layer. + * The event contains: the layer. + * + * @param notification + */ + public void layerRemoved(Notification notification); + + /** + * Method called when a layer is moved inside a {@link LayerOperator}. + * The event contains: the layer. + * + * @param notification + */ + public void layerMoved(Notification notification); + + /** + * Method called when a layer is set. + * The event contains: the layer. + * + * @param notification + */ + public void layerSet(Notification notification); + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/IUmlNamedElementChangedEventListener.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/IUmlNamedElementChangedEventListener.java new file mode 100755 index 0000000..41c11e3 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/IUmlNamedElementChangedEventListener.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.notifier; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.uml2.uml.NamedElement; + + +/** + * Class implementing this interface can listen to event from a {@link NamedElement}. + * + * @author cedric dumoulin + * + */ +public interface IUmlNamedElementChangedEventListener { + + /** + * Called by events when a property is changed in a {@link NamedElement} + * + * @param msg + */ + public void valueChanged(Notification msg); + + + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/LayersTreeEventNotifier.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/LayersTreeEventNotifier.java new file mode 100755 index 0000000..59df8ac --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/LayersTreeEventNotifier.java @@ -0,0 +1,207 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.notifier; + +import static org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.Activator.log; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.util.EContentAdapter; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersPackage; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStack; + + +/** + * Notifier/observers firing events concerning the structure of the tree of layers. + * Obeserver should implements {@link ILayersTreeEventListener} and register themself to this + * notifier. + * + * + * @author cedric dumoulin + * + */ +public class LayersTreeEventNotifier extends EContentAdapter { + + /** + * List of listener to notify. + */ + protected List<ILayersTreeEventListener> listeners = new ArrayList<ILayersTreeEventListener>(); + + /** + * Constructor. + * + * @param layersStack + * The observed {@link LayersStack}. + */ + public LayersTreeEventNotifier() { + } + + /** + * Dispose this object. + */ + public void dispose() { + if (isDisposed()) { + return; + } + listeners.clear(); + listeners = null; + } + + /** + * Return true if the object is disposed. + * + * @return + */ + public boolean isDisposed() { + return listeners == null; + } + + /** + * Called when something happen on the tree. + * + * @see org.eclipse.emf.ecore.util.EContentAdapter#notifyChanged(org.eclipse.emf.common.notify.Notification) + * + * @param notification + */ + @Override + public void notifyChanged(Notification notification) { + if (log.isDebugEnabled()) { + log.debug(this.getClass().getSimpleName() + ".notifyChanged( " + + notification.getFeature() + ")"); + } + + // Self atttach + super.notifyChanged(notification); + + // Check layers modification + // There is two sources: LayerOperator::layers and LayersStack::layers + if (notification.getFeature() == LayersPackage.eINSTANCE.getLayerOperator_Layers() + || notification.getFeature() == LayersPackage.eINSTANCE.getLayersStack_Layers()) { + // LayerOperator::layers || LayersStack::layers + // check the event type. + switch (notification.getEventType()) { + case Notification.SET: + fireLayerSet(notification); + break; + case Notification.ADD: + // A layer is added + fireLayerAdded(notification); + break; + case Notification.REMOVE: + // A layer is removed + fireLayerRemoved(notification); + break; + case Notification.MOVE: + // A layer is moved + fireLayerMoved(notification); + break; + } + } + } + + /** + * This Adapter is for {@link LayersTreeEventNotifier}. + * + * @see org.eclipse.emf.common.notify.impl.AdapterImpl#isAdapterForType(java.lang.Object) + * + * @param type + * @return + */ + @Override + public boolean isAdapterForType(Object type) { + return type == LayersTreeEventNotifier.class; + } + + /** + * Add the specified listener to the list of listener. + * Do not add it if the listener is already in the list. + * + * @param listener + */ + public void addLayersModelEventListener(ILayersTreeEventListener listener) { + + if (listener == null) { + return; + } + + // Check if exist + if (listeners.contains(listener)) { + return; + } + + listeners.add(listener); + } + + /** + * Remove the specified listener from the list of listeners. + * + * @param listener + */ + public void removeLayersModelEventListener(ILayersTreeEventListener listener) { + + listeners.remove(listener); + } + + /** + * Method called when a layer is added to one layer. + * The event contains: the layer. + * + * @param notification + */ + public void fireLayerSet(Notification notification) { + + for (ILayersTreeEventListener listener : listeners) { + listener.layerSet(notification); + } + } + + /** + * Method called when a layer is added to one layer. + * The event contains: the layer. + * + * @param notification + */ + public void fireLayerAdded(Notification notification) { + + for (ILayersTreeEventListener listener : listeners) { + listener.layerAdded(notification); + } + } + + /** + * Method called when a layer is removed from one layer. + * The event contains: the layer. + * + * @param notification + */ + public void fireLayerRemoved(Notification notification) { + + for (ILayersTreeEventListener listener : listeners) { + listener.layerRemoved(notification); + } + } + + /** + * Method called when a layer is moved in LayerStack. + * The event contains: the layer. + * + * @param notification + */ + public void fireLayerMoved(Notification notification) { + + for (ILayersTreeEventListener listener : listeners) { + listener.layerMoved(notification); + } + } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/LayersTreeEventNotifierFactory.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/LayersTreeEventNotifierFactory.java new file mode 100755 index 0000000..a7a0c2a --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/LayersTreeEventNotifierFactory.java @@ -0,0 +1,70 @@ +/***************************************************************************** + * Copyright (c) 2013 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.internal.infra.gmfdiag.layers.model.notifier; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStack; + +/** + * Factory used to create a {@link LayersTreeEventNotifier}. + * The factory ensures that there is only one Notifier for a given {@link LayersStack}. + * + * @author cedric dumoulin + * + */ +public class LayersTreeEventNotifierFactory extends AdapterFactoryImpl { + + /** + * Global factory. + */ + static public LayersTreeEventNotifierFactory instance = new LayersTreeEventNotifierFactory(); + + /** + * Convenience method. + * + * @param target + * @return + */ + public LayersTreeEventNotifier adapt(Notifier target) { + return (LayersTreeEventNotifier) adapt(target, LayersTreeEventNotifier.class); + } + + /** + * + * @see org.eclipse.emf.common.notify.impl.AdapterFactoryImpl#createAdapter(org.eclipse.emf.common.notify.Notifier) + * + * @param target + * @return + */ + @Override + protected Adapter createAdapter(Notifier target) { + return new LayersTreeEventNotifier(); + } + + /** + * This Factory is for {@link LayersTreeEventNotifier}. + * + * @see org.eclipse.emf.common.notify.impl.AdapterFactoryImpl#isFactoryForType(java.lang.Object) + * + * @param type + * @return + */ + @Override + public boolean isFactoryForType(Object type) { + return type == LayersTreeEventNotifier.class; + } +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/UmlNamedElementChangedEventNotifier.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/UmlNamedElementChangedEventNotifier.java new file mode 100755 index 0000000..a4ca69b --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/UmlNamedElementChangedEventNotifier.java @@ -0,0 +1,181 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.notifier; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.util.EContentAdapter; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStack; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStackApplication; +import org.eclipse.uml2.uml.NamedElement; + + +/** + * An EMF {@link Adapter} listening on uml::NamedElement properties changes. + * + * This class listen to a {@link NamedElement} and send following events to listeners: + * <ul> + * <li>valueChanged</li> + * </ul> + * + * @author cedric dumoulin + * + */ +public class UmlNamedElementChangedEventNotifier extends EContentAdapter { + + boolean isDisposed = false; + + /** + * List of listener to notify. + */ + protected List<IUmlNamedElementChangedEventListener> listeners = new ArrayList<IUmlNamedElementChangedEventListener>(); + + /** + * Something happen on the tree of object + * + * @see org.eclipse.emf.ecore.util.EContentAdapter#notifyChanged(org.eclipse.emf.common.notify.Notification) + * + * @param msg + */ + @Override + public void notifyChanged(Notification notification) { + + // Self atttach + super.notifyChanged(notification); + + // Retain only NamedElement + if (!(notification.getNotifier() instanceof NamedElement)) { + return; + } + + // No more filter: all events are forwarded + fireValueChangedEvent(notification); + + // // We are only interested in NamedElement (from newValue if set, or oldValue if removed) + // Object newValue = notification.getNewValue(); + // if( ! (newValue instanceof NamedElement || notification.getOldValue() instanceof NamedElement ) ) { + // return; + // } + // // Check diagram modification + // // There is 4 sources: View::persistedChildren and View::transientChildren + // // Diagram::persistedChildren and Diagram::transientChildren + // Object feature = notification.getFeature(); + // if( feature == UMLPackage.eINSTANCE.getNamedElement() + // || feature == NotationPackage.eINSTANCE.getView_TransientChildren() + // || feature == NotationPackage.eINSTANCE.getDiagram_PersistedEdges() + // || feature == NotationPackage.eINSTANCE.getDiagram_TransientEdges() ) { + // // LayerOperator::layers || LayersStack::layers + // // check the event type. + // switch(notification.getEventType()) { + // case Notification.SET: + // + // break; + // case Notification.ADD: + // // A view is added + // fireValueChangedEvent(notification); + // break; + // case Notification.REMOVE: + // // A layer is removed + // fireDiagramViewRemovedEvent(notification); + // break; + // } + // } + + }; + + /** + * This Adapter is for {@link LayersTreeEventNotifier}. + * + * @see org.eclipse.emf.common.notify.impl.AdapterImpl#isAdapterForType(java.lang.Object) + * + * @param type + * @return + */ + @Override + public boolean isAdapterForType(Object type) { + return type == UmlNamedElementChangedEventNotifier.class; + } + + /** + * Constructor. + * + * @param layersModel + */ + public UmlNamedElementChangedEventNotifier() { + } + + /** + * Dispose the synchronizer + */ + public void dispose() { + + if (isDisposed()) { + return; + } + + isDisposed = true; + listeners.clear(); + } + + /** + * Return true if the object is disposed. + * + * @return + */ + public boolean isDisposed() { + return isDisposed == true; + } + + /** + * Add the specified listener to the list of listener. + * Do not add it if the listener is already in the list. + * + * @param listener + */ + public void addEventListener(IUmlNamedElementChangedEventListener listener) { + + if (listener == null) { + return; + } + + // Check if exist + if (listeners.contains(listener)) { + return; + } + + listeners.add(listener); + } + + /** + * Remove the specified listener from the list of listeners. + * + * @param listener + */ + public void removeEventListener(IUmlNamedElementChangedEventListener listener) { + + listeners.remove(listener); + } + + /** + * Called by events when a {@link LayersStack} is added to the {@link LayersStackApplication} + * + * @param msg + */ + protected void fireValueChangedEvent(Notification msg) { + for (IUmlNamedElementChangedEventListener listener : listeners) { + listener.valueChanged(msg); + } + } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/UmlNamedElementChangedEventNotifierFactory.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/UmlNamedElementChangedEventNotifierFactory.java new file mode 100755 index 0000000..e461611 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/UmlNamedElementChangedEventNotifierFactory.java @@ -0,0 +1,70 @@ +/***************************************************************************** + * Copyright (c) 2013 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.internal.infra.gmfdiag.layers.model.notifier; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStack; + +/** + * Factory used to create a {@link UmlNamedElementChangedEventNotifier}. + * The factory ensures that there is only one Notifier for a given {@link LayersStack}. + * + * @author cedric dumoulin + * + */ +public class UmlNamedElementChangedEventNotifierFactory extends AdapterFactoryImpl { + + /** + * Global factory. + */ + static public UmlNamedElementChangedEventNotifierFactory instance = new UmlNamedElementChangedEventNotifierFactory(); + + /** + * Convenience method. + * + * @param target + * @return + */ + public UmlNamedElementChangedEventNotifier adapt(Notifier target) { + return (UmlNamedElementChangedEventNotifier) adapt(target, UmlNamedElementChangedEventNotifier.class); + } + + /** + * + * @see org.eclipse.emf.common.notify.impl.AdapterFactoryImpl#createAdapter(org.eclipse.emf.common.notify.Notifier) + * + * @param target + * @return + */ + @Override + protected Adapter createAdapter(Notifier target) { + return new UmlNamedElementChangedEventNotifier(); + } + + /** + * This Factory is for {@link UmlNamedElementChangedEventNotifier}. + * + * @see org.eclipse.emf.common.notify.impl.AdapterFactoryImpl#isFactoryForType(java.lang.Object) + * + * @param type + * @return + */ + @Override + public boolean isFactoryForType(Object type) { + return type == UmlNamedElementChangedEventNotifier.class; + } +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/package-info.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/package-info.java new file mode 100755 index 0000000..3462554 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/notifier/package-info.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +/** + * This package provides reusable event notifiers. + * + * @author cedric dumoulin + * + */ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.notifier; + diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/operators/BooleanAndOperator.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/operators/BooleanAndOperator.java new file mode 100755 index 0000000..7002f0c --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/operators/BooleanAndOperator.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.operators; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.LayersException; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.command.ComputePropertyValueCommand; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.BooleanInstance; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersFactory; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.TypeInstance; + + +/** + * @author cedric dumoulin + * + */ +public class BooleanAndOperator implements CustomPropertyOperatorsInstance { + + public static final BooleanInstance FALSE_INSTANCE; + public static final BooleanInstance TRUE_INSTANCE; + + static { + FALSE_INSTANCE = LayersFactory.eINSTANCE.createBooleanInstance(); + FALSE_INSTANCE.setValue(false); + TRUE_INSTANCE = LayersFactory.eINSTANCE.createBooleanInstance(); + TRUE_INSTANCE.setValue(true); + } + + /** + * + * @see org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.operators.CustomPropertyOperatorsInstance#getComputePropertyValueCommand(org.eclipse.emf.common.util.EList) + * + * @param property + * @return + * @throws LayersException + */ + @Override + public ComputePropertyValueCommand getComputePropertyValueCommand(EList<ComputePropertyValueCommand> nestedCommand) throws LayersException { + return new BooleanAndOperatorCommand(nestedCommand); + } + + + /** + * Class implementing an And command. + * + */ + class BooleanAndOperatorCommand implements ComputePropertyValueCommand { + + EList<ComputePropertyValueCommand> nestedCommand; + + /** + * + * Constructor. + * + * @param nestedCommand + */ + public BooleanAndOperatorCommand(EList<ComputePropertyValueCommand> nestedCommand) { + this.nestedCommand = nestedCommand; + } + + /** + * Compute the value. + * + * @see org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.command.ComputePropertyValueCommand#getCmdValue() + * + * @return + * @throws LayersException + */ + @Override + public TypeInstance getCmdValue() throws LayersException { + + // Do an boolean and: all value should be true. + // Return as soon as a false is encountered + for (ComputePropertyValueCommand curCmd : nestedCommand) { + boolean curCmdRes = ((BooleanInstance) curCmd.getCmdValue()).isValue(); + if (curCmdRes == false) { + return FALSE_INSTANCE; + } + } + + return TRUE_INSTANCE; + } + + } +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/operators/BooleanOrOperator.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/operators/BooleanOrOperator.java new file mode 100755 index 0000000..9816faf --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/operators/BooleanOrOperator.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.operators; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.LayersException; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.command.ComputePropertyValueCommand; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.BooleanInstance; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersFactory; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.TypeInstance; + + +/** + * @author cedric dumoulin + * + */ +public class BooleanOrOperator implements CustomPropertyOperatorsInstance { + + public static final BooleanInstance FALSE_INSTANCE; + public static final BooleanInstance TRUE_INSTANCE; + + static { + FALSE_INSTANCE = LayersFactory.eINSTANCE.createBooleanInstance(); + FALSE_INSTANCE.setValue(false); + TRUE_INSTANCE = LayersFactory.eINSTANCE.createBooleanInstance(); + TRUE_INSTANCE.setValue(true); + } + + /** + * + * @see org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.operators.CustomPropertyOperatorsInstance#getComputePropertyValueCommand(org.eclipse.emf.common.util.EList) + * + * @param property + * @return + * @throws LayersException + */ + @Override + public ComputePropertyValueCommand getComputePropertyValueCommand(EList<ComputePropertyValueCommand> nestedCommand) throws LayersException { + return new BooleanOrOperatorCommand(nestedCommand); + } + + + /** + * Class implementing an And command. + * + */ + class BooleanOrOperatorCommand implements ComputePropertyValueCommand { + + EList<ComputePropertyValueCommand> nestedCommand; + + /** + * + * Constructor. + * + * @param nestedCommand + */ + public BooleanOrOperatorCommand(EList<ComputePropertyValueCommand> nestedCommand) { + this.nestedCommand = nestedCommand; + } + + /** + * Compute the value. + * + * @see org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.command.ComputePropertyValueCommand#getCmdValue() + * + * @return + * @throws LayersException + */ + @Override + public TypeInstance getCmdValue() throws LayersException { + + // Do an boolean or: at least one value should be true. + // Return as soon as a true is encountered + for (ComputePropertyValueCommand curCmd : nestedCommand) { + boolean curCmdRes = ((BooleanInstance) curCmd.getCmdValue()).isValue(); + if (curCmdRes == true) { + return TRUE_INSTANCE; + } + } + + return FALSE_INSTANCE; + } + + } +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/operators/CustomPropertyOperatorsInstance.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/operators/CustomPropertyOperatorsInstance.java new file mode 100755 index 0000000..a4601be --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/operators/CustomPropertyOperatorsInstance.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.operators; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.LayersException; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.command.ComputePropertyValueCommand; + + +/** + * Interface to be implemented by operators declared as "custom". + * + * @author cedric dumoulin + * + */ +public interface CustomPropertyOperatorsInstance { + + /** + * Return the command allowing to compute the value resulting on applying this operator on the specified properties. + * + * @param property + * @return The command returning the result + * @throws LayersException + */ + public ComputePropertyValueCommand getComputePropertyValueCommand(EList<ComputePropertyValueCommand> property) throws LayersException; +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/operators/FillAverageOperator.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/operators/FillAverageOperator.java new file mode 100755 index 0000000..964f8fb --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/operators/FillAverageOperator.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * 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: + * Cedric Dumoulin - cedric.dumoulin@lifl.fr + ******************************************************************************/ +package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.operators; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.LayersException; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.command.ComputePropertyValueCommand; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.BooleanInstance; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.ColorInstance; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.FillInstance; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersFactory; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.TypeInstance; + + +/** + * @author cedric dumoulin + * + */ +public class FillAverageOperator implements CustomPropertyOperatorsInstance { + + public static final BooleanInstance FALSE_INSTANCE; + public static final BooleanInstance TRUE_INSTANCE; + + static { + FALSE_INSTANCE = LayersFactory.eINSTANCE.createBooleanInstance(); + FALSE_INSTANCE.setValue(false); + TRUE_INSTANCE = LayersFactory.eINSTANCE.createBooleanInstance(); + TRUE_INSTANCE.setValue(true); + } + + /** + * + * @see org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.operators.CustomPropertyOperatorsInstance#getComputePropertyValueCommand(org.eclipse.emf.common.util.EList) + * + * @param property + * @return + * @throws LayersException + */ + @Override + public ComputePropertyValueCommand getComputePropertyValueCommand(EList<ComputePropertyValueCommand> nestedCommand) throws LayersException { + return new FillAverageCommand(nestedCommand); + } + + + /** + * Class implementing an And command. + * + */ + class FillAverageCommand implements ComputePropertyValueCommand { + + EList<ComputePropertyValueCommand> nestedCommand; + + /** + * + * Constructor. + * + * @param nestedCommand + */ + public FillAverageCommand(EList<ComputePropertyValueCommand> nestedCommand) { + this.nestedCommand = nestedCommand; + } + + /** + * Compute the value. + * + * @see org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.command.ComputePropertyValueCommand#getCmdValue() + * + * @return + * @throws LayersException + */ + @Override + public TypeInstance getCmdValue() throws LayersException { + + int fill = 0; + int color = 0; + // compute the average values + for (ComputePropertyValueCommand curCmd : nestedCommand) { + FillInstance curValue = ((FillInstance) curCmd.getCmdValue()); + fill += curValue.getTransparency(); + color += curValue.getFillColor().getValue(); + } + + // Create a result + FillInstance res = LayersFactory.eINSTANCE.createFillInstance(); + ColorInstance colorInstance = LayersFactory.eINSTANCE.createColorInstance(); + res.setFillColor(colorInstance); + res.setTransparency(fill / nestedCommand.size()); + res.getFillColor().setValue(color / nestedCommand.size()); + return res; + } + + } +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/util/Collections3.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/util/Collections3.java new file mode 100755 index 0000000..ca54419 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/util/Collections3.java @@ -0,0 +1,76 @@ +/***************************************************************************** + * Copyright (c) 2013 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.internal.infra.gmfdiag.layers.model.util; + +import java.util.ArrayList; +import java.util.Collection; + +import com.google.common.collect.Collections2; + +/** + * Set of utility methods for Collections. + * + * @see Collections2 + * + * @author cedric dumoulin + * + */ +public class Collections3 { + + /** + * Reset the toChange list to the content of the newContent list. + * Minimize the change calls on the toChange list. + * This method ensure that there is at most 2 writing calls to the list to modify: one + * removeAll(toBeRemoved) and one addAll(toBeAdded). + * + * @param toChange + * @param newContent + */ + public static <E> void resetListTo(Collection<E> toChange, Collection<E> newContent) { + + // Compute removed and added + Collection<E> elementsToRemove = new ArrayList<E>(); + Collection<E> elementsToAdd = new ArrayList<E>(); + + // Compute added and removed elements. Walk both list 2 times. + // This could certainly be improved. + // TODO improve the algorithm + + // Compute added elements + for (E o : newContent) { + if (!toChange.contains(o)) { + elementsToAdd.add(o); + continue; + } + } + + // Compute removed elements + for (E o : toChange) { + if (!newContent.contains(o)) { + elementsToRemove.add(o); + continue; + } + } + + // Change the list + if (!elementsToRemove.isEmpty()) { + toChange.removeAll(elementsToRemove); + } + if (!elementsToAdd.isEmpty()) { + toChange.addAll(elementsToAdd); + } + } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/util/DiagramViewToListSynchronizer.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/util/DiagramViewToListSynchronizer.java new file mode 100755 index 0000000..29eadd2 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/util/DiagramViewToListSynchronizer.java @@ -0,0 +1,118 @@ +/***************************************************************************** + * Copyright (c) 2013 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.internal.infra.gmfdiag.layers.model.util; + +import java.util.Collection; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.gmf.runtime.notation.Diagram; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.notifier.DiagramViewChangedEventNotifier; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.notifier.DiagramViewChangedEventNotifierFactory; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.notifier.IDiagramViewEventListener; + +import com.google.common.collect.Iterables; + +/** + * This class allows to synchronize a specfied list with {@link View} elements from the specified {@link Diagram}. + * + * @author cedric dumoulin + * + */ +public class DiagramViewToListSynchronizer { + + protected Diagram diagram; + + protected Collection<View> synchronizedList; + + /** + * Listener on Diagram's View event. + * Synchronize the associated list according to the event. + */ + private IDiagramViewEventListener viewEventListener = new IDiagramViewEventListener() { + + @Override + public void diagramViewRemoved(Notification msg) { + // Add the removed view from the list + synchronizedList.remove(msg.getOldValue()); + + } + + @Override + public void diagramViewAdded(Notification msg) { + + View view = (View) msg.getNewValue(); + if (synchronizedList.contains(view)) { + return; + } + // add element + synchronizedList.add(view); + } + }; + + /** + * Constructor. + * + * @param diagram + * @param synchronizedList + */ + public DiagramViewToListSynchronizer(Diagram diagram, Collection<View> synchronizedList) { + this.synchronizedList = synchronizedList; + + // Listen to diagram's view event + setDiagram(diagram); + } + + /** + * The diagram should be set later. + * Constructor. + * + * @param synchronizedList + */ + public DiagramViewToListSynchronizer(Collection<View> synchronizedList) { + this.synchronizedList = synchronizedList; + } + + /** + * Set the diagram synchronized to the list. + * + * @param diagram + */ + public void setDiagram(Diagram diagram) { + + DiagramViewChangedEventNotifier notifier; + // stop listening on old diagram if any + Diagram oldDiagram = this.diagram; + if (oldDiagram != null) { + notifier = DiagramViewChangedEventNotifierFactory.instance.adapt(oldDiagram); + notifier.removeEventListener(viewEventListener); + } + // Reset the list and add view responding to the predicate + synchronizedList.clear(); + + Iterable<View> filteredList = Iterables.filter(diagram.getChildren(), LayerDiagramViewPredicate.instance); + for (View view : filteredList) { + synchronizedList.add(view); + } + + // attach to new diagram + this.diagram = diagram; + if (diagram != null) { + notifier = DiagramViewChangedEventNotifierFactory.instance.adapt(diagram); + notifier.addEventListener(viewEventListener); + } + + } +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/util/LayerDiagramViewPredicate.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/util/LayerDiagramViewPredicate.java new file mode 100755 index 0000000..f047af3 --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/util/LayerDiagramViewPredicate.java @@ -0,0 +1,64 @@ +/***************************************************************************** + * Copyright (c) 2013 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.internal.infra.gmfdiag.layers.model.util; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.gmf.runtime.notation.Edge; +import org.eclipse.gmf.runtime.notation.Shape; +import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.Layer; +import org.eclipse.uml2.uml.NamedElement; + +import com.google.common.base.Predicate; + +/** + * A Predicate used to filter {@link View} allowed by {@link Layer}. + * + * @author cedric dumoulin + * + */ +public class LayerDiagramViewPredicate implements Predicate<View> { + + /** + * Singleton instnace. + */ + public static final LayerDiagramViewPredicate instance = new LayerDiagramViewPredicate(); + + /** + * Return true if the view is allowed by Layers. + * + * @see com.google.common.base.Predicate#apply(java.lang.Object) + * + * @param view + * @return + */ + @Override + public boolean apply(View view) { + + // View should be Shape or Edge + if (!(view instanceof Shape || view instanceof Edge)) { + return false; + } + + // Domain element should be set and should be NamedElement + EObject ele = view.getElement(); + if (ele == null || !(ele instanceof NamedElement)) { + return false; + } + // ok + return true; + } + +} diff --git a/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/util/ObservableListView.java b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/util/ObservableListView.java new file mode 100755 index 0000000..3c6b9aa --- /dev/null +++ b/layers/plugins/org.eclipse.papyrus.infra.gmfdiag.layers.model/src/org/eclipse/papyrus/internal/infra/gmfdiag/layers/model/util/ObservableListView.java @@ -0,0 +1,353 @@ +/***************************************************************************** + * Copyright (c) 2013 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.internal.infra.gmfdiag.layers.model.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import com.google.common.collect.ForwardingList; +import com.google.common.collect.Lists; +import com.google.common.eventbus.EventBus; + +/** + * An observable list notifying of events on the delegated list. + * This view allows to observe a provided list. + * The following events are notified: + * <ul> + * <li>elements added</li> + * <li>elements removed</li> + * <li></li> + * <li></li> + * </ul> + * + * @author cedric dumoulin + * + */ +public class ObservableListView<E> extends ForwardingList<E> { + + protected List<E> delegate; + + protected EventBus eventBus = new EventBus(ObservableListView.class.getName()); + + /** + * Construct an observable list with a {@link ArrayList} as delegate. + * Constructor. + * + */ + public ObservableListView() { + this(new ArrayList<E>()); + } + + /** + * Constructor. + * Build an observable list based on the provided list. + * + * @param delegate + */ + public ObservableListView(List<E> delegate) { + this.delegate = delegate; + } + + @Override + protected List<E> delegate() { + return delegate; + } + + /** + * @return the eventBus + */ + public EventBus getEventBus() { + return eventBus; + } + + @Override + public boolean add(E element) { + boolean isModified = delegate().add(element); + if (isModified) { + eventBus.post(new ObservableListEvent(element)); + } + + return isModified; + } + + @Override + public boolean addAll(Collection<? extends E> collection) { + boolean isModified = delegate().addAll(collection); + if (isModified) { + eventBus.post(new ObservableListEvent(collection)); + } + + return isModified; + } + + @Override + public void add(int index, E element) { + delegate().add(index, element); + eventBus.post(new ObservableListEvent(element)); + } + + @Override + public boolean addAll(int index, Collection<? extends E> elements) { + // TODO Auto-generated method stub + boolean isModified = delegate().addAll(index, elements); + if (isModified) { + eventBus.post(new ObservableListEvent(elements)); + } + + return isModified; + } + + @Override + public E remove(int index) { + E removed = super.remove(index); + getEventBus().post(new ObservableListEvent(null, removed)); + + return removed; + } + + @SuppressWarnings("unchecked") + @Override + public boolean remove(Object object) { + boolean isRemoved = super.remove(object); + if (isRemoved) { + getEventBus().post(new ObservableListEvent(null, (E) object)); + } + return isRemoved; + } + + /** + * + * @see com.google.common.collect.ForwardingCollection#removeAll(java.util.Collection) + * + * @param collection + * @return + */ + @Override + public boolean removeAll(Collection<?> collection) { + // Compute the removed elements (for the events) + List<E> removedElements = Lists.newArrayList(delegate()); + removedElements.retainAll(collection); + + // Do remove + boolean isRemoved = super.removeAll(collection); + if (isRemoved) { + getEventBus().post(new ObservableListEvent(null, removedElements)); + } + return isRemoved; + } + + /** + * Reset the collection to the specified collection. + * Throw events containing the added and removed elements. + * + * @param collection + * @return + */ + public boolean resetTo(Collection<? extends E> collection) { + + // Compute removed and added + Collection<E> elementsToRemove = new ArrayList<E>(); + Collection<E> elementsToAdd = new ArrayList<E>(); + + // Cached list of attached elements + Collection<? extends E> attachedElements = delegate(); + + // Compute added and removed elements. Walk both list 2 times. + // This could certainly be improved. + // TODO improve the algorithm + + // Compute added elements + for (E o : collection) { + if (!attachedElements.contains(o)) { + elementsToAdd.add(o); + continue; + } + } + + // Compute removed elements + for (E o : attachedElements) { + if (!collection.contains(o)) { + elementsToRemove.add(o); + continue; + } + } + + // Change the list + delegate().clear(); + delegate().addAll(collection); + + // Fire event + boolean isModified = !(elementsToAdd.isEmpty() && elementsToRemove.isEmpty()); + if (isModified) { + getEventBus().post(new ObservableListEvent(elementsToAdd, elementsToRemove)); + } + + return isModified; + } + + /** + * Event used to specify that the list is changed + * + * @author cedric dumoulin + * + */ + public class ObservableListEvent { + + Collection<? extends E> addedElements = Collections.emptyList(); + Collection<? extends E> removedElements = Collections.emptyList(); + + /** + * + * Constructor. + * + */ + public ObservableListEvent() { + this.addedElements = Collections.emptyList(); + this.removedElements = Collections.emptyList(); + } + + /** + * + * Constructor. + * + */ + public ObservableListEvent(Collection<? extends E> addedElements) { + if (addedElements != null) { + this.addedElements = addedElements; + } else { + this.addedElements = Collections.emptyList(); + } + + this.removedElements = Collections.emptyList(); + } + + /** + * Constructor. + * + * @param addedElements + * added elements or null + * @param removedElements + * removed elements or null + */ + public ObservableListEvent(Collection<? extends E> addedElements, Collection<? extends E> removedElements) { + if (addedElements != null) { + this.addedElements = addedElements; + } else { + this.addedElements = Collections.emptyList(); + } + + if (removedElements != null) { + this.removedElements = removedElements; + } else { + this.removedElements = Collections.emptyList(); + } + } + + /** + * + * Constructor. + * + * @param addedElement + * An element added or null; + * @param removedElement + * An element added or null + */ + public ObservableListEvent(E addedElement, E removedElement) { + + if (addedElement != null) { + addedElements = Collections.singletonList(addedElement); + } else { + addedElements = Collections.emptyList(); + } + + if (removedElement != null) { + removedElements = Collections.singletonList(removedElement); + } else { + removedElements = Collections.emptyList(); + } + } + + /** + * + * Constructor. + * + * @param addedElement + * An element added or null; + */ + public ObservableListEvent(E addedElement) { + + if (addedElement != null) { + addedElements = Collections.singletonList(addedElement); + } else { + addedElements = Collections.emptyList(); + } + removedElements = Collections.emptyList(); + } + + /** + * @return the addedElements + */ + public Collection<? extends E> getAddedElements() { + return addedElements; + } + + // /** + // * @param addedElements the addedElements to set + // */ + // public void setAddedElements(List<E> addedElements) { + // this.addedElements = addedElements; + // } + // + // /** + // * @param addedElements the addedElements to set + // */ + // public void setAddedElements(E addedElement) { + // this.addedElements = Collections.singletonList(addedElement); + // } + + /** + * @return the removedElements + */ + public Collection<? extends E> getRemovedElements() { + return removedElements; + } + + // /** + // * @param removedElements the removedElements to set + // */ + // public void setRemovedElements(List<E> removedElements) { + // this.removedElements = removedElements; + // } + // + // /** + // * @param removedElements the removedElements to set + // */ + // public void setRemovedElements(E removedElement) { + // this.removedElements = Collections.singletonList(removedElement); + // } + } + + /** + * Return the underlying list. This can be used as an unnotifying version of the list. + * + * @return + */ + public List<E> getUnnotifyingList() { + return delegate(); + + } +} |