Bug 478395 - Add API to create model elements with eg initialized contributorURI
diff --git a/bundles/runtime/org.eclipse.fx.ui.workbench.base/src/org/eclipse/fx/ui/workbench/base/internal/ModelServiceImpl.java b/bundles/runtime/org.eclipse.fx.ui.workbench.base/src/org/eclipse/fx/ui/workbench/base/internal/ModelServiceImpl.java
index a33452f..6c65a7b 100644
--- a/bundles/runtime/org.eclipse.fx.ui.workbench.base/src/org/eclipse/fx/ui/workbench/base/internal/ModelServiceImpl.java
+++ b/bundles/runtime/org.eclipse.fx.ui.workbench.base/src/org/eclipse/fx/ui/workbench/base/internal/ModelServiceImpl.java
@@ -10,14 +10,19 @@
  *******************************************************************************/

 package org.eclipse.fx.ui.workbench.base.internal;

 

+import java.util.function.Function;

+import java.util.function.Supplier;

+

 import org.eclipse.e4.ui.model.application.MApplication;

 import org.eclipse.e4.ui.model.application.MApplicationElement;

+import org.eclipse.e4.ui.workbench.modeling.EModelService;

 import org.eclipse.emf.ecore.EObject;

 import org.eclipse.emf.ecore.resource.Resource;

 import org.eclipse.emf.ecore.xmi.XMIResource;

 import org.eclipse.fx.ui.workbench.services.ModelService;

 import org.eclipse.jdt.annotation.NonNull;

 import org.eclipse.jdt.annotation.Nullable;

+import org.osgi.framework.FrameworkUtil;

 import org.osgi.service.component.annotations.Component;

 

 /**

@@ -41,11 +46,85 @@
 	public <M extends MApplicationElement> @Nullable M getElementInstance(@NonNull MApplication m, @NonNull String uniqueId) {

 		return (M) ((XMIResource) ((EObject)m).eResource()).getEObject(uniqueId);

 	}

-	

+

 	@Override

 	public MApplication getRoot(@NonNull MApplicationElement e) {

 		Resource eResource = ((EObject)e).eResource();

 		return eResource != null ? (MApplication) eResource.getContents().get(0) : null;

 	}

 

+	static class ModelElementFactoryImpl implements ModelElementFactory {

+		@NonNull

+		private final EModelService modelService;

+		@NonNull

+		private final Supplier<@NonNull String> contributor;

+

+		public ModelElementFactoryImpl(@NonNull EModelService modelService, @NonNull Supplier<@NonNull String> contributor) {

+			this.modelService = modelService;

+			this.contributor = contributor;

+		}

+

+		@Override

+		public <T extends MApplicationElement> @NonNull T createModelElement(@NonNull Class<@NonNull T> clazz) {

+			return createModelElement(clazz, this.contributor, (e) -> e);

+		}

+

+		@Override

+		public <T extends MApplicationElement> @NonNull T createModelElement(@NonNull Class<@NonNull T> clazz, @NonNull Function<@NonNull T, @NonNull T> processor) {

+			return createModelElement(clazz, this.contributor, processor);

+		}

+

+		@Override

+		public <T extends MApplicationElement> @NonNull T createModelElement(@NonNull Class<@NonNull T> clazz, @NonNull Supplier<@NonNull String> contributor) {

+			return createModelElement(clazz, contributor, (t) -> t);

+		}

+

+		@Override

+		public <T extends MApplicationElement> @NonNull T createModelElement(@NonNull Class<@NonNull T> clazz, @NonNull Supplier<@NonNull String> contributor, Function<@NonNull T, @NonNull T> processor) {

+			T element = this.modelService.createModelElement(clazz);

+			element.setContributorURI("platform:/plugin/"+ contributor); //$NON-NLS-1$

+			element = processor.apply(element);

+			return element;

+		}

+

+		@Override

+		public <T extends MApplicationElement> @NonNull Supplier<T> createModelElementCreator(@NonNull Class<@NonNull T> clazz) {

+			return createModelElementCreator(clazz, this.contributor, (t) -> t);

+		}

+

+		@Override

+		public <T extends MApplicationElement> @NonNull Supplier<T> createModelElementCreator(@NonNull Class<@NonNull T> clazz, @NonNull Function<@NonNull T, @NonNull T> processor) {

+			return createModelElementCreator(clazz, this.contributor, processor);

+		}

+

+		@Override

+		public <T extends MApplicationElement> @NonNull Supplier<T> createModelElementCreator(@NonNull Class<@NonNull T> clazz, @NonNull Supplier<@NonNull String> contributor) {

+			return createModelElementCreator(clazz, contributor, (t) -> t);

+		}

+

+		@Override

+		public <T extends MApplicationElement> @NonNull Supplier<T> createModelElementCreator(@NonNull Class<@NonNull T> clazz, @NonNull Supplier<@NonNull String> contributor, Function<@NonNull T, @NonNull T> processor) {

+			return () -> createModelElement(clazz, contributor, processor);

+		}

+	}

+

+	@Override

+	public @NonNull ModelElementFactory createModelElementFactory(@NonNull Class<?> owner, @NonNull EModelService modelService) {

+		return new ModelElementFactoryImpl(modelService, getBundleNameSupplier(owner));

+	}

+

+	@Override

+	public @NonNull String getBundleName(Class<?> clazz) {

+		String bundleId = FrameworkUtil.getBundle(clazz).getSymbolicName();

+		if( bundleId == null ) {

+			throw new IllegalStateException("Could not extract the bundle name from the '"+clazz+"'");  //$NON-NLS-1$//$NON-NLS-2$

+		}

+		return bundleId;

+	}

+

+	@Override

+	public @NonNull Supplier<@NonNull String> getBundleNameSupplier(Class<?> clazz) {

+		String id = getBundleName(clazz);

+		return () -> id;

+	}

 }

diff --git a/bundles/runtime/org.eclipse.fx.ui.workbench.services/src/org/eclipse/fx/ui/workbench/services/ModelService.java b/bundles/runtime/org.eclipse.fx.ui.workbench.services/src/org/eclipse/fx/ui/workbench/services/ModelService.java
index c898a68..c02a6e2 100644
--- a/bundles/runtime/org.eclipse.fx.ui.workbench.services/src/org/eclipse/fx/ui/workbench/services/ModelService.java
+++ b/bundles/runtime/org.eclipse.fx.ui.workbench.services/src/org/eclipse/fx/ui/workbench/services/ModelService.java
@@ -10,21 +10,25 @@
  *******************************************************************************/

 package org.eclipse.fx.ui.workbench.services;

 

+import java.util.function.Function;

+import java.util.function.Supplier;

+

 import org.eclipse.e4.ui.model.application.MApplication;

 import org.eclipse.e4.ui.model.application.MApplicationElement;

+import org.eclipse.e4.ui.workbench.modeling.EModelService;

 import org.eclipse.jdt.annotation.NonNull;

 import org.eclipse.jdt.annotation.Nullable;

 

 /**

  * Service used to handle model stuff

- * 

+ *

  * @noimplement

  * @since 2.0

  */

 public interface ModelService {

 	/**

 	 * Get global unique identifier for the given model element

-	 * 

+	 *

 	 * @param element

 	 *            the element

 	 * @return the unique identifier

@@ -33,7 +37,7 @@
 

 	/**

 	 * Get the real element for the given id

-	 * 

+	 *

 	 * @param m

 	 *            the application element

 	 * @param uniqueId

@@ -44,10 +48,145 @@
 

 	/**

 	 * Get the root element of the model

-	 * 

+	 *

 	 * @param e

 	 *            the current element

 	 * @return the root element

 	 */

 	public @Nullable MApplication getRoot(@NonNull MApplicationElement e);

+

+	/**

+	 * Factory to create model elements

+	 */

+	public interface ModelElementFactory {

+		/**

+		 * Create a model element instance and initialize the

+		 * {@link MApplicationElement#setContributorURI(String)}

+		 *

+		 * @param clazz

+		 *            the model instance type

+		 * @return the instance

+		 */

+		public <T extends MApplicationElement> @NonNull T createModelElement(@NonNull Class<@NonNull T> clazz);

+

+		/**

+		 * Create a model element instance, initialize the

+		 * {@link MApplicationElement#setContributorURI(String)} and run the element

+		 * through the provided processor

+		 *

+		 * @param clazz

+		 *            the model instance type

+		 * @param processor

+		 *            the processor to eg initialize the element

+		 * @return the model instance

+		 */

+		public <T extends MApplicationElement> @NonNull T createModelElement(@NonNull Class<@NonNull T> clazz, @NonNull Function<@NonNull T, @NonNull T> processor);

+

+		/**

+		 * Create a model element instance and initialize the

+		 * {@link MApplicationElement#setContributorURI(String)} with the value

+		 * provided by the contributor supplier

+		 *

+		 * @param clazz

+		 *            the model instance type

+		 * @param contributor

+		 *            the contributor supplier

+		 * @return the instance

+		 */

+		public <T extends MApplicationElement> @NonNull T createModelElement(@NonNull Class<@NonNull T> clazz, @NonNull Supplier<@NonNull String> contributor);

+

+		/**

+		 * Create a model element instance, initialize the

+		 * {@link MApplicationElement#setContributorURI(String)} with the value

+		 * provided by the contributor supplier and run the element through the

+		 * provided processor

+		 *

+		 * @param clazz

+		 *            the model instance type

+		 * @param contributor

+		 *            the contributor supplier

+		 * @param processor

+		 *            the processor to eg initialize the element

+		 * @return the instance

+		 */

+		public <T extends MApplicationElement> @NonNull T createModelElement(@NonNull Class<@NonNull T> clazz, @NonNull Supplier<@NonNull String> contributor, Function<@NonNull T, @NonNull T> processor);

+

+		/**

+		 * Create a supplier who creates a model element instance and initializes

+		 * the {@link MApplicationElement#setContributorURI(String)}

+		 *

+		 * @param clazz

+		 *            the model instance type

+		 * @return the instance

+		 */

+		public <T extends MApplicationElement> @NonNull Supplier<T> createModelElementCreator(@NonNull Class<@NonNull T> clazz);

+

+		/**

+		 * Create a supplier who creates a model element instance, initializes the

+		 * {@link MApplicationElement#setContributorURI(String)} and run the element

+		 * through the provided processor

+		 *

+		 * @param clazz

+		 *            the model instance type

+		 * @param processor

+		 *            the processor to eg initialize the element

+		 * @return the model instance

+		 */

+		public <T extends MApplicationElement> @NonNull Supplier<T> createModelElementCreator(@NonNull Class<@NonNull T> clazz, @NonNull Function<@NonNull T, @NonNull T> processor);

+

+		/**

+		 * Create a supplier who creates a model element instance and initializes

+		 * the {@link MApplicationElement#setContributorURI(String)} with the value

+		 * provided by the contributor supplier

+		 *

+		 * @param clazz

+		 *            the model instance type

+		 * @param contributor

+		 *            the contributor supplier

+		 * @return the instance

+		 */

+		public <T extends MApplicationElement> @NonNull Supplier<T> createModelElementCreator(@NonNull Class<@NonNull T> clazz, @NonNull Supplier<@NonNull String> contributor);

+

+		/**

+		 * Create a supplier who creates a model element instance, initializes the

+		 * {@link MApplicationElement#setContributorURI(String)} with the value

+		 * provided by the contributor supplier and run the element through the

+		 * provided processor

+		 *

+		 * @param clazz

+		 *            the model instance type

+		 * @param contributor

+		 *            the contributor supplier

+		 * @param processor

+		 *            the processor to eg initialize the element

+		 * @return the instance

+		 */

+		public <T extends MApplicationElement> @NonNull Supplier<T> createModelElementCreator(@NonNull Class<@NonNull T> clazz, @NonNull Supplier<@NonNull String> contributor, Function<@NonNull T, @NonNull T> processor);

+	}

+

+	/**

+	 * Create a factory to create model elements

+	 * @param owner the owner of the model element

+	 * @param modelService the model service used to create the elements

+	 * @return the factory

+	 */

+	public @NonNull ModelElementFactory createModelElementFactory(@NonNull Class<?> owner, @NonNull EModelService modelService);

+

+	/**

+	 * Get the name of the bundle

+	 *

+	 * @param clazz

+	 *            the clazz

+	 * @return the bundle name

+	 */

+	public @NonNull String getBundleName(@NonNull Class<?> clazz);

+

+	/**

+	 * Get a supplier for the bundle name

+	 *

+	 * @param clazz

+	 *            the clazz

+	 * @return the bundle name

+	 */

+	public @NonNull Supplier<@NonNull String> getBundleNameSupplier(@NonNull Class<?> clazz);

 }