Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcletavernie2011-10-25 12:15:13 +0000
committercletavernie2011-10-25 12:15:13 +0000
commit7803af6503cc8502ffd1d9a5ad20424d166b1a27 (patch)
treefd10425521b1cff4ec9698358e00b9f33d8360e9 /plugins/views/properties
parent67a2d96fe9d52f6efb7adfbad40044fadb56ca86 (diff)
downloadorg.eclipse.papyrus-7803af6503cc8502ffd1d9a5ad20424d166b1a27.tar.gz
org.eclipse.papyrus-7803af6503cc8502ffd1d9a5ad20424d166b1a27.tar.xz
org.eclipse.papyrus-7803af6503cc8502ffd1d9a5ad20424d166b1a27.zip
359057: [Architecture - SVN - Build] The Papyrus architecture should be refactored
https://bugs.eclipse.org/bugs/show_bug.cgi?id=359057
Diffstat (limited to 'plugins/views/properties')
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/.classpath7
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/.project34
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/.settings/org.eclipse.jdt.core.prefs8
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/META-INF/MANIFEST.MF24
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/about.html28
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/build.properties7
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/EMFFeatureDescriptor.gifbin0 -> 123 bytes
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/ReplacedSection.gifbin0 -> 150 bytes
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/Section.gifbin0 -> 351 bytes
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SectionSet.gifbin0 -> 351 bytes
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SubFeatureContainer.gifbin0 -> 109 bytes
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SubFeatureExpandableContainer.gifbin0 -> 139 bytes
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SubFeatureGroupContainer.gifbin0 -> 99 bytes
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/Tab.gifbin0 -> 245 bytes
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/plugin.properties12
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/Activator.java77
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/provider/EMFObjectLabelProvider.java172
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/provider/XMLBasedTabDescriptorProvider.java184
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/DynamicSection.java261
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/DynamicSectionDescriptor.java367
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/DynamicTabDescriptor.java68
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/GetTabDescriptorsFromConfiguration.java36
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/IEnhancedFilter.java31
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/IPropertyTabViewProvider.java30
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/PropertyServiceUtil.java36
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/PropertyTabViewProviderParser.java511
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionDescriptorState.java544
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionDispatcher.java127
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionSetDescriptor.java143
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionSetDescriptorState.java269
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/StatesStore.java156
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/TabDescriptorState.java235
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/XMLPropertyTabViewProvider.java349
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/DynamicSubFeatureSection.java127
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/DynamicSubFeatureSectionDescriptor.java261
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/EMFSimpleSubFeatureDescriptor.java197
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/ExpandableContainerDescriptor.java198
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/GroupContainerDescriptor.java186
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SimpleContainerDescriptor.java68
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SubFeatureContainerDescriptor.java45
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SubFeatureContainerDescriptorState.java114
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SubFeatureDescriptor.java83
42 files changed, 4995 insertions, 0 deletions
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/.classpath b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/.classpath
new file mode 100644
index 00000000000..2d1a4302f04
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/.project b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/.project
new file mode 100644
index 00000000000..0abe5f1581c
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.papyrus.properties.tabbed.core</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/.settings/org.eclipse.jdt.core.prefs b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..24276453b0e
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Wed Apr 14 17:03:01 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/META-INF/MANIFEST.MF b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..78382dfe6a4
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/META-INF/MANIFEST.MF
@@ -0,0 +1,24 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.papyrus.properties.tabbed.core;singleton:=true
+Bundle-Version: 0.9.0.qualifier
+Bundle-Activator: org.eclipse.papyrus.properties.tabbed.core.Activator
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.ui.views.properties.tabbed,
+ org.eclipse.emf.ecore;bundle-version="2.6.0",
+ org.eclipse.emf.edit.ui;bundle-version="2.6.0",
+ org.eclipse.gmf.runtime.common.core;bundle-version="1.2.0",
+ org.eclipse.gmf.runtime.common.ui;bundle-version="1.3.0",
+ org.eclipse.papyrus.core;bundle-version="0.8.0",
+ org.eclipse.papyrus.properties.runtime;bundle-version="0.8.0",
+ org.eclipse.papyrus.log;bundle-version="0.8.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.papyrus.properties.tabbed.core,
+ org.eclipse.papyrus.properties.tabbed.core.provider,
+ org.eclipse.papyrus.properties.tabbed.core.view,
+ org.eclipse.papyrus.properties.tabbed.core.view.subfeatures
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/about.html b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/about.html
new file mode 100644
index 00000000000..209103075a7
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>November 14, 2008</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/build.properties b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/build.properties
new file mode 100644
index 00000000000..ad6792e8a61
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/build.properties
@@ -0,0 +1,7 @@
+#
+#Mon Sep 12 09:30:07 CEST 2011
+bin.includes=META-INF/,.,bin/,plugin.properties,icons/,about.html
+output..=bin/
+src.includes=about.html,icons/,plugin.properties,META-INF/,.,bin/
+source..=src/
+bin..=bin/
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/EMFFeatureDescriptor.gif b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/EMFFeatureDescriptor.gif
new file mode 100644
index 00000000000..bc9944a7d53
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/EMFFeatureDescriptor.gif
Binary files differ
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/ReplacedSection.gif b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/ReplacedSection.gif
new file mode 100644
index 00000000000..c01c38436f0
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/ReplacedSection.gif
Binary files differ
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/Section.gif b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/Section.gif
new file mode 100644
index 00000000000..645141285f7
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/Section.gif
Binary files differ
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SectionSet.gif b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SectionSet.gif
new file mode 100644
index 00000000000..645141285f7
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SectionSet.gif
Binary files differ
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SubFeatureContainer.gif b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SubFeatureContainer.gif
new file mode 100644
index 00000000000..7bb44f59cc8
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SubFeatureContainer.gif
Binary files differ
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SubFeatureExpandableContainer.gif b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SubFeatureExpandableContainer.gif
new file mode 100644
index 00000000000..3eb5e02a4d5
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SubFeatureExpandableContainer.gif
Binary files differ
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SubFeatureGroupContainer.gif b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SubFeatureGroupContainer.gif
new file mode 100644
index 00000000000..d85b06b9d3f
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/SubFeatureGroupContainer.gif
Binary files differ
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/Tab.gif b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/Tab.gif
new file mode 100644
index 00000000000..67053e449d2
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/icons/Tab.gif
Binary files differ
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/plugin.properties b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/plugin.properties
new file mode 100644
index 00000000000..a15d01869ae
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/plugin.properties
@@ -0,0 +1,12 @@
+#################################################################################
+# Copyright (c) 2010 CEA LIST.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - initial API and implementation
+##################################################################################
+pluginName=Papyrus Tabbed Properties Core (Incubation)
+providerName=Eclipse Modeling Project
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/Activator.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/Activator.java
new file mode 100644
index 00000000000..4bd0bdb0ba2
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/Activator.java
@@ -0,0 +1,77 @@
+package org.eclipse.papyrus.properties.tabbed.core;
+
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.papyrus.log.LogHelper;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ /** identifier of the plugin */
+ public static final String PLUGIN_ID = "org.eclipse.papyrus.properties.tabbed.core"; //$NON-NLS-1$
+
+ /** singleton instance of this plugin */
+ private static Activator plugin;
+
+ /** Logging helper */
+ public static LogHelper log;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ log = new LogHelper(plugin);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns the image from the given image descriptor
+ *
+ * @param path
+ * the path of the image to be displayed
+ * @return the image found
+ */
+ public static Image getImage(String path) {
+ final ImageRegistry registry = getDefault().getImageRegistry();
+ Image image = registry.get(path);
+ if(image == null) {
+ registry.put(path, Activator.imageDescriptorFromPlugin(PLUGIN_ID, path));
+ image = registry.get(path);
+ }
+ return image;
+
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/provider/EMFObjectLabelProvider.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/provider/EMFObjectLabelProvider.java
new file mode 100644
index 00000000000..e51f2c94bb9
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/provider/EMFObjectLabelProvider.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.provider;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * This class handles title label for tabbed properties.
+ *
+ * @author Jerome Benois
+ */
+public class EMFObjectLabelProvider extends AdapterFactoryLabelProvider implements ILabelProvider {
+
+ /** item provider class */
+ private static final Class<?> IItemLabelProviderClass = IItemLabelProvider.class;
+
+ /** list of adapter factories, identified by their Ids */
+ private static Map<String, AdapterFactory> factories = new HashMap<String, AdapterFactory>();
+
+ /** emf item provider facctories */
+ private static final String EXT_FACTORIES = "org.eclipse.emf.edit.itemProviderAdapterFactories"; //$NON-NLS-1$
+
+ /**
+ * Creates a new EMFObjectLabelProvider.
+ */
+ public EMFObjectLabelProvider() {
+ super(new ReflectiveItemProviderAdapterFactory());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getText(Object element) {
+ String title = ""; //$NON-NLS-1$
+ EObject eObject = getModel(element);
+ IItemLabelProvider itemLabelProvider = getItemLabelProvider(eObject);
+ if(itemLabelProvider != null) {
+ title = itemLabelProvider.getText(eObject);
+ }
+
+ if("".equals(title)) { //$NON-NLS-1$
+ title = super.getText(eObject);
+ }
+
+ return title;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Image getImage(Object element) {
+ Image result = null;
+ EObject eObject = getModel(element);
+ IItemLabelProvider itemLabelProvider = getItemLabelProvider(eObject);
+ if(itemLabelProvider != null) {
+ result = getImageFromObject(itemLabelProvider.getImage(eObject));
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the EObject from the given element
+ *
+ * @param element
+ * the element to adapt
+ * @return the EObject from the given element
+ */
+ private EObject getModel(Object element) {
+ EObject eObject = null;
+ if(element != null && element instanceof StructuredSelection) {
+ StructuredSelection selection = (StructuredSelection)element;
+ Object o = selection.getFirstElement();
+ if(o instanceof EObject) {
+ eObject = (EObject)o;
+ } else if(o instanceof IGraphicalEditPart) {
+ IGraphicalEditPart editPart = (IGraphicalEditPart)o;
+ eObject = editPart.resolveSemanticElement();
+ } // try to adapt into EObject
+ else if(o instanceof IAdaptable) {
+ eObject = (EObject)((IAdaptable)o).getAdapter(EObject.class);
+ }
+
+ }
+ return eObject;
+ }
+
+ /**
+ * Returns the item provider for the given object
+ *
+ * @param eObject
+ * the object to display
+ * @return the item label provider for the given eobject
+ */
+ private IItemLabelProvider getItemLabelProvider(EObject eObject) {
+ IItemLabelProvider itemLabelProvider = null;
+ if(eObject != null) {
+ AdapterFactory adapterFactory = getEditFactory(eObject);
+ if(adapterFactory != null) {
+ return (IItemLabelProvider)adapterFactory.adapt(eObject, IItemLabelProviderClass);
+ }
+ }
+ return itemLabelProvider;
+ }
+
+ /**
+ * Gets the edit factory.
+ *
+ * @param eobject
+ * the eobject
+ *
+ * @return the edits the factory
+ */
+ public static AdapterFactory getEditFactory(EObject eobject) {
+ String uri = eobject.eClass().getEPackage().getNsURI();
+ return getFactory(uri);
+ }
+
+ /**
+ * Gets the factory from uri.
+ *
+ * @param uri
+ * the uri
+ *
+ * @return the factory
+ */
+ public static AdapterFactory getFactory(String uri) {
+ AdapterFactory factory = factories.get(uri);
+ if(factory == null) {
+ IConfigurationElement[] extensions = Platform.getExtensionRegistry().getConfigurationElementsFor(EXT_FACTORIES);
+ for(IConfigurationElement e : extensions) {
+ if(uri.equals(e.getAttribute("uri"))) { //$NON-NLS-1$
+ try {
+ factory = (AdapterFactory)e.createExecutableExtension("class"); //$NON-NLS-1$
+ if(factory != null) {
+ factories.put(uri, factory);
+ }
+ } catch (CoreException e1) {
+ // do nothing
+ }
+ }
+ }
+ }
+ return factory;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/provider/XMLBasedTabDescriptorProvider.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/provider/XMLBasedTabDescriptorProvider.java
new file mode 100644
index 00000000000..b1fd13d6ff2
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/provider/XMLBasedTabDescriptorProvider.java
@@ -0,0 +1,184 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.provider;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.papyrus.core.editor.CoreMultiDiagramEditor;
+import org.eclipse.papyrus.properties.tabbed.core.Activator;
+import org.eclipse.papyrus.properties.tabbed.core.view.PropertyServiceUtil;
+import org.eclipse.papyrus.properties.tabbed.core.view.XMLPropertyTabViewProvider;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyRegistry;
+import org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyRegistryFactory;
+import org.eclipse.ui.views.properties.tabbed.AbstractTabDescriptor;
+import org.eclipse.ui.views.properties.tabbed.ISectionDescriptor;
+import org.eclipse.ui.views.properties.tabbed.ITabDescriptor;
+import org.eclipse.ui.views.properties.tabbed.ITabDescriptorProvider;
+
+
+/**
+ * Provider for {@link ITabDescriptor} published in the xml file for properties view.
+ */
+@SuppressWarnings("restriction")
+public class XMLBasedTabDescriptorProvider implements ITabDescriptorProvider, IPreferenceChangeListener {
+
+ /**
+ * Creates a new XMLBasedTabDescriptorProvider.
+ *
+ */
+ public XMLBasedTabDescriptorProvider() {
+ // register listener on preferences for the proeprties runtime plugin
+ IEclipsePreferences prefs = new InstanceScope().getNode(org.eclipse.papyrus.properties.runtime.Activator.ID);
+ prefs.addPreferenceChangeListener(this);
+ }
+
+ /** list of available tab descriptors */
+ protected ITabDescriptor[] descriptors = null;
+
+ /**
+ * {@inheritDoc}
+ */
+ public ITabDescriptor[] getTabDescriptors(IWorkbenchPart part, ISelection selection) {
+ if(descriptors == null && part instanceof CoreMultiDiagramEditor && selection != null) {
+ List<ITabDescriptor> descriptors = new ArrayList<ITabDescriptor>();
+
+ List<List<ITabDescriptor>> list = PropertyServiceUtil.getTabDescriptors();
+ for(List<ITabDescriptor> sub : list) {
+ descriptors.addAll((List<ITabDescriptor>)sub);
+ }
+ // get all tab descriptors for the registered extension points
+ TabbedPropertyRegistry registry = TabbedPropertyRegistryFactory.getInstance().createRegistry((CoreMultiDiagramEditor)part);
+
+ // invoke dynamically on the tab registry, as method is private
+ // problem of implementation of tabbed properties tabbed registry. Either contribution using extension points, either a tabprovider
+ // both contribution can not exist together, the only solution is to make a workaround.
+ try {
+ Method method = TabbedPropertyRegistry.class.getDeclaredMethod("getAllTabDescriptors");
+ method.setAccessible(true);
+ ITabDescriptor[] registeredTabDesriptors;
+
+ registeredTabDesriptors = (ITabDescriptor[])method.invoke(registry);
+ if(registeredTabDesriptors != null) {
+ descriptors.addAll(Arrays.asList(registeredTabDesriptors));
+ }
+ } catch (IllegalArgumentException e) {
+ Activator.log.error(e);
+ } catch (IllegalAccessException e) {
+ Activator.log.error(e);
+ } catch (InvocationTargetException e) {
+ Activator.log.error(e);
+ } catch (SecurityException e) {
+ Activator.log.error(e);
+ } catch (NoSuchMethodException e) {
+ Activator.log.error(e);
+ }
+
+
+ // for all descriptors, section should be ordered at this time... Could be time consuming!
+ for(ITabDescriptor descriptor : descriptors) {
+ orderSectionInTabDescriptor(descriptor);
+ }
+
+ this.descriptors = descriptors.toArray(new ITabDescriptor[descriptors.size()]);
+ }
+ return (descriptors != null) ? descriptors : new ITabDescriptor[0];
+ }
+
+ /**
+ * Orders the section descriptors present in the specified tab descriptor
+ *
+ * @param tabDescriptor
+ * the descriptor to order
+ */
+ @SuppressWarnings("unchecked")
+ protected void orderSectionInTabDescriptor(ITabDescriptor tabDescriptor) {
+ // generates the map (id, sectiondescriptor) to speed up the search
+ final Map<String, ISectionDescriptor> map = new HashMap<String, ISectionDescriptor>();
+ for(ISectionDescriptor descriptor : (List<ISectionDescriptor>)tabDescriptor.getSectionDescriptors()) {
+ map.put(descriptor.getId(), descriptor);
+ }
+
+ Collections.sort(tabDescriptor.getSectionDescriptors(), new Comparator<ISectionDescriptor>() {
+
+ /**
+ * @param section0
+ * the first section descriptor to compare
+ * @param section1
+ * the second section descriptor to compare
+ * @return an integer greater than 1 if the first section should be placed before the second
+ */
+ public int compare(ISectionDescriptor section0, ISectionDescriptor section1) {
+ // retrieve the list of previous section for first section
+ int delta = 0;
+ ISectionDescriptor previousSection0 = getPreviousSection(section0);
+ while(previousSection0 != null) {
+ delta++;
+ if(section1.equals(previousSection0)) {
+ return delta;
+ }
+ previousSection0 = getPreviousSection(previousSection0);
+ }
+ delta = 0;
+ ISectionDescriptor previousSection1 = getPreviousSection(section1);
+ while(previousSection1 != null) {
+ delta--;
+ if(section0.equals(previousSection1)) {
+ return delta;
+ }
+ previousSection1 = getPreviousSection(previousSection1);
+
+ }
+ return 0;
+ }
+
+ /**
+ * Returns the list of sections which are before section0
+ *
+ * @param section
+ * the section to test
+ * @return the list of sections which are before section0
+ */
+ public ISectionDescriptor getPreviousSection(ISectionDescriptor section) {
+ String afterId = section.getAfterSection();
+ if(afterId == AbstractTabDescriptor.TOP) {
+ return null;
+ } else {
+ return map.get(afterId);
+ }
+ }
+ });
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void preferenceChange(PreferenceChangeEvent event) {
+ if(XMLPropertyTabViewProvider.PROPERTY_VIEW_CUSTOMIZATIONS_ID.equals(event.getKey())) {
+ // reset cache
+ descriptors = null;
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/DynamicSection.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/DynamicSection.java
new file mode 100644
index 00000000000..1ca239f74e9
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/DynamicSection.java
@@ -0,0 +1,261 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.papyrus.properties.runtime.view.IFragmentDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.content.AbstractContainerDescriptor;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+
+/**
+ * Section using controllers for content.
+ */
+public class DynamicSection extends AbstractPropertySection {
+
+ /** semantic resolver */
+ public static final String SEMANTIC_RESOLVER = "Semantic";
+
+ /** id of the graphic resolver */
+ public static final String GRAPHIC_RESOLVER = "Graphic";
+
+ /** id of the edit part resolver */
+ public static final String EDIT_PART_RESOLVER = "EditPart";
+
+ /** the parent for the created composites in this section */
+ protected Composite parent;
+
+ /** Elements being selected */
+ protected List<Object> objectsToEdit;
+
+ /** list of controllers created for this section */
+ protected final List<AbstractContainerDescriptor> containers;
+
+ /** tabbed property sheet page */
+ protected TabbedPropertySheetPage tabbedPropertySheetPage;
+
+ /** list of fragment descriptors that compose the section */
+ protected List<IFragmentDescriptor> fragmentDescriptors;
+
+ /** adapter id used to resolve elements */
+ protected final String adapterId;
+
+ /**
+ * Creates a new DynamicSection.
+ *
+ * @param fragmentDescriptors
+ * list of fragments contained by this section
+ * @param adapterId
+ * id of the adapter to use to resolvbe objects
+ */
+ public DynamicSection(List<IFragmentDescriptor> fragmentDescriptors, String adapterId) {
+ this.fragmentDescriptors = fragmentDescriptors;
+ this.containers = new ArrayList<AbstractContainerDescriptor>();
+ this.adapterId = adapterId;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void createControls(Composite parent, TabbedPropertySheetPage tabbedPropertySheetPage) {
+ super.createControls(parent, tabbedPropertySheetPage);
+ // force new layout to grid layout, not fill layout
+ parent.setLayout(new GridLayout(1, true));
+ this.tabbedPropertySheetPage = tabbedPropertySheetPage;
+ // creates a composite that has a grid layout
+ this.parent = tabbedPropertySheetPage.getWidgetFactory().createComposite(parent);
+ GridData data = new GridData(GridData.FILL_BOTH);
+ this.parent.setLayoutData(data);
+ GridLayout layout = new GridLayout(1, true);
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ this.parent.setLayout(layout);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dispose() {
+ for(AbstractContainerDescriptor container : containers) {
+ container.dispose();
+ container = null;
+ }
+ super.dispose();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setInput(IWorkbenchPart part, ISelection selection) {
+ super.setInput(part, selection);
+ if(!(selection instanceof IStructuredSelection)) {
+ return;
+ }
+
+ // retrieve selected elements
+ // even if is is a list of objects, each object in it should be an EObject...
+ List<Object> newObjects = new ArrayList<Object>();
+ Iterator<?> it = ((IStructuredSelection)selection).iterator();
+ while(it.hasNext()) {
+ Object newObject = getAdaptedObject(it.next());
+ if(newObject != null) {
+ newObjects.add(newObject);
+ }
+ }
+
+ refreshDisplay(newObjects);
+
+ // force the parent to layout
+ parent.layout(false, true);
+ }
+
+ /**
+ * Returns the object adapated to the property view (ex: edit part into the underlying model element
+ *
+ * @param objectToAdapt
+ * the object to adapt
+ * @return the object adapted to the property view
+ */
+ public Object getAdaptedObject(Object objectToAdapt) {
+ if(SEMANTIC_RESOLVER.equals(adapterId)) {
+ return resolveSemanticElement(objectToAdapt);
+ }
+ if(GRAPHIC_RESOLVER.equals(adapterId)) {
+ return resolveGraphicElement(objectToAdapt);
+ }
+ if(EDIT_PART_RESOLVER.equals(adapterId)) {
+ return resolveEditPart(objectToAdapt);
+ }
+ return objectToAdapt;
+ }
+
+ /**
+ * Resolves the semantic element for the specified object
+ *
+ * @param objectToAdapt
+ * the object to retrieve
+ * @return the semantic element for the specified object
+ */
+ protected EObject resolveSemanticElement(Object objectToAdapt) {
+ if(objectToAdapt instanceof EObject) {
+ return (EObject)objectToAdapt;
+ } else if(objectToAdapt instanceof IAdaptable) {
+ IAdaptable adaptable = (IAdaptable)objectToAdapt;
+ if(adaptable.getAdapter(EObject.class) != null) {
+ return (EObject)adaptable.getAdapter(EObject.class);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Resolves the edit part for the specified object
+ *
+ * @param objectToAdapt
+ * the object to retrieve
+ * @return the edit part for the specified object
+ */
+ protected EditPart resolveEditPart(Object objectToAdapt) {
+ if(objectToAdapt instanceof EditPart) {
+ return (EditPart)objectToAdapt;
+ } else if(objectToAdapt instanceof IAdaptable) {
+ IAdaptable adaptable = (IAdaptable)objectToAdapt;
+ if(adaptable.getAdapter(EditPart.class) != null) {
+ return (EditPart)adaptable.getAdapter(EditPart.class);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Resolves the semantic element for the specified object
+ *
+ * @param objectToAdapt
+ * the object to retrieve
+ * @return the semantic element for the specified object
+ */
+ protected View resolveGraphicElement(Object objectToAdapt) {
+ if(objectToAdapt instanceof View) {
+ return (View)objectToAdapt;
+ } else if(objectToAdapt instanceof IAdaptable) {
+ IAdaptable adaptable = (IAdaptable)objectToAdapt;
+ if(adaptable.getAdapter(View.class) != null) {
+ return (View)adaptable.getAdapter(View.class);
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * Refreshes the display (if necessary) for the given set of objects
+ *
+ * @param newObjects
+ * the list of object to edit
+ */
+ protected void refreshDisplay(List<Object> newObjects) {
+ // the editing domain should not be null.
+ // the list should not be empty, and it should not be the same as before. In the latter case, there is no need to update the property section
+ if(!newObjects.isEmpty() && !newObjects.equals(objectsToEdit)) {
+ objectsToEdit = newObjects;
+
+ for(AbstractContainerDescriptor container : containers) {
+ container.dispose();
+ }
+ containers.clear();
+
+ // generate the content of the section, given the configuration
+ for(IFragmentDescriptor viewDescriptor : fragmentDescriptors) {
+ for(AbstractContainerDescriptor descriptor : viewDescriptor.getContainerDescriptors()) {
+ descriptor.createContent(this.parent, this.tabbedPropertySheetPage.getWidgetFactory(), objectsToEdit);
+ containers.add(descriptor);
+ }
+ }
+ }
+ }
+
+ // /**
+ // * Resolve semantic element from a given object. The object tries to be adapted into a {@link EObject}, if possible.
+ // *
+ // * @param object
+ // * the object to resolve
+ // * @return <code>null</code> or the semantic element associated to the specified object
+ // */
+ // protected EObject resolveSemanticObject(Object object) {
+ // if(object instanceof EObject) {
+ // return (EObject)object;
+ // } else if(object instanceof IAdaptable) {
+ // IAdaptable adaptable = (IAdaptable)object;
+ // if(adaptable.getAdapter(EObject.class) != null) {
+ // return (EObject)adaptable.getAdapter(EObject.class);
+ // }
+ // }
+ // return null;
+ // }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/DynamicSectionDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/DynamicSectionDescriptor.java
new file mode 100644
index 00000000000..efd292ae869
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/DynamicSectionDescriptor.java
@@ -0,0 +1,367 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.IFragmentDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.views.properties.tabbed.AbstractSectionDescriptor;
+import org.eclipse.ui.views.properties.tabbed.ISection;
+import org.w3c.dom.Node;
+
+
+/**
+ * Descriptor for sections using controllers.
+ */
+public class DynamicSectionDescriptor extends AbstractSectionDescriptor implements IEnhancedFilter, IConfigurableDescriptor {
+
+ /** semantic resolver */
+ public static final String SEMANTIC_RESOLVER = "Semantic";
+
+ /** id of the graphic resolver */
+ public static final String GRAPHIC_RESOLVER = "Graphic";
+
+ /** id of the edit part resolver */
+ public static final String EDIT_PART_RESOLVER = "EditPart";
+
+ /** section class managing the content */
+ protected ISection section;
+
+ /** id of the section */
+ protected final String id;
+
+ /** id of the tab contributed */
+ protected final String tabId;
+
+ /** stores the unparsed configuration, waiting for the section to be used */
+ protected Node unparsedSectionNode;
+
+ /** indicates if the section has already been parsed */
+ protected boolean unparsed = true;
+
+ /** indicates if the parse was correct */
+ protected boolean parseSectionFailed = false;
+
+ /** list of constraints on this element. This could be OCL, java constraints for example */
+ protected final List<IConstraintDescriptor> constraints;
+
+ /** size of selection */
+ protected final int selectionSize;
+
+ /** object adapter id */
+ protected final String adapterId;
+
+ /** list of replaced ids */
+ protected final List<String> replacedSectionIds;
+
+ /** section which should be before this one */
+ protected final String afterSectionId;
+
+ /** list of fragments to display in the section */
+ protected final List<IFragmentDescriptor> fragmentDescriptors;
+
+
+
+ /**
+ * Creates a new DynamicSectionDescriptor.
+ *
+ * @param id
+ * unique identifier of this section descriptor
+ * @param tabId
+ * id of the tab where this section should be added
+ * @param constraints
+ * the constraints placed on this section, so it should be displayed or not
+ * @param selectionSize
+ * size of the selection
+ * @param adapterID
+ * name of the adapter
+ * @param replacedSectionIds
+ * id of the section replaced by this one
+ * @param afterSectionId
+ * identifier of the section which should be placed before this one
+ * @param fragmentDescriptors
+ * fragments to display in the section
+ */
+ public DynamicSectionDescriptor(String id, String tabId, List<IConstraintDescriptor> constraints, int selectionSize, String adapterID, List<String> replacedSectionIds, String afterSectionId, List<IFragmentDescriptor> fragmentDescriptors) {
+ this.id = id;
+ this.tabId = tabId;
+ this.constraints = constraints;
+ this.selectionSize = selectionSize;
+ this.adapterId = adapterID;
+ this.replacedSectionIds = replacedSectionIds;
+ this.afterSectionId = afterSectionId;
+ this.fragmentDescriptors = fragmentDescriptors;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getEnablesFor() {
+ return selectionSize;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getAfterSection() {
+ if(afterSectionId == null) {
+ return super.getAfterSection();
+ }
+ return afterSectionId;
+ }
+
+ /**
+ * Returns the adapterId for this section descriptor
+ *
+ * @return the adapterId for this section descriptor
+ */
+ public String getAdapterId() {
+ return adapterId;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ISection getSectionClass() {
+ return new DynamicSection(fragmentDescriptors, getAdapterId());
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getTargetTab() {
+ return tabId;
+ }
+
+ /**
+ * Sets the unparsed content for the descriptor.
+ *
+ * @param sectionNode
+ * the node configuring the described section.
+ */
+ public void setUnparsedContent(Node sectionNode) {
+ this.unparsedSectionNode = sectionNode;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IEnhancedFilter getFilter() {
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean select(Object toTest) {
+ return SectionDispatcher.getInstance().isSectionDisplayed(this, toTest);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean appliesTo(IWorkbenchPart part, ISelection selection) {
+ // check all
+ List<DynamicSectionDescriptor> filteredDescriptors = SectionDispatcher.getInstance().getDisplayedSections(part, selection);
+
+ // now, compare the current descriptor. Is it in the list of filtered descriptors ?
+ return filteredDescriptors.contains(this);
+ }
+
+ /**
+ * Determines if this section applies to the selection, without inheritance issue. The section, even if overriden by another visible section, will
+ * return <code>true</code>
+ *
+ * @param part
+ * the current workbench part.
+ * @param selection
+ * the selection.
+ * @return <code>true</code> if this section applies to the current
+ * selection.
+ */
+ public boolean appliesToWithoutSectionInheritance(IWorkbenchPart part, ISelection selection) {
+ return super.appliesTo(part, selection);
+ }
+
+ /**
+ * Returns the constraints
+ *
+ * @return the constraints
+ */
+ public List<IConstraintDescriptor> getConstraints() {
+ return constraints;
+ }
+
+ /**
+ * Returns the object adapated to the property view (ex: edit part into the underlying model element
+ *
+ * @param objectToAdapt
+ * the object to adapt
+ * @return the object adapted to the property view
+ */
+ public Object getAdaptedObject(Object objectToAdapt) {
+ if(SEMANTIC_RESOLVER.equals(adapterId)) {
+ return resolveSemanticElement(objectToAdapt);
+ }
+ if(GRAPHIC_RESOLVER.equals(adapterId)) {
+ return resolveGraphicElement(objectToAdapt);
+ }
+ if(EDIT_PART_RESOLVER.equals(adapterId)) {
+ return resolveEditPart(objectToAdapt);
+ }
+ return objectToAdapt;
+ }
+
+ /**
+ * Resolves the semantic element for the specified object
+ *
+ * @param objectToAdapt
+ * the object to retrieve
+ * @return the semantic element for the specified object
+ */
+ protected EObject resolveSemanticElement(Object objectToAdapt) {
+ if(objectToAdapt instanceof EObject) {
+ return (EObject)objectToAdapt;
+ } else if(objectToAdapt instanceof IAdaptable) {
+ IAdaptable adaptable = (IAdaptable)objectToAdapt;
+ if(adaptable.getAdapter(EObject.class) != null) {
+ return (EObject)adaptable.getAdapter(EObject.class);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Resolves the edit part for the specified object
+ *
+ * @param objectToAdapt
+ * the object to retrieve
+ * @return the edit part for the specified object
+ */
+ protected EditPart resolveEditPart(Object objectToAdapt) {
+ if(objectToAdapt instanceof EditPart) {
+ return (EditPart)objectToAdapt;
+ } else if(objectToAdapt instanceof IAdaptable) {
+ IAdaptable adaptable = (IAdaptable)objectToAdapt;
+ if(adaptable.getAdapter(EditPart.class) != null) {
+ return (EditPart)adaptable.getAdapter(EditPart.class);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Resolves the semantic element for the specified object
+ *
+ * @param objectToAdapt
+ * the object to retrieve
+ * @return the semantic element for the specified object
+ */
+ protected View resolveGraphicElement(Object objectToAdapt) {
+ if(objectToAdapt instanceof View) {
+ return (View)objectToAdapt;
+ } else if(objectToAdapt instanceof IAdaptable) {
+ IAdaptable adaptable = (IAdaptable)objectToAdapt;
+ if(adaptable.getAdapter(View.class) != null) {
+ return (View)adaptable.getAdapter(View.class);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean selectWithoutVisibility(Object objectToTest) {
+ // all constraints provided by the section descriptor should be valid.
+ List<IConstraintDescriptor> constraintDescriptors = getConstraints();
+ if(constraintDescriptors == null || constraintDescriptors.isEmpty()) {
+ // something went wrong during definition or parsing, ignore this section
+ Activator.log.warn("No constraints found for descriptor : " + this.getText());
+ return false;
+ }
+
+ // adapt the selection using adapters provided by the section descriptor
+ Object adaptedObject = getAdaptedObject(objectToTest);
+
+ for(IConstraintDescriptor constraintDescriptor : constraintDescriptors) {
+ if(!constraintDescriptor.select(adaptedObject)) {
+ return false;
+ }
+ }
+
+ // then, is this section in the hidden views (preferences ?)for this kind of object ?
+ return true;
+ }
+
+
+ /**
+ * Returns the replacedSectionIds
+ *
+ * @return the replacedSectionIds
+ */
+ public List<String> getReplacedSectionIds() {
+ return replacedSectionIds;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "Section: " + getId() + " in tab: " + getTargetTab();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return org.eclipse.papyrus.properties.tabbed.core.Activator.getImage("/icons/Section.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public SectionDescriptorState createState(boolean readOnly) {
+ return new SectionDescriptorState(this, readOnly);
+ }
+
+ /**
+ * Returns the list of fragment descriptors for this section
+ *
+ * @return the list of fragment descriptors for this section
+ */
+ public List<IFragmentDescriptor> getFragmentDescriptors() {
+ return fragmentDescriptors;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/DynamicTabDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/DynamicTabDescriptor.java
new file mode 100644
index 00000000000..849424cf68b
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/DynamicTabDescriptor.java
@@ -0,0 +1,68 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view;
+
+import org.eclipse.ui.views.properties.tabbed.AbstractTabDescriptor;
+
+
+/**
+ * Descriptor for tabs used in tabbed properties.
+ */
+public class DynamicTabDescriptor extends AbstractTabDescriptor {
+
+ /** category of the tab */
+ private final String category;
+
+ /** id of the tab */
+ private final String id;
+
+ /** label of the tab */
+ private final String label;
+
+ /**
+ * Creates a new DynamicTabDescriptor.
+ *
+ * @param category
+ * the category of the tab
+ * @param id
+ * the unique identifier for the tab
+ * @param label
+ * the label of the tab
+ */
+ public DynamicTabDescriptor(String category, String id, String label) {
+ this.category = category;
+ this.id = id;
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getCategory() {
+ return category;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getLabel() {
+ return label;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/GetTabDescriptorsFromConfiguration.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/GetTabDescriptorsFromConfiguration.java
new file mode 100644
index 00000000000..b8e5fc1e017
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/GetTabDescriptorsFromConfiguration.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+import org.eclipse.papyrus.properties.runtime.view.IPropertyViewOperation;
+import org.eclipse.ui.views.properties.tabbed.ITabDescriptor;
+
+
+/**
+ * Retrieves the list of tab descriptors for the papyrus property view
+ */
+public class GetTabDescriptorsFromConfiguration implements IPropertyViewOperation {
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<ITabDescriptor> execute(IProvider provider) {
+ if(provider instanceof IPropertyTabViewProvider) {
+ return ((IPropertyTabViewProvider)provider).getTabDescriptors();
+ }
+ return Collections.emptyList();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/IEnhancedFilter.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/IEnhancedFilter.java
new file mode 100644
index 00000000000..c69f01356f1
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/IEnhancedFilter.java
@@ -0,0 +1,31 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view;
+
+import org.eclipse.jface.viewers.IFilter;
+
+
+/**
+ * Improved interface for section filters, as the section can also be removed by another one which could be enabled.
+ */
+public interface IEnhancedFilter extends IFilter {
+
+ /**
+ * Indicates if the element can display the selected object, without any display preference
+ *
+ * @param objectToTest
+ * the object to Test
+ * @return <code>true</code> if the filtered element is enable, without display preferences filter.
+ */
+ public boolean selectWithoutVisibility(Object objectToTest);
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/IPropertyTabViewProvider.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/IPropertyTabViewProvider.java
new file mode 100644
index 00000000000..0d8c1e1a03a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/IPropertyTabViewProvider.java
@@ -0,0 +1,30 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view;
+
+import java.util.List;
+
+import org.eclipse.ui.views.properties.tabbed.ITabDescriptor;
+
+
+/**
+ * Interface for Tabbed property view providers
+ */
+public interface IPropertyTabViewProvider {
+
+ /**
+ * Returns the list of tab descriptors for tab described in the configuration file
+ *
+ * @return the list of tab descriptors for tab described in the configuration file or an empty list
+ */
+ public List<ITabDescriptor> getTabDescriptors();
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/PropertyServiceUtil.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/PropertyServiceUtil.java
new file mode 100644
index 00000000000..1ceb7f8d791
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/PropertyServiceUtil.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view;
+
+import java.util.List;
+
+import org.eclipse.gmf.runtime.common.core.service.ExecutionStrategy;
+import org.eclipse.papyrus.properties.runtime.view.PropertyViewService;
+import org.eclipse.ui.views.properties.tabbed.ITabDescriptor;
+
+
+/**
+ * Util class for {@link PropertyViewService}
+ */
+public class PropertyServiceUtil {
+
+ /**
+ * Returns the tab descriptors for the property view service
+ *
+ * @return the tab descriptors for the property view service
+ */
+ @SuppressWarnings("unchecked")
+ public static List<List<ITabDescriptor>> getTabDescriptors() {
+ return ExecutionStrategy.REVERSE.execute(PropertyViewService.getInstance(), new GetTabDescriptorsFromConfiguration());
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/PropertyTabViewProviderParser.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/PropertyTabViewProviderParser.java
new file mode 100644
index 00000000000..65600d590fe
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/PropertyTabViewProviderParser.java
@@ -0,0 +1,511 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.view.DialogDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.FragmentDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.IFragmentDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.PredefinedFragmentDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.PropertyViewProviderParser;
+import org.eclipse.papyrus.properties.runtime.view.XMLParseException;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.eclipse.papyrus.properties.tabbed.core.view.subfeatures.DynamicSubFeatureSectionDescriptor;
+import org.eclipse.papyrus.properties.tabbed.core.view.subfeatures.EMFSimpleSubFeatureDescriptor;
+import org.eclipse.papyrus.properties.tabbed.core.view.subfeatures.ExpandableContainerDescriptor;
+import org.eclipse.papyrus.properties.tabbed.core.view.subfeatures.GroupContainerDescriptor;
+import org.eclipse.papyrus.properties.tabbed.core.view.subfeatures.SimpleContainerDescriptor;
+import org.eclipse.papyrus.properties.tabbed.core.view.subfeatures.SubFeatureContainerDescriptor;
+import org.eclipse.papyrus.properties.tabbed.core.view.subfeatures.SubFeatureDescriptor;
+import org.eclipse.ui.views.properties.tabbed.ISectionDescriptor;
+import org.eclipse.ui.views.properties.tabbed.ITabDescriptor;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+/**
+ * Parser for the property tab view provider
+ */
+public class PropertyTabViewProviderParser extends PropertyViewProviderParser {
+
+ /** name of the property tab node */
+ protected static final Object NODE_NAME_PROPERTY_TAB_VIEW = "propertyTabView";
+
+ /** key for the id attribute */
+ protected static final String ID = "id";
+
+ /** key for the category attribute */
+ protected static final String CATEGORY = "category";
+
+ /** key for the label attribute */
+ protected static final String LABEL = "label";
+
+ /** attribute name for tab identifier */
+ protected static final String TAB_ID = "tabId";
+
+ /** attribute name for adapter identifier */
+ protected static final String ADAPTER_ID = "adapterId";
+
+ /** node name for sections */
+ protected static final String NODE_NAME_SECTION = "section";
+
+ /** node name for section sets */
+ protected static final String NODE_NAME_SECTION_SET = "sectionSet";
+
+ /** node name for tab */
+ protected static final String NODE_NAME_TAB = "tab";
+
+ /** node name for id */
+ protected static final String NODE_NAME_ID = "id";
+
+ /** attribute for name */
+ protected static final String ATTRIBUTE_NAME = "name";
+
+ /** node name for sub feature sections */
+ protected static final String NODE_NAME_SECTION_SUBFEATURE = "subFeatureSection";
+
+ /** name of the attribute: after section */
+ protected static final String AFTER_SECTION_ID = "afterSection";
+
+ /** link to the list of all available tab descriptors */
+ protected List<ITabDescriptor> tabDescriptors;
+
+ /** list of all tab descriptors provided specifically by this provider */
+ protected List<ITabDescriptor> providedTabDescriptors = new ArrayList<ITabDescriptor>();
+
+ /** list of provided section sets by the provider using this parser */
+ private List<SectionSetDescriptor> providedSectionSets = new ArrayList<SectionSetDescriptor>();
+
+ /**
+ * Creates a new PropertyTabViewProviderParser.
+ *
+ * @param tabDescriptors
+ * list of already available tab descriptors
+ */
+ public PropertyTabViewProviderParser(List<ITabDescriptor> tabDescriptors) {
+ this.tabDescriptors = tabDescriptors;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void parseXMLfile(Document document, Map<String, FragmentDescriptor> predefinedFragments, Map<String, DialogDescriptor> predefinedDialogs) throws XMLParseException {
+ this.predefinedFragments = predefinedFragments;
+ this.predefinedDialogs = predefinedDialogs;
+ NodeList views = document.getChildNodes();
+ for(int i = 0; i < views.getLength(); i++) {
+ Node propertyViewNode = views.item(i);
+ // check this is a "propertyTabView" node, not a comment or a text format node.
+ if(NODE_NAME_PROPERTY_TAB_VIEW.equals(propertyViewNode.getNodeName())) {
+ parsePropertyTabViewNode(propertyViewNode);
+ }
+ }
+ }
+
+ /**
+ * Parses the property view node and adds a view Descriptor to the list of view descriptor maintained by this provider
+ *
+ * @param propertyViewNode
+ * the configuration node of the property view
+ * @throws XMLParseException
+ * parsing failed
+ */
+ protected void parsePropertyTabViewNode(Node propertyViewNode) throws XMLParseException {
+
+ // retrieve plugin id for this contribution, to get the bundle class loader
+ String pluginId = getPluginIdFromTopNode(propertyViewNode);
+ bundle = Platform.getBundle(pluginId);
+
+ // retrieve each child node which is a view
+ NodeList children = propertyViewNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ // check this is a view node (not a comment or a formatting children)
+
+ Node childNode = children.item(i);
+ String childNodeName = childNode.getNodeName();
+ if(NODE_NAME_SECTION_SET.equals(childNodeName)) {
+ getProvidedSectionSets().add(parseSectionSetNode(childNode));
+ } else if(NODE_NAME_TAB.equals(childNodeName)) {
+ DynamicTabDescriptor tabDescriptor = parseTab(childNode);
+ providedTabDescriptors.add(tabDescriptor);
+ // make contribution to tab descriptors
+ tabDescriptors.add(tabDescriptor);
+ }
+ }
+ }
+
+ /**
+ * Parses the tab node configured by the specified node
+ *
+ * @param node
+ * the configuration node for the tab
+ * @return descriptor created by the parser
+ */
+ protected DynamicTabDescriptor parseTab(Node node) {
+ NamedNodeMap attributes = node.getAttributes();
+ String id = null;
+ String label = null;
+ String category = null;
+
+ Node childNode = attributes.getNamedItem(ID);
+ if(childNode != null) {
+ id = childNode.getNodeValue();
+ } else {
+ Activator.log.error("impossible to parse id for the tab using " + node, null);
+ }
+ childNode = attributes.getNamedItem(CATEGORY);
+ if(childNode != null) {
+ category = childNode.getNodeValue();
+ } else {
+ Activator.log.error("impossible to parse category for the tab using " + node, null);
+ }
+ childNode = attributes.getNamedItem(LABEL);
+ if(childNode != null) {
+ label = childNode.getNodeValue();
+ } else {
+ Activator.log.error("impossible to parse label for the tab using " + node, null);
+ }
+
+ if(label != null && id != null && category != null) {
+ DynamicTabDescriptor tabDescriptor = new DynamicTabDescriptor(category, id, label);
+ return tabDescriptor;
+ }
+ return null;
+ }
+
+ /**
+ * Parses the section node set and add the found sections in their corresponding tab descriptors
+ *
+ * @param sectionSetNode
+ * the section set node to parse
+ * @return section set descriptor returned by the parser
+ */
+ protected SectionSetDescriptor parseSectionSetNode(Node sectionSetNode) {
+
+ List<DynamicSectionDescriptor> sectionDescriptors = new ArrayList<DynamicSectionDescriptor>();
+ List<IConstraintDescriptor> constraintDescriptors = new ArrayList<IConstraintDescriptor>();
+ int selectionSize = 0;
+
+ // retrieve name
+ NamedNodeMap attributes = sectionSetNode.getAttributes();
+ String name = null;
+ if(attributes != null) {
+ Node node = attributes.getNamedItem(ATTRIBUTE_NAME);
+ if(node != null) {
+ name = node.getNodeValue();
+ }
+ }
+
+ // parses the children of the section set : [1..1] context and [1..*] sections
+ NodeList children = sectionSetNode.getChildNodes();
+
+ Node contextNode = null;
+ List<Node> sectionNodes = new ArrayList<Node>();
+
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ String nodeName = child.getNodeName();
+ if("context".equals(nodeName)) {
+ contextNode = child;
+ } else if(NODE_NAME_SECTION.equals(nodeName) || NODE_NAME_SECTION_SUBFEATURE.equals(nodeName)) {
+ sectionNodes.add(child);
+ }
+ }
+
+ // check both context node and list of sections
+ if(contextNode == null || sectionNodes.isEmpty()) {
+ Activator.log.error("impossible to find a context node or a list of sections for section set " + name, null);
+ return null;
+ }
+
+ // parses constraints that will be given to each section
+ List<IConstraintDescriptor> constraintDescriptors2 = parseConstraints(contextNode);
+ assert (constraintDescriptors2 != null && !constraintDescriptors2.isEmpty()) : "constraints should not be null...";
+ constraintDescriptors.addAll(constraintDescriptors2);
+
+ // parse size
+ selectionSize = parseSelectionSize(contextNode);
+
+ for(Node sectionNode : sectionNodes) {
+ DynamicSectionDescriptor sectionDescriptor = parseSectionNode(sectionNode, constraintDescriptors, selectionSize);
+ sectionDescriptors.add(sectionDescriptor);
+ }
+
+ return new SectionSetDescriptor(name, sectionDescriptors, constraintDescriptors, selectionSize);
+ }
+
+ /**
+ * Parses the given section node
+ *
+ * @param sectionNode
+ * the section to parse
+ * @param constraints
+ * the list of constraints applied to the descriptor
+ * @param selectionSize
+ * size of the selection
+ * @return the created descriptor
+ */
+ @SuppressWarnings("unchecked")
+ protected DynamicSectionDescriptor parseSectionNode(Node sectionNode, List<IConstraintDescriptor> constraints, int selectionSize) {
+
+ // Is this a subfeature section or a "standard one"
+ String nodeName = sectionNode.getNodeName();
+ boolean isSubFeatureSection = false;
+ if(nodeName.equals(NODE_NAME_SECTION_SUBFEATURE)) {
+ isSubFeatureSection = true;
+ }
+
+ // read attributes
+ NamedNodeMap attributes = sectionNode.getAttributes();
+ String id = null;
+ String tabId = null;
+ String adapterId = null;
+ String afterSection = null;
+ if(attributes != null) {
+ Node node = attributes.getNamedItem(ID);
+ if(node != null) {
+ id = node.getNodeValue();
+ }
+
+ node = attributes.getNamedItem(TAB_ID);
+ if(node != null) {
+ tabId = node.getNodeValue();
+ }
+
+ node = attributes.getNamedItem(ADAPTER_ID);
+ if(node != null) {
+ adapterId = node.getNodeValue();
+ }
+
+ node = attributes.getNamedItem(AFTER_SECTION_ID);
+ if(node != null) {
+ afterSection = node.getNodeValue();
+ }
+ }
+
+ List<String> replacedSectionsId = new ArrayList<String>();
+ List<IFragmentDescriptor> fragmentDescriptors = new ArrayList<IFragmentDescriptor>();
+ try {
+ NodeList children = sectionNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node childNode = children.item(i);
+ if("replacedSections".equals(childNode.getNodeName())) {
+ replacedSectionsId = parseReplacedSectionIds(childNode);
+ } else if(NODE_NAME_FRAGMENT.equals(childNode.getNodeName())) {
+ IFragmentDescriptor fragmentDescriptor = parseFragmentOrPredefinedFragment(childNode);
+ if(fragmentDescriptor != null) {
+ fragmentDescriptors.add(fragmentDescriptor);
+ }
+ }
+ }
+ } catch (XMLParseException e) {
+ Activator.log.error("Problem during parsing of replaced sections for node " + sectionNode, e);
+ }
+
+ if(isSubFeatureSection) {
+ // parse additional information
+ int maxColumn = 2;
+ if(attributes != null) {
+ Node node = attributes.getNamedItem("maxColumn");
+ if(node != null) {
+ maxColumn = Integer.parseInt(node.getNodeValue());
+ }
+ }
+
+ // retrieve the subfeature descriptor
+ NodeList children = sectionNode.getChildNodes();
+ SubFeatureDescriptor subFeatureDescriptor = null;
+ SubFeatureContainerDescriptor subFeatureContainerDescriptor = null;
+ for(int i = 0; i < children.getLength(); i++) {
+ Node childNode = children.item(i);
+ if("subFeatureDescriptor".equals(childNode.getNodeName())) {
+ // retrieve feature name
+ String name = childNode.getAttributes().getNamedItem("featureName").getNodeValue();
+ subFeatureDescriptor = new EMFSimpleSubFeatureDescriptor(name);
+ } else if("subFeatureDescriptorContainer".equals(childNode.getNodeName())) {
+ subFeatureContainerDescriptor = parseSubFeatureContainerDescriptorNode(childNode);
+ }
+ }
+ DynamicSectionDescriptor descriptor = new DynamicSubFeatureSectionDescriptor(id, tabId, constraints, selectionSize, adapterId, replacedSectionsId, afterSection, fragmentDescriptors, subFeatureDescriptor, maxColumn, subFeatureContainerDescriptor);
+ descriptor.setUnparsedContent(sectionNode);
+ // retrieve the tab to add section to it.
+ // this means that the descriptor for the tab should already exist.
+ for(ITabDescriptor tabDescriptor : tabDescriptors) {
+ if(tabDescriptor.getId().equals(tabId)) {
+ tabDescriptor.getSectionDescriptors().add(descriptor);
+ return descriptor;
+ }
+ }
+ } else {
+ DynamicSectionDescriptor descriptor = new DynamicSectionDescriptor(id, tabId, constraints, selectionSize, adapterId, replacedSectionsId, afterSection, fragmentDescriptors);
+ descriptor.setUnparsedContent(sectionNode);
+ // retrieve the tab to add section to it.
+ // this means that the descriptor for the tab should already exist.
+ for(ITabDescriptor tabDescriptor : tabDescriptors) {
+ if(tabDescriptor.getId().equals(tabId)) {
+ // should check if the tab descriptor already contains this section descriptor
+ boolean contains = false;
+ for(ISectionDescriptor dynamicSectionDescriptor : (List<ISectionDescriptor>)tabDescriptor.getSectionDescriptors()) {
+ String sectionId = dynamicSectionDescriptor.getId();
+ if(id.equals(sectionId)) {
+ contains = true;
+ //Activator.log.error("Trying to add a section which already exists", null);
+ }
+ }
+ if(!contains) {
+ tabDescriptor.getSectionDescriptors().add(descriptor);
+ }
+ return descriptor;
+ }
+ }
+ }
+ // should never happen
+ return null;
+ }
+
+ /**
+ * Parses the sub feature container descriptor node
+ *
+ * @param descriptorNode
+ * the node to parse
+ * @return the descriptor
+ */
+ protected SubFeatureContainerDescriptor parseSubFeatureContainerDescriptorNode(Node descriptorNode) {
+ String type = "simpleContainer";
+ NamedNodeMap attributes = descriptorNode.getAttributes();
+ if(attributes != null) {
+ Node typeNode = attributes.getNamedItem("type");
+ if(typeNode != null) {
+ type = typeNode.getNodeValue();
+ }
+ } else {
+ return new SimpleContainerDescriptor();
+ }
+
+ if("simpleContainer".equals(type)) {
+ return new SimpleContainerDescriptor();
+ } else if(GroupContainerDescriptor.GROUP_CONTAINER_TYPE.equals(type)) {
+ String label = "";
+ // attributes are not null, otherwise, the method would have already returned new simpleContainer
+ Node labelNode = attributes.getNamedItem("label");
+ if(labelNode != null) {
+ label = labelNode.getNodeValue();
+ }
+ return new GroupContainerDescriptor(label);
+ } else if(ExpandableContainerDescriptor.EXPANDABLE_CONTAINER_TYPE.equals(type)) {
+ String label = "";
+ Node labelNode = attributes.getNamedItem("label");
+ if(labelNode != null) {
+ label = labelNode.getNodeValue();
+ }
+ return new ExpandableContainerDescriptor(label);
+ }
+ return new SimpleContainerDescriptor();
+ }
+
+ /**
+ * Parses a fragment node, either a predefined node or a locally defined node
+ *
+ * @param fragmentNode
+ * the node to parse
+ */
+ protected IFragmentDescriptor parseFragmentOrPredefinedFragment(Node fragmentNode) {
+ NamedNodeMap attributes = fragmentNode.getAttributes();
+ if(attributes != null) {
+ Node attribute = attributes.getNamedItem(ATTRIBUTE_PREDEFINED_ID);
+ if(attribute != null) {
+ return new PredefinedFragmentDescriptor(attribute.getNodeValue());
+ }
+ }
+
+ // this is a locally defined fragment.
+ // parse it as it was a predefinition of fragment
+ FragmentDescriptor fragmentDescriptor;
+ try {
+ fragmentDescriptor = parseFragment(fragmentNode);
+ if(fragmentDescriptor != null) {
+ predefinedFragments.put(fragmentDescriptor.getId(), fragmentDescriptor);
+ }
+ return fragmentDescriptor;
+ } catch (XMLParseException e) {
+ Activator.log.error(e);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the list of replaced sections ids, given the configuration node
+ *
+ * @param replacedSectionsNode
+ * the node to parse
+ * @return the list of filtered ids.
+ * @throws XMLParseException
+ * exception thrown when parsing goes wrong
+ */
+ protected List<String> parseReplacedSectionIds(Node replacedSectionsNode) throws XMLParseException {
+ List<String> list = new ArrayList<String>();
+ NodeList children = replacedSectionsNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if("replacedSection".equals(child.getNodeName())) {
+ // retrieve attribute id
+ NamedNodeMap attributes = child.getAttributes();
+ if(attributes != null) {
+ Node idNode = attributes.getNamedItem(NODE_NAME_ID);
+ if(idNode != null) {
+ list.add(idNode.getNodeValue());
+ } else {
+ throw new XMLParseException("impossible to fin the id attribute in the replacedSection node " + child);
+ }
+ } else {
+ throw new XMLParseException("impossible to find attributes in the replacedSection node " + child);
+ }
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Returns the result of the parsing
+ *
+ * @return the result of the parsing
+ */
+ protected List<ITabDescriptor> getResult() {
+ return tabDescriptors;
+ }
+
+ /**
+ * Returns the provided section sets by this provider
+ *
+ * @return the provided section sets by this provider
+ */
+ public List<SectionSetDescriptor> getProvidedSectionSets() {
+ return providedSectionSets;
+ }
+
+ /**
+ * Returns the provided TabDescriptors by this provider
+ *
+ * @return the provided TabDescriptors by this provider
+ */
+ public List<ITabDescriptor> getProvidedTabDescriptors() {
+ return providedTabDescriptors;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionDescriptorState.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionDescriptorState.java
new file mode 100644
index 00000000000..f0f943ef3ac
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionDescriptorState.java
@@ -0,0 +1,544 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.state.AbstractState;
+import org.eclipse.papyrus.properties.runtime.state.IFragmentDescriptorState;
+import org.eclipse.papyrus.properties.runtime.state.IState;
+import org.eclipse.papyrus.properties.runtime.state.ITraversableModelElement;
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.IFragmentDescriptor;
+import org.eclipse.papyrus.properties.tabbed.core.Activator;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.views.properties.tabbed.AbstractSectionDescriptor;
+import org.eclipse.ui.views.properties.tabbed.ISectionDescriptor;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * State for section descriptors
+ */
+public class SectionDescriptorState extends AbstractState {
+
+ /** section descriptor managed by this state */
+ protected DynamicSectionDescriptor sectionDescriptor;
+
+ /** list of fragment descriptor states */
+ protected List<IFragmentDescriptorState> fragmentDescriptorStates = new ArrayList<IFragmentDescriptorState>();
+
+ /** list of replaced sections */
+ protected List<ReplacedSectionState> replacedSectionStates = new ArrayList<ReplacedSectionState>();
+
+ /** change support for this bean */
+ protected PropertyChangeSupport changeSupport;
+
+ /** id of the section managed by this state */
+ protected String id;
+
+ /** id of the tab in which the section managed by this state is */
+ protected String targetTab;
+
+ /** adapter Identifier for the descriptor */
+ protected String adapterId;
+
+ /** id of the section which should be before this one */
+ protected String afterSection;
+
+ /**
+ * Creates a new SectionDescriptorState.
+ *
+ * @param sectionDescriptor
+ * the section descriptor managed by this state
+ * @param readOnly
+ * read only mode of the state
+ */
+ public SectionDescriptorState(DynamicSectionDescriptor sectionDescriptor, boolean readOnly) {
+ super(readOnly);
+ this.sectionDescriptor = sectionDescriptor;
+ id = sectionDescriptor.getId();
+ targetTab = sectionDescriptor.getTargetTab();
+ adapterId = sectionDescriptor.getAdapterId();
+ afterSection = sectionDescriptor.getAfterSection();
+
+ List<String> replaceSections = sectionDescriptor.getReplacedSectionIds();
+ for(String replacedSectionId : replaceSections) {
+ getReplacedSectionStates().add(new ReplacedSectionState(replacedSectionId));
+ }
+
+ List<IFragmentDescriptor> fragmentDescriptors = sectionDescriptor.getFragmentDescriptors();
+ for(IFragmentDescriptor fragmentDescriptor : fragmentDescriptors) {
+ /// retrieve the descriptor and creates a state on it
+ if(fragmentDescriptor != null) {
+ getFragmentDescriptorStates().add(fragmentDescriptor.createState(readOnly));
+ }
+ }
+ // register change support
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * Returns the section Descriptor managed by this state
+ *
+ * @return the section Descriptor managed by this state
+ */
+ public DynamicSectionDescriptor getDescriptor() {
+ return sectionDescriptor;
+ }
+
+ /**
+ * Returns the fragmentDescriptor States for the section descriptor
+ *
+ * @return the fragmentDescriptorStates for the section descriptor
+ */
+ public List<IFragmentDescriptorState> getFragmentDescriptorStates() {
+ return fragmentDescriptorStates;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return "SectionDescriptorStateDialog";
+ }
+
+ /**
+ * Adds a property change listener to this class
+ *
+ * @param listener
+ * the listener to add
+ */
+ public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * Removes a property change listener from this class
+ *
+ * @param listener
+ * the listener to remove
+ */
+ public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * Sets the id of the controller managed by this state
+ *
+ * @param id
+ * the id to set
+ */
+ public void setId(String id) {
+ String oldId = this.id;
+ this.id = id;
+
+ changeSupport.firePropertyChange("id", oldId, id);
+ }
+
+ /**
+ * Returns the id of the controller managed by this state
+ *
+ * @return the id of the controller managed by this state
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Returns the adapterId for this section descriptor state
+ *
+ * @return the adapterId for this section descriptor state
+ */
+ public String getAdapterId() {
+ return adapterId;
+ }
+
+ /**
+ * Returns the IDs of available tabs from state store
+ *
+ * @return the list of IDs from state store
+ */
+ public List<String> getAvailableTargetTab() {
+ ArrayList<String> result = new ArrayList<String>();
+
+ //Those available in state
+ List<TabDescriptorState> tabStates = StatesStore.getTabDescriptorStates();
+ for(TabDescriptorState tabDescriptorState : tabStates) {
+ result.add(tabDescriptorState.getId());
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the IDs of available afterSection from state store
+ *
+ * @return the list of IDs from state store
+ */
+ public List<String> getAvailableAfterSection() {
+ ArrayList<String> result = new ArrayList<String>();
+
+ //Top element
+ result.add(ISectionDescriptor.TOP);
+
+ //Those available in state
+ List<SectionSetDescriptorState> sectionSetDescriptorStates = StatesStore.getSectionSetDescriptorStates();
+ for(SectionSetDescriptorState sectionSetDescriptorState : sectionSetDescriptorStates) {
+ List<SectionDescriptorState> sectionDescriptorStates = sectionSetDescriptorState.getSectionDescriptorStates();
+ for(SectionDescriptorState sectionDescriptorState : sectionDescriptorStates) {
+ result.add(sectionDescriptorState.getId());
+ }
+ }
+
+
+
+ return result;
+ }
+
+
+ /**
+ * Sets the adapterId for this section descriptor state
+ *
+ * @param adapterId
+ * the adapterId to set for this section descriptor state
+ */
+ public void setAdapterId(String adapterId) {
+ String oldId = this.adapterId;
+ this.adapterId = adapterId;
+
+ changeSupport.firePropertyChange("adapterId", oldId, adapterId);
+ }
+
+ /**
+ * Sets the targetTab
+ *
+ * @param targetTab
+ * the targetTab to set
+ */
+ public void setTargetTab(String targetTab) {
+ String oldTargetTab = this.targetTab;
+ this.targetTab = targetTab;
+
+ changeSupport.firePropertyChange("targetTab", oldTargetTab, targetTab);
+ }
+
+ /**
+ * Returns the targetTab
+ *
+ * @return the targetTab
+ */
+ public String getTargetTab() {
+ return targetTab;
+ }
+
+ /**
+ * Sets the afterSection
+ *
+ * @param afterSection
+ * the afterSection to set
+ */
+ public void setAfterSection(String afterSection) {
+ changeSupport.firePropertyChange("afterSection", this.afterSection, this.afterSection = afterSection);
+ }
+
+ /**
+ * Returns the afterSection
+ *
+ * @return the afterSection
+ */
+ public String getAfterSection() {
+ return afterSection;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Section: ");
+ buffer.append(getId());
+ buffer.append(" in tab: ");
+ buffer.append(getTargetTab());
+ if(getAfterSection() != AbstractSectionDescriptor.TOP) {
+ buffer.append(" after section: ");
+ buffer.append(getAfterSection());
+ } else {
+ buffer.append(" (unordered)");
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<? extends ITraversableModelElement> getChildren() {
+ List<ITraversableModelElement> children = new ArrayList<ITraversableModelElement>();
+ children.addAll(getReplacedSectionStates());
+ children.addAll(getFragmentDescriptorStates());
+ return children;
+ }
+
+ /**
+ * Adds a fragment descriptor state and throws an event using the change support
+ *
+ * @param state
+ * the state to add
+ */
+ public void addFragmentDescriptorState(IFragmentDescriptorState state) {
+ fragmentDescriptorStates.add(state);
+
+ changeSupport.firePropertyChange(PROPERTY_ADD_CHILD, null, state);
+ }
+
+ /**
+ * Adds a fragment descriptor state and throws an event using the change support
+ *
+ * @param state
+ * the state to add
+ */
+ public void removeFragmentDescriptorState(IFragmentDescriptorState state) {
+ fragmentDescriptorStates.remove(state);
+
+ changeSupport.firePropertyChange(PROPERTY_REMOVE_CHILD, null, state);
+ }
+
+ /**
+ * Serializes this section descriptor state
+ *
+ * @param document
+ * document used to create XML nodes
+ *
+ * @return the node result of the parsing of this state
+ */
+ public Node generateNode(Document document) {
+ Element node = document.createElement("section");
+ node.setAttribute("id", getId());
+ node.setAttribute("tabId", getTargetTab());
+ node.setAttribute("adapterId", getAdapterId());
+ node.setAttribute("afterSection", getAfterSection());
+
+ generateReplacedSectionStates(node, document);
+
+ generateFragmentDescriptorStateNodes(node, document);
+
+ return node;
+ }
+
+ /**
+ * generates the replaced sections ids
+ *
+ * @param node
+ * the node where to add the generated nodes
+ * @param document
+ * the document used to create XML elements
+ */
+ protected void generateReplacedSectionStates(Element node, Document document) {
+ /*
+ * <replacedSections>
+ * <replacedSection id="singleClassifierSection"/>
+ * </replacedSections>
+ */
+ if(getReplacedSectionStates() != null && !getReplacedSectionStates().isEmpty()) {
+ Element root = document.createElement("replacedSections");
+ for(ReplacedSectionState state : getReplacedSectionStates()) {
+ root.appendChild(state.generateNode(document));
+ }
+ node.appendChild(root);
+ }
+
+ }
+
+ /**
+ * Generates for children fragment descriptors
+ *
+ * @param node
+ * the parent node for generated nodes
+ * @param document
+ * the document used to create elements
+ */
+ protected void generateFragmentDescriptorStateNodes(Element node, Document document) {
+ for(IFragmentDescriptorState fragmentDescriptorState : getFragmentDescriptorStates()) {
+ node.appendChild(fragmentDescriptorState.generateNode(document));
+ }
+ }
+
+ /**
+ * Returns the replacedSectionStates
+ *
+ * @return the replacedSectionStates
+ */
+ public List<ReplacedSectionState> getReplacedSectionStates() {
+ return replacedSectionStates;
+ }
+
+ /**
+ * Adds the id to the list of replaced sections
+ *
+ * @param id
+ * the id to add
+ */
+ public void addReplacedSectionState(ReplacedSectionState id) {
+ replacedSectionStates.add(id);
+ changeSupport.firePropertyChange(PROPERTY_ADD_CHILD, null, replacedSectionStates);
+ }
+
+ /**
+ * Removes the id from the list of replaced sections
+ *
+ * @param id
+ * the id to remove
+ */
+ public void removeReplacedSectionState(ReplacedSectionState id) {
+ replacedSectionStates.remove(id);
+ changeSupport.firePropertyChange(PROPERTY_REMOVE_CHILD, null, replacedSectionStates);
+ }
+
+
+ /**
+ * State for the replaced section
+ */
+ public class ReplacedSectionState implements IState, ITraversableModelElement {
+
+ /** id of the replaced section */
+ private String id;
+
+ /** change support for this bean */
+ private PropertyChangeSupport changeSupport;
+
+ /**
+ * Creates a new SectionDescriptorState.ReplacedSectionState.
+ *
+ * @param id
+ * identifier of the section to replace
+ *
+ */
+ public ReplacedSectionState(String id) {
+ this.id = id;
+
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "Replaced Section: " + getId();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/ReplacedSection.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IConfigurableDescriptor getDescriptor() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return "ReplacedSectionStateDialog";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node generateNode(Document document) {
+ Element node = document.createElement("replacedSection");
+ node.setAttribute("id", id);
+ return node;
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isReadOnly() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<? extends ITraversableModelElement> getChildren() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * Returns the id
+ *
+ * @return the id
+ */
+ public String getId() {
+ return id;
+ }
+
+
+ /**
+ * Sets the id
+ *
+ * @param id
+ * the id to set
+ */
+ public void setId(String id) {
+ changeSupport.firePropertyChange("id", this.id, this.id = id);
+ }
+
+ /**
+ * Returns the IDs of available sections from state store
+ *
+ * @return the list of IDs
+ */
+ public List<String> getAvailableId() {
+ ArrayList<String> result = new ArrayList<String>();
+
+ //Those available in state
+ List<SectionSetDescriptorState> sectionSetDescriptorStates = StatesStore.getSectionSetDescriptorStates();
+ for(SectionSetDescriptorState sectionSetDescriptorState : sectionSetDescriptorStates) {
+ List<SectionDescriptorState> sectionDescriptorStates = sectionSetDescriptorState.getSectionDescriptorStates();
+ for(SectionDescriptorState sectionDescriptorState : sectionDescriptorStates) {
+ result.add(sectionDescriptorState.getId());
+ }
+ }
+
+ return result;
+ }
+
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionDispatcher.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionDispatcher.java
new file mode 100644
index 00000000000..71412a0c08e
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionDispatcher.java
@@ -0,0 +1,127 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.views.properties.tabbed.ISectionDescriptor;
+import org.eclipse.ui.views.properties.tabbed.ITabDescriptor;
+
+/**
+ * This class chooses which section should be visible or not, given the current selection
+ */
+public class SectionDispatcher {
+
+ /** instance of this class */
+ protected static SectionDispatcher instance;
+
+ /** current selection */
+ protected ISelection selection;
+
+ /** cache list of valid descriptors */
+ protected List<DynamicSectionDescriptor> validSectionDescriptors;
+
+ /**
+ * Creates a new SectionDispatcher. This constructor is not visible, using singleton pattern.
+ */
+ protected SectionDispatcher() {
+ }
+
+ /**
+ * Returns the singleton instance of this dispatcher.
+ *
+ * @return the singleton instance of this dispatcher
+ */
+ public synchronized static SectionDispatcher getInstance() {
+ if(instance == null) {
+ instance = new SectionDispatcher();
+ }
+ return instance;
+ }
+
+ /**
+ * Returns <code>true</code> if the given section should be displayed for the current object
+ *
+ * @param dynamicSectionDescriptor
+ * the descriptor of the section to test
+ * @param objectToTest
+ * the object to test
+ * @return <code>true</code> if the section should be displayed.
+ */
+ public boolean isSectionDisplayed(DynamicSectionDescriptor dynamicSectionDescriptor, Object objectToTest) {
+ IEnhancedFilter filter = dynamicSectionDescriptor.getFilter();
+ boolean enable = filter.selectWithoutVisibility(objectToTest);
+ return enable;
+ }
+
+ /**
+ * Returns the set of available sections for a given selection. Used to make perfomance improvement
+ *
+ * @param part
+ * the current workbench part.
+ * @param selection
+ * the selection
+ * @return the list of valid descriptors for the current selection
+ */
+ public List<DynamicSectionDescriptor> getDisplayedSections(IWorkbenchPart part, ISelection selection) {
+ if(selection == null) {
+ validSectionDescriptors = new ArrayList<DynamicSectionDescriptor>();
+ } else {
+ // check selection is equivalent to the computed one
+ if(!selection.equals(this.selection)) {
+ this.selection = selection;
+ validSectionDescriptors = new ArrayList<DynamicSectionDescriptor>();
+ // compute the list for this selection
+ List<DynamicSectionDescriptor> availableSectionDescriptors = new ArrayList<DynamicSectionDescriptor>();
+
+ // retrieve the tab descriptors for the given description.
+ // for all section descriptors in the tab descriptor, check if the section should be displayed or not.
+ // then, remove from the visible list the elements which are filtered by other sections
+ for(List<ITabDescriptor> tabDescriptors : PropertyServiceUtil.getTabDescriptors()) {
+ for(ITabDescriptor tabDescriptor : tabDescriptors) {
+ for(Object descriptor : tabDescriptor.getSectionDescriptors()) {
+ ISectionDescriptor sectionDescriptor = (ISectionDescriptor)descriptor;
+ if(sectionDescriptor instanceof DynamicSectionDescriptor) {
+ boolean enable = ((DynamicSectionDescriptor)sectionDescriptor).appliesToWithoutSectionInheritance(part, selection);;
+ if(enable) {
+ availableSectionDescriptors.add((DynamicSectionDescriptor)sectionDescriptor);
+ }
+ }
+ }
+ }
+ }
+
+ // the list of available descriptors is now available, now remove from the list the section descriptors which are erased by others
+ for(DynamicSectionDescriptor currentDescriptor : availableSectionDescriptors) {
+ boolean isRemoved = false;
+ String currentId = currentDescriptor.getId();
+ // is this descriptor removed by another one ?
+ for(DynamicSectionDescriptor descriptor : availableSectionDescriptors) {
+ if(descriptor.getReplacedSectionIds().contains(currentId)) {
+ isRemoved = true;
+ }
+ }
+
+ if(!isRemoved) {
+ validSectionDescriptors.add(currentDescriptor);
+ }
+ }
+ }
+ }
+
+ // returns the list set in cache
+ return validSectionDescriptors;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionSetDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionSetDescriptor.java
new file mode 100644
index 00000000000..c61d2f03bde
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionSetDescriptor.java
@@ -0,0 +1,143 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view;
+
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.AppliedStereotypeConstraintDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.ObjectTypeConstraintDescriptor;
+import org.eclipse.papyrus.properties.tabbed.core.Activator;
+import org.eclipse.swt.graphics.Image;
+
+
+/**
+ * Descriptor for section set (used mostly for configuration purpose)
+ */
+public class SectionSetDescriptor implements IConfigurableDescriptor {
+
+ /** list of section descriptors own by this section set */
+ private final List<DynamicSectionDescriptor> sectionDescriptors;
+
+ /** list of constraint descriptors placed on this section set */
+ private final List<IConstraintDescriptor> constraintDescriptors;
+
+ /** name of this section set, mostly used during configuration or debug time */
+ private final String name;
+
+ /** size of the selection */
+ private final int selectionSize;
+
+ /**
+ * Creates a new SectionSetDescriptor.
+ *
+ * @param name
+ * name of the section state
+ * @param sectionDescriptors
+ * list of contained section descriptors
+ * @param constraintDescriptors
+ * list of constraints on the section descriptor
+ * @param selectionSize
+ * size of the selection
+ *
+ */
+ public SectionSetDescriptor(String name, List<DynamicSectionDescriptor> sectionDescriptors, List<IConstraintDescriptor> constraintDescriptors, int selectionSize) {
+ this.name = name;
+ this.sectionDescriptors = sectionDescriptors;
+ this.constraintDescriptors = constraintDescriptors;
+ this.selectionSize = selectionSize;
+ }
+
+ /**
+ * Returns the sectionDescriptors owned by the described section set
+ *
+ * @return the sectionDescriptors owned by the described section set
+ */
+ public List<DynamicSectionDescriptor> getSectionDescriptors() {
+ return sectionDescriptors;
+ }
+
+ /**
+ * Returns the constraintDescriptors placed on the described section set
+ *
+ * @return the constraintDescriptors placed on the described section set
+ */
+ public List<IConstraintDescriptor> getConstraintDescriptors() {
+ return constraintDescriptors;
+ }
+
+ /**
+ * Returns the size of the selection for this described section set
+ *
+ * @return the size of the selection for this described section set
+ */
+ public int getSelectionSize() {
+ return selectionSize;
+ }
+
+ /**
+ * Returns the name of this section set descriptor
+ *
+ * @return the name of this section set descriptor
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(getName());
+ buffer.append(": ");
+ // retrieve metaclass constraint
+ String metaclassName = "";
+ for(IConstraintDescriptor constraintDescriptor : getConstraintDescriptors()) {
+ if(constraintDescriptor instanceof ObjectTypeConstraintDescriptor) {
+ metaclassName = ((ObjectTypeConstraintDescriptor)constraintDescriptor).getElementClass().getCanonicalName();
+ }
+ }
+ buffer.append(metaclassName);
+
+ // now append selection size between '[' and ']'
+ int selectionSize = getSelectionSize();
+ buffer.append(" [");
+ buffer.append((selectionSize >= 0) ? selectionSize : "*");
+ buffer.append(']');
+
+ // append stereotype required
+ for(IConstraintDescriptor constraintDescriptor : getConstraintDescriptors()) {
+ if(constraintDescriptor instanceof AppliedStereotypeConstraintDescriptor) {
+ buffer.append('<');
+ buffer.append(((AppliedStereotypeConstraintDescriptor)constraintDescriptor).getStereotypeQualifiedNames());
+ buffer.append('>');
+ }
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/SectionSet.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public SectionSetDescriptorState createState(boolean readOnly) {
+ return new SectionSetDescriptorState(this, readOnly);
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionSetDescriptorState.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionSetDescriptorState.java
new file mode 100644
index 00000000000..19f3ff7ecb3
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/SectionSetDescriptorState.java
@@ -0,0 +1,269 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.state.AbstractState;
+import org.eclipse.papyrus.properties.runtime.state.ITraversableModelElement;
+import org.eclipse.papyrus.properties.runtime.view.constraints.AppliedStereotypeConstraintDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.ConstraintDescriptorState;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.ObjectTypeConstraintDescriptor;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * State for section set descriptors
+ */
+public class SectionSetDescriptorState extends AbstractState {
+
+ /** list of sections for this section set */
+ protected final List<SectionDescriptorState> sectionDescriptorStates = new ArrayList<SectionDescriptorState>();
+
+ /** list of constraints for this section set */
+ protected final List<ConstraintDescriptorState> constraintDescriptorStates = new ArrayList<ConstraintDescriptorState>();
+
+ /** descriptor for section sets */
+ protected final SectionSetDescriptor sectionSetDescriptor;
+
+ /** name of the section set descriptor */
+ private String name;
+
+ /** selection size */
+ private int selectionSize;
+
+ /** change support for this bean */
+ private PropertyChangeSupport changeSupport;
+
+ /**
+ * Returns the sectionSetDescriptor managed by this state
+ *
+ * @return the sectionSetDescriptor managed by this state
+ */
+ public SectionSetDescriptor getDescriptor() {
+ return sectionSetDescriptor;
+ }
+
+ /**
+ * Creates a new SectionSetDescriptorState.
+ *
+ * @param sectionSetDescriptor
+ * descriptor for section sets
+ * @param readOnly
+ * read only mode of the state
+ */
+ public SectionSetDescriptorState(SectionSetDescriptor sectionSetDescriptor, boolean readOnly) {
+ super(readOnly);
+ this.sectionSetDescriptor = sectionSetDescriptor;
+ this.name = sectionSetDescriptor.getName();
+ this.selectionSize = sectionSetDescriptor.getSelectionSize();
+
+ // retrieve and build the states for the children sections
+ for(DynamicSectionDescriptor abstractSectionDescriptor : sectionSetDescriptor.getSectionDescriptors()) {
+ SectionDescriptorState sectionState = abstractSectionDescriptor.createState(readOnly);
+ sectionDescriptorStates.add(sectionState);
+ }
+
+ // retrieve and build the states for the children sections
+ for(IConstraintDescriptor constraintDescriptor : sectionSetDescriptor.getConstraintDescriptors()) {
+ ConstraintDescriptorState constraintState = constraintDescriptor.createState(readOnly);
+ constraintDescriptorStates.add(constraintState);
+ }
+ // register change support
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * Sets the name
+ *
+ * @param name
+ * the name to set
+ */
+ public void setName(String name) {
+ changeSupport.firePropertyChange("name", this.name, this.name = name);
+ }
+
+ /**
+ * Returns the name
+ *
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the selectionSize
+ *
+ * @param selectionSize
+ * the selectionSize to set
+ */
+ public void setSelectionSize(int selectionSize) {
+ changeSupport.firePropertyChange("selectionSize", this.selectionSize, this.selectionSize = selectionSize);
+ }
+
+ /**
+ * Returns the selectionSize
+ *
+ * @return the selectionSize
+ */
+ public int getSelectionSize() {
+ return selectionSize;
+ }
+
+ /**
+ * Returns the label for this section set descriptor state
+ *
+ * @return the label for this section set descriptor state
+ */
+ public String getLabel() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(name);
+ buffer.append(": ");
+ // retrieve metaclass constraint
+ String metaclassName = "";
+ for(IConstraintDescriptor constraintDescriptor : getDescriptor().getConstraintDescriptors()) {
+ if(constraintDescriptor instanceof ObjectTypeConstraintDescriptor) {
+ metaclassName = ((ObjectTypeConstraintDescriptor)constraintDescriptor).getElementClass().getCanonicalName();
+ }
+ }
+ buffer.append(metaclassName);
+
+ // now append selection size between '[' and ']'
+ buffer.append(" [");
+ buffer.append((selectionSize >= 0) ? selectionSize : "*");
+ buffer.append(']');
+
+ // append stereotype required
+ for(IConstraintDescriptor constraintDescriptor : getDescriptor().getConstraintDescriptors()) {
+ if(constraintDescriptor instanceof AppliedStereotypeConstraintDescriptor) {
+ buffer.append('<');
+ buffer.append(((AppliedStereotypeConstraintDescriptor)constraintDescriptor).getStereotypeQualifiedNames());
+ buffer.append('>');
+ }
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * Returns the constraintDescriptor States for this section set
+ *
+ * @return the constraintDescriptor States for this section set
+ */
+ public List<ConstraintDescriptorState> getConstraintDescriptorStates() {
+ return constraintDescriptorStates;
+ }
+
+ /**
+ * Returns the sectionDescriptor States for this section set
+ *
+ * @return the sectionDescriptor States for this section set
+ */
+ public List<SectionDescriptorState> getSectionDescriptorStates() {
+ return sectionDescriptorStates;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return "SectionSetDescriptorStateDialog";
+ }
+
+ /**
+ * Adds a property change listener to this class
+ *
+ * @param listener
+ * the listener to add
+ */
+ public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * Removes a property change listener from this class
+ *
+ * @param listener
+ * the listener to remove
+ */
+ public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<? extends ITraversableModelElement> getChildren() {
+ List<ITraversableModelElement> children = new ArrayList<ITraversableModelElement>();
+ children.addAll(getConstraintDescriptorStates());
+ children.addAll(getSectionDescriptorStates());
+ return children;
+ }
+
+ /**
+ * adds a section descriptor state and fire a add event
+ *
+ * @param state
+ * the state to add
+ */
+ public void addSectionDescriptorState(SectionDescriptorState state) {
+ sectionDescriptorStates.add(state);
+ changeSupport.firePropertyChange(PROPERTY_ADD_CHILD, null, sectionDescriptorStates);
+ }
+
+ /**
+ * adds a section descriptor state and fire a add event
+ *
+ * @param state
+ * the state to add
+ */
+ public void removeSectionDescriptorState(SectionDescriptorState state) {
+ sectionDescriptorStates.remove(state);
+ changeSupport.firePropertyChange(PROPERTY_REMOVE_CHILD, null, sectionDescriptorStates);
+ }
+
+ /**
+ * Serializes this section set descriptor state
+ *
+ * @param document
+ * document used to create XML nodes
+ *
+ * @return the node result of the parsing of this state
+ */
+ public Node generateNode(Document document) {
+ Element sectionSetDescriptorNode = document.createElement("sectionSet");
+ sectionSetDescriptorNode.setAttribute("name", name);
+
+ // create the context
+ Element contextNode = document.createElement("context");
+ contextNode.setAttribute("enablesFor", "" + selectionSize);
+ // generate for each constraint
+ for(ConstraintDescriptorState constraintState : getConstraintDescriptorStates()) {
+ Node node = constraintState.generateNode(document);
+ contextNode.appendChild(node);
+ }
+ sectionSetDescriptorNode.appendChild(contextNode);
+
+ // generate for section
+ for(SectionDescriptorState sectionState : getSectionDescriptorStates()) {
+ Node node = sectionState.generateNode(document);
+ sectionSetDescriptorNode.appendChild(node);
+ }
+ return sectionSetDescriptorNode;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/StatesStore.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/StatesStore.java
new file mode 100644
index 00000000000..8d53d15eee5
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/StatesStore.java
@@ -0,0 +1,156 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Florian Noyrit (CEA LIST) florian.noyrit@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view;
+
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.papyrus.properties.tabbed.core.Activator;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.views.properties.tabbed.ISectionDescriptor;
+
+/**
+ * This class stores the states: sectionSets and tabs
+ * It provides corresponding retrieve and store methods
+ */
+public class StatesStore {
+
+ /** available tab states for this wizard page */
+ protected static Vector<TabDescriptorState> tabDescriptorStates;
+
+ /** available section states for this wizard page */
+ protected static List<SectionSetDescriptorState> sectionSetDescriptorStates;
+
+ /**
+ * Get the tab descriptor states.
+ *
+ * @return the list of descriptor states
+ */
+ public static List<TabDescriptorState> getTabDescriptorStates() {
+ return tabDescriptorStates;
+ }
+
+ /**
+ * Set the tab descriptor states.
+ *
+ * @param tabDescriptorStates2
+ * the list to set
+ */
+ public static void setTabDescriptorStates(List<TabDescriptorState> tabDescriptorStates2) {
+ tabDescriptorStates = new Vector<TabDescriptorState>(tabDescriptorStates2);
+ }
+
+ /**
+ * Get the sectionSet descriptor states.
+ *
+ * @return the list of section descriptor states
+ */
+ public static List<SectionSetDescriptorState> getSectionSetDescriptorStates() {
+ return sectionSetDescriptorStates;
+ }
+
+ /**
+ * Set the tab sectionSet states.
+ *
+ * @param sectionSeDescriptorStates2
+ * the list to set
+ */
+ public static void setSectionSetDescriptorStates(List<SectionSetDescriptorState> sectionSeDescriptorStates2) {
+ sectionSetDescriptorStates = new Vector<SectionSetDescriptorState>(sectionSeDescriptorStates2);
+ }
+
+ /**
+ * Get the text for the tab mentioned TargetTab of a section.
+ *
+ * @param id
+ * the id of the tab to get the text from
+ * @return the text corresponding to the tab
+ */
+ public static String getTextSectionDescriptorStateTargetTab(String id) {
+ for(TabDescriptorState tabDescriptorState : tabDescriptorStates) {
+ if(tabDescriptorState.getId().compareTo(id) == 0) {
+ return tabDescriptorState.getText();
+ }
+
+ }
+ return null;
+ }
+
+ /**
+ * Get the text for the section mentioned in AfterSection of a section.
+ *
+ * @param id
+ * the id of the section to get the text from
+ * @return the text corresponding to the section
+ */
+ public static String getTextSectionDescriptorStateAfterSection(String id) {
+
+ if(id.equals(ISectionDescriptor.TOP)) {
+ return id;
+ }
+
+ for(SectionSetDescriptorState sectionSetDescriptorState : sectionSetDescriptorStates) {
+ for(SectionDescriptorState sectionDescriptorState : sectionSetDescriptorState.getSectionDescriptorStates()) {
+ if(sectionDescriptorState.getId().compareTo(id) == 0) {
+ return sectionDescriptorState.getText();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get the text for the section mentioned in id of a replacedSection.
+ *
+ * @param id
+ * the id of the section to get the text from
+ * @return the text corresponding to the section
+ */
+ public static String getTextReplacedSectionStateId(String id) {
+ for(SectionSetDescriptorState sectionSetDescriptorState : sectionSetDescriptorStates) {
+ for(SectionDescriptorState sectionDescriptorState : sectionSetDescriptorState.getSectionDescriptorStates()) {
+ if(sectionDescriptorState.getId().compareTo(id) == 0) {
+ return sectionDescriptorState.getText();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get the image for the tab (corresponding to TargetTab of a section).
+ *
+ * @return the image for a tab
+ */
+ public static Image getImageSectionDescriptorStateTargetTab() {
+ return Activator.getImage("/icons/Tab.gif");
+ }
+
+ /**
+ * Get the image for the section (corresponding to AfterSection of a section).
+ *
+ * @return the image for a section
+ */
+ public static Image getImageSectionDescriptorStateAfterSection() {
+ return Activator.getImage("/icons/Section.gif");
+ }
+
+ /**
+ * Get the image for the section (corresponding to Id of a replacedSection).
+ *
+ * @return the image for a section
+ */
+ public static Image getImageReplacedSectionStateId() {
+ return Activator.getImage("/icons/Section.gif");
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/TabDescriptorState.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/TabDescriptorState.java
new file mode 100644
index 00000000000..199f88dd3b4
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/TabDescriptorState.java
@@ -0,0 +1,235 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.state.AbstractState;
+import org.eclipse.papyrus.properties.runtime.state.ITraversableModelElement;
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+import org.eclipse.papyrus.properties.tabbed.core.Activator;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.views.properties.tabbed.ITabDescriptor;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * State for tab descriptors
+ */
+public class TabDescriptorState extends AbstractState {
+
+ /** tab descriptor managed by this state */
+ protected ITabDescriptor tabDescriptor;
+
+ /** change support for this bean */
+ private PropertyChangeSupport changeSupport;
+
+ /** id of the tab descriptor */
+ private String id;
+
+ /** category of the tab descriptor */
+ private String category;
+
+ /** label of the tab descriptor */
+ private String label;
+
+ /** after tab info of the tab descriptor */
+ private String afterTab;
+
+ /**
+ * Creates a new TabDescriptorState.
+ *
+ * @param tabDescriptor
+ * tab descriptor managed by this state
+ * @param readOnly
+ * read only mode of the descriptor
+ */
+ public TabDescriptorState(ITabDescriptor tabDescriptor, boolean readOnly) {
+ super(readOnly);
+ this.tabDescriptor = tabDescriptor;
+ this.id = tabDescriptor.getId();
+ this.label = tabDescriptor.getLabel();
+ this.afterTab = tabDescriptor.getAfterTab();
+ this.category = tabDescriptor.getCategory();
+
+ // register change support
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+
+ /**
+ * Returns the tabDescriptor managed by this state
+ *
+ * @return the tabDescriptor managed by this state
+ */
+ public ITabDescriptor getTabDescriptor() {
+ return tabDescriptor;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return label + " (Caterory: " + category + ")";
+ }
+
+ /**
+ * Returns the id of the descriptor managed by this state
+ *
+ * @return the id of the descriptor managed by this state
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Returns the label of the descriptor managed by this state
+ *
+ * @return the label of the descriptor managed by this state
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * Returns the after tab info of the descriptor managed by this state
+ *
+ * @return the after tab info of the descriptor managed by this state
+ */
+ public String getAfterTab() {
+ return afterTab;
+ }
+
+ /**
+ * Returns the category of the descriptor managed by this state
+ *
+ * @return the category of the descriptor managed by this state
+ */
+ public String getCategory() {
+ return category;
+ }
+
+ /**
+ * Sets the id of this tab
+ *
+ * @param id
+ * the identifier to set
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * Sets the new label for this state
+ *
+ * @param label
+ * the new label to set
+ */
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ /**
+ * Sets the new after tab info for this state
+ *
+ * @param afterTab
+ * the new after tab to set
+ */
+ public void setAfterTab(String afterTab) {
+ this.afterTab = afterTab;
+ }
+
+ /**
+ * Sets the new category for this state
+ *
+ * @param category
+ * the new category to set
+ */
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/Tab.gif");
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public IConfigurableDescriptor getDescriptor() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return "TabDescriptorStateDialog";
+ }
+
+ /**
+ * Adds a property change listener to this class
+ *
+ * @param listener
+ * the listener to add
+ */
+ public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * Removes a property change listener from this class
+ *
+ * @param listener
+ * the listener to remove
+ */
+ public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node generateNode(Document document) {
+ Element tabDescriptorNode = document.createElement("tab");
+ tabDescriptorNode.setAttribute("category", category);
+ tabDescriptorNode.setAttribute("id", id);
+ tabDescriptorNode.setAttribute("label", label);
+
+ List<TabDescriptorState> tabDescriptorStates = StatesStore.getTabDescriptorStates();
+ int index = tabDescriptorStates.indexOf(this);
+ if(index != 0) {
+ tabDescriptorNode.setAttribute("afterTab", tabDescriptorStates.get(index - 1).id);
+ }
+
+ return tabDescriptorNode;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<? extends ITraversableModelElement> getChildren() {
+ return Collections.emptyList();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/XMLPropertyTabViewProvider.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/XMLPropertyTabViewProvider.java
new file mode 100644
index 00000000000..6eb33702b18
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/XMLPropertyTabViewProvider.java
@@ -0,0 +1,349 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.view.PropertyViewProviderParser;
+import org.eclipse.papyrus.properties.runtime.view.XMLParseException;
+import org.eclipse.papyrus.properties.runtime.view.XMLPropertyViewProvider;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.XMLMemento;
+import org.eclipse.ui.views.properties.tabbed.ITabDescriptor;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+/**
+ * Provider for the tabbed properties view, based on an xml description of the content
+ */
+public class XMLPropertyTabViewProvider extends XMLPropertyViewProvider implements IPropertyTabViewProvider {
+
+ /** list of tab descriptors provided by this provider */
+ protected List<ITabDescriptor> tabDescriptors = new ArrayList<ITabDescriptor>();
+
+ /** stores the configuration child, need in case of customization */
+ protected IConfigurationElement properyViewContributionConfigurationElement;
+
+ /** bundle that declares this extension */
+ protected Bundle bundle;
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected PropertyViewProviderParser createParser() {
+ return new PropertyTabViewProviderParser(tabDescriptors);
+ }
+
+ /**
+ * Returns the id of this provider
+ *
+ * @return the id of this provider
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean provides(IOperation operation) {
+ if(operation instanceof GetTabDescriptorsFromConfiguration) {
+ return true;
+ }
+ return super.provides(operation);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<ITabDescriptor> getTabDescriptors() {
+ return tabDescriptors;
+ }
+
+
+ /**
+ * Configures this provider, retrieving the xml file and parsing it.
+ *
+ * @param element
+ * the configuration element for this provider
+ */
+ public void configure(IConfigurationElement element) {
+ // 1. retrieve path of the xml file
+ IConfigurationElement[] children = element.getChildren();
+ bundle = Platform.getBundle(element.getContributor().getName());
+ if(bundle == null) {
+ Activator.log.warn("Ignoring extension " + element + ". Impossible to find bundle " + bundle); //$NON-NLS-1$ //$NON-NLS-2$
+ return;
+ }
+ for(IConfigurationElement child : children) {
+ if(PROPERTY_VIEW_CONTRIBUTION.equals(child.getName())) {
+ // this is one of the configuration, parses the config itself, i.e. retrieve the xml file
+ // there is only one property view contribution child, it is possible to store this to reuse this later during customization exercise.
+ properyViewContributionConfigurationElement = child;
+ name = child.getAttribute(NAME);
+ id = child.getAttribute(ID);
+ if(id == null) {
+ Activator.log.error("impossible to find id for this contribution: " + name, null); //$NON-NLS-1$
+ return;
+ }
+ description = child.getAttribute(DESCRIPTION);
+ String iconPath = child.getAttribute(ICON);
+ if(iconPath != null) {
+ iconDescriptor = Activator.imageDescriptorFromPlugin(element.getContributor().getName(), iconPath);
+ }
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ try {
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+
+ // retrieve xml file from path
+ // this path can be the path given in the plugin.xml file, but it could also be given by preferences..
+ // first, check if a preference is present for this contribution
+ String path = getCustomization(id);
+ InputStream stream = getConfigurationContent();
+ // the file should never be null in this implementation, but sub-classes could return null
+ if(stream == null) {
+ throw new IOException("Impossible to load file: " + path); //$NON-NLS-1$
+ } else {
+ Document document = documentBuilder.parse(stream);
+ getParser().parseXMLfile(document, this.predefinedFragments, this.predefinedDialogs);
+ }
+ } catch (ParserConfigurationException e) {
+ Activator.log.error(e);
+ } catch (IOException e) {
+ Activator.log.error(e);
+ } catch (SAXException e) {
+ Activator.log.error(e);
+ } catch (XMLParseException e) {
+ Activator.log.error(e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the file that defines the content of the property view defined by this provider
+ *
+ * @return the file, located either in the plugin defining the provider, or in the preference area of the plugin
+ * @throws IOException
+ * exception thrown when configuration file could not be found
+ */
+ public InputStream getConfigurationContent() throws IOException {
+ // check if there is a local definition for the content of the property view
+ String path = getCustomization(id);
+ InputStream stream = null;
+ if(path != null) {
+ // load the local file
+ Activator.log.debug("Loading local file for provider: " + id + " in: " + path); // $NON-NLS-1$ $NON-NLS-2$
+ stream = getLocalXmlfileContent(properyViewContributionConfigurationElement, path, bundle);
+ } else {
+ // no custom for this file. Use the one in the plugin jar file
+ stream = getXmlFile(properyViewContributionConfigurationElement, properyViewContributionConfigurationElement.getAttribute(XML_PATH), bundle);
+ }
+ // the file should never be null in this implementation, but sub-classes could return null
+ if(stream == null) {
+ throw new IOException("Impossible to load file: " + path); //$NON-NLS-1$
+ } else {
+ return stream;
+ }
+ }
+
+ /**
+ * Returns the content of the file, in the preference area
+ *
+ * @param child
+ * the configuration element
+ * @param path
+ * the path to the file, from the plugin preference place in .metadata place.
+ * @param bundle
+ * the bundle which defines the extension
+ * @return the content of the file
+ * @throws FileNotFoundException
+ */
+ protected InputStream getLocalXmlfileContent(IConfigurationElement child, String path, Bundle bundle) throws FileNotFoundException {
+ return new FileInputStream(getLocalXmlfile(path));
+ }
+
+ /**
+ * Returns the file, in the preference area
+ *
+ * @param path
+ * the path to the file, from the plugin preference place in .metadata place.
+ * @return the file in the preference area
+ */
+ public File getLocalXmlfile(String path) {
+ File file = Activator.getDefault().getStateLocation().append(path).toFile();
+ return file;
+ }
+
+ /**
+ * Retrieves the root memento from the plugin preferences if there were existing property
+ * customizations.
+ *
+ * @return the root memento. if needed, it creates one.
+ */
+ protected XMLMemento getExistingCustomizations() {
+ String sValue = getPreferenceStore().getString(PROPERTY_VIEW_CUSTOMIZATIONS_ID);
+ try {
+ if(sValue != null && !sValue.equals("")) { //$NON-NLS-1$
+ XMLMemento rootMemento = XMLMemento.createReadRoot(new StringReader(sValue));
+ return rootMemento;
+ } else {
+ return XMLMemento.createWriteRoot(PROPERTY_VIEW_CUSTOMIZATIONS_ID);
+ }
+ } catch (WorkbenchException e) {
+ Activator.log.error("Impossible to read preferences", e); //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ /**
+ * Returns the preference store used by this provider
+ *
+ * @return the preference store used by this provider
+ */
+ protected IPreferenceStore getPreferenceStore() {
+ return Activator.getDefault().getPreferenceStore();
+ }
+
+ /**
+ * Saves the given root memento into the preferences
+ *
+ * @param rootMemento
+ * the memento to save
+ */
+ public void saveCustomizations(XMLMemento rootMemento) {
+ // save memento
+ StringWriter writer = new StringWriter();
+ try {
+ rootMemento.save(writer);
+
+ if(getPreferenceStore() != null) {
+ getPreferenceStore().setValue(PROPERTY_VIEW_CUSTOMIZATIONS_ID, writer.toString());
+ }
+ } catch (IOException e) {
+ Activator.log.error("input/ouput exception", e); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Returns the customization for the specified provider, find using its identifier
+ *
+ * @param providerId
+ * id of the provider
+ * @return the path of the file
+ */
+ public String getCustomization(String providerId) {
+ XMLMemento root = getExistingCustomizations();
+ IMemento[] mementos = root.getChildren(PROPERTY_VIEW_CUSTOMIZATION);
+ for(int i = 0; i < mementos.length; i++) {
+ IMemento memento = mementos[i];
+ // check the id
+ String id = memento.getString(ID);
+ if(providerId.equals(id)) {
+ return memento.getString(MEMENTO_PATH);
+ }
+ }
+ return null;
+
+ }
+
+ /**
+ * Updates the configuration file for the content of the property view.
+ *
+ * @param file
+ * the new file that contains the content
+ */
+ public void setConfigurationFile(File file) {
+ XMLMemento root = getExistingCustomizations();
+ IMemento memento = retrieveMemento(root);
+
+ if(memento == null) {
+ memento = createMemento(root);
+ }
+
+ updateMemento(memento, file.getName());
+
+ // saving customization. The preferences being updated, this should allow providers to update
+ saveCustomizations(root);
+ }
+
+ /**
+ * Updates the memento, giving the new path for this provider
+ *
+ * @param memento
+ * the memento to update
+ * @param filePath
+ * the path to the new file
+ */
+ protected void updateMemento(IMemento memento, String filePath) {
+ memento.putString(MEMENTO_PATH, filePath);
+ }
+
+ /**
+ * Creates a memento, and appends it to the specified memento
+ *
+ * @param root
+ * the root memento where to add the created memento
+ * @return the newly created memento
+ */
+ protected IMemento createMemento(XMLMemento root) {
+ IMemento newMemento = root.createChild(PROPERTY_VIEW_CUSTOMIZATION);
+ newMemento.putString(ID, getId());
+ return newMemento;
+ }
+
+ /**
+ * Retrieves the memento from the specified memento
+ *
+ * @param root
+ * the root memento where to look for the memento
+ * @return <code>null</code> if not found, the found memento in other case.
+ */
+ protected IMemento retrieveMemento(XMLMemento root) {
+ IMemento[] mementos = root.getChildren(PROPERTY_VIEW_CUSTOMIZATION);
+
+ // retrieve memento. If not existing, create a new one
+ for(int i = 0; i < mementos.length; i++) {
+ IMemento memento = mementos[i];
+ // check the id
+ String id = memento.getString(ID);
+ if(getId().equals(id)) {
+ return memento;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/DynamicSubFeatureSection.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/DynamicSubFeatureSection.java
new file mode 100644
index 00000000000..576d2471083
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/DynamicSubFeatureSection.java
@@ -0,0 +1,127 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view.subfeatures;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.view.IFragmentDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.content.AbstractContainerDescriptor;
+import org.eclipse.papyrus.properties.tabbed.core.view.DynamicSection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * This section handles sub features of the current selected element.
+ * <P>
+ * It does not handle currently multi-selection of objects.
+ * </P>
+ */
+public class DynamicSubFeatureSection extends DynamicSection {
+
+ /** Elements being currently edited. This corresponds to the values holded by the sub-feature */
+ protected List<Object> subElementsToEdit;
+
+ /** feature descriptor to access to sub elements to edit */
+ protected final SubFeatureDescriptor subFeatureDescriptor;
+
+ /** number max of columns */
+ protected final int maxColumn;
+
+ /** main container for the sub feature section */
+ protected final SubFeatureContainerDescriptor subFeatureContainerDescriptor;
+
+ /**
+ * Creates a new DynamicSubFeatureSection.
+ *
+ * @param viewDescriptors
+ * the list of fragment descriptors contained by this section
+ * @param subFeatureDescriptor
+ * the descriptor for the sub feature
+ * @param maxColumn
+ * the number of columns max
+ * @param subFeatureContainerDescriptor
+ * descriptor of the container
+ */
+ public DynamicSubFeatureSection(List<IFragmentDescriptor> viewDescriptors, SubFeatureDescriptor subFeatureDescriptor, int maxColumn, SubFeatureContainerDescriptor subFeatureContainerDescriptor, String adapterId) {
+ super(viewDescriptors, adapterId);
+ this.subFeatureDescriptor = subFeatureDescriptor;
+ this.maxColumn = maxColumn;
+ this.subFeatureContainerDescriptor = subFeatureContainerDescriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void refreshDisplay(List<Object> newObjects) {
+ // the editing domain should not be null.
+ // the list should not be empty, and it should not be the same as before. In the latter case, there is no need to update the property section
+ if(!newObjects.isEmpty() && !newObjects.equals(objectsToEdit)) {
+ objectsToEdit = newObjects;
+
+ // compute new list of sub elements to edit
+ List<Object> subObjects = getSubFeatureDescriptor().getSubElementsToEdit(objectsToEdit);
+ if(!subObjects.isEmpty() && !subObjects.equals(subElementsToEdit)) {
+ subElementsToEdit = subObjects;
+
+ for(AbstractContainerDescriptor container : containers) {
+ container.dispose();
+ }
+ containers.clear();
+
+ // the composite holding all sub containers should be removed
+ subFeatureContainerDescriptor.disposeContainer();
+
+ // create the new Composite, then sub groups
+ Composite mainComposite = subFeatureContainerDescriptor.createContainer(parent, getWidgetFactory());
+ mainComposite.setLayout(new GridLayout(Math.min(maxColumn, subElementsToEdit.size()), true));
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ mainComposite.setLayoutData(data);
+
+ for(Object subElement : subElementsToEdit) {
+ // generate the content of the section, given the configuration
+ for(IFragmentDescriptor viewDescriptor : fragmentDescriptors) {
+ for(AbstractContainerDescriptor descriptor : viewDescriptor.getContainerDescriptors()) {
+ descriptor.createContent(mainComposite, this.tabbedPropertySheetPage.getWidgetFactory(), Arrays.asList(subElement));
+ containers.add(descriptor);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if the specified composite is not <code>null</code> and not disposed
+ *
+ * @param mainComposite
+ * the composite to test
+ * @return <code>true</code> if the composite is not <code>null</code> neither disposed
+ */
+ protected boolean isValid(Composite mainComposite) {
+ return (mainComposite != null && !mainComposite.isDisposed());
+ }
+
+ /**
+ * Returns the feature descriptor that gives access to the sub elements
+ *
+ * @return the feature descriptor that gives access to the sub elements
+ */
+ protected SubFeatureDescriptor getSubFeatureDescriptor() {
+ return subFeatureDescriptor;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/DynamicSubFeatureSectionDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/DynamicSubFeatureSectionDescriptor.java
new file mode 100644
index 00000000000..60f2db2a887
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/DynamicSubFeatureSectionDescriptor.java
@@ -0,0 +1,261 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view.subfeatures;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.state.ITraversableModelElement;
+import org.eclipse.papyrus.properties.runtime.view.IFragmentDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.eclipse.papyrus.properties.tabbed.core.view.DynamicSectionDescriptor;
+import org.eclipse.papyrus.properties.tabbed.core.view.SectionDescriptorState;
+import org.eclipse.papyrus.properties.tabbed.core.view.subfeatures.SubFeatureDescriptor.SubFeatureDescriptorState;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.views.properties.tabbed.ISection;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * Descriptor for sections using controllers.
+ */
+public class DynamicSubFeatureSectionDescriptor extends DynamicSectionDescriptor {
+
+ /** maximal number of columns in the display */
+ protected final int maxColumn;
+
+ /** descriptor to give access to the sub-elements */
+ protected final SubFeatureDescriptor subFeatureDescriptor;
+
+ /** descriptor for container */
+ protected final SubFeatureContainerDescriptor subFeatureContainerDescriptor;
+
+ /**
+ * Creates a new DynamicSectionDescriptor.
+ *
+ * @param id
+ * identifier of the section descriptor
+ * @param tabId
+ * identifier of the tab where the section will be displayed
+ * @param constraints
+ * list of constraints used to see if the section should be displayed or not
+ * @param selectionSize
+ * size of the selection
+ * @param adapterID
+ * identifier of the adapter
+ * @param replacedSectionIds
+ * list of replaced sections by this one
+ * @param afterSectionId
+ * identifier of the section this one should be placed after
+ * @param fragmentDescriptors
+ * list of fragments descriptors inside this section
+ * @param subFeatureDescriptor
+ * descriptor of the sub-feature
+ * @param maxColumn
+ * number max of columns for the layout
+ * @param containerDescriptor
+ * descriptor of the container
+ */
+ public DynamicSubFeatureSectionDescriptor(String id, String tabId, List<IConstraintDescriptor> constraints, int selectionSize, String adapterID, List<String> replacedSectionIds, String afterSectionId, List<IFragmentDescriptor> fragmentDescriptors, SubFeatureDescriptor subFeatureDescriptor, int maxColumn, SubFeatureContainerDescriptor containerDescriptor) {
+ super(id, tabId, constraints, selectionSize, adapterID, replacedSectionIds, afterSectionId, fragmentDescriptors);
+ this.maxColumn = maxColumn;
+ this.subFeatureDescriptor = subFeatureDescriptor;
+ this.subFeatureContainerDescriptor = containerDescriptor;
+ }
+
+ /**
+ * Returns the subFeatureDescriptor for this descriptor
+ *
+ * @return the subFeatureDescriptor for this descriptor
+ */
+ public SubFeatureDescriptor getSubFeatureDescriptor() {
+ return subFeatureDescriptor;
+ }
+
+ /**
+ * Returns the subFeatureContainerDescriptor for this descriptor
+ *
+ * @return the subFeatureContainerDescriptor for this descriptor
+ */
+ public SubFeatureContainerDescriptor getSubFeatureContainerDescriptor() {
+ return subFeatureContainerDescriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ISection getSectionClass() {
+ return new DynamicSubFeatureSection(fragmentDescriptors, subFeatureDescriptor, maxColumn, subFeatureContainerDescriptor, adapterId);
+ }
+
+ /**
+ * Returns the maximum column number for the layout
+ *
+ * @return the maximum column number for the layout
+ */
+ public int getMaxColumn() {
+ return maxColumn;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public SubFeatureSectionDescriptorState createState(boolean readOnly) {
+ return new SubFeatureSectionDescriptorState(this, readOnly);
+ }
+
+ /**
+ * State for {@link SubFeatureContainerDescriptor}
+ */
+ public class SubFeatureSectionDescriptorState extends SectionDescriptorState {
+
+ /** state for the {@link SubFeatureDescriptor} */
+ private SubFeatureDescriptorState subFeatureDescriptorState;
+
+ /** state for the {@link SubFeatureContainerDescriptor} */
+ private SubFeatureContainerDescriptorState subFeatureContainerDescriptorState;
+
+ /** number max of column for this sub feature section */
+ private int maxColumn;
+
+ /** change support for this bean */
+ private PropertyChangeSupport changeSupport;
+
+ /**
+ * Creates a new SubFeatureSectionDescriptorState.
+ *
+ * @param sectionDescriptor
+ * descriptor managed by this state
+ * @param readOnly
+ * read only mode of this state
+ */
+ public SubFeatureSectionDescriptorState(DynamicSubFeatureSectionDescriptor sectionDescriptor, boolean readOnly) {
+ super(sectionDescriptor, readOnly);
+
+ maxColumn = sectionDescriptor.getMaxColumn();
+
+ subFeatureDescriptorState = sectionDescriptor.getSubFeatureDescriptor().createState(readOnly);
+ subFeatureContainerDescriptorState = sectionDescriptor.getSubFeatureContainerDescriptor().createState(readOnly);
+ // register change support
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getEditionDialogId() {
+ return "SubFeatureSectionDescriptorStateDialog";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+ super.addPropertyChangeListener(listener);
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+ super.removePropertyChangeListener(listener);
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<? extends ITraversableModelElement> getChildren() {
+ List<ITraversableModelElement> list = new ArrayList<ITraversableModelElement>();
+ list.add(subFeatureDescriptorState);
+ list.add(subFeatureContainerDescriptorState);
+ list.addAll(super.getChildren());
+ return list;
+ }
+
+ /**
+ * Returns the subFeatureDescriptorState for this state
+ *
+ * @return the subFeatureDescriptorState for this state
+ */
+ public SubFeatureDescriptorState getSubFeatureDescriptorState() {
+ return subFeatureDescriptorState;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Node generateNode(Document document) {
+ Element node = document.createElement("subFeatureSection");
+ node.setAttribute("id", getId());
+ node.setAttribute("tabId", getTargetTab());
+ node.setAttribute("adapterId", getAdapterId());
+ node.setAttribute("maxColumn", "" + maxColumn);
+
+ node.appendChild(subFeatureDescriptorState.generateNode(document));
+ node.appendChild(subFeatureContainerDescriptorState.generateNode(document));
+
+ generateReplacedSectionStates(node, document);
+
+ generateFragmentDescriptorStateNodes(node, document);
+ return node;
+ }
+
+ /**
+ * Sets the maxColumn for this state
+ *
+ * @param maxColumn
+ * the maxColumn to set
+ */
+ public void setMaxColumn(int maxColumn) {
+ changeSupport.firePropertyChange("maxColumn", this.maxColumn, this.maxColumn = maxColumn);
+ }
+
+ /**
+ * Returns the maxColumn for this state
+ *
+ * @return the maxColumn for this state
+ */
+ public int getMaxColumn() {
+ return maxColumn;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getText() {
+ return "Sub-Feature Section: " + getId() + " in tab: " + getTargetTab() + " (max column:" + maxColumn + ")";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return org.eclipse.papyrus.properties.tabbed.core.Activator.getImage("/icons/Section.gif");
+ }
+
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/EMFSimpleSubFeatureDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/EMFSimpleSubFeatureDescriptor.java
new file mode 100644
index 00000000000..7776af376e7
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/EMFSimpleSubFeatureDescriptor.java
@@ -0,0 +1,197 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view.subfeatures;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.swt.graphics.Image;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * Simple sub feature descriptor for emf objects. It only looks in a given feature of the list of given EObjects
+ */
+public class EMFSimpleSubFeatureDescriptor extends SubFeatureDescriptor {
+
+ /** name of the feature to edit */
+ protected final String featureNameToEdit;
+
+ /**
+ * Creates a new EMFSimpleSubFeatureDescriptor.
+ *
+ * @param featureName
+ * the name of the feature to edit
+ */
+ public EMFSimpleSubFeatureDescriptor(String featureName) {
+ this.featureNameToEdit = featureName;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<Object> getSubElementsToEdit(List<Object> editedObjects) {
+ List<Object> results = new ArrayList<Object>();
+ for(Object object : editedObjects) {
+ if(object instanceof EObject) {
+ EStructuralFeature feature = ((EObject)object).eClass().getEStructuralFeature(featureNameToEdit);
+ if(feature != null) {
+ Object values = ((EObject)object).eGet(feature);
+ if(values instanceof List<?>) {
+ results.addAll((List<Object>)values);
+ } else if(values != null) {
+ results.add(values);
+ }
+ } else {
+ Activator.log.error("Impossible to find the feature [" + featureNameToEdit + "] for object: " + object, null);
+ }
+ }
+ }
+ return results;
+ }
+
+ /**
+ * Returns the name of the feature to edit
+ *
+ * @return the name of the feature to edit
+ */
+ public String getFeatureNameToEdit() {
+ return featureNameToEdit;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "EMF Feature: " + featureNameToEdit;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return org.eclipse.papyrus.properties.tabbed.core.Activator.getImage("/icons/EMFFeatureDescriptor.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public EMFSimpleSubFeatureDescriptorState createState(boolean readOnly) {
+ return new EMFSimpleSubFeatureDescriptorState(this, readOnly);
+ }
+
+ /**
+ * State for {@link EMFSimpleSubFeatureDescriptor}
+ */
+ public class EMFSimpleSubFeatureDescriptorState extends SubFeatureDescriptorState {
+
+ /** change support for this bean */
+ private PropertyChangeSupport changeSupport;
+
+ /** name of the feature to edit */
+ private String featureNameState;
+
+ /**
+ * Creates a new EMFSimpleSubFeatureDescriptorState.
+ *
+ * @param emfSimpleSubFeatureDescriptor
+ * the descriptor to customize
+ * @param readOnly
+ * read only mode of this state
+ */
+ public EMFSimpleSubFeatureDescriptorState(EMFSimpleSubFeatureDescriptor emfSimpleSubFeatureDescriptor, boolean readOnly) {
+ super(emfSimpleSubFeatureDescriptor, readOnly);
+
+ featureNameState = emfSimpleSubFeatureDescriptor.getFeatureNameToEdit();
+
+ // register change support
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public EMFSimpleSubFeatureDescriptor getDescriptor() {
+ return (EMFSimpleSubFeatureDescriptor)super.getDescriptor();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "EMF Feature: " + featureNameState;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return "EMFSimpleSubFeatureDescriptorStateDialog";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * customizes the featureNameState
+ *
+ * @param featureNameState
+ * the featureNameState to set
+ */
+ public void setFeatureNameState(String featureNameState) {
+ String oldFeatureName = this.featureNameState;
+ this.featureNameState = featureNameState;
+
+ changeSupport.firePropertyChange("featureNameState", oldFeatureName, this.featureNameState);
+ }
+
+ /**
+ * Returns the customized feature Name
+ *
+ * @return the customized feature Name
+ */
+ public String getFeatureNameState() {
+ return featureNameState;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node generateNode(Document document) {
+ //<subFeatureDescriptor featureName="memberEnd">
+ //</subFeatureDescriptor>
+ Element node = document.createElement("subFeatureDescriptor");
+ node.setAttribute("featureName", getFeatureNameState());
+ return node;
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/ExpandableContainerDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/ExpandableContainerDescriptor.java
new file mode 100644
index 00000000000..ae1d16f3fe6
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/ExpandableContainerDescriptor.java
@@ -0,0 +1,198 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view.subfeatures;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+import org.eclipse.papyrus.properties.tabbed.core.Activator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+
+/**
+ * Creates an expandable container
+ */
+public class ExpandableContainerDescriptor extends SubFeatureContainerDescriptor {
+
+ /** constant for serialization of the type of container */
+ public static final String EXPANDABLE_CONTAINER_TYPE = "expandableContainer";
+
+ /** label of the bar */
+ protected final String label;
+
+ /** main composite described by this descriptor */
+ protected Section section;
+
+ /**
+ * Creates a new ExpandableContainerDescriptor.
+ *
+ * @param label
+ * label of the expandable composite
+ */
+ public ExpandableContainerDescriptor(String label) {
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Composite createContainer(Composite parent, TabbedPropertySheetWidgetFactory widgetFactory) {
+ section = widgetFactory.createSection(parent, Section.TITLE_BAR | Section.TWISTIE | Section.EXPANDED);
+ section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ Composite expandableContainer = widgetFactory.createComposite(section);
+ section.setText(label);
+
+ widgetFactory.paintBordersFor(expandableContainer);
+ section.setClient(expandableContainer);
+
+ return expandableContainer;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void disposeContainer() {
+ if(section != null && !section.isDisposed()) {
+ section.dispose();
+ section = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "SubFeature Expandable Container: " + label;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/SubFeatureExpandableContainer.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ExpandableContainerDescriptorState createState(boolean readOnly) {
+ return new ExpandableContainerDescriptorState(this, readOnly);
+ }
+
+ /**
+ * Returns the label of the container
+ *
+ * @return the label of the container
+ */
+ public String getLabel() {
+ return label;
+ }
+
+
+ /**
+ * state for {@link ExpandableContainerDescriptor}
+ */
+ public class ExpandableContainerDescriptorState extends SubFeatureContainerDescriptorState {
+
+ /** label cached by this state */
+ private String label;
+
+ /** change support */
+ private PropertyChangeSupport changeSupport;
+
+ /**
+ * Creates a new ExpandableContainerDescriptorState.
+ *
+ * @param descriptor
+ * the descriptor managed by this state
+ * @param readOnly
+ * the read only mode
+ */
+ public ExpandableContainerDescriptorState(ExpandableContainerDescriptor descriptor, boolean readOnly) {
+ super(descriptor, readOnly);
+
+ label = descriptor.getLabel();
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getEditionDialogId() {
+ return "SubFeatureExpandableContainerDescriptorStateDialog";
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * Returns the label of the descriptor managed by this state
+ *
+ * @return the label of the descriptor managed by this state
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "SubFeature Expandable Container: " + label;
+ }
+
+ /**
+ * Sets the label of the descriptor managed by this state
+ *
+ * @param label
+ * the label to set
+ */
+ public void setLabel(String label) {
+ changeSupport.firePropertyChange("label", this.label, this.label = label);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void generateAttributes(Element node, Document document) {
+ node.setAttribute("label", label);
+ node.setAttribute("type", EXPANDABLE_CONTAINER_TYPE);
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/GroupContainerDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/GroupContainerDescriptor.java
new file mode 100644
index 00000000000..1b9798ad2c1
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/GroupContainerDescriptor.java
@@ -0,0 +1,186 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view.subfeatures;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+import org.eclipse.papyrus.properties.tabbed.core.Activator;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+
+/**
+ * Creates a group container
+ */
+public class GroupContainerDescriptor extends SubFeatureContainerDescriptor {
+
+ /** constant for serialization of the type of container */
+ public static final String GROUP_CONTAINER_TYPE = "groupContainer";
+
+ /** label of the group */
+ protected final String label;
+
+ /** composite managed by this descripor */
+ private Group composite;
+
+ /**
+ * Creates a new GroupContainerDescriptor.
+ *
+ * @param label
+ * label of the group
+ */
+ public GroupContainerDescriptor(String label) {
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Composite createContainer(Composite parent, TabbedPropertySheetWidgetFactory widgetFactory) {
+ composite = widgetFactory.createGroup(parent, label);
+ return composite;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void disposeContainer() {
+ if(composite != null && !composite.isDisposed()) {
+ composite.dispose();
+ composite = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "SubFeature Group Container: " + label;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/SubFeatureGroupContainer.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public GroupContainerDescriptorState createState(boolean readOnly) {
+ return new GroupContainerDescriptorState(this, readOnly);
+ }
+
+
+ /**
+ * Returns the label
+ *
+ * @return the label
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * state for {@link GroupContainerDescriptor}
+ */
+ public class GroupContainerDescriptorState extends SubFeatureContainerDescriptorState {
+
+ /** label cached by this state */
+ private String label;
+
+ /** change support */
+ private PropertyChangeSupport changeSupport;
+
+ /**
+ * Creates a new GroupContainerDescriptorState.
+ *
+ * @param descriptor
+ * the descriptor managed by this state
+ * @param readOnly
+ * the read only mode
+ */
+ public GroupContainerDescriptorState(GroupContainerDescriptor descriptor, boolean readOnly) {
+ super(descriptor, readOnly);
+
+ label = descriptor.getLabel();
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getEditionDialogId() {
+ return "SubFeatureGroupContainerDescriptorStateDialog";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * Returns the label of the descriptor managed by this state
+ *
+ * @return the label of the descriptor managed by this state
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * Sets the label of the descriptor managed by this state
+ *
+ * @param label
+ * the label to set
+ */
+ public void setLabel(String label) {
+ changeSupport.firePropertyChange("label", this.label, this.label = label);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "SubFeature Group Container: " + label;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void generateAttributes(Element node, Document document) {
+ node.setAttribute("label", label);
+ node.setAttribute("type", GROUP_CONTAINER_TYPE);
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SimpleContainerDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SimpleContainerDescriptor.java
new file mode 100644
index 00000000000..990f6c0dfb6
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SimpleContainerDescriptor.java
@@ -0,0 +1,68 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view.subfeatures;
+
+import org.eclipse.papyrus.properties.tabbed.core.Activator;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+
+/**
+ * Simple container descriptor
+ */
+public class SimpleContainerDescriptor extends SubFeatureContainerDescriptor {
+
+ /** composite created by this descriptor */
+ private Composite composite;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Composite createContainer(Composite parent, TabbedPropertySheetWidgetFactory widgetFactory) {
+ composite = widgetFactory.createComposite(parent);
+ return composite;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void disposeContainer() {
+ if(composite != null && !composite.isDisposed()) {
+ composite.dispose();
+ composite = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "Simple container";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/SubFeatureContainer.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public SubFeatureContainerDescriptorState createState(boolean readOnly) {
+ return new SubFeatureContainerDescriptorState(this, readOnly);
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SubFeatureContainerDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SubFeatureContainerDescriptor.java
new file mode 100644
index 00000000000..ab7a5bb5a03
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SubFeatureContainerDescriptor.java
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view.subfeatures;
+
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+
+/**
+ * Descriptor for containers for subfeatures section
+ */
+public abstract class SubFeatureContainerDescriptor implements IConfigurableDescriptor {
+
+ /**
+ * Creates the container for the section (sub feature)
+ *
+ * @param parent
+ * parent of created composite
+ * @param widgetFactory
+ * widgetFactory used to create composite
+ * @return the newly create composite
+ */
+ public abstract Composite createContainer(Composite parent, TabbedPropertySheetWidgetFactory widgetFactory);
+
+ /**
+ * Dispose the main container managed by this descriptor
+ */
+ public abstract void disposeContainer();
+
+ /**
+ * {@inheritDoc}
+ */
+ public abstract SubFeatureContainerDescriptorState createState(boolean readOnly);
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SubFeatureContainerDescriptorState.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SubFeatureContainerDescriptorState.java
new file mode 100644
index 00000000000..bf238c52a51
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SubFeatureContainerDescriptorState.java
@@ -0,0 +1,114 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view.subfeatures;
+
+import java.beans.PropertyChangeListener;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.state.AbstractState;
+import org.eclipse.papyrus.properties.runtime.state.ITraversableModelElement;
+import org.eclipse.papyrus.properties.tabbed.core.Activator;
+import org.eclipse.swt.graphics.Image;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * state for {@link SubFeatureContainerDescriptor}
+ */
+public class SubFeatureContainerDescriptorState extends AbstractState {
+
+ /** descriptor managed by this state */
+ protected final SubFeatureContainerDescriptor descriptor;
+
+ /**
+ * Creates a new SubFeatureContainerDescriptorState.
+ *
+ * @param descriptor
+ * the descriptor managed by his state
+ * @param readOnly
+ * <code>true</code> if this state should be in read-only mode
+ */
+ public SubFeatureContainerDescriptorState(SubFeatureContainerDescriptor descriptor, boolean readOnly) {
+ super(readOnly);
+ this.descriptor = descriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public SubFeatureContainerDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ // nothing here
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ // nothing here
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node generateNode(Document document) {
+ Element node = document.createElement("subFeatureDescriptorContainer");
+
+ generateAttributes(node, document);
+
+ return node;
+ }
+
+ /**
+ * Generates the attributes for the root node
+ *
+ * @param node
+ * the node for which attributes are set
+ * @param document
+ * the document used to create elements
+ */
+ protected void generateAttributes(Element node, Document document) {
+ node.setAttribute("type", "simpleContainer");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<? extends ITraversableModelElement> getChildren() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Image getImage() {
+ return Activator.getImage("/icons/SubFeatureContainer.gif");
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SubFeatureDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SubFeatureDescriptor.java
new file mode 100644
index 00000000000..53f0ee0f914
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties.tabbed.core/src/org/eclipse/papyrus/properties/tabbed/core/view/subfeatures/SubFeatureDescriptor.java
@@ -0,0 +1,83 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.tabbed.core.view.subfeatures;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.state.AbstractState;
+import org.eclipse.papyrus.properties.runtime.state.ITraversableModelElement;
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+
+
+/**
+ * Feature descriptor for sub features of an element
+ */
+public abstract class SubFeatureDescriptor implements IConfigurableDescriptor {
+
+ /**
+ * Returns the list of sub elements for a given set of objects
+ *
+ * @param editedObjects
+ * the list of selected objects
+ * @return the list of sub elements for a given set of objects or an empty list
+ */
+ public abstract List<Object> getSubElementsToEdit(List<Object> editedObjects);
+
+ /**
+ * {@inheritDoc}
+ */
+ public abstract SubFeatureDescriptorState createState(boolean readOnly);
+
+ /**
+ * State for {@link SubFeatureDescriptor}
+ */
+ public abstract class SubFeatureDescriptorState extends AbstractState {
+
+ /** managed descriptor */
+ private SubFeatureDescriptor descriptor;
+
+ /**
+ * Creates a new SubFeatureDescriptor.SubFeatureDescriptionState.
+ *
+ * @param descriptor
+ * the descriptor to manage
+ * @param readOnly
+ * read only mode of this state
+ */
+ public SubFeatureDescriptorState(SubFeatureDescriptor descriptor, boolean readOnly) {
+ super(readOnly);
+ this.descriptor = descriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public SubFeatureDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return "";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<? extends ITraversableModelElement> getChildren() {
+ return Collections.emptyList();
+ }
+ }
+}

Back to the top