Bug 424536 - Integration with Properties View
diff --git a/org.eclipse.xwt.ui.workbench/META-INF/MANIFEST.MF b/org.eclipse.xwt.ui.workbench/META-INF/MANIFEST.MF
index dcba6d8..2a7fa35 100644
--- a/org.eclipse.xwt.ui.workbench/META-INF/MANIFEST.MF
+++ b/org.eclipse.xwt.ui.workbench/META-INF/MANIFEST.MF
@@ -19,7 +19,10 @@
  org.eclipse.core.databinding;bundle-version="1.3.0",

  org.eclipse.jface.databinding;bundle-version="1.3.100",

  org.eclipse.e4.ui.workbench;bundle-version="0.9.1",

- org.eclipse.e4.ui.di;bundle-version="0.9.0"

+ org.eclipse.e4.ui.di;bundle-version="0.9.0",

+ org.eclipse.ui.views.properties.tabbed;bundle-version="3.6.0",

+ org.eclipse.emf;bundle-version="2.6.0",

+ org.eclipse.emf.edit;bundle-version="2.10.0"

 Bundle-RequiredExecutionEnvironment: J2SE-1.5

 Bundle-ActivationPolicy: lazy

 Export-Package: org.eclipse.xwt.ui.workbench,

diff --git a/org.eclipse.xwt.ui.workbench/src/org/eclipse/xwt/ui/workbench/properties/ApplicationPropertySheetPage.java b/org.eclipse.xwt.ui.workbench/src/org/eclipse/xwt/ui/workbench/properties/ApplicationPropertySheetPage.java
new file mode 100644
index 0000000..29e3956
--- /dev/null
+++ b/org.eclipse.xwt.ui.workbench/src/org/eclipse/xwt/ui/workbench/properties/ApplicationPropertySheetPage.java
@@ -0,0 +1,39 @@
+/*******************************************************************************

+ * Copyright (c) 2006, 2014 Soyatec (http://www.soyatec.com) and others.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ * 

+ * Contributors:

+ *     Soyatec - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.xwt.ui.workbench.properties;

+

+import org.eclipse.emf.edit.domain.EditingDomain;

+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;

+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;

+

+public class ApplicationPropertySheetPage extends TabbedPropertySheetPage {

+

+	private EditingDomain editingDomain;

+

+	public ApplicationPropertySheetPage(

+			EditingDomain editingDomain,

+			ITabbedPropertySheetPageContributor tabbedPropertySheetPageContributor) {

+		this(editingDomain, tabbedPropertySheetPageContributor, true);

+	}

+

+	public ApplicationPropertySheetPage(

+			EditingDomain editingDomain,

+			ITabbedPropertySheetPageContributor tabbedPropertySheetPageContributor,

+			boolean showTitleBar) {

+		super(tabbedPropertySheetPageContributor, showTitleBar);

+		this.editingDomain = editingDomain;

+	}

+

+	public EditingDomain getEditingDomain() {

+		return editingDomain;

+	}

+

+}

diff --git a/org.eclipse.xwt.ui.workbench/src/org/eclipse/xwt/ui/workbench/properties/XWTSection.java b/org.eclipse.xwt.ui.workbench/src/org/eclipse/xwt/ui/workbench/properties/XWTSection.java
new file mode 100644
index 0000000..be06ee5
--- /dev/null
+++ b/org.eclipse.xwt.ui.workbench/src/org/eclipse/xwt/ui/workbench/properties/XWTSection.java
@@ -0,0 +1,139 @@
+/*******************************************************************************

+ * Copyright (c) 2006, 2014 Soyatec (http://www.soyatec.com) and others.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ * 

+ * Contributors:

+ *     Soyatec - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.xwt.ui.workbench.properties;

+

+import java.net.URL;

+

+import org.eclipse.jface.viewers.ISelection;

+import org.eclipse.jface.viewers.IStructuredSelection;

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.layout.GridData;

+import org.eclipse.swt.layout.GridLayout;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Control;

+import org.eclipse.swt.widgets.Label;

+import org.eclipse.ui.IWorkbenchPart;

+import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection;

+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;

+import org.eclipse.xwt.DefaultLoadingContext;

+import org.eclipse.xwt.ILoadingContext;

+import org.eclipse.xwt.XWT;

+

+public class XWTSection extends AbstractPropertySection {

+	private ILoadingContext loadingContext = new DefaultLoadingContext(

+			getClass().getClassLoader());

+

+	private URL sectionURL;

+

+	private Composite self;

+

+	public XWTSection(URL sectionURL) {

+		this.sectionURL = sectionURL;

+	}

+

+	@Override

+	public void createControls(Composite parent,

+			TabbedPropertySheetPage aTabbedPropertySheetPage) {

+		self = new Composite(parent, SWT.NONE);

+

+		GridLayout layout = new GridLayout(1, false);

+		layout.marginHeight = 0;

+		layout.marginWidth = 0;

+		self.setLayout(layout);

+

+		layout = new GridLayout(1, false);

+		layout.verticalSpacing = 5;

+		layout.marginHeight = 5;

+		layout.marginWidth = 5;

+		parent.setLayout(layout);

+

+		GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);

+		self.setLayoutData(data);

+

+		self.setBackground(parent.getBackground());

+		self.setBackgroundMode(SWT.INHERIT_DEFAULT);

+	}

+

+	@Override

+	public void refresh() {

+		if (self == null || self.isDisposed()) {

+			dispose();

+			return;

+		}

+		for (Control child : self.getChildren()) {

+			child.dispose();

+		}

+		Object source = getDataObject();

+		if (source == null) {

+			return;

+		}

+		if (sectionURL != null) {

+			createSection(self, sectionURL, source);

+		}

+		layout(self);

+	}

+

+	private Object getDataObject() {

+		IStructuredSelection selection = getSelection();

+		return selection.getFirstElement();

+	}

+

+	private Control createSection(Composite parent, URL xwtFile, Object source) {

+		ILoadingContext xwtContext = XWT.getLoadingContext();

+		XWT.setLoadingContext(loadingContext);

+

+		Control control = null;

+		try {

+			control = (Control) XWT.load(parent, xwtFile, source);

+

+			if (control != null) {

+				control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,

+						true));

+			}

+		} catch (Exception ex) {

+			Label label = new Label(parent, SWT.NONE);

+			label.setText("An error occured in the property view. The file " + xwtFile + " could not be loaded"); //$NON-NLS-1$ //$NON-NLS-2$

+			ex.printStackTrace();

+		}

+		// layout(parent);

+

+		XWT.setLoadingContext(xwtContext);

+

+		return control;

+	}

+

+	private void layout(Composite parent) {

+		parent.getParent().getParent().layout();

+		parent.getParent().layout();

+		parent.layout();

+	}

+

+	@Override

+	public void dispose() {

+		if (self != null) {

+			self.dispose();

+		}

+		super.dispose();

+	}

+

+	@Override

+	public void setInput(IWorkbenchPart part, ISelection selection) {

+		if (selection == getSelection()) {

+			return;

+		}

+		super.setInput(part, selection);

+	}

+

+	@Override

+	public IStructuredSelection getSelection() {

+		return (IStructuredSelection) super.getSelection();

+	}

+}

diff --git a/org.eclipse.xwt.ui.workbench/src/org/eclipse/xwt/ui/workbench/properties/XWTSectionDescriptor.java b/org.eclipse.xwt.ui.workbench/src/org/eclipse/xwt/ui/workbench/properties/XWTSectionDescriptor.java
new file mode 100644
index 0000000..9cd4140
--- /dev/null
+++ b/org.eclipse.xwt.ui.workbench/src/org/eclipse/xwt/ui/workbench/properties/XWTSectionDescriptor.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * Copyright (c) 2006, 2014 Soyatec (http://www.soyatec.com) and others.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ * 

+ * Contributors:

+ *     Soyatec - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.xwt.ui.workbench.properties;

+

+import java.net.URL;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.eclipse.core.runtime.Assert;

+import org.eclipse.ui.views.properties.tabbed.AbstractSectionDescriptor;

+import org.eclipse.ui.views.properties.tabbed.ISection;

+import org.eclipse.xwt.IConstants;

+

+public class XWTSectionDescriptor extends AbstractSectionDescriptor {

+

+	private String id;

+	private String targetTab;

+	private String sectionTypeName;

+	private List<String> inputTypes;

+

+	public XWTSectionDescriptor(String id, String targetTab,

+			String sectionTypeName) {

+		Assert.isNotNull(id, "Section id can not be null");

+		Assert.isNotNull(targetTab, "Tab id can not be null");

+		Assert.isNotNull(sectionTypeName,

+				"URL for renderering section can not be null");

+		this.id = id;

+		this.targetTab = targetTab;

+		this.sectionTypeName = sectionTypeName;

+	}

+

+	public String getId() {

+		return id;

+	}

+

+	public ISection getSectionClass() {

+		URL sectionURL = null;

+		try {

+			Class<?> type = Class.forName(sectionTypeName);

+			sectionURL = type.getResource(type.getSimpleName()

+					+ IConstants.XWT_EXTENSION_SUFFIX);

+		} catch (ClassNotFoundException e) {

+			e.printStackTrace();

+		}

+		return new XWTSection(sectionURL);

+	}

+

+	public String getTargetTab() {

+		return targetTab;

+	}

+

+	public List<String> getInputTypes() {

+		if (inputTypes == null) {

+			inputTypes = new ArrayList<String>();

+		}

+		return inputTypes;

+	}

+

+	public void addInputType(String inputType) {

+		getInputTypes().add(inputType);

+	}

+}

diff --git a/org.eclipse.xwt.ui.workbench/src/org/eclipse/xwt/ui/workbench/properties/XWTTabDescriptor.java b/org.eclipse.xwt.ui.workbench/src/org/eclipse/xwt/ui/workbench/properties/XWTTabDescriptor.java
new file mode 100644
index 0000000..416f1e4
--- /dev/null
+++ b/org.eclipse.xwt.ui.workbench/src/org/eclipse/xwt/ui/workbench/properties/XWTTabDescriptor.java
@@ -0,0 +1,41 @@
+/*******************************************************************************

+ * Copyright (c) 2006, 2014 Soyatec (http://www.soyatec.com) and others.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ * 

+ * Contributors:

+ *     Soyatec - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.xwt.ui.workbench.properties;

+

+import org.eclipse.core.runtime.Assert;

+import org.eclipse.ui.views.properties.tabbed.AbstractTabDescriptor;

+

+public class XWTTabDescriptor extends AbstractTabDescriptor {

+

+	private String id;

+	private String label;

+	private String category;

+

+	public XWTTabDescriptor(String id, String label, String category) {

+		Assert.isNotNull(id, "Tab id can not be null");

+		this.id = id;

+		this.category = category;

+		this.label = label;

+	}

+

+	public String getCategory() {

+		return category;

+	}

+

+	public String getId() {

+		return id;

+	}

+

+	public String getLabel() {

+		return label;

+	}

+

+}

diff --git a/org.eclipse.xwt.ui.workbench/src/org/eclipse/xwt/ui/workbench/properties/XWTTabDescriptorProvider.java b/org.eclipse.xwt.ui.workbench/src/org/eclipse/xwt/ui/workbench/properties/XWTTabDescriptorProvider.java
new file mode 100644
index 0000000..44b4afa
--- /dev/null
+++ b/org.eclipse.xwt.ui.workbench/src/org/eclipse/xwt/ui/workbench/properties/XWTTabDescriptorProvider.java
@@ -0,0 +1,109 @@
+/*******************************************************************************

+ * Copyright (c) 2006, 2014 Soyatec (http://www.soyatec.com) and others.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ * 

+ * Contributors:

+ *     Soyatec - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.xwt.ui.workbench.properties;

+

+import java.lang.reflect.InvocationTargetException;

+import java.lang.reflect.Method;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.eclipse.jface.viewers.ISelection;

+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.ITabDescriptor;

+import org.eclipse.ui.views.properties.tabbed.ITabDescriptorProvider;

+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;

+

+@SuppressWarnings("restriction")

+public abstract class XWTTabDescriptorProvider implements ITabDescriptorProvider {

+

+	private IWorkbenchPart previousPart;

+

+	private ISelection previousSelection;

+

+	private ITabDescriptor[] cachedResult;

+

+	public ITabDescriptor[] getTabDescriptors(IWorkbenchPart part,

+			ISelection selection) {

+		if (part != previousPart || selection != previousSelection) {

+			this.previousPart = part;

+			this.previousSelection = selection;

+			List<ITabDescriptor> descriptors = new ArrayList<ITabDescriptor>();

+

+			addTabDescriptors(descriptors);

+

+			// TODO: 2. Define/Get "category" of a TabDescriptor.

+

+			// TODO: Add custom defined Tabs and Section from extensions.

+			// FIXME: In some cases (e.g. Selection in the Papyrus Tree

+			// outline), the IWorkbenchPart is not an

+			// ITabbedPropertySheetPageContributor

+			// TODO: Investigate on this case and fix the issue (contributor ==

+			// null in this case)

+			ITabbedPropertySheetPageContributor contributor;

+			if (part instanceof ITabbedPropertySheetPageContributor) {

+				contributor = (ITabbedPropertySheetPageContributor) part;

+			} else {

+				contributor = (ITabbedPropertySheetPageContributor) (part

+						.getAdapter(ITabbedPropertySheetPageContributor.class));

+			}

+

+			if (contributor != null) {

+				// get all tab descriptors for the registered extension points

+				// Memory leak here

+				TabbedPropertyRegistry registry = TabbedPropertyRegistryFactory

+						.getInstance().createRegistry(contributor);

+

+				// 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"); //$NON-NLS-1$

+					method.setAccessible(true);

+					ITabDescriptor[] registeredTabDesriptors;

+

+					registeredTabDesriptors = (ITabDescriptor[]) method

+							.invoke(registry);

+

+					if (registeredTabDesriptors != null) {

+						for (ITabDescriptor descriptor : registeredTabDesriptors) {

+							if (descriptor.getSectionDescriptors().size() > 0) {

+								descriptors.add(descriptor);

+							}

+						}

+					}

+				} catch (IllegalArgumentException e) {

+					e.printStackTrace();

+				} catch (IllegalAccessException e) {

+					e.printStackTrace();

+				} catch (InvocationTargetException e) {

+					e.printStackTrace();

+				} catch (SecurityException e) {

+					e.printStackTrace();

+				} catch (NoSuchMethodException e) {

+					e.printStackTrace();

+				}

+			}

+

+			// TODO: need a sort?

+			cachedResult = descriptors.toArray(new ITabDescriptor[descriptors

+					.size()]);

+		}

+		return cachedResult;

+	}

+

+	abstract protected void addTabDescriptors(List<ITabDescriptor> descriptors);

+}