You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2006/07/28 04:18:02 UTC

svn commit: r426358 [1/2] - in /incubator/cayenne/soc/trunk/cayenne-rop/rop-browser: ./ META-INF/ src/org/apache/cayenne/ropbrowser/ src/org/apache/cayenne/ropbrowser/actions/ src/org/apache/cayenne/ropbrowser/commands/ src/org/apache/cayenne/ropbrowse...

Author: aadamchik
Date: Thu Jul 27 19:18:00 2006
New Revision: 426358

URL: http://svn.apache.org/viewvc?rev=426358&view=rev
Log:
CAY-612 - client patch

Added:
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/ExistingAction.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/RemoveAction.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/ExistingObjectCommand.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/ExistingObjectRequest.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/RemoveObjectCommand.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/wizards/
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/wizards/SelectObjectPage.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/wizards/SelectParametersPage.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/wizards/SelectQueryWizard.java
Modified:
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/.classpath
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/META-INF/MANIFEST.MF
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/build.properties
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ConnectionManager.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ObjectEditor.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ObjectEditorContextMenuProvider.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ObjectEditorInput.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/DeleteAction.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/HideAction.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/InsertAction.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/ExpandRelationshipCommand.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/HideElementCommand.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/PopOutCommand.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/figures/ElementFigure.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/figures/SingleFigure.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/layout/DelegatingLayoutManager.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/layout/DirectedGraphLayoutVisitor.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/AbstractObject.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/CollectionModelElement.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/ElementDiagram.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/ModelElement.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/SingleModelElement.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/parts/CollectionEditPart.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/parts/ConnectionEditPart.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/parts/ElementDiagramEditPart.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/parts/ElementEditPart.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/parts/SingleEditPart.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/policies/ElementXYLayoutEditPolicy.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/policies/SelectionHandlesEditPolicy.java
    incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/views/ControlPanelView.java

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/.classpath
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/.classpath?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/.classpath (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/.classpath Thu Jul 27 19:18:00 2006
@@ -7,8 +7,8 @@
 	<classpathentry kind="lib" path="lib/commons-lang-2.1.jar"/>
 	<classpathentry kind="lib" path="lib/commons-logging.jar"/>
 	<classpathentry kind="lib" path="lib/hessian-3.0.13.jar"/>
-	<classpathentry sourcepath="G:/soc/smack-dev-2.2.1/source" kind="lib" path="lib/smack-2.2.1.jar"/>
 	<classpathentry kind="lib" path="lib/smackx-2.2.1.jar"/>
+	<classpathentry sourcepath="G:/soc/smack-dev-2.2.1/source" kind="lib" path="lib/smack-2.2.1.jar"/>
 	<classpathentry sourcepath="/cayenne-java/src/cayenne/java" kind="lib" path="lib/cayenne-client-nodeps-1.2.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/META-INF/MANIFEST.MF?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/META-INF/MANIFEST.MF (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/META-INF/MANIFEST.MF Thu Jul 27 19:18:00 2006
@@ -10,7 +10,9 @@
  lib/commons-logging.jar,
  lib/commons-lang-2.1.jar,
  lib/commons-collections-3.1.jar,
- lib/cayenne-client-nodeps-1.2.jar
+ lib/cayenne-client-nodeps-1.2.jar,
+ lib/smack-2.2.1.jar,
+ lib/smackx-2.2.1.jar
 Require-Bundle: org.eclipse.core.runtime,
  org.eclipse.ui,
  org.eclipse.ui.forms,

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/build.properties
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/build.properties?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/build.properties (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/build.properties Thu Jul 27 19:18:00 2006
@@ -5,4 +5,7 @@
                lib/commons-logging.jar,\
                lib/commons-lang-2.1.jar,\
                lib/commons-collections-3.1.jar,\
-               lib/cayenne-client-nodeps-1.2.jar
\ No newline at end of file
+               lib/cayenne-client-nodeps-1.2.jar,\
+               lib/smack-2.2.1.jar,\
+               lib/smackx-2.2.1.jar
+

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ConnectionManager.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ConnectionManager.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ConnectionManager.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ConnectionManager.java Thu Jul 27 19:18:00 2006
@@ -25,6 +25,7 @@
 import org.objectstyle.cayenne.DataChannel;
 import org.objectstyle.cayenne.ObjectContext;
 import org.objectstyle.cayenne.event.EventSubject;
+import org.objectstyle.cayenne.graph.GraphEvent;
 import org.objectstyle.cayenne.remote.ClientChannel;
 import org.objectstyle.cayenne.remote.ClientConnection;
 import org.objectstyle.cayenne.remote.hessian.HessianConnection;
@@ -39,10 +40,10 @@
 	
 	private static ConnectionManager _ref;
 	/** All connections made by the application */
-	private Hashtable<String, ClientConnection> connections;
+	private Hashtable<String, DataChannel> connections;
 	
 	private ConnectionManager() {
-		connections = new Hashtable<String, ClientConnection>();
+		connections = new Hashtable<String, DataChannel>();
 	}
 	
 	public static ConnectionManager getInstance() {
@@ -57,21 +58,27 @@
 	 * @param address full address of the Cayenne web service (eg http://localhost:8080/rop-browser/rop-browser)
 	 * @return ObjectContext connected to the given address
 	 */
-	public ObjectContext getObjectContext(String address) {
+	public ObjectContext getNewObjectContext(String address) {
 		
-		ClientConnection connection;
+		DataChannel channel;
 		
 		if (connections.containsKey(address)) {
-			connection = connections.get(address);
+			channel = connections.get(address);
 		}
 		else {
-			connection = new HessianConnection(address, null, null, "conference");
-			connections.put(address, connection);
+			HessianConnection connection = new HessianConnection(address, null, null, "conference");
+			channel = new ClientChannel(connection);
+			connections.put(address, channel);
 		}
-		DataChannel channel = new ClientChannel(connection);
-		// TODO configure query caching
-		ObjectContext context = new CayenneContext(channel);
 		
+		ObjectContext context = new CayenneContext(channel, true, false);
+		// TODO XMPP notification of graph changes; DataChannel.* ?
+		channel.getEventManager().addListener(this, "handleXMPP", GraphEvent.class, DataChannel.GRAPH_CHANGED_SUBJECT);
+		channel.getEventManager().addListener(this, "handleXMPP", GraphEvent.class, DataChannel.GRAPH_FLUSHED_SUBJECT);
 		return context;
+	}
+	
+	public void handleXMPP(GraphEvent event) {
+		System.out.println("XMPP : " + event.toString());
 	}
 }

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ObjectEditor.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ObjectEditor.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ObjectEditor.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ObjectEditor.java Thu Jul 27 19:18:00 2006
@@ -19,8 +19,10 @@
 import java.util.EventObject;
 
 import org.apache.cayenne.ropbrowser.actions.DeleteAction;
+import org.apache.cayenne.ropbrowser.actions.ExistingAction;
 import org.apache.cayenne.ropbrowser.actions.HideAction;
 import org.apache.cayenne.ropbrowser.actions.InsertAction;
+import org.apache.cayenne.ropbrowser.actions.RemoveAction;
 import org.apache.cayenne.ropbrowser.actions.RollbackAction;
 import org.apache.cayenne.ropbrowser.actions.SetNameAction;
 import org.apache.cayenne.ropbrowser.actions.ToggleLayoutAction;
@@ -123,12 +125,9 @@
 		return false;
 	}
 	
-	/**
-	 * Initialises the editor for a given context and query.
-	 */
 	protected void setInput(IEditorInput input) {
 		super.setInput(input);
-		elementDiagram = new ElementDiagram(((ObjectEditorInput) input).getContext(), ((ObjectEditorInput) input).getQuery());
+		elementDiagram = new ElementDiagram(((ObjectEditorInput) input).getContext());
 	}
 	
 	protected void createActions() {
@@ -142,7 +141,15 @@
 		getActionRegistry().registerAction(action);
 		getSelectionActions().add(action.getId());
 		
+		action = new RemoveAction(this);
+		getActionRegistry().registerAction(action);
+		getSelectionActions().add(action.getId());
+		
 		action = new InsertAction(this);
+		getActionRegistry().registerAction(action);
+		getSelectionActions().add(action.getId());
+		
+		action = new ExistingAction(this, elementDiagram.getObjectContext());
 		getActionRegistry().registerAction(action);
 		getSelectionActions().add(action.getId());
 		

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ObjectEditorContextMenuProvider.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ObjectEditorContextMenuProvider.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ObjectEditorContextMenuProvider.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ObjectEditorContextMenuProvider.java Thu Jul 27 19:18:00 2006
@@ -17,8 +17,10 @@
 package org.apache.cayenne.ropbrowser;
 
 import org.apache.cayenne.ropbrowser.actions.DeleteAction;
+import org.apache.cayenne.ropbrowser.actions.ExistingAction;
 import org.apache.cayenne.ropbrowser.actions.HideAction;
 import org.apache.cayenne.ropbrowser.actions.InsertAction;
+import org.apache.cayenne.ropbrowser.actions.RemoveAction;
 import org.apache.cayenne.ropbrowser.actions.RollbackAction;
 import org.apache.cayenne.ropbrowser.actions.SetNameAction;
 import org.apache.cayenne.ropbrowser.actions.ToggleLayoutAction;
@@ -79,7 +81,17 @@
 			menu.appendToGroup(GEFActionConstants.GROUP_EDIT, action);
 		}
 		
+		action = getAction(RemoveAction.ID);
+		if (action.isEnabled()) {
+			menu.appendToGroup(GEFActionConstants.GROUP_EDIT, action);
+		}
+		
 		action = getAction(InsertAction.ID);
+		if (action.isEnabled()) {
+			menu.appendToGroup(GEFActionConstants.GROUP_EDIT, action);
+		}
+		
+		action = getAction(ExistingAction.ID);
 		if (action.isEnabled()) {
 			menu.appendToGroup(GEFActionConstants.GROUP_EDIT, action);
 		}

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ObjectEditorInput.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ObjectEditorInput.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ObjectEditorInput.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/ObjectEditorInput.java Thu Jul 27 19:18:00 2006
@@ -28,15 +28,11 @@
  * @author Marcel Gordon
  */
 public class ObjectEditorInput implements IEditorInput {
-
-	/** name of the query stored in the Cayenne data map */
-	protected String query;
-	/** context in which the query exists */
-	protected ObjectContext context;
 	
-	public ObjectEditorInput(ObjectContext context, String query) {
+	private ObjectContext context;
+
+	public ObjectEditorInput(ObjectContext context) {
 		this.context = context;
-		this.query = query;
 	}
 	
 	public boolean exists() {
@@ -51,7 +47,7 @@
 	 * The name of the query contained in the Cayenne data map.
 	 */
 	public String getName() {
-		return query;
+		return "Object editor";
 	}
 
 	public IPersistableElement getPersistable() {
@@ -59,32 +55,21 @@
 	}
 
 	public String getToolTipText() {
-		return query;
+		return "Object editor";
 	}
 
 	public Object getAdapter(Class adapter) {
 		return null;
 	}
 
-	public String getQuery() {
-		return query;
-	}
-
-	/**
-	 * @return the context in which the query is found
-	 */
-	public ObjectContext getContext() {
-		return context;
-	}
-	
 	/**
 	 * Used to determine whether to open a new editor.
 	 */
 	public boolean equals(Object o) {
-		if (o instanceof ObjectEditorInput) {
-			ObjectEditorInput input = (ObjectEditorInput) o;
-			return (input.getContext() == getContext() && input.getQuery().equals(getQuery()));
-		}
 		return false;
+	}
+
+	public ObjectContext getContext() {
+		return context;
 	}
 }

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/DeleteAction.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/DeleteAction.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/DeleteAction.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/DeleteAction.java Thu Jul 27 19:18:00 2006
@@ -30,13 +30,14 @@
 	
 	private Request request;
 	
-	public static final String ID = "org.apache.cayenne.ropbrowser.actions.ExpungeAction";
+	public static final String ID = "org.apache.cayenne.ropbrowser.actions.DeleteAction";
 	public static final String DELETE_REQUEST = "Delete";
 	
 	public DeleteAction(IWorkbenchPart part) {
 		super(part);
 		setId(ID);
 		setText("Delete");
+		setToolTipText("Remove the current object from this element and delete it from the database");
 		request = new Request(DELETE_REQUEST);
 	}
 

Added: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/ExistingAction.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/ExistingAction.java?rev=426358&view=auto
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/ExistingAction.java (added)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/ExistingAction.java Thu Jul 27 19:18:00 2006
@@ -0,0 +1,102 @@
+/*
+ *  Copyright 2006 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.cayenne.ropbrowser.actions;
+
+import java.util.List;
+
+import org.apache.cayenne.ropbrowser.commands.ExistingObjectRequest;
+import org.apache.cayenne.ropbrowser.model.AbstractObject;
+import org.apache.cayenne.ropbrowser.model.ModelElement;
+import org.apache.cayenne.ropbrowser.model.SingleModelElement;
+import org.apache.cayenne.ropbrowser.parts.CollectionEditPart;
+import org.apache.cayenne.ropbrowser.parts.ElementEditPart;
+import org.apache.cayenne.ropbrowser.parts.SingleEditPart;
+import org.apache.cayenne.ropbrowser.wizards.SelectQueryWizard;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.commands.CompoundCommand;
+import org.eclipse.gef.ui.actions.SelectionAction;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbenchPart;
+import org.objectstyle.cayenne.ObjectContext;
+
+public class ExistingAction extends SelectionAction {
+	
+	private ExistingObjectRequest request;
+	
+	private ObjectContext context;
+	
+	private String entityName;
+	
+	public static final String ID = "org.apache.cayenne.ropbrowser.actions.ExistingAction";
+	
+	public ExistingAction(IWorkbenchPart part, ObjectContext context) {
+		super(part);
+		setId(ID);
+		setText("Insert existing object...");
+		request = new ExistingObjectRequest();
+		this.context = context;
+	}
+
+	protected boolean calculateEnabled() {
+		return canPerformAction();
+	}
+	
+	public void run() {
+		SelectQueryWizard wizard = new SelectQueryWizard(context, entityName, SelectQueryWizard.RETURN_OBJECT);
+		WizardDialog dialog = new WizardDialog(Display.getCurrent().getActiveShell(), wizard);
+		dialog.create();
+		if (dialog.open() == WizardDialog.OK) {
+			request.setSelectedObject(wizard.getSelectedObject());
+			execute(getCommand());
+		}
+	}
+	
+	private boolean canPerformAction() {
+		if (getSelectedObjects().isEmpty())
+			return false;
+		List parts = getSelectedObjects();
+		for (int i=0; i<parts.size(); i++){
+			Object o = parts.get(i);
+			if (!(o instanceof CollectionEditPart) && !(o instanceof SingleEditPart)) {
+				return false;
+			}
+			
+			// ensure that they all have the same entity name
+			ModelElement element = (ModelElement) ((ElementEditPart) o).getModel();
+			if (i == 0) {
+				entityName = element.getName(); 
+			}
+			else if (!element.getName().equals(entityName)) {
+				return false;
+			}
+		}
+		return true;
+	}
+	
+	private Command getCommand() {
+		List editparts = getSelectedObjects();
+		CompoundCommand cc = new CompoundCommand();
+		for (int i=0; i < editparts.size(); i++) {
+			EditPart part = (EditPart)editparts.get(i);
+			cc.add(part.getCommand(request));
+		}
+		return cc;
+	}
+}

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/HideAction.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/HideAction.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/HideAction.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/HideAction.java Thu Jul 27 19:18:00 2006
@@ -58,9 +58,6 @@
 			if (!(o instanceof ElementEditPart)) {
 				return false;
 			}
-			if (((ElementEditPart) o).isRoot()) {
-				return false;
-			}
 		}
 		return true;
 	}

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/InsertAction.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/InsertAction.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/InsertAction.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/InsertAction.java Thu Jul 27 19:18:00 2006
@@ -55,14 +55,14 @@
 		List parts = getSelectedObjects();
 		for (int i=0; i<parts.size(); i++){
 			Object o = parts.get(i);
-			if (o instanceof CollectionEditPart) {
-				return true;
+			if (!(o instanceof CollectionEditPart) && !(o instanceof SingleEditPart)) {
+				return false;
 			}
-			if ((o instanceof SingleEditPart) && (((SingleModelElement) ((SingleEditPart) o).getModel()).getCurrentObject() == null)) {
-				return true;
+			if ((o instanceof SingleEditPart) && !(((SingleModelElement) ((SingleEditPart) o).getModel()).isNull())) {
+				return false;
 			}
 		}
-		return false;
+		return true;
 	}
 	
 	private Command getCommand() {

Added: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/RemoveAction.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/RemoveAction.java?rev=426358&view=auto
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/RemoveAction.java (added)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/actions/RemoveAction.java Thu Jul 27 19:18:00 2006
@@ -0,0 +1,77 @@
+/*
+ *  Copyright 2006 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.cayenne.ropbrowser.actions;
+
+import java.util.List;
+
+import org.apache.cayenne.ropbrowser.model.CollectionModelElement;
+import org.apache.cayenne.ropbrowser.model.ModelElement;
+import org.apache.cayenne.ropbrowser.parts.CollectionEditPart;
+import org.apache.cayenne.ropbrowser.parts.ElementEditPart;
+import org.apache.cayenne.ropbrowser.parts.SingleEditPart;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.commands.CompoundCommand;
+import org.eclipse.gef.ui.actions.SelectionAction;
+import org.eclipse.ui.IWorkbenchPart;
+
+public class RemoveAction extends SelectionAction {
+	
+	private Request request;
+	
+	public static final String ID = "org.apache.cayenne.ropbrowser.actions.RemoveAction";
+	public static final String REMOVE_REQUEST = "Remove";
+	
+	public RemoveAction(IWorkbenchPart part) {
+		super(part);
+		setId(ID);
+		setText("Remove object");
+		setToolTipText("Remove the current object from this element without deleting it");
+		request = new Request(REMOVE_REQUEST);
+	}
+
+	protected boolean calculateEnabled() {
+		return canPerformAction();
+	}
+	
+	public void run() {
+		execute(getCommand());
+	}
+	
+	private boolean canPerformAction() {
+		if (getSelectedObjects().isEmpty())
+			return false;
+		List parts = getSelectedObjects();
+		for (int i=0; i<parts.size(); i++){
+			Object o = parts.get(i);
+			if (((ModelElement) ((ElementEditPart) o).getModel()).isNull()) {
+				return false;
+			}
+		}
+		return true;
+	}
+	
+	private Command getCommand() {
+		List editparts = getSelectedObjects();
+		CompoundCommand cc = new CompoundCommand();
+		for (int i=0; i < editparts.size(); i++) {
+			EditPart part = (EditPart)editparts.get(i);
+			cc.add(part.getCommand(request));
+		}
+		return cc;
+	}
+}

Added: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/ExistingObjectCommand.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/ExistingObjectCommand.java?rev=426358&view=auto
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/ExistingObjectCommand.java (added)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/ExistingObjectCommand.java Thu Jul 27 19:18:00 2006
@@ -0,0 +1,103 @@
+/*
+ *  Copyright 2006 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.cayenne.ropbrowser.commands;
+
+import org.apache.cayenne.ropbrowser.model.AbstractObject;
+import org.apache.cayenne.ropbrowser.model.CollectionModelElement;
+import org.apache.cayenne.ropbrowser.model.Connection;
+import org.apache.cayenne.ropbrowser.model.ModelElement;
+import org.apache.cayenne.ropbrowser.model.RelationshipConnection;
+import org.apache.cayenne.ropbrowser.model.SingleModelElement;
+import org.eclipse.gef.commands.Command;
+import org.objectstyle.cayenne.map.ObjEntity;
+
+public class ExistingObjectCommand extends Command {
+	
+	/** ModelElement to insert a record into. */
+	private final ModelElement element;
+	
+	private final AbstractObject object;
+	
+	/**
+	 * Create a command that will remove the ModelElement from its parent ElementDiagram.
+	 * @param parent the ElementDiagram containing the child
+	 * @param child    the ModelElement to remove
+	 * @throws IllegalArgumentException if any parameter is null
+	 */
+	public ExistingObjectCommand(ModelElement element, AbstractObject object) {
+		if (element == null) {
+			throw new IllegalArgumentException();
+		}
+		setLabel("existing object");
+		this.element = element;
+		this.object = object;
+	}
+	
+	/**
+	 * @see org.eclipse.gef.commands.Command#canUndo()
+	 */
+	public boolean canUndo() {
+		return false;
+	}
+	
+	public boolean canExecute() {
+		return !element.contains(object);
+	}
+	
+	/**
+	 * @see org.eclipse.gef.commands.Command#execute()
+	 */
+	public void execute() {
+		if (element instanceof CollectionModelElement) {
+			element.addObject(object);
+		}
+		else if (element instanceof SingleModelElement) {
+			if (element.isNull()) {
+				ModelElement existing = element.getDiagram().getSingleElementForObject(object);
+				if (existing == null) { // no existing element - just set this one up
+					element.addObject(object);
+				}
+				else { // a single model element with this object already exists; link to it
+					for (Connection conn : element.getTargetConnections()) {
+						if (conn instanceof RelationshipConnection) {
+							RelationshipConnection relConn = (RelationshipConnection) conn;
+							relConn.getSource().getCurrentObject().setRelationship(relConn.getRelationship(), element.getCurrentObject(), object);
+							RelationshipConnection newConn = new RelationshipConnection(relConn.getSource(), existing, relConn.getRelationship());
+						}
+					}
+					Command recCommand = new HideElementCommand(element);
+					recCommand.execute();
+				}
+			}
+			else {
+				for (Connection conn : element.getTargetConnections()) {
+					if (conn instanceof RelationshipConnection) {
+						RelationshipConnection relConn = (RelationshipConnection) conn;
+						relConn.getSource().getCurrentObject().setRelationship(relConn.getRelationship(), element.getCurrentObject(), object);
+					}
+				}
+				element.setObject(object);
+				element.getDiagram().createMemberConnections(element);
+				for (Connection conn : element.getSourceConnections()) {
+					if (conn instanceof RelationshipConnection) { // this should always be true
+						Command recCommand = new ContractRelationshipCommand((RelationshipConnection) conn);
+						recCommand.execute();
+					}
+				}
+			}
+		}
+	}
+}

Added: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/ExistingObjectRequest.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/ExistingObjectRequest.java?rev=426358&view=auto
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/ExistingObjectRequest.java (added)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/ExistingObjectRequest.java Thu Jul 27 19:18:00 2006
@@ -0,0 +1,38 @@
+/*
+ *  Copyright 2006 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.cayenne.ropbrowser.commands;
+
+import org.apache.cayenne.ropbrowser.model.AbstractObject;
+import org.eclipse.gef.Request;
+
+public class ExistingObjectRequest extends Request {
+
+	private AbstractObject selectedObject;
+	
+	public static final String EXISTING_REQUEST = "Existing Object";
+
+	public ExistingObjectRequest() {
+		super(EXISTING_REQUEST);
+	}
+
+	public AbstractObject getSelectedObject() {
+		return selectedObject;
+	}
+
+	public void setSelectedObject(AbstractObject selectedObject) {
+		this.selectedObject = selectedObject;
+	}
+}

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/ExpandRelationshipCommand.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/ExpandRelationshipCommand.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/ExpandRelationshipCommand.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/ExpandRelationshipCommand.java Thu Jul 27 19:18:00 2006
@@ -58,10 +58,10 @@
 		ModelElement newElement;
 		
 		if (relationship.isToMany()) {
-			newElement = new CollectionModelElement(source.getDiagram(), relationship.getTargetEntityName());
+			newElement = new CollectionModelElement(relationship.getTargetEntityName());
 		}
 		else {
-			newElement = new SingleModelElement(source.getDiagram(), relationship.getTargetEntityName());
+			newElement = new SingleModelElement(relationship.getTargetEntityName());
 		}
 		
 		newElement.setObject(value);
@@ -69,7 +69,6 @@
 		if (source.getDiagram().addElement(newElement)) {
 			// add the element as a new element; check for member connections
 			conn = new RelationshipConnection(source, newElement, relationship);
-			source.getDiagram().createMemberConnections(newElement);
 		}
 		else {
 			// the element exists; just connect it in a relationship to this one

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/HideElementCommand.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/HideElementCommand.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/HideElementCommand.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/HideElementCommand.java Thu Jul 27 19:18:00 2006
@@ -101,10 +101,14 @@
 			command.undo();
 		}		
 		for (Connection conn : sourceConnections) {
-			conn.connect();
+			if (conn instanceof RelationshipConnection) {
+				conn.connect();
+			}
 		}
 		for (Connection conn : targetConnections) {
-			conn.connect();
+			if (conn instanceof RelationshipConnection) {
+				conn.connect();
+			}
 		}
 		element.getDiagram().addElement(element);
 	}

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/PopOutCommand.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/PopOutCommand.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/PopOutCommand.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/PopOutCommand.java Thu Jul 27 19:18:00 2006
@@ -53,11 +53,9 @@
 	 * @see org.eclipse.gef.commands.Command#redo()
 	 */
 	public void redo() {
-		newElement = new SingleModelElement(element.getDiagram(), element.getName());
+		newElement = new SingleModelElement(element.getName());
 		newElement.setObject(element.getCurrentObject());
-		if (element.getDiagram().addElement(newElement)) {
-			element.getDiagram().createMemberConnections(newElement);
-		}
+		element.getDiagram().addElement(newElement);
 	}
 	
 	/**

Added: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/RemoveObjectCommand.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/RemoveObjectCommand.java?rev=426358&view=auto
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/RemoveObjectCommand.java (added)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/commands/RemoveObjectCommand.java Thu Jul 27 19:18:00 2006
@@ -0,0 +1,57 @@
+/*
+ *  Copyright 2006 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.cayenne.ropbrowser.commands;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.cayenne.ropbrowser.model.Connection;
+import org.apache.cayenne.ropbrowser.model.ModelElement;
+import org.eclipse.gef.commands.Command;
+
+public class RemoveObjectCommand extends Command {
+	
+	/** ModelElement to remove. */
+	private final ModelElement element;
+	
+	/**
+	 * Create a command that will remove the ModelElement from its parent ElementDiagram.
+	 * @param parent the ElementDiagram containing the child
+	 * @param child    the ModelElement to remove
+	 * @throws IllegalArgumentException if any parameter is null
+	 */
+	public RemoveObjectCommand(ModelElement element) {
+		if (element == null) {
+			throw new IllegalArgumentException();
+		}
+		setLabel("remove from collection");
+		this.element = element;
+	}
+	
+	/**
+	 * @see org.eclipse.gef.commands.Command#canUndo()
+	 */
+	public boolean canUndo() {
+		return false;
+	}
+	
+	/**
+	 * @see org.eclipse.gef.commands.Command#execute()
+	 */
+	public void execute() {
+		element.removeObject(element.getCurrentObject());
+	}
+}

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/figures/ElementFigure.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/figures/ElementFigure.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/figures/ElementFigure.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/figures/ElementFigure.java Thu Jul 27 19:18:00 2006
@@ -92,9 +92,9 @@
 	}
 
 	protected void setAttributes(AbstractObject model) {
-		if (model != null) {
-			getAttributeCompartment().removeAll();
-			
+		getAttributeCompartment().removeAll();
+		
+		if (model != null) {			
 			Iterator i = model.getAttributes().iterator();
 			while (i.hasNext()) {
 				Attribute a = (Attribute) i.next();

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/figures/SingleFigure.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/figures/SingleFigure.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/figures/SingleFigure.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/figures/SingleFigure.java Thu Jul 27 19:18:00 2006
@@ -35,7 +35,7 @@
 	
 	protected void setBackgroundColour() {
 		if (getElementCast().getCurrentObject() != null &&
-				getElementCast().isDeleted()) {
+				getElementCast().getCurrentObject().isDeleted()) {
 			name.setBackgroundColor(ColorConstants.red);
 		}
 		else {

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/layout/DelegatingLayoutManager.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/layout/DelegatingLayoutManager.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/layout/DelegatingLayoutManager.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/layout/DelegatingLayoutManager.java Thu Jul 27 19:18:00 2006
@@ -108,6 +108,8 @@
 		}
 		else
 		{
+			// TODO allow drag single element onto null single element to set relationship
+			// and single element into collection to add into relationship
 			diagram.installEditPolicy(EditPolicy.LAYOUT_ROLE, new SelectionHandlesEditPolicy());
 		}
 	}

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/layout/DirectedGraphLayoutVisitor.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/layout/DirectedGraphLayoutVisitor.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/layout/DirectedGraphLayoutVisitor.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/layout/DirectedGraphLayoutVisitor.java Thu Jul 27 19:18:00 2006
@@ -158,8 +158,20 @@
 
 	protected void applyResults(ConnectionEditPart connection)
 	{
+		/*
+		 * This has been removed in order to ensure that when the layout is toggled
+		 * from automatic to manual, the connections don't have fixed bendpoints
+		 * in them. This does not seem to have affected the auto layout at all.
+		 * Begs the question - what was it all about in the first place?
+		 */
+		
+		((PolylineConnection) connection.getConnectionFigure()).setRoutingConstraint(Collections.EMPTY_LIST);
+		
+		/*
 		Edge e = (Edge) partToNodesMap.get(connection);
 		NodeList nodes = e.vNodes;
+		
+		 
 
 		PolylineConnection conn = (PolylineConnection) connection.getConnectionFigure();
 		if (nodes != null)
@@ -170,7 +182,7 @@
 				Node vn = nodes.getNode(i);
 				int x = vn.x;
 				int y = vn.y;
-				if (e.isFeedback)
+				if (e.isFeedback())
 				{
 					bends.add(new AbsoluteBendpoint(x, y + vn.height));
 					bends.add(new AbsoluteBendpoint(x, y));
@@ -188,6 +200,7 @@
 		{
 			conn.setRoutingConstraint(Collections.EMPTY_LIST);
 		}
+		*/
 	}
 
 }

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/AbstractObject.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/AbstractObject.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/AbstractObject.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/AbstractObject.java Thu Jul 27 19:18:00 2006
@@ -44,37 +44,36 @@
 public class AbstractObject extends PersistentObject {
 
 	protected static SimpleDateFormat dateFormatter = new SimpleDateFormat("dd/MM/yyyy");
-	/** Delegate used to implemenent property-change-support. */
-	private transient PropertyChangeSupport pcsDelegate = new PropertyChangeSupport(this);
+	public static final String PROP_DELETED = "AbstractObject.Deleted";
+	public static final String PROP_MODIFIED = "AbstractObject.Modified";
 	
 	protected Collection attributes;
 	
-	public String getName() {
-		return this.getClass().getSimpleName();
-	}
+	/** Delegate used to implemenent property-change-support. */
+	private transient PropertyChangeSupport pcsDelegate = new PropertyChangeSupport(this);
 	
-	/**
-	 * @return a collection of {@link Relationship} objects.
+	/** 
+	 * Attach a non-null PropertyChangeListener to this object.
+	 * @param l a non-null PropertyChangeListener instance
+	 * @throws IllegalArgumentException if the parameter is null
 	 */
-	public Collection getRelationships() {
-		if(objectContext != null) {
-			return objectContext.getEntityResolver().getObjEntity(getName()).getRelationships();
+	public synchronized void addPropertyChangeListener(PropertyChangeListener l) {
+		if (l == null) {
+			throw new IllegalArgumentException();
 		}
-		return Collections.EMPTY_LIST;
+		pcsDelegate.addPropertyChangeListener(l);
 	}
-
-	/**
-	 * @return a collection of {@link org.objectstyle.cayenne.map.Attribute} objects.
+	
+	/** 
+	 * Report a property change to registered listeners (for example edit parts).
+	 * @param property the programmatic name of the property that changed
+	 * @param oldValue the old value of this property
+	 * @param newValue the new value of this property
 	 */
-	public Collection getAttributes() {
-		if (attributes != null) {
-			return attributes;
-		}
-		else if (objectContext != null) {
-			attributes = objectContext.getEntityResolver().getObjEntity(getName()).getAttributes();
-			return attributes;
+	protected void firePropertyChange(String property, Object oldValue, Object newValue) {
+		if (pcsDelegate.hasListeners(property)) {
+			pcsDelegate.firePropertyChange(property, oldValue, newValue);
 		}
-		return Collections.EMPTY_LIST;
 	}
 	
 	/**
@@ -94,20 +93,44 @@
 		}
 		return null;
 	}
+
+	/**
+	 * @return a collection of {@link org.objectstyle.cayenne.map.Attribute} objects.
+	 */
+	public Collection getAttributes() {
+		if (attributes != null) {
+			return attributes;
+		}
+		else if (objectContext != null) {
+			attributes = objectContext.getEntityResolver().getObjEntity(getName()).getAttributes();
+			return attributes;
+		}
+		return Collections.EMPTY_LIST;
+	}
 	
-	public void setRelationship(Relationship rel, AbstractObject oldValue, AbstractObject newValue) {
+	public String getName() {
+		return this.getClass().getSimpleName();
+	}
+	
+	/**
+	 * Generates the property descriptors for this object.
+	 * Should cache the results for efficiency.
+	 * @return array of IPropertyDescriptors for the objects attributes
+	 */
+	public IPropertyDescriptor[] getPropertyDescriptors() {
 		if (objectContext != null) {
-			
-			EntityResolver resolver = objectContext.getEntityResolver();
-			ClassDescriptor descriptor = resolver.getClassDescriptor(getName());
-			
-			descriptor.getProperty(rel.getName()).writeProperty(this, oldValue, newValue);
-			
-			// notify objectContext about simple property change
-	        objectContext.propertyChanged(this, rel.getName(), oldValue, newValue);
-	        
-	        firePropertyChange(rel.getName(), oldValue, newValue);
+			EntityResolver entityResolver = getObjectContext().getEntityResolver();
+			ObjEntity entity = entityResolver.getObjEntity(getName());
+			Iterator attributes = entity.getAttributes().iterator();
+			IPropertyDescriptor[] properties = new IPropertyDescriptor[entity.getAttributes().size()];
+			int i = 0;
+			while (attributes.hasNext()) {
+				ObjAttribute attribute = (ObjAttribute) attributes.next();
+				properties[i++] = new TextPropertyDescriptor(attribute.getName(), attribute.getName());
+			}
+			return properties;
 		}
+		return new IPropertyDescriptor[0];
 	}
 
 	/**
@@ -148,6 +171,21 @@
 	}
 
 	/**
+	 * @return a collection of {@link Relationship} objects.
+	 */
+	public Collection getRelationships() {
+		if(objectContext != null) {
+			return objectContext.getEntityResolver().getObjEntity(getName()).getRelationships();
+		}
+		return Collections.EMPTY_LIST;
+	}
+
+	public boolean isDeleted() {
+		return (getPersistenceState() == PersistenceState.DELETED) ||
+				(getPersistenceState() == PersistenceState.TRANSIENT);
+	}
+
+	/**
 	 * Determines if a given property is set for this object.
 	 * @param id the name of the property
 	 * @return true if the property is set; false otherwise.
@@ -155,13 +193,36 @@
 	public boolean isPropertySet(Object id) {
 		return getPropertyValue(id) != null;
 	}
-
+	
+	/** 
+	 * Remove a PropertyChangeListener from this component.
+	 * @param l a PropertyChangeListener instance
+	 */
+	public synchronized void removePropertyChangeListener(PropertyChangeListener l) {
+		if (l != null) {
+			pcsDelegate.removePropertyChangeListener(l);
+		}
+	}
+	
 	/**
 	 * Resets the value of the given property. Does nothing.
 	 * @param id the name of the property
 	 */
 	public void resetPropertyValue(Object id) {
 	}
+	
+	public void setPersistenceState(int persistenceState) {
+		int oldState = getPersistenceState();
+		super.setPersistenceState(persistenceState);
+		switch (persistenceState) {
+			case PersistenceState.DELETED : 
+				firePropertyChange(PROP_DELETED, oldState, persistenceState);
+				break;
+			case PersistenceState.TRANSIENT : //moving to transient means deleted in this context
+				firePropertyChange(PROP_DELETED, oldState, persistenceState);
+				break;
+		} 
+	}
 
 	/**
 	 * Sets the value of a property of the object
@@ -206,66 +267,20 @@
 	        // notify objectContext about simple property change
 	        objectContext.propertyChanged(this, id.toString(), oldValue, newValue);
 	        
-	        firePropertyChange(id.toString(), oldValue, newValue);
-		}
-	}
-	
-	/** 
-	 * Attach a non-null PropertyChangeListener to this object.
-	 * @param l a non-null PropertyChangeListener instance
-	 * @throws IllegalArgumentException if the parameter is null
-	 */
-	public synchronized void addPropertyChangeListener(PropertyChangeListener l) {
-		if (l == null) {
-			throw new IllegalArgumentException();
-		}
-		pcsDelegate.addPropertyChangeListener(l);
-	}
-	
-	/** 
-	 * Report a property change to registered listeners (for example edit parts).
-	 * @param property the programmatic name of the property that changed
-	 * @param oldValue the old value of this property
-	 * @param newValue the new value of this property
-	 */
-	protected void firePropertyChange(String property, Object oldValue, Object newValue) {
-		if (pcsDelegate.hasListeners(property)) {
-			pcsDelegate.firePropertyChange(property, oldValue, newValue);
-		}
-	}
-	
-	/** 
-	 * Remove a PropertyChangeListener from this component.
-	 * @param l a PropertyChangeListener instance
-	 */
-	public synchronized void removePropertyChangeListener(PropertyChangeListener l) {
-		if (l != null) {
-			pcsDelegate.removePropertyChangeListener(l);
+	        firePropertyChange(PROP_MODIFIED, null, this);
 		}
 	}
 
-	/**
-	 * Generates the property descriptors for this object.
-	 * Should cache the results for efficiency.
-	 * @return array of IPropertyDescriptors for the objects attributes
-	 */
-	public IPropertyDescriptor[] getPropertyDescriptors() {
+	public void setRelationship(Relationship rel, AbstractObject oldValue, AbstractObject newValue) {
 		if (objectContext != null) {
-			EntityResolver entityResolver = getObjectContext().getEntityResolver();
-			ObjEntity entity = entityResolver.getObjEntity(getName());
-			Iterator attributes = entity.getAttributes().iterator();
-			IPropertyDescriptor[] properties = new IPropertyDescriptor[entity.getAttributes().size()];
-			int i = 0;
-			while (attributes.hasNext()) {
-				ObjAttribute attribute = (ObjAttribute) attributes.next();
-				properties[i++] = new TextPropertyDescriptor(attribute.getName(), attribute.getName());
-			}
-			return properties;
+			
+			EntityResolver resolver = objectContext.getEntityResolver();
+			ClassDescriptor descriptor = resolver.getClassDescriptor(getName());
+			
+			descriptor.getProperty(rel.getName()).writeProperty(this, oldValue, newValue);
+			
+			// notify objectContext about simple property change
+	        objectContext.propertyChanged(this, rel.getName(), oldValue, newValue);
 		}
-		return new IPropertyDescriptor[0];
-	}
-
-	public boolean isDeleted() {
-		return (getPersistenceState() == PersistenceState.DELETED);
 	}
 }

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/CollectionModelElement.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/CollectionModelElement.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/CollectionModelElement.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/CollectionModelElement.java Thu Jul 27 19:18:00 2006
@@ -36,7 +36,7 @@
  * @author Marcel Gordon
  *
  */
-public class CollectionModelElement extends ModelElement implements PropertyChangeListener {
+public class CollectionModelElement extends ModelElement {
 	
 	/**
 	 * Property descriptors for total records and current record for use with the Eclipse Properties view.
@@ -44,9 +44,20 @@
 	protected static IPropertyDescriptor [] descriptors;
 	
 	/**
-	 * List of AbstractObjects displayed by this element.
+	 * Property for the currently displayed AbstractObject.
 	 */
-	protected List<AbstractObject> objects;
+	public static String PROP_CURRENT_RECORD = "Collection.RecordNo";
+	/**
+	 * Property for the total number of records stored.
+	 */
+	public static String PROP_TOTAL_RECORDS = "Collection.TotalRecords";
+	static {
+		descriptors = new IPropertyDescriptor[] {
+			new TextPropertyDescriptor(PROP_CURRENT_RECORD, "Current Record"),
+			new PropertyDescriptor(PROP_TOTAL_RECORDS, "Total Records")
+		};
+	}
+	
 	/**
 	 * The AbstractObject currently being displayed.
 	 */
@@ -57,71 +68,43 @@
 	protected int currentRecord;
 	
 	/**
-	 * Property for the currently displayed AbstractObject.
-	 */
-	public static String PROP_CURRENT_RECORD = "Collection.RecordNo";
-	/**
-	 * Property for the total number of records stored.
+	 * List of AbstractObjects displayed by this element.
 	 */
-	public static String PROP_TOTAL_RECORDS = "Collection.TotalRecords";
+	protected List<AbstractObject> objects;
 	
 	protected IPropertyDescriptor[] properties = null;
 	
-	static {
-		descriptors = new IPropertyDescriptor[] {
-			new TextPropertyDescriptor(PROP_CURRENT_RECORD, "Current Record"),
-			new PropertyDescriptor(PROP_TOTAL_RECORDS, "Total Records")
-		};
-	}
-	
 	/**
 	 * @param createdFrom the ModelElement which initiated this element's creation.
 	 */
-	public CollectionModelElement(ElementDiagram diagram, String name) {
-		super(diagram, name);
+	public CollectionModelElement(String name) {
+		super(name);
 	}
 	
-	/**
-	 * Set the records to be displayed. Adds itself as a listener
-	 * to all the AbstractObjects in the list in order to fire its
-	 * own property change events when the underlying data is changed.
-	 * @param value may be null, an empty list or a list of AbstractObjects.
-	 */
-	public void setObject(Object value) {
-		
-		List oldObjects = this.objects;
-		this.currentRecord = 0;
-		
-		if (value instanceof AbstractObject) {
-			this.objects = new ArrayList<AbstractObject>();
-			this.objects.add((AbstractObject) value);
-			this.current = (AbstractObject) value;
-		}
-		else if (value instanceof List) {
-			this.objects = (List) value;
-			if (this.objects.isEmpty()) {
-				this.current = null;
-			}
-			else {
-				this.current = this.objects.get(currentRecord);
-			}
-		}
-		else {
-			this.objects = new ArrayList<AbstractObject>();
-			this.current = null;
-		}
-		
-		for (AbstractObject object : objects) {
+	public void addObject(AbstractObject object) {
+		if (!objects.contains(object)) {
+			objects.add(object);
 			object.addPropertyChangeListener(this);
+			firePropertyChange(PROP_TOTAL_RECORDS, null, objects);
+			firePropertyChange(PROP_RECORDS, null, objects);
+			validateCurrent();
 		}
-		
-		if (getCurrentObject() != null) {
-			name = getCurrentObject().getName();
-		}
-		
-		firePropertyChange(PROP_RECORDS, oldObjects, objects);
 	}
 	
+	public boolean contains(AbstractObject object) {
+		if (objects == null) {
+			return false;
+		}
+		return objects.contains(object);
+	}
+
+	/**
+	 * @return the AbstractObject currently being displayed.
+	 */
+	public AbstractObject getCurrentObject() {
+		return current;
+	}
+
 	/**
 	 * Get the IPropertyDescriptors for use in the Eclipse Properties view.
 	 * Creates the property descriptor array once on demand.
@@ -154,13 +137,24 @@
 		if (id.toString().equals(PROP_TOTAL_RECORDS)) {
 			return Integer.toString(objects.size());
 		}
-		if (current != null) {
-			return current.getPropertyValue(id);
-		}
-		return null;
+		return super.getPropertyValue(id);
 	}
 
 	@Override
+	public boolean isContextless() {
+		for (AbstractObject object : objects) {
+			if (object.getObjectContext() != null) {
+				return false;
+			}
+		}
+		return !isNull();
+	}
+	
+	@Override
+	public boolean isNull() {
+		return (objects == null || objects.isEmpty());
+	}
+	
 	public boolean isPropertySet(Object id) {
 		if (id.toString().equals(PROP_CURRENT_RECORD)) {
 			return true;
@@ -168,36 +162,9 @@
 		if (id.toString().equals(PROP_TOTAL_RECORDS)) {
 			return true;
 		}
-		if (current != null) { 
-			return current.isPropertySet(id);
-		}
-		return false;
+		return super.isPropertySet(id);
 	}
 
-	@Override
-	public void resetPropertyValue(Object id) {
-		if (id.toString().equals(PROP_CURRENT_RECORD)) {
-			currentRecord = 0;
-			this.current = this.objects.get(currentRecord);
-		}
-		else if (current != null) {
-			current.resetPropertyValue(id);
-		}
-	}
-
-	@Override
-	public void setPropertyValue(Object id, Object value) {
-		if (id.toString().equals(PROP_CURRENT_RECORD)) {
-			int oldCurrent = currentRecord;
-			currentRecord = Integer.parseInt(value.toString());
-			this.current = this.objects.get(currentRecord);
-			firePropertyChange(id.toString(), new Integer(oldCurrent), new Integer(currentRecord));
-		}
-		else if (current != null) {
-			current.setPropertyValue(id, value);
-		}
-	}
-	
 	/**
 	 * Scrolls through the AbstractObject list, cycling back to the start once the
 	 * end is reached.
@@ -218,13 +185,6 @@
 	}
 
 	/**
-	 * @return the AbstractObject currently being displayed.
-	 */
-	public AbstractObject getCurrentObject() {
-		return current;
-	}
-
-	/**
 	 * Scrolls backwards through the AbstractObject list, cycling to the end once the
 	 * start is reached.
 	 */
@@ -242,30 +202,97 @@
 			firePropertyChange(PROP_CURRENT_RECORD, new Integer(oldCurrent), new Integer(currentRecord));
 		}
 	}
+	
+	public void removeObject(AbstractObject object) {
+		if (objects != null) {
+			if (objects.remove(object)) {
+				for (Connection conn : getSourceConnections()) {
+					if (conn instanceof MemberConnection && conn.getTarget().contains(object)) { // should always be true
+						conn.disconnect();
+					}
+				}
+				validateCurrent();
+				firePropertyChange(PROP_RECORDS, null, objects);
+				firePropertyChange(PROP_TOTAL_RECORDS, objects.size() + 1, objects.size());
+			}
+		}
+	}
 
-	/**
-	 * Listens for property changes in the underlying AbstractObjects
-	 * and fires property change notifications of its own.
-	 */
-	public void propertyChange(PropertyChangeEvent evt) {
-		firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
+	@Override
+	public void resetPropertyValue(Object id) {
+		if (id.toString().equals(PROP_CURRENT_RECORD)) {
+			currentRecord = 0;
+			this.current = this.objects.get(currentRecord);
+		}
+		else {
+			super.resetPropertyValue(id);
+		}
 	}
 
-	public boolean contains(AbstractObject object) {
-		if (objects == null) {
-			return false;
+	/**
+	 * Set the records to be displayed. Adds itself as a listener
+	 * to all the AbstractObjects in the list in order to fire its
+	 * own property change events when the underlying data is changed.
+	 * @param value may be null, an empty list or a list of AbstractObjects.
+	 */
+	public void setObject(Object value) {
+		
+		if (value == this.objects) {
+			return;
 		}
-		return objects.contains(object);
+		
+		List<AbstractObject> oldObjects = this.objects;
+		this.currentRecord = 0;
+		
+		if (oldObjects != null) {
+			for (AbstractObject oldObject : oldObjects) {
+				oldObject.removePropertyChangeListener(this);
+			}
+		}
+		
+		if (value instanceof AbstractObject) {
+			this.objects = new ArrayList<AbstractObject>();
+			this.objects.add((AbstractObject) value);
+			this.current = (AbstractObject) value;
+		}
+		else if (value instanceof List) {
+			this.objects = (List) value;
+			if (this.objects.isEmpty()) {
+				this.current = null;
+			}
+			else {
+				this.current = this.objects.get(currentRecord);
+			}
+		}
+		else {
+			this.objects = new ArrayList<AbstractObject>();
+			this.current = null;
+		}
+		
+		for (AbstractObject object : objects) {
+			object.addPropertyChangeListener(this);
+		}
+		
+		if (getCurrentObject() != null) {
+			name = getCurrentObject().getName();
+		}
+		
+		firePropertyChange(PROP_RECORDS, oldObjects, objects);
 	}
 
-	public void removeObject(AbstractObject object) {
-		if (objects.remove(object)) {
-			validateCurrent();
-			firePropertyChange(PROP_RECORDS, null, objects);
-			firePropertyChange(PROP_TOTAL_RECORDS, objects.size() + 1, objects.size());
+	@Override
+	public void setPropertyValue(Object id, Object value) {
+		if (id.toString().equals(PROP_CURRENT_RECORD)) {
+			int oldCurrent = currentRecord;
+			currentRecord = Integer.parseInt(value.toString());
+			this.current = this.objects.get(currentRecord);
+			firePropertyChange(id.toString(), new Integer(oldCurrent), new Integer(currentRecord));
+		}
+		else {
+			super.setPropertyValue(id, value);
 		}
 	}
-	
+
 	protected void validateCurrent() {
 		if (currentRecord > objects.size() - 1 || !objects.contains(current)) {
 			currentRecord = 0;
@@ -279,30 +306,18 @@
 		}
 	}
 
-	public void addObject(AbstractObject object) {
-		objects.add(object);
-		object.addPropertyChangeListener(this);
-		firePropertyChange(PROP_TOTAL_RECORDS, null, objects);
-		firePropertyChange(PROP_RECORDS, null, objects);
-		validateCurrent();
-	}
-
 	@Override
-	public boolean isNull() {
-		return (objects == null || objects.isEmpty());
-	}
-
-	public void memberObjectChanged() {
-		firePropertyChange(PROP_RECORDS, null, objects);
-	}
-
-	@Override
-	public boolean isContextless() {
-		for (AbstractObject object : objects) {
-			if (object.getObjectContext() != null) {
-				return false;
+	public void removeDeletedObjects() {
+		if (objects != null) {
+			ArrayList<AbstractObject> deleted = new ArrayList<AbstractObject>();
+			for (AbstractObject object : objects) {
+				if (object.isDeleted()) {
+					deleted.add(object);
+				}
+			}
+			for (AbstractObject object : deleted) {
+				removeObject(object);
 			}
 		}
-		return !isNull();
 	}
 }

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/ElementDiagram.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/ElementDiagram.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/ElementDiagram.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/ElementDiagram.java Thu Jul 27 19:18:00 2006
@@ -32,8 +32,6 @@
  */
 public class ElementDiagram {
 	
-	// TODO label connections (not just tooltip)
-	
 	public static final String PROP_COMMIT = "ObjectDiagram.GraphCommitted";
 	public static final String PROP_LAYOUT = "ObjectDiagram.LayoutChanged";
 	/** property indicating a node (element) has been added */
@@ -56,18 +54,17 @@
 	 * @param query the name of the query contained in the Cayenne data map from which
 	 * this diagram is initialised
 	 */
-	public ElementDiagram(ObjectContext context, String query) {
+	public ElementDiagram(ObjectContext context) {
 		this.context = context;
 		
-		NamedQuery select = new NamedQuery(query);
-		Object matches = this.context.performQuery(select);
-		CollectionModelElement rootElement = new CollectionModelElement(null, "ROOT");
+		autoLayout = true;
+	}
+	
+	public void addRootElement(Object matches) {
+		CollectionModelElement rootElement = new CollectionModelElement("ROOT");
 		rootElement.setObject(matches);
 		rootElement.setRoot(true);
-		rootElement.setDiagram(this);
 		addElement(rootElement);
-		
-		autoLayout = true;
 	}
 
 	/**
@@ -77,8 +74,10 @@
 	 */	
 	public boolean addElement(ModelElement element) {
 		if (element != null) {
+			element.setDiagram(this);
 			if (!elements.contains(element)) {
 				elements.add(element);
+				createMemberConnections(element);
 				
 				firePropertyChange(PROP_NODE_ADDED, null, element);
 				
@@ -101,13 +100,20 @@
 	}
 	
 	public void commitChanges() {
-		removeDeletedObjects();
 		context.commitChanges();
 		firePropertyChange(PROP_COMMIT, false, true);
+		for (ModelElement element : elements) {
+			element.removeDeletedObjects();
+		}
 	}
 	
 	public void createMemberConnections(ModelElement element) {
 		if (element instanceof CollectionModelElement) {
+			for (Connection conn : element.getSourceConnections()) {
+				if (conn instanceof MemberConnection) {
+					conn.disconnect();
+				}
+			}
 			for (ModelElement child : elements) {
 				if (child instanceof SingleModelElement) {
 					if (((CollectionModelElement) element).contains(child.getCurrentObject())) {
@@ -118,6 +124,11 @@
 			}
 		}
 		else if (element instanceof SingleModelElement) {
+			for (Connection conn : element.getTargetConnections()) {
+				if (conn instanceof MemberConnection) {
+					conn.disconnect();
+				}
+			}
 			for (ModelElement child : elements) {
 				if (child instanceof CollectionModelElement) {
 					if (((CollectionModelElement) child).contains(element.getCurrentObject())) {
@@ -149,6 +160,15 @@
 		}
 		return null;
 	}
+	
+	public ModelElement getSingleElementForObject(AbstractObject newObject) {
+		for (ModelElement element : elements) {
+			if (element.getCurrentObject() == newObject) {
+				return element;
+			}
+		}
+		return null;
+	}
 
 	/** Return a List of Objects in this diagram.  The returned List should not be modified. */
 	public List<ModelElement> getElements() {
@@ -163,14 +183,6 @@
 		return autoLayout;
 	}
 
-	private void removeDeletedObjects() {
-		Collection deleted = context.deletedObjects();
-		for (Object o : deleted) {
-			AbstractObject abstractObject = (AbstractObject) o;
-			removeObjectFromDiagram(abstractObject);
-		}
-	}
-
 	/**
 	 * Remove an element from the diagram
 	 * @param element the element to remove
@@ -183,14 +195,6 @@
 			return true;
 		}
 		return false;
-	}
-	
-	private void removeObjectFromDiagram(AbstractObject current) {
-		for (ModelElement element : elements) {
-			if (element instanceof CollectionModelElement) {
-				((CollectionModelElement) element).removeObject(current);
-			}
-		}
 	}
 
 	/** 

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/ModelElement.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/ModelElement.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/ModelElement.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/ModelElement.java Thu Jul 27 19:18:00 2006
@@ -16,6 +16,7 @@
  */
 package org.apache.cayenne.ropbrowser.model;
 
+import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeSupport;
 import java.util.ArrayList;
@@ -33,53 +34,44 @@
  * 
  * @author Marcel Gordon
  */
-public abstract class ModelElement implements IPropertySource {
+public abstract class ModelElement implements IPropertySource, PropertyChangeListener {
 	
-	/** Property indicating that a source connection has been added or removed */
-	public static final String PROP_SOURCE_CONN = "ModelElement.sourceConnection";
-	
-	/** Property indicating that a target connection has been added or removed */
-	public static final String PROP_TARGET_CONN = "ModelElement.targetConnection";
-
 	/** Property indicating a transient visual property has changed */
 	public static final String PROP_BOUNDS = "ModelElement.bounds";
 	
+	public static final String PROP_NAME = "ModelElement.Name";
+
 	/**
 	 * Property for changes to the records being displayed by this element.
 	 */
 	public static final String PROP_RECORDS = "ModelElement.Records";
 	
-	public static final String PROP_NAME = "ModelElement.Name";
+	/** Property indicating that a source connection has been added or removed */
+	public static final String PROP_SOURCE_CONN = "ModelElement.sourceConnection";
+	
+	/** Property indicating that a target connection has been added or removed */
+	public static final String PROP_TARGET_CONN = "ModelElement.targetConnection";
+	
+	private boolean alreadyPolled = false;
+	
+	private Rectangle bounds;
 	
 	protected ElementDiagram diagram;
 	
 	protected String name;
-	
 	/** Delegate used to implemenent property-change-support. */
 	private transient PropertyChangeSupport pcsDelegate = new PropertyChangeSupport(this);
 	
-	protected List<Connection> sourceConnections = new ArrayList<Connection>();
-	protected List<Connection> targetConnections = new ArrayList<Connection>();
-	
 	protected boolean root = false;
 	
-	private boolean alreadyPolled = false;
+	protected List<Connection> sourceConnections = new ArrayList<Connection>();
 
-	private Rectangle bounds;
-	
-	public ModelElement(ElementDiagram diagram) {
-		this.diagram = diagram;
-	}
+	protected List<Connection> targetConnections = new ArrayList<Connection>();
 	
-	public ModelElement(ElementDiagram diagram, String name) {
-		this.diagram = diagram;
+	public ModelElement(String name) {
 		this.name = name;
 	}
 
-	public void setRoot(boolean root) {
-		this.root = root;
-	}
-	
 	/**
 	 * Add a connection to the ModelElement. The connection will
 	 * be added to the source or target list depending upon its
@@ -103,6 +95,8 @@
 		}
 	}
 	
+	public abstract void addObject(AbstractObject object);
+	
 	/** 
 	 * Attach a non-null PropertyChangeListener to this object.
 	 * @param l a non-null PropertyChangeListener instance
@@ -115,6 +109,12 @@
 		pcsDelegate.addPropertyChangeListener(l);
 	}
 
+	public abstract boolean contains(AbstractObject object);
+
+	public void deleteCurrentObject() {
+		getCurrentObject().getObjectContext().deleteObject(getCurrentObject());
+	}
+	
 	/** 
 	 * Report a property change to registered listeners (for example edit parts).
 	 * @param property the programmatic name of the property that changed
@@ -126,11 +126,21 @@
 			pcsDelegate.firePropertyChange(property, oldValue, newValue);
 		}
 	}
+	
+	/**
+	 * @return Returns the bounds.
+	 */
+	public Rectangle getBounds()
+	{
+		return bounds;
+	}
+	
+	public abstract AbstractObject getCurrentObject();
 
 	public ElementDiagram getDiagram() {
 		return diagram;
 	}
-	
+
 	/**
 	 * Returns a value for this property source that can be edited in a property sheet.
 	 * @return this instance
@@ -143,8 +153,6 @@
 		return name;
 	}
 	
-	public abstract AbstractObject getCurrentObject();
-
 	/**
 	 * Property descriptors for editing via the Eclipse Properties view.
 	 * <p>Default implementation returns an array of size 0. Extending classes
@@ -153,11 +161,16 @@
 	public IPropertyDescriptor[] getPropertyDescriptors() {
 		return new IPropertyDescriptor[0];
 	}
-
+	
 	/**
 	 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object) 
 	 */
-	public abstract Object getPropertyValue(Object id);
+	public Object getPropertyValue(Object id) {
+		if (getCurrentObject() != null) {
+			return getCurrentObject().getPropertyValue(id);
+		}
+		return null;
+	}
 	
 	/** 
 	 * @return copy of the List of Connections originating at the ModelElement.
@@ -174,10 +187,63 @@
 	}
 	
 	/**
+	 * Listens for property changes in the underlying AbstractObjects
+	 * and fires property change notifications of its own.
+	 */
+	public void propertyChange(PropertyChangeEvent evt) {
+		firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
+	}
+	
+	public boolean isConnectedToRoot() {
+		if (isRoot()) {
+			return true;
+		}
+		if (!alreadyPolled) {
+			alreadyPolled = true;
+			for (Connection conn : getTargetConnections()) {
+				if (conn.getSource().isConnectedToRoot()) {
+					alreadyPolled = false;
+					return true;
+				}
+			}
+		}
+		
+		alreadyPolled = false;
+		return false;
+	}
+
+	/**
+	 * Check if the element has objects, but none with a context.
+	 * If isNull returns true, isContextless should return false (ie an element
+	 * that is null is not contextless).
+	 */
+	public abstract boolean isContextless();
+	
+	public abstract boolean isNull();
+	
+	/**
 	 * @see org.eclipse.ui.views.properties.IPropertySource#isPropertySet(java.lang.Object) 
 	 */
-	public abstract boolean isPropertySet(Object id);
+	public boolean isPropertySet(Object id) {
+		if (getCurrentObject() != null) {
+			return getCurrentObject().isPropertySet(id);
+		}
+		return false;
+	}
+	
+	public boolean isRoot() {
+		return this.root;
+	}
 	
+	public void modifyBounds(Rectangle newBounds) {
+		Rectangle oldBounds = this.bounds;
+		if (!newBounds.equals(oldBounds))
+		{
+			this.bounds = newBounds;
+			firePropertyChange(PROP_BOUNDS, oldBounds, this.bounds);
+		}
+	}
+
 	/**
 	 * Remove a connection from the ModelElement. The connection
 	 * will be removed from the source or target list depending
@@ -195,7 +261,7 @@
 			firePropertyChange(PROP_TARGET_CONN, null, conn);
 		}
 	}
-	
+
 	/** 
 	 * Remove a PropertyChangeListener from this component.
 	 * @param l a PropertyChangeListener instance
@@ -205,63 +271,13 @@
 			pcsDelegate.removePropertyChangeListener(l);
 		}
 	}
-	
-	/**
-	 * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object)
-	 */
-	public abstract void resetPropertyValue(Object id);
 
-	public void setDiagram(ElementDiagram diagram) {
-		this.diagram = diagram;
-	}
-	
-	public abstract void setObject(Object object);
-	
 	/**
-	 * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
+	 * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object)
 	 */
-	public abstract void setPropertyValue(Object id, Object value);
-	
-	public boolean isConnectedToRoot() {
-		if (isRoot()) {
-			return true;
-		}
-		if (!alreadyPolled) {
-			alreadyPolled = true;
-			for (Connection conn : getTargetConnections()) {
-				if (conn.getSource().isConnectedToRoot()) {
-					alreadyPolled = false;
-					return true;
-				}
-			}
-		}
-		
-		alreadyPolled = false;
-		return false;
-	}
-	
-	public boolean isRoot() {
-		return this.root;
-	}
-
-	public void deleteCurrentObject() {
-		getCurrentObject().getObjectContext().deleteObject(getCurrentObject());
-		firePropertyChange(PROP_RECORDS, null, getCurrentObject());
-		for (Connection conn : getTargetConnections()) {
-			if (conn instanceof MemberConnection) {
-				((MemberConnection) conn).getSource().memberObjectChanged();
-			}
-		}
-	}
-
-	public abstract void addObject(AbstractObject object);
-
-	public void modifyBounds(Rectangle newBounds) {
-		Rectangle oldBounds = this.bounds;
-		if (!newBounds.equals(oldBounds))
-		{
-			this.bounds = newBounds;
-			firePropertyChange(PROP_BOUNDS, oldBounds, this.bounds);
+	public void resetPropertyValue(Object id) {
+		if (getCurrentObject() != null) {
+			getCurrentObject().resetPropertyValue(id);
 		}
 	}
 
@@ -269,26 +285,32 @@
 		this.bounds = newBounds;
 	}
 	
-	/**
-	 * @return Returns the bounds.
-	 */
-	public Rectangle getBounds()
-	{
-		return bounds;
+	public void setDiagram(ElementDiagram diagram) {
+		this.diagram = diagram;
 	}
 	
-	public abstract boolean isNull();
-
 	public void setName(String newName) {
 		String oldName = name;
 		name = newName;
 		firePropertyChange(PROP_NAME, oldName, name);
 	}
 
+	public abstract void setObject(Object object);
+
 	/**
-	 * Check if the element has objects, but none with a context.
-	 * If isNull returns true, isContextless should return false (ie an element
-	 * that is null is not contextless).
+	 * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
 	 */
-	public abstract boolean isContextless();
+	public void setPropertyValue(Object id, Object value) {
+		if (getCurrentObject() != null) {
+			getCurrentObject().setPropertyValue(id, value);
+		}
+	}
+
+	public void setRoot(boolean root) {
+		this.root = root;
+	}
+
+	public abstract void removeObject(AbstractObject object);
+
+	public abstract void removeDeletedObjects();
 }

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/SingleModelElement.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/SingleModelElement.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/SingleModelElement.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/model/SingleModelElement.java Thu Jul 27 19:18:00 2006
@@ -31,7 +31,7 @@
  * @author Marcel Gordon
  *
  */
-public class SingleModelElement extends ModelElement implements PropertyChangeListener {
+public class SingleModelElement extends ModelElement {
 	
 	/**
 	 * List of AbstractObjects displayed by this element.
@@ -42,8 +42,8 @@
 	/**
 	 * @param createdFrom the ModelElement which initiated this element's creation.
 	 */
-	public SingleModelElement(ElementDiagram diagram, String name) {
-		super(diagram, name);
+	public SingleModelElement(String name) {
+		super(name);
 	}
 	
 	/**
@@ -54,8 +54,16 @@
 	 */
 	public void setObject(Object value) {
 		
+		if (value == this.object) {
+			return;
+		}
+		
 		AbstractObject oldObject = this.object;
 		
+		if (oldObject != null) {
+			oldObject.removePropertyChangeListener(this);
+		}
+		
 		this.object = (AbstractObject) value;
 		
 		if (object != null) {
@@ -78,36 +86,6 @@
 		}
 		return new IPropertyDescriptor[0];
 	}
-
-	@Override
-	public Object getPropertyValue(Object id) {
-		if (object != null) {
-			return object.getPropertyValue(id);
-		}
-		return null;
-	}
-
-	@Override
-	public boolean isPropertySet(Object id) {
-		if (object != null) {
-			return object.isPropertySet(id);
-		}
-		return false;
-	}
-
-	@Override
-	public void resetPropertyValue(Object id) {
-		if (object != null) {
-			object.resetPropertyValue(id);
-		}
-	}
-
-	@Override
-	public void setPropertyValue(Object id, Object value) {
-		if (object != null) {
-			object.setPropertyValue(id, value);
-		}
-	}
 	
 	/**
 	 * @return the AbstractObject objectly being displayed.
@@ -115,14 +93,6 @@
 	public AbstractObject getCurrentObject() {
 		return object;
 	}
-
-	/**
-	 * Listens for property changes in the underlying AbstractObject
-	 * and fires property change notifications of its own.
-	 */
-	public void propertyChange(PropertyChangeEvent evt) {
-		firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
-	}
 	
 	/**
 	 * Used to compare two CollectionModelElements to determine if one is
@@ -136,33 +106,17 @@
 		return false;
 	}
 
-	public ModelElement followRelationship(Relationship relationship) {
-		for (Connection conn : getSourceConnections()) {
-			if (conn instanceof RelationshipConnection) {
-				if (((RelationshipConnection) conn).getRelationship() == relationship) {
-					return conn.getTarget();
-				}
-			}
-		}
-		return null;
-	}
-
 	@Override
 	public void addObject(AbstractObject object) {
 		for (Connection conn : getTargetConnections()) {
 			if (conn instanceof RelationshipConnection) {
 				RelationshipConnection relConn = (RelationshipConnection) conn;
-				conn.getSource().getCurrentObject().setRelationship(relConn.getRelationship(), getCurrentObject(), object);
-				//object.setRelationship(relConn.getRelationship(), null, conn.getSource().getCurrentObject()); wrong relationship name - need inverse
+				relConn.getSource().getCurrentObject().setRelationship(relConn.getRelationship(), getCurrentObject(), object);
 			}
 		}
 		setObject(object);
 	}
 
-	public boolean isDeleted() {
-		return getCurrentObject().isDeleted();
-	}
-
 	@Override
 	public boolean isNull() {
 		return (object == null);
@@ -171,5 +125,35 @@
 	@Override
 	public boolean isContextless() {
 		return (getCurrentObject() != null && getCurrentObject().getObjectContext() == null);
+	}
+
+	@Override
+	public boolean contains(AbstractObject object) {
+		return (this.object == object);
+	}
+
+	@Override
+	public void removeObject(AbstractObject object) {
+		if (this.object == object && object != null) {
+			for (Connection conn : getTargetConnections()) {
+				if (conn instanceof RelationshipConnection) {
+					RelationshipConnection relConn = (RelationshipConnection) conn;
+					relConn.getSource().getCurrentObject().setRelationship(relConn.getRelationship(), getCurrentObject(), null);
+				}
+				if (conn instanceof MemberConnection) {
+					conn.disconnect();
+				}
+			}
+			setObject(null);
+		}
+	}
+
+	@Override
+	public void removeDeletedObjects() {
+		if (getCurrentObject() != null) {
+			if (getCurrentObject().isDeleted()) {
+				removeObject(getCurrentObject());
+			}
+		}
 	}
 }

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/parts/CollectionEditPart.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/parts/CollectionEditPart.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/parts/CollectionEditPart.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/parts/CollectionEditPart.java Thu Jul 27 19:18:00 2006
@@ -21,6 +21,8 @@
 import org.apache.cayenne.ropbrowser.actions.HideAction;
 import org.apache.cayenne.ropbrowser.actions.InsertAction;
 import org.apache.cayenne.ropbrowser.actions.SetNameAction;
+import org.apache.cayenne.ropbrowser.commands.ExistingObjectCommand;
+import org.apache.cayenne.ropbrowser.commands.ExistingObjectRequest;
 import org.apache.cayenne.ropbrowser.commands.HideElementCommand;
 import org.apache.cayenne.ropbrowser.commands.ObjectInsertCommand;
 import org.apache.cayenne.ropbrowser.commands.SetNameElementCommand;
@@ -65,18 +67,6 @@
 		return figure;
 	}
 	
-	/**
-	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
-	 */
-	public void propertyChange(PropertyChangeEvent evt) {
-		super.propertyChange(evt);
-		
-		String prop = evt.getPropertyName();
-		if (!ModelElement.PROP_BOUNDS.equals(prop) && !ModelElement.PROP_TARGET_CONN.equals(prop) && !ModelElement.PROP_SOURCE_CONN.equals(prop)) {
-			((ElementFigure) getFigure()).refresh();
-		}
-	}
-
 	private CollectionModelElement getModelCast() {
 		return (CollectionModelElement) getModel();
 	}

Modified: incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/parts/ConnectionEditPart.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/parts/ConnectionEditPart.java?rev=426358&r1=426357&r2=426358&view=diff
==============================================================================
--- incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/parts/ConnectionEditPart.java (original)
+++ incubator/cayenne/soc/trunk/cayenne-rop/rop-browser/src/org/apache/cayenne/ropbrowser/parts/ConnectionEditPart.java Thu Jul 27 19:18:00 2006
@@ -26,6 +26,7 @@
 import org.eclipse.draw2d.PolylineConnection;
 import org.eclipse.gef.EditPolicy;
 import org.eclipse.gef.editparts.AbstractConnectionEditPart;
+import org.eclipse.gef.editpolicies.ConnectionEndpointEditPolicy;
 
 /**
  * An EditPart for the {@link org.apache.cayenne.ropbrowser.model.Connection} class,
@@ -37,6 +38,8 @@
 
 	@Override
 	protected void createEditPolicies() {
+		// TODO reconnection?
+		installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE, new EndpointsEditPolicy());
 	}
 	
 	/**
@@ -53,5 +56,11 @@
 			connection.setToolTip(new Label(((RelationshipConnection) getModel()).getRelationship().getName()));
 		}
 		return connection;
+	}
+	
+	
+	// TODO reconnection?
+	class EndpointsEditPolicy extends ConnectionEndpointEditPolicy {
+		
 	}
 }