Bug 394315 - Enable injecting behavior objects in DiagramEditor

*Moved creation of the behavior objects from constructor to init method
of DiagramEditor (DiagramBehavior) and DiagramBehavior
(Default*Behavior)
*Removed final modifiers for behavior fields
*Added check for null in dispose methods to avoid NPEs in case of failed
initialization
*Adapted to Diagrams in Views changes
*Allow DiagramComposite clients to customize DiagramBehavior

Change-Id: I63295f2537d4f1c6742f7cc91eeee90609fc292b
diff --git a/examples/org.eclipse.graphiti.examples.common/src/org/eclipse/graphiti/examples/common/handler/DoubleDiagramDialog.java b/examples/org.eclipse.graphiti.examples.common/src/org/eclipse/graphiti/examples/common/handler/DoubleDiagramDialog.java
index ef96806..377889a 100644
--- a/examples/org.eclipse.graphiti.examples.common/src/org/eclipse/graphiti/examples/common/handler/DoubleDiagramDialog.java
+++ b/examples/org.eclipse.graphiti.examples.common/src/org/eclipse/graphiti/examples/common/handler/DoubleDiagramDialog.java
@@ -52,13 +52,13 @@
 		layout.numColumns = 2;
 
 		URI diagramURI = URI.createPlatformResourceURI(firstResource.getFullPath().toString(), true);
-		DiagramComposite diagramComposite = new DiagramComposite(null, control, SWT.BORDER);
+		DiagramComposite diagramComposite = new DiagramComposite(control, SWT.BORDER);
 
 		IDiagramEditorInput input = new DiagramEditorInput(diagramURI, null);
 		diagramComposite.setInput(input);
 
 		URI diagramURI2 = URI.createPlatformResourceURI(secondResource.getFullPath().toString(), true);
-		DiagramComposite diagramComposite2 = new DiagramComposite(null, control, SWT.BORDER);
+		DiagramComposite diagramComposite2 = new DiagramComposite(control, SWT.BORDER);
 
 		IDiagramEditorInput input2 = new DiagramEditorInput(diagramURI2, null);
 		diagramComposite2.setInput(input2);
diff --git a/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/editor/DiagramBehavior.java b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/editor/DiagramBehavior.java
index f393ad2..846f0f4 100644
--- a/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/editor/DiagramBehavior.java
+++ b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/editor/DiagramBehavior.java
@@ -9,6 +9,7 @@
  *
  * Contributors:
  *    pjpaulin - Bug 352120 - Initial API, implementation and documentation
+ *    mwenz - Bug 394315 - Enable injecting behavior objects in DiagramEditor
  *
  * </copyright>
  *
@@ -151,11 +152,11 @@
 
 	private IDiagramContainerUI diagramContainer;
 
-	private final DefaultUpdateBehavior updateBehavior;
-	private final DefaultPaletteBehavior paletteBehaviour;
-	private final DefaultPersistencyBehavior persistencyBehavior;
-	private final DefaultMarkerBehavior markerBehavior;
-	private final DefaultRefreshBehavior refreshBehavior;
+	private DefaultUpdateBehavior updateBehavior;
+	private DefaultPaletteBehavior paletteBehaviour;
+	private DefaultPersistencyBehavior persistencyBehavior;
+	private DefaultMarkerBehavior markerBehavior;
+	private DefaultRefreshBehavior refreshBehavior;
 
 	private PictogramElement pictogramElementsForSelection[];
 	private IConfigurationProviderInternal configurationProvider;
@@ -176,12 +177,6 @@
 
 	public DiagramBehavior(IDiagramContainerUI diagramContainer) {
 		this.diagramContainer = diagramContainer;
-		markerBehavior = createMarkerBehavior();
-		updateBehavior = createUpdateBehavior();
-		paletteBehaviour = createPaletteBehaviour();
-		persistencyBehavior = createPersistencyBehavior();
-		refreshBehavior = createRefreshBehavior();
-
 	}
 
 	/**
@@ -312,6 +307,31 @@
 	// ------------------ Initialization ---------------------------------------
 
 	/**
+	 * Hook to initialize the default sub behavior instances used by this editor
+	 * behavior. The default implementation simply delegates to the create
+	 * methods for the various objects. In case other default behavior
+	 * implementation should be used, clients should override these create
+	 * methods instead of this method.
+	 * 
+	 * @see #createMarkerBehavior()
+	 * @see #createUpdateBehavior()
+	 * @see #createPaletteBehaviour()
+	 * @see #createPersistencyBehavior()
+	 * @see #createRefreshBehavior()
+	 */
+	protected void initDefaultBehaviors() {
+		// Initialize behavior objects first, they are needed already within the
+		// init method. We cannot create these objects in the constructor of
+		// diagram editor because that would prevent injecting them, see
+		// Bugzilla 394315
+		markerBehavior = createMarkerBehavior();
+		updateBehavior = createUpdateBehavior();
+		paletteBehaviour = createPaletteBehaviour();
+		persistencyBehavior = createPersistencyBehavior();
+		refreshBehavior = createRefreshBehavior();
+	}
+
+	/**
 	 * Sets the given {@link IDiagramEditorInput} object as the input for this
 	 * behavior instance. The default implementation here cares about loading
 	 * the diagram from the EMF {@link Resource} the input points to, sets the
diff --git a/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/editor/DiagramComposite.java b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/editor/DiagramComposite.java
index b065323..eac0503 100644
--- a/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/editor/DiagramComposite.java
+++ b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/editor/DiagramComposite.java
@@ -10,6 +10,7 @@
  * Contributors:
  *    pjpaulin - initial API, implementation and documentation
  *    pjpaulin - Bug 352120 - Now uses IDiagramContainerUI interface
+ *    mwenz - Bug 394315 - Enable injecting behavior objects in DiagramEditor
  *
  * </copyright>
  *
@@ -49,11 +50,11 @@
 public class DiagramComposite extends GraphicalComposite implements IDiagramContainerUI {
 
 	private DiagramBehavior diagramBehavior;
+	private IWorkbenchPart ownedPart;
 
 	public DiagramComposite(IWorkbenchPart ownedPart, Composite parent, int style) {
 		super(parent, style);
-		diagramBehavior = new DiagramBehavior(this);
-		diagramBehavior.setParentPart(ownedPart);
+		this.ownedPart = ownedPart;
 		setEditDomain(new DefaultEditDomain(null));
 	}
 
@@ -61,6 +62,14 @@
 		this(null, parent, style);
 	}
 
+	protected DiagramBehavior createDiagramBehavior(IWorkbenchPart parentPart) {
+		DiagramBehavior diagramBehavior = new DiagramBehavior(this);
+		diagramBehavior.setParentPart(parentPart);
+		diagramBehavior.initDefaultBehaviors();
+
+		return diagramBehavior;
+	}
+
 	public void setInput(IDiagramEditorInput input) {
 		TransactionalEditingDomain editingDomain = GraphitiUiInternal.getEmfService()
 				.createResourceSetAndEditingDomain();
@@ -68,6 +77,9 @@
 	}
 
 	public void setInput(TransactionalEditingDomain editingDomain, IDiagramEditorInput input) {
+		if (diagramBehavior == null) {
+			diagramBehavior = createDiagramBehavior(ownedPart);
+		}
 
 		// assign editing domain to update behavior
 		getUpdateBehavior().setEditingDomain(editingDomain);
@@ -149,7 +161,9 @@
 			getWorkbenchPart().getSite().getPage().removeSelectionListener(this);
 		}
 
-		this.diagramBehavior.disposeBeforeGefDispose();
+		if (diagramBehavior != null) {
+			diagramBehavior.disposeBeforeGefDispose();
+		}
 
 		RuntimeException exc = null;
 		try {
@@ -158,7 +172,9 @@
 			exc = e;
 		}
 
-		this.diagramBehavior.disposeAfterGefDispose();
+		if (diagramBehavior != null) {
+			diagramBehavior.disposeAfterGefDispose();
+		}
 
 		if (exc != null) {
 			throw exc;
diff --git a/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/editor/DiagramEditor.java b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/editor/DiagramEditor.java
index a62d834..6ce4e07 100644
--- a/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/editor/DiagramEditor.java
+++ b/plugins/org.eclipse.graphiti.ui/src/org/eclipse/graphiti/ui/editor/DiagramEditor.java
@@ -33,6 +33,7 @@
  *    mwenz - Bug 396893 - Enable the registration of the drop target listeners configurable
  *    pjpaulin - Bug 352120 - Main implementation of DiagramEditor - API BREAKAGE HERE
  *    pjpaulin - Bug 352120 - Renamed from DiagramEditorImpl so that classes extending DiagramEditor do not break
+ *    mwenz - Bug 394315 - Enable injecting behavior objects in DiagramEditor
  *
  * </copyright>
  *
@@ -149,8 +150,6 @@
 	 */
 	public DiagramEditor() {
 		super();
-		diagramBehavior = new DiagramBehavior(this);
-		diagramBehavior.setParentPart(this);
 	}
 
 	/**
@@ -194,7 +193,7 @@
 	 * 
 	 */
 	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
-		// TODO check move parts to DiagramBehavior
+		diagramBehavior = createDiagramBehavior();
 
 		// Eclipse may call us with other inputs when a file is to be
 		// opened. Try to convert this to a valid diagram input.
@@ -230,6 +229,23 @@
 	}
 
 	/**
+	 * Creates the behavior object that cares about the common (behavioral)
+	 * coding shared between editors, views and other composites. See
+	 * {@link DiagramBehavior} for details and the default implementation.
+	 * Override to change the behavior.
+	 * 
+	 * @return a new instance of {@link DiagramBehavior}
+	 * @since 0.10
+	 */
+	protected DiagramBehavior createDiagramBehavior() {
+		DiagramBehavior diagramBehavior = new DiagramBehavior(this);
+		diagramBehavior.setParentPart(this);
+		diagramBehavior.initDefaultBehaviors();
+
+		return diagramBehavior;
+	}
+
+	/**
 	 * Is called by the {@link #init(IEditorSite, IEditorInput)} method in case
 	 * the {@link IEditorInput} instance passed is no {@link DiagramEditorInput}
 	 * . This method should try to convert the passed input object to a
@@ -478,7 +494,9 @@
 	 * <code>super.dispose()</code> in case you override this method!
 	 */
 	public void dispose() {
-		diagramBehavior.disposeBeforeGefDispose();
+		if (diagramBehavior != null) {
+			diagramBehavior.disposeBeforeGefDispose();
+		}
 
 		RuntimeException exc = null;
 		if (getEditDomain() != null) {
@@ -491,7 +509,9 @@
 			}
 		}
 
-		diagramBehavior.disposeAfterGefDispose();
+		if (diagramBehavior != null) {
+			diagramBehavior.disposeAfterGefDispose();
+		}
 
 		if (exc != null) {
 			throw exc;