cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From skolbac...@apache.org
Subject [1/3] cayenne git commit: CAY-2001 | Saving a display state of Project
Date Fri, 17 Apr 2015 11:28:25 GMT
Repository: cayenne
Updated Branches:
  refs/heads/master 85a127bd3 -> 1f514c4b1


CAY-2001 | Saving a display state of Project


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/2888668b
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/2888668b
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/2888668b

Branch: refs/heads/master
Commit: 2888668b11071e4dae0082f13d324aae53b805b2
Parents: 85a127b
Author: Savva Kolbachev <s.kolbachev@gmail.com>
Authored: Wed Apr 15 18:12:16 2015 +0300
Committer: Savva Kolbachev <s.kolbachev@gmail.com>
Committed: Wed Apr 15 18:12:16 2015 +0300

----------------------------------------------------------------------
 docs/doc/src/main/resources/RELEASE-NOTES.txt   |   1 +
 .../modeler/CayenneModelerController.java       |   9 +-
 .../cayenne/modeler/ProjectController.java      |  24 +-
 .../apache/cayenne/modeler/ProjectTreeView.java |  57 +-
 .../modeler/editor/ProcedureTabbedView.java     |  14 +-
 .../modeler/pref/ProjectStatePreferences.java   | 323 ++++++++
 .../cayenne/modeler/util/ProjectStateUtil.java  | 785 +++++++++++++++++++
 7 files changed, 1190 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/2888668b/docs/doc/src/main/resources/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/docs/doc/src/main/resources/RELEASE-NOTES.txt b/docs/doc/src/main/resources/RELEASE-NOTES.txt
index 66d3f09..533dfda 100644
--- a/docs/doc/src/main/resources/RELEASE-NOTES.txt
+++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt
@@ -17,6 +17,7 @@ Changes/New Features:
 CAY-1991 More control over generated String property names
 CAY-1992 Allow to exclude DataMap java class from Modeler class generation
 CAY-1995 Add support for iterators to Select
+CAY-2001 Saving a display state of Project
 
 Bug Fixes:
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2888668b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerController.java
index 87772b7..9f32197 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerController.java
@@ -28,6 +28,7 @@ import org.apache.cayenne.modeler.pref.ComponentGeometry;
 import org.apache.cayenne.modeler.pref.FSPath;
 import org.apache.cayenne.modeler.util.CayenneController;
 import org.apache.cayenne.modeler.util.FileFilters;
+import org.apache.cayenne.modeler.util.ProjectStateUtil;
 import org.apache.cayenne.project.Project;
 import org.apache.cayenne.project.validation.ProjectValidator;
 import org.apache.cayenne.validation.ValidationFailure;
@@ -60,7 +61,7 @@ public class CayenneModelerController extends CayenneController {
 
     protected CayenneModelerFrame frame;
 	private EditorView editorView;
-    
+
     public CayenneModelerController(){}
 
     public CayenneModelerController(Application application) {
@@ -106,6 +107,7 @@ public class CayenneModelerController extends CayenneController {
         frame.addWindowListener(new WindowAdapter() {
 
             public void windowClosing(WindowEvent e) {
+                ProjectStateUtil.saveLastState(projectController);
                 getApplication().getActionManager().getAction(ExitAction.class).exit();
             }
         });
@@ -188,7 +190,8 @@ public class CayenneModelerController extends CayenneController {
      * Action method invoked on project closing.
      */
     public void projectClosedAction() {
-        
+        ProjectStateUtil.saveLastState(projectController);
+
         // --- update view
         frame.setView(null);
 
@@ -238,6 +241,8 @@ public class CayenneModelerController extends CayenneController {
             frame.fireRecentFileListChanged();
         }
 
+        ProjectStateUtil.fireLastState(projectController);
+
         // for validation purposes combine load failures with post-load validation (not
         // sure if that'll cause duplicate messages?).
         List<ValidationFailure> allFailures = new ArrayList<ValidationFailure>();

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2888668b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectController.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectController.java
index 2b8c668..4d75685 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectController.java
@@ -104,6 +104,7 @@ import org.apache.cayenne.modeler.event.QueryDisplayListener;
 import org.apache.cayenne.modeler.event.RelationshipDisplayEvent;
 import org.apache.cayenne.modeler.pref.DataMapDefaults;
 import org.apache.cayenne.modeler.pref.DataNodeDefaults;
+import org.apache.cayenne.modeler.pref.ProjectStatePreferences;
 import org.apache.cayenne.modeler.util.CayenneController;
 import org.apache.cayenne.modeler.util.CircularArray;
 import org.apache.cayenne.modeler.util.Comparators;
@@ -240,7 +241,7 @@ public class ProjectController extends CayenneController {
     protected CircularArray controllerStateHistory;
     protected int maxHistorySize = 20;
 
-    private EntityResolver entityResolver;    
+    private EntityResolver entityResolver;
 
     /**
      * Project files watcher. When project file is changed, user will be asked
@@ -390,6 +391,11 @@ public class ProjectController extends CayenneController {
 
     }
 
+    public ProjectStatePreferences getProjectStatePreferences() {
+        return (ProjectStatePreferences) application.getCayenneProjectPreferences().getProjectDetailObject(
+                ProjectStatePreferences.class, getPreferenceForDataDomain());
+    }
+
     public void projectOpened() {
         CayenneModelerFrame frame = (CayenneModelerFrame) getView();
         addDataNodeDisplayListener(frame);
@@ -568,6 +574,10 @@ public class ProjectController extends CayenneController {
         return currentState.parentPath;
     }
 
+    public DisplayEvent getLastDisplayEvent() {
+        return currentState.event;
+    }
+
     public void addDomainDisplayListener(DomainDisplayListener listener) {
         listenerList.add(DomainDisplayListener.class, listener);
     }
@@ -607,7 +617,7 @@ public class ProjectController extends CayenneController {
     public void removeDbEntityListener(DbEntityListener listener) {
         listenerList.remove(DbEntityListener.class, listener);
     }
-    
+
     public void addProjectOnSaveListener(ProjectOnSaveListener listener) {
     	listenerList.add(ProjectOnSaveListener.class, listener);
     }
@@ -615,7 +625,7 @@ public class ProjectController extends CayenneController {
     public void removeProjectOnSaveListener(ProjectOnSaveListener listener) {
     	listenerList.remove(ProjectOnSaveListener.class, listener);
     }
-    
+
     public void addObjEntityListener(ObjEntityListener listener) {
         listenerList.add(ObjEntityListener.class, listener);
     }
@@ -1586,7 +1596,7 @@ public class ProjectController extends CayenneController {
 
     /**
      * adds callback method manipulation listener
-     * 
+     *
      * @param listener
      *            listener
      */
@@ -1596,7 +1606,7 @@ public class ProjectController extends CayenneController {
 
     /**
      * fires callback method manipulation event
-     * 
+     *
      * @param e
      *            event
      */
@@ -1623,7 +1633,7 @@ public class ProjectController extends CayenneController {
 
     /**
      * adds listener class manipulation listener
-     * 
+     *
      * @param listener
      *            listener
      */
@@ -1633,7 +1643,7 @@ public class ProjectController extends CayenneController {
 
     /**
      * fires entity listener manipulation event
-     * 
+     *
      * @param e
      *            event
      */

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2888668b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectTreeView.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectTreeView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectTreeView.java
index b38a7aa..4c002b0 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectTreeView.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectTreeView.java
@@ -96,6 +96,7 @@ import javax.swing.tree.ExpandVetoException;
 import javax.swing.tree.MutableTreeNode;
 import javax.swing.tree.TreePath;
 import javax.swing.tree.TreeSelectionModel;
+import java.awt.Rectangle;
 import java.awt.dnd.DnDConstants;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
@@ -150,7 +151,8 @@ public class ProjectTreeView extends JTree implements DomainDisplayListener,
                         for (int i = 0; i < paths.length; i++) {
                             projectPaths[i] = createProjectPath(paths[i]);
 
-                            if(i>0 && paths[i].getParentPath() != paths[i-1].getParentPath()) {
+                            TreePath parentPath = paths[i].getParentPath();
+                            if(i>0 && parentPath != null && !parentPath.equals(paths[i - 1].getParentPath())) {
                                 commonParentPath = false;
                             }
                         }
@@ -187,13 +189,17 @@ public class ProjectTreeView extends JTree implements DomainDisplayListener,
             @Override
             public void treeWillExpand(TreeExpansionEvent e) throws ExpandVetoException {
                 TreePath path = e.getPath();
-                processSelection(path);
+                if (!isPathSelected(path) && !isSelectionEmpty()) {
+                    setSelectionPath(path);
+                }
             }
 
             @Override
             public void treeWillCollapse(TreeExpansionEvent e) throws ExpandVetoException {
                 TreePath path = e.getPath();
-                processSelection(path);
+                if (!isPathSelected(path) && !isSelectionEmpty()) {
+                    setSelectionPath(path);
+                }
             }
         };
 
@@ -218,6 +224,7 @@ public class ProjectTreeView extends JTree implements DomainDisplayListener,
         mediator.addProcedureDisplayListener(this);
         mediator.addQueryListener(this);
         mediator.addQueryDisplayListener(this);
+        mediator.addMultipleObjectsDisplayListener(this);
 
         mediator.getApplication().getActionManager().setupCutCopyPaste(
                 this,
@@ -363,9 +370,35 @@ public class ProjectTreeView extends JTree implements DomainDisplayListener,
         });
     }
 
-    public void currentObjectsChanged(
-            MultipleObjectsDisplayEvent e,
-            Application application) {
+    public void currentObjectsChanged(MultipleObjectsDisplayEvent e, Application application) {
+        if (e.getSource() == this || e.getParentNode() == null) {
+            return;
+        }
+
+        ConfigurationNode[] nodes = e.getNodes();
+        TreePath[] treePaths = new TreePath[nodes.length];
+
+        for (int i = 0; i < nodes.length; i++) {
+            DefaultMutableTreeNode treeNode = getProjectModel().getNodeForObjectPath(new Object[] {e.getParentNode(), nodes[i]});
+            if (treeNode != null) {
+                treePaths[i] = new TreePath(treeNode.getPath());
+            } else if (e.getParentNode() == nodes[i]) {
+                treeNode = getProjectModel().getNodeForObjectPath(new Object[] {e.getParentNode()});
+                treePaths[i] = new TreePath(treeNode.getPath());
+            }
+        }
+
+        if (!isVisible(treePaths[0])) {
+            makeVisible(treePaths[0]);
+
+            Rectangle bounds = getPathBounds(treePaths[0]);
+            if (bounds != null) {
+                bounds.height = getVisibleRect().height;
+                scrollRectToVisible(bounds);
+            }
+        }
+
+        setSelectionPaths(treePaths);
     }
 
     public void procedureAdded(ProcedureEvent e) {
@@ -772,7 +805,17 @@ public class ProjectTreeView extends JTree implements DomainDisplayListener,
     /** Makes node current, visible and selected. */
     protected void showNode(DefaultMutableTreeNode node) {
         TreePath path = new TreePath(node.getPath());
-        scrollPathToVisible(path);
+
+        if (!isVisible(path)) {
+            makeVisible(path);
+
+            Rectangle bounds = getPathBounds(path);
+            if (bounds != null) {
+                bounds.height = getVisibleRect().height;
+                scrollRectToVisible(bounds);
+            }
+        }
+
         setSelectionPath(path);
     }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2888668b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureTabbedView.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureTabbedView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureTabbedView.java
index f74e2dc..ab2f1f8 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureTabbedView.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureTabbedView.java
@@ -19,13 +19,6 @@
 
 package org.apache.cayenne.modeler.editor;
 
-import java.awt.Component;
-
-import javax.swing.JScrollPane;
-import javax.swing.JTabbedPane;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-
 import org.apache.cayenne.map.ProcedureParameter;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
@@ -35,6 +28,12 @@ import org.apache.cayenne.modeler.event.ProcedureDisplayListener;
 import org.apache.cayenne.modeler.event.ProcedureParameterDisplayEvent;
 import org.apache.cayenne.modeler.event.ProcedureParameterDisplayListener;
 
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.awt.Component;
+
 /**
  * Tabbed panel for stored procedure editing.
  * 
@@ -94,6 +93,7 @@ public class ProcedureTabbedView extends JTabbedPane implements ProcedureDisplay
         ProcedureParameter[] parameters = e.getProcedureParameters();
 
         if (parameters.length > 0) {
+            setSelectedComponent(procedureParameterPanel);
             procedureParameterPanel.selectParameters(parameters);
         }
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2888668b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/ProjectStatePreferences.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/ProjectStatePreferences.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/ProjectStatePreferences.java
new file mode 100644
index 0000000..502f037
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/ProjectStatePreferences.java
@@ -0,0 +1,323 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.modeler.pref;
+
+import org.apache.cayenne.pref.RenamedPreferences;
+
+import java.util.prefs.Preferences;
+
+public class ProjectStatePreferences extends RenamedPreferences {
+
+    private String event;
+    private String domain;
+    private String node;
+    private String dataMap;
+    private String objEntity;
+    private String dbEntity;
+    private String embeddable;
+    private String embAttrs;
+    private String objAttrs;
+    private String dbAttrs;
+    private String objRels;
+    private String dbRels;
+    private String procedure;
+    private String procedureParams;
+    private String query;
+    private String multipleObjects;
+    private String parentObject;
+
+    public static final String EVENT_PROPERTY = "event";
+    public static final String DOMAIN_PROPERTY = "domain";
+    public static final String NODE_PROPERTY = "node";
+    public static final String DATA_MAP_PROPERTY = "dataMap";
+    public static final String OBJ_ENTITY_PROPERTY = "objEntity";
+    public static final String DB_ENTITY_PROPERTY = "dbEntity";
+    public static final String EMBEDDABLE_PROPERTY = "embeddable";
+    public static final String EMBEDDABLE_ATTRS_PROPERTY = "embAttrs";
+    public static final String OBJ_ATTRS_PROPERTY = "objAttrs";
+    public static final String DB_ATTRS_PROPERTY = "dbAttrs";
+    public static final String OBJ_RELS_PROPERTY = "objRels";
+    public static final String DB_RELS_PROPERTY = "dbRels";
+    public static final String PROCEDURE_PROPERTY = "procedure";
+    public static final String PROCEDURE_PARAMS_PROPERTY = "procedureParams";
+    public static final String QUERY_PROPERTY = "query";
+    public static final String MULTIPLE_OBJECTS_PROPERTY = "multipleObjects";
+    public static final String PARENT_OBJECT_PROPERTY = "parentObject";
+
+    public ProjectStatePreferences(Preferences pref) {
+        super(pref);
+    }
+
+    public String getEvent() {
+        if (event == null) {
+            event = getCurrentPreference().get(EVENT_PROPERTY, "");
+        }
+
+        return event;
+    }
+
+    public void setEvent(String event) {
+        this.event = event;
+        if (event != null) {
+            getCurrentPreference().put(EVENT_PROPERTY, event);
+        }
+    }
+
+    public String getDomain() {
+        if (domain == null) {
+            domain = getCurrentPreference().get(DOMAIN_PROPERTY, "");
+        }
+
+        return domain;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+        if (domain != null) {
+            getCurrentPreference().put(DOMAIN_PROPERTY, domain);
+        }
+    }
+
+    public String getNode() {
+        if (node == null) {
+            node = getCurrentPreference().get(NODE_PROPERTY, "");
+        }
+
+        return node;
+    }
+
+    public void setNode(String node) {
+        this.node = node;
+        if (node != null) {
+            getCurrentPreference().put(NODE_PROPERTY, node);
+        }
+    }
+
+    public String getDataMap() {
+        if (dataMap == null) {
+            dataMap = getCurrentPreference().get(DATA_MAP_PROPERTY, "");
+        }
+
+        return dataMap;
+    }
+
+    public void setDataMap(String dataMap) {
+        this.dataMap = dataMap;
+        if (dataMap != null) {
+            getCurrentPreference().put(DATA_MAP_PROPERTY, dataMap);
+        }
+    }
+
+    public String getObjEntity() {
+        if (objEntity == null) {
+            objEntity = getCurrentPreference().get(OBJ_ENTITY_PROPERTY, "");
+        }
+
+        return objEntity;
+    }
+
+    public void setObjEntity(String objEntity) {
+        this.objEntity = objEntity;
+        if (objEntity != null) {
+            getCurrentPreference().put(OBJ_ENTITY_PROPERTY, objEntity);
+        }
+    }
+
+    public String getDbEntity() {
+        if (dbEntity == null) {
+            dbEntity = getCurrentPreference().get(DB_ENTITY_PROPERTY, "");
+        }
+
+        return dbEntity;
+    }
+
+    public void setDbEntity(String dbEntity) {
+        this.dbEntity = dbEntity;
+        if (dbEntity != null) {
+            getCurrentPreference().put(DB_ENTITY_PROPERTY, dbEntity);
+        }
+    }
+
+    public String getEmbeddable() {
+        if (embeddable == null) {
+            embeddable = getCurrentPreference().get(EMBEDDABLE_PROPERTY, "");
+        }
+
+        return embeddable;
+    }
+
+    public void setEmbeddable(String embeddable) {
+        this.embeddable = embeddable;
+        if (embeddable != null) {
+            getCurrentPreference().put(EMBEDDABLE_PROPERTY, embeddable);
+        }
+    }
+
+    public String getEmbAttrs() {
+        if (embAttrs == null) {
+            embAttrs = getCurrentPreference().get(EMBEDDABLE_ATTRS_PROPERTY, "");
+        }
+
+        return embAttrs;
+    }
+
+    public void setEmbAttrs(String embAttrs) {
+        this.embAttrs = embAttrs;
+        if (embAttrs != null) {
+            getCurrentPreference().put(EMBEDDABLE_ATTRS_PROPERTY, embAttrs);
+        }
+    }
+
+    public String getObjAttrs() {
+        if (objAttrs == null) {
+            objAttrs = getCurrentPreference().get(OBJ_ATTRS_PROPERTY, "");
+        }
+
+        return objAttrs;
+    }
+
+    public void setObjAttrs(String objAttrs) {
+        this.objAttrs = objAttrs;
+        if (objAttrs != null) {
+            getCurrentPreference().put(OBJ_ATTRS_PROPERTY, objAttrs);
+        }
+    }
+
+    public String getDbAttrs() {
+        if (dbAttrs == null) {
+            dbAttrs = getCurrentPreference().get(DB_ATTRS_PROPERTY, "");
+        }
+
+        return dbAttrs;
+    }
+
+    public void setDbAttrs(String dbAttrs) {
+        this.dbAttrs = dbAttrs;
+        if (dbAttrs != null) {
+            getCurrentPreference().put(DB_ATTRS_PROPERTY, dbAttrs);
+        }
+    }
+
+    public String getObjRels() {
+        if (objRels == null) {
+            objRels = getCurrentPreference().get(OBJ_RELS_PROPERTY, "");
+        }
+
+        return objRels;
+    }
+
+    public void setObjRels(String objRels) {
+        this.objRels = objRels;
+        if (objRels != null) {
+            getCurrentPreference().put(OBJ_RELS_PROPERTY, objRels);
+        }
+    }
+
+    public String getDbRels() {
+        if (dbRels == null) {
+            dbRels = getCurrentPreference().get(DB_RELS_PROPERTY, "");
+        }
+
+        return dbRels;
+    }
+
+    public void setDbRels(String dbRels) {
+        this.dbRels = dbRels;
+        if (dbRels != null) {
+            getCurrentPreference().put(DB_RELS_PROPERTY, dbRels);
+        }
+    }
+
+    public String getProcedure() {
+        if (procedure == null) {
+            procedure = getCurrentPreference().get(PROCEDURE_PROPERTY, "");
+        }
+
+        return procedure;
+    }
+
+    public void setProcedure(String procedure) {
+        this.procedure = procedure;
+        if (procedure != null) {
+            getCurrentPreference().put(PROCEDURE_PROPERTY, procedure);
+        }
+    }
+
+    public String getProcedureParams() {
+        if (procedureParams == null) {
+            procedureParams = getCurrentPreference().get(PROCEDURE_PARAMS_PROPERTY, "");
+        }
+
+        return procedureParams;
+    }
+
+    public void setProcedureParams(String procedureParams) {
+        this.procedureParams = procedureParams;
+        if (procedureParams != null) {
+            getCurrentPreference().put(PROCEDURE_PARAMS_PROPERTY, procedureParams);
+        }
+    }
+
+    public String getQuery() {
+        if (query == null) {
+            query = getCurrentPreference().get(QUERY_PROPERTY, "");
+        }
+
+        return query;
+    }
+
+    public void setQuery(String query) {
+        this.query = query;
+        if (query != null) {
+            getCurrentPreference().put(QUERY_PROPERTY, query);
+        }
+    }
+
+    public String getMultipleObjects() {
+        if (multipleObjects == null) {
+            multipleObjects = getCurrentPreference().get(MULTIPLE_OBJECTS_PROPERTY, "");
+        }
+
+        return multipleObjects;
+    }
+
+    public void setMultipleObjects(String multipleObjects) {
+        this.multipleObjects = multipleObjects;
+        if (multipleObjects != null) {
+            getCurrentPreference().put(MULTIPLE_OBJECTS_PROPERTY, multipleObjects);
+        }
+    }
+
+    public String getParentObject() {
+        if (parentObject == null) {
+            parentObject = getCurrentPreference().get(PARENT_OBJECT_PROPERTY, "");
+        }
+
+        return parentObject;
+    }
+
+    public void setParentObject(String parentObject) {
+        this.parentObject = parentObject;
+        if (parentObject != null) {
+            getCurrentPreference().put(PARENT_OBJECT_PROPERTY, parentObject);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/2888668b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ProjectStateUtil.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ProjectStateUtil.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ProjectStateUtil.java
new file mode 100644
index 0000000..98158ba
--- /dev/null
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ProjectStateUtil.java
@@ -0,0 +1,785 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.modeler.util;
+
+import org.apache.cayenne.configuration.ConfigurationNode;
+import org.apache.cayenne.configuration.DataChannelDescriptor;
+import org.apache.cayenne.configuration.DataNodeDescriptor;
+import org.apache.cayenne.map.Attribute;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.Embeddable;
+import org.apache.cayenne.map.EmbeddableAttribute;
+import org.apache.cayenne.map.Entity;
+import org.apache.cayenne.map.ObjAttribute;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.map.Procedure;
+import org.apache.cayenne.map.ProcedureParameter;
+import org.apache.cayenne.map.Relationship;
+import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.event.AttributeDisplayEvent;
+import org.apache.cayenne.modeler.event.DataMapDisplayEvent;
+import org.apache.cayenne.modeler.event.DataNodeDisplayEvent;
+import org.apache.cayenne.modeler.event.DisplayEvent;
+import org.apache.cayenne.modeler.event.DomainDisplayEvent;
+import org.apache.cayenne.modeler.event.EmbeddableAttributeDisplayEvent;
+import org.apache.cayenne.modeler.event.EmbeddableDisplayEvent;
+import org.apache.cayenne.modeler.event.EntityDisplayEvent;
+import org.apache.cayenne.modeler.event.MultipleObjectsDisplayEvent;
+import org.apache.cayenne.modeler.event.ProcedureDisplayEvent;
+import org.apache.cayenne.modeler.event.ProcedureParameterDisplayEvent;
+import org.apache.cayenne.modeler.event.QueryDisplayEvent;
+import org.apache.cayenne.modeler.event.RelationshipDisplayEvent;
+import org.apache.cayenne.modeler.pref.ProjectStatePreferences;
+import org.apache.cayenne.query.Query;
+import org.apache.cayenne.util.CayenneMapEntry;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.prefs.BackingStoreException;
+
+public final class ProjectStateUtil {
+
+    private static ProjectStatePreferences preferences;
+
+    private ProjectStateUtil() {
+    }
+
+    public static void saveLastState(ProjectController controller) {
+        DisplayEvent displayEvent = controller.getLastDisplayEvent();
+        Object[] multiplyObjects = controller.getCurrentPaths();
+
+        if (displayEvent == null && multiplyObjects == null) {
+            return;
+        }
+
+        preferences = controller.getProjectStatePreferences();
+        if (preferences.getCurrentPreference() == null) {
+            return;
+        }
+
+        try {
+            preferences.getCurrentPreference().clear();
+        } catch (BackingStoreException e) {
+            // ignore exception
+        }
+
+        if (displayEvent != null) {
+            DisplayEventType.valueOf(displayEvent.getClass().getSimpleName()).saveLastDisplayEvent(controller);
+        } else {
+            DisplayEventType.MultipleObjectsDisplayEvent.saveLastDisplayEvent(controller);
+        }
+    }
+
+    public static void fireLastState(ProjectController controller) {
+        preferences = controller.getProjectStatePreferences();
+
+        String displayEventName = preferences.getEvent();
+        if (!displayEventName.isEmpty()) {
+            DisplayEventType.valueOf(displayEventName).fireLastDisplayEvent(controller);
+        }
+    }
+
+    private static enum DisplayEventType {
+
+        DomainDisplayEvent {
+            @Override
+            void fireLastDisplayEvent(ProjectController controller) {
+                DataChannelDescriptor dataChannel = (DataChannelDescriptor) controller.getProject().getRootNode();
+                if (!dataChannel.getName().equals(preferences.getDomain())) {
+                    return;
+                }
+
+                DomainDisplayEvent domainDisplayEvent = new DomainDisplayEvent(this, dataChannel);
+                controller.fireDomainDisplayEvent(domainDisplayEvent);
+            }
+
+            @Override
+            void saveLastDisplayEvent(ProjectController controller) {
+                preferences.setEvent(DomainDisplayEvent.toString());
+                preferences.setDomain(controller.getCurrentDataChanel().getName());
+            }
+        },
+
+        DataNodeDisplayEvent {
+            @Override
+            void fireLastDisplayEvent(ProjectController controller) {
+                DataChannelDescriptor dataChannel = (DataChannelDescriptor) controller.getProject().getRootNode();
+                if (!dataChannel.getName().equals(preferences.getDomain())) {
+                    return;
+                }
+
+                DataNodeDescriptor dataNode = dataChannel.getNodeDescriptor(preferences.getNode());
+                if (dataNode == null) {
+                    return;
+                }
+
+                DataNodeDisplayEvent dataNodeDisplayEvent = new DataNodeDisplayEvent(this, dataChannel, dataNode);
+                controller.fireDataNodeDisplayEvent(dataNodeDisplayEvent);
+            }
+
+            @Override
+            void saveLastDisplayEvent(ProjectController controller) {
+                preferences.setEvent(DataNodeDisplayEvent.toString());
+                preferences.setDomain(controller.getCurrentDataChanel().getName());
+                preferences.setNode(controller.getCurrentDataNode().getName());
+            }
+        },
+
+        DataMapDisplayEvent {
+            @Override
+            void fireLastDisplayEvent(ProjectController controller) {
+                DataChannelDescriptor dataChannel = (DataChannelDescriptor) controller.getProject().getRootNode();
+                if (!dataChannel.getName().equals(preferences.getDomain())) {
+                    return;
+                }
+
+                DataNodeDescriptor dataNode = dataChannel.getNodeDescriptor(preferences.getNode());
+                DataMap dataMap = dataChannel.getDataMap(preferences.getDataMap());
+                if (dataMap == null) {
+                    return;
+                }
+
+                DataMapDisplayEvent dataMapDisplayEvent = new DataMapDisplayEvent(this, dataMap, dataChannel, dataNode);
+                controller.fireDataMapDisplayEvent(dataMapDisplayEvent);
+            }
+
+            @Override
+            void saveLastDisplayEvent(ProjectController controller) {
+                preferences.setEvent(DataMapDisplayEvent.toString());
+                preferences.setDomain(controller.getCurrentDataChanel().getName());
+                preferences.setNode(controller.getCurrentDataNode() != null ? controller.getCurrentDataNode().getName() : "");
+                preferences.setDataMap(controller.getCurrentDataMap().getName());
+            }
+        },
+
+        EntityDisplayEvent {
+            @Override
+            void fireLastDisplayEvent(ProjectController controller) {
+                DataChannelDescriptor dataChannel = (DataChannelDescriptor) controller.getProject().getRootNode();
+                if (!dataChannel.getName().equals(preferences.getDomain())) {
+                    return;
+                }
+
+                DataNodeDescriptor dataNode = dataChannel.getNodeDescriptor(preferences.getNode());
+                DataMap dataMap = dataChannel.getDataMap(preferences.getDataMap());
+                if (dataMap == null) {
+                    return;
+                }
+
+                Entity entity = getLastEntity(dataMap);
+                if (entity == null) {
+                    return;
+                }
+
+                EntityDisplayEvent entityDisplayEvent = new EntityDisplayEvent(this, entity, dataMap, dataNode, dataChannel);
+                if (entity instanceof ObjEntity) {
+                    controller.fireObjEntityDisplayEvent(entityDisplayEvent);
+                } else if (entity instanceof DbEntity) {
+                    controller.fireDbEntityDisplayEvent(entityDisplayEvent);
+                }
+            }
+
+            @Override
+            void saveLastDisplayEvent(ProjectController controller) {
+                if (controller.getCurrentObjAttributes().length != 0 || controller.getCurrentDbAttributes().length != 0) {
+                    AttributeDisplayEvent.saveLastDisplayEvent(controller);
+                } else if (controller.getCurrentObjRelationships().length != 0 || controller.getCurrentDbRelationships().length != 0) {
+                    RelationshipDisplayEvent.saveLastDisplayEvent(controller);
+                } else {
+                    preferences.setEvent(EntityDisplayEvent.toString());
+                    preferences.setDomain(controller.getCurrentDataChanel().getName());
+                    preferences.setNode(controller.getCurrentDataNode() != null ? controller.getCurrentDataNode().getName() : "");
+                    preferences.setDataMap(controller.getCurrentDataMap().getName());
+
+                    if (controller.getCurrentObjEntity() != null) {
+                        preferences.setObjEntity(controller.getCurrentObjEntity().getName());
+                        preferences.setDbEntity(null);
+                    } else if (controller.getCurrentDbEntity() != null) {
+                        preferences.setDbEntity(controller.getCurrentDbEntity().getName());
+                        preferences.setObjEntity(null);
+                    }
+                }
+            }
+        },
+
+        AttributeDisplayEvent {
+            @Override
+            void fireLastDisplayEvent(ProjectController controller) {
+                DataChannelDescriptor dataChannel = (DataChannelDescriptor) controller.getProject().getRootNode();
+                if (!dataChannel.getName().equals(preferences.getDomain())) {
+                    return;
+                }
+
+                DataNodeDescriptor dataNode = dataChannel.getNodeDescriptor(preferences.getNode());
+                DataMap dataMap = dataChannel.getDataMap(preferences.getDataMap());
+                if (dataMap == null) {
+                    return;
+                }
+
+                Entity entity = getLastEntity(dataMap);
+                if (entity == null) {
+                    return;
+                }
+
+                Attribute[] attributes = getLastEntityAttributes(entity);
+
+                EntityDisplayEvent entityDisplayEvent = new EntityDisplayEvent(this, entity, dataMap, dataNode, dataChannel);
+                AttributeDisplayEvent attributeDisplayEvent = new AttributeDisplayEvent(this, attributes, entity, dataMap, dataChannel);
+
+                if (entity instanceof ObjEntity) {
+                    controller.fireObjEntityDisplayEvent(entityDisplayEvent);
+                    controller.fireObjAttributeDisplayEvent(attributeDisplayEvent);
+                } else if (entity instanceof DbEntity) {
+                    controller.fireDbEntityDisplayEvent(entityDisplayEvent);
+                    controller.fireDbAttributeDisplayEvent(attributeDisplayEvent);
+                }
+            }
+
+            @Override
+            void saveLastDisplayEvent(ProjectController controller) {
+                preferences.setEvent(AttributeDisplayEvent.toString());
+                preferences.setDomain(controller.getCurrentDataChanel().getName());
+                preferences.setNode(controller.getCurrentDataNode() != null ? controller.getCurrentDataNode().getName() : "");
+                preferences.setDataMap(controller.getCurrentDataMap().getName());
+
+                if (controller.getCurrentObjEntity() != null) {
+                    preferences.setObjEntity(controller.getCurrentObjEntity().getName());
+                    preferences.setObjAttrs(parseToString(controller.getCurrentObjAttributes()));
+                    preferences.setDbEntity(null);
+                } else if (controller.getCurrentDbEntity() != null) {
+                    preferences.setDbEntity(controller.getCurrentDbEntity().getName());
+                    preferences.setDbAttrs(parseToString(controller.getCurrentDbAttributes()));
+                    preferences.setObjEntity(null);
+                }
+            }
+        },
+
+        RelationshipDisplayEvent {
+            @Override
+            void fireLastDisplayEvent(ProjectController controller) {
+                DataChannelDescriptor dataChannel = (DataChannelDescriptor) controller.getProject().getRootNode();
+                if (!dataChannel.getName().equals(preferences.getDomain())) {
+                    return;
+                }
+
+                DataNodeDescriptor dataNode = dataChannel.getNodeDescriptor(preferences.getNode());
+                DataMap dataMap = dataChannel.getDataMap(preferences.getDataMap());
+                if (dataMap == null) {
+                    return;
+                }
+
+                Entity entity = getLastEntity(dataMap);
+                if (entity == null) {
+                    return;
+                }
+
+                Relationship[] relationships = getLastEntityRelationships(entity);
+
+                EntityDisplayEvent entityDisplayEvent = new EntityDisplayEvent(this, entity, dataMap, dataNode, dataChannel);
+                RelationshipDisplayEvent displayEvent = new RelationshipDisplayEvent(this, relationships, entity, dataMap, dataChannel);
+
+                if (entity instanceof ObjEntity) {
+                    controller.fireObjEntityDisplayEvent(entityDisplayEvent);
+                    controller.fireObjRelationshipDisplayEvent(displayEvent);
+                } else if (entity instanceof DbEntity) {
+                    controller.fireDbEntityDisplayEvent(entityDisplayEvent);
+                    controller.fireDbRelationshipDisplayEvent(displayEvent);
+                }
+            }
+
+            @Override
+            void saveLastDisplayEvent(ProjectController controller) {
+                preferences.setEvent(RelationshipDisplayEvent.toString());
+                preferences.setDomain(controller.getCurrentDataChanel().getName());
+                preferences.setNode(controller.getCurrentDataNode() != null ? controller.getCurrentDataNode().getName() : "");
+                preferences.setDataMap(controller.getCurrentDataMap().getName());
+
+                if (controller.getCurrentObjEntity() != null) {
+                    preferences.setObjEntity(controller.getCurrentObjEntity().getName());
+                    preferences.setObjRels(parseToString(controller.getCurrentObjRelationships()));
+                    preferences.setDbEntity(null);
+                } else if (controller.getCurrentDbEntity() != null) {
+                    preferences.setDbEntity(controller.getCurrentDbEntity().getName());
+                    preferences.setDbRels(parseToString(controller.getCurrentDbRelationships()));
+                    preferences.setObjEntity(null);
+                }
+            }
+        },
+
+        EmbeddableDisplayEvent {
+            @Override
+            void fireLastDisplayEvent(ProjectController controller) {
+                DataChannelDescriptor dataChannel = (DataChannelDescriptor) controller.getProject().getRootNode();
+                if (!dataChannel.getName().equals(preferences.getDomain())) {
+                    return;
+                }
+
+                DataMap dataMap = dataChannel.getDataMap(preferences.getDataMap());
+                if (dataMap == null) {
+                    return;
+                }
+
+                Embeddable embeddable = dataMap.getEmbeddable(preferences.getEmbeddable());
+                if (embeddable == null) {
+                    return;
+                }
+
+                EmbeddableDisplayEvent embeddableDisplayEvent = new EmbeddableDisplayEvent(this, embeddable, dataMap, dataChannel);
+                controller.fireEmbeddableDisplayEvent(embeddableDisplayEvent);
+            }
+
+            @Override
+            void saveLastDisplayEvent(ProjectController controller) {
+                if (controller.getCurrentEmbAttributes().length != 0) {
+                    EmbeddableAttributeDisplayEvent.saveLastDisplayEvent(controller);
+                } else {
+                    preferences.setEvent(EmbeddableDisplayEvent.toString());
+                    preferences.setDomain(controller.getCurrentDataChanel().getName());
+                    preferences.setDataMap(controller.getCurrentDataMap().getName());
+                    preferences.setEmbeddable(controller.getCurrentEmbeddable().getClassName());
+                }
+            }
+        },
+
+        EmbeddableAttributeDisplayEvent {
+            @Override
+            void fireLastDisplayEvent(ProjectController controller) {
+                DataChannelDescriptor dataChannel = (DataChannelDescriptor) controller.getProject().getRootNode();
+                if (!dataChannel.getName().equals(preferences.getDomain())) {
+                    return;
+                }
+
+                DataMap dataMap = dataChannel.getDataMap(preferences.getDataMap());
+                if (dataMap == null) {
+                    return;
+                }
+
+                Embeddable embeddable = dataMap.getEmbeddable(preferences.getEmbeddable());
+                if (embeddable == null) {
+                    return;
+                }
+
+                EmbeddableDisplayEvent embeddableDisplayEvent = new EmbeddableDisplayEvent(this, embeddable, dataMap, dataChannel);
+                controller.fireEmbeddableDisplayEvent(embeddableDisplayEvent);
+
+                EmbeddableAttribute[] embeddableAttributes = getLastEmbeddableAttributes(embeddable);
+                EmbeddableAttributeDisplayEvent attributeDisplayEvent = new EmbeddableAttributeDisplayEvent(this, embeddable, embeddableAttributes, dataMap, dataChannel);
+                controller.fireEmbeddableAttributeDisplayEvent(attributeDisplayEvent);
+            }
+
+            @Override
+            void saveLastDisplayEvent(ProjectController controller) {
+                preferences.setEvent(EmbeddableAttributeDisplayEvent.toString());
+                preferences.setDomain(controller.getCurrentDataChanel().getName());
+                preferences.setDataMap(controller.getCurrentDataMap().getName());
+                preferences.setEmbeddable(controller.getCurrentEmbeddable().getClassName());
+
+                EmbeddableAttribute[] currentEmbAttributes = controller.getCurrentEmbAttributes();
+                if (currentEmbAttributes == null) {
+                    preferences.setEmbAttrs("");
+                } else {
+                    StringBuilder sb = new StringBuilder();
+                    for (EmbeddableAttribute embeddableAttribute : currentEmbAttributes) {
+                        sb.append(embeddableAttribute.getName()).append(",");
+                    }
+                    preferences.setEmbAttrs(sb.toString());
+                }
+            }
+        },
+
+        ProcedureDisplayEvent {
+            @Override
+            void fireLastDisplayEvent(ProjectController controller) {
+                DataChannelDescriptor dataChannel = (DataChannelDescriptor) controller.getProject().getRootNode();
+                if (!dataChannel.getName().equals(preferences.getDomain())) {
+                    return;
+                }
+
+                DataMap dataMap = dataChannel.getDataMap(preferences.getDataMap());
+                if (dataMap == null) {
+                    return;
+                }
+
+                Procedure procedure = dataMap.getProcedure(preferences.getProcedure());
+                if (procedure == null) {
+                    return;
+                }
+
+                ProcedureDisplayEvent procedureDisplayEvent = new ProcedureDisplayEvent(this, procedure, dataMap, dataChannel);
+                controller.fireProcedureDisplayEvent(procedureDisplayEvent);
+            }
+
+            @Override
+            void saveLastDisplayEvent(ProjectController controller) {
+                if (controller.getCurrentProcedureParameters().length != 0) {
+                    ProcedureParameterDisplayEvent.saveLastDisplayEvent(controller);
+                } else {
+                    preferences.setEvent(ProcedureDisplayEvent.toString());
+                    preferences.setDomain(controller.getCurrentDataChanel().getName());
+                    preferences.setDataMap(controller.getCurrentDataMap().getName());
+                    preferences.setProcedure(controller.getCurrentProcedure().getName());
+                }
+            }
+        },
+
+        ProcedureParameterDisplayEvent {
+            @Override
+            void fireLastDisplayEvent(ProjectController controller) {
+                DataChannelDescriptor dataChannel = (DataChannelDescriptor) controller.getProject().getRootNode();
+                if (!dataChannel.getName().equals(preferences.getDomain())) {
+                    return;
+                }
+
+                DataMap dataMap = dataChannel.getDataMap(preferences.getDataMap());
+                if (dataMap == null) {
+                    return;
+                }
+
+                Procedure procedure = dataMap.getProcedure(preferences.getProcedure());
+                if (procedure == null) {
+                    return;
+                }
+
+                ProcedureDisplayEvent procedureDisplayEvent = new ProcedureDisplayEvent(this, procedure, dataMap, dataChannel);
+                controller.fireProcedureDisplayEvent(procedureDisplayEvent);
+
+                ProcedureParameter[] procedureParameters = getLastProcedureParameters(procedure);
+                ProcedureParameterDisplayEvent procedureParameterDisplayEvent =
+                        new ProcedureParameterDisplayEvent(this, procedureParameters, procedure, dataMap, dataChannel);
+                controller.fireProcedureParameterDisplayEvent(procedureParameterDisplayEvent);
+            }
+
+            @Override
+            void saveLastDisplayEvent(ProjectController controller) {
+                preferences.setEvent(ProcedureParameterDisplayEvent.toString());
+                preferences.setDomain(controller.getCurrentDataChanel().getName());
+                preferences.setDataMap(controller.getCurrentDataMap().getName());
+                preferences.setProcedure(controller.getCurrentProcedure().getName());
+                preferences.setProcedureParams(parseToString(controller.getCurrentProcedureParameters()));
+            }
+        },
+
+        QueryDisplayEvent {
+            @Override
+            void fireLastDisplayEvent(ProjectController controller) {
+                DataChannelDescriptor dataChannel = (DataChannelDescriptor) controller.getProject().getRootNode();
+                if (!dataChannel.getName().equals(preferences.getDomain())) {
+                    return;
+                }
+
+                DataMap dataMap = dataChannel.getDataMap(preferences.getDataMap());
+                if (dataMap == null) {
+                    return;
+                }
+
+                Query query = dataMap.getQuery(preferences.getQuery());
+                if (query == null) {
+                    return;
+                }
+
+                QueryDisplayEvent queryDisplayEvent = new QueryDisplayEvent(this, query, dataMap, dataChannel);
+                controller.fireQueryDisplayEvent(queryDisplayEvent);
+            }
+
+            @Override
+            void saveLastDisplayEvent(ProjectController controller) {
+                preferences.setEvent(QueryDisplayEvent.toString());
+                preferences.setDomain(controller.getCurrentDataChanel().getName());
+                preferences.setDataMap(controller.getCurrentDataMap().getName());
+                preferences.setQuery(controller.getCurrentQuery().getName());
+            }
+        },
+
+        MultipleObjectsDisplayEvent {
+            @Override
+            void fireLastDisplayEvent(ProjectController controller) {
+                DataChannelDescriptor dataChannel = (DataChannelDescriptor) controller.getProject().getRootNode();
+
+                String parentObjectName = preferences.getParentObject();
+                ConfigurationNode parentObject;
+                ConfigurationNode[] multipleObjects;
+
+                if (dataChannel.getDataMap(parentObjectName) != null) {
+                    DataMap dataMap = dataChannel.getDataMap(parentObjectName);
+                    parentObject = dataMap;
+                    multipleObjects = getLastMultipleObjects(dataMap);
+                } else if (dataChannel.getNodeDescriptor(parentObjectName) != null) {
+                    DataNodeDescriptor dataNode = dataChannel.getNodeDescriptor(parentObjectName);
+                    parentObject = dataNode;
+                    multipleObjects = getLastMultipleObjects(dataNode);
+                } else {
+                    parentObject = dataChannel;
+                    multipleObjects = getLastMultipleObjects(dataChannel);
+                }
+
+                MultipleObjectsDisplayEvent multipleDisplayEvent = new MultipleObjectsDisplayEvent(this, multipleObjects, parentObject);
+                controller.fireMultipleObjectsDisplayEvent(multipleDisplayEvent);
+            }
+
+            @Override
+            void saveLastDisplayEvent(ProjectController controller) {
+                preferences.setEvent(MultipleObjectsDisplayEvent.toString());
+                preferences.setParentObject(getObjectName(controller.getCurrentParentPath()));
+
+                Object[] multipleObjects = controller.getCurrentPaths();
+                if (multipleObjects == null) {
+                    preferences.setMultipleObjects("");
+                } else {
+                    StringBuilder sb = new StringBuilder();
+                    for (Object object : multipleObjects) {
+                        String objectName = getObjectName(object);
+                        if (!objectName.isEmpty()) {
+                            sb.append(objectName).append(",");
+                        }
+                    }
+                    preferences.setMultipleObjects(sb.toString());
+                }
+            }
+        };
+
+        abstract void fireLastDisplayEvent(ProjectController controller);
+
+        abstract void saveLastDisplayEvent(ProjectController controller);
+    }
+
+    private static Entity getLastEntity(DataMap dataMap) {
+        return !preferences.getObjEntity().isEmpty()
+                ? dataMap.getObjEntity(preferences.getObjEntity())
+                : dataMap.getDbEntity(preferences.getDbEntity());
+    }
+
+    private static Attribute[] getLastEntityAttributes(Entity entity) {
+        return (entity instanceof ObjEntity)
+                ? getLastObjEntityAttributes((ObjEntity) entity)
+                : getLastDbEntityAttributes((DbEntity) entity);
+    }
+
+    private static Relationship[] getLastEntityRelationships(Entity entity) {
+        return (entity instanceof ObjEntity)
+                ? getLastObjEntityRelationships((ObjEntity) entity)
+                : getLastDbEntityRelationships((DbEntity) entity);
+    }
+
+    private static ObjAttribute[] getLastObjEntityAttributes(ObjEntity objEntity) {
+        List<ObjAttribute> attributeList = new ArrayList<ObjAttribute>();
+        ObjAttribute[] attributes = new ObjAttribute[0];
+
+        String objAttrs = preferences.getObjAttrs();
+        if (!objAttrs.isEmpty()) {
+            String[] lastObjAttrs = objAttrs.split(",");
+            for (String objAttrName : lastObjAttrs) {
+                attributeList.add(objEntity.getAttribute(objAttrName));
+            }
+        }
+
+        return attributeList.toArray(attributes);
+    }
+
+    private static DbAttribute[] getLastDbEntityAttributes(DbEntity dbEntity) {
+        List<DbAttribute> attributeList = new ArrayList<DbAttribute>();
+        DbAttribute[] attributes = new DbAttribute[0];
+
+        String dbAttrs = preferences.getDbAttrs();
+        if (!dbAttrs.isEmpty()) {
+            String[] lastDbAttrs = dbAttrs.split(",");
+            for (String dbAttrName : lastDbAttrs) {
+                attributeList.add(dbEntity.getAttribute(dbAttrName));
+            }
+        }
+
+        return attributeList.toArray(attributes);
+    }
+
+    private static ObjRelationship[] getLastObjEntityRelationships(ObjEntity objEntity) {
+        List<ObjRelationship> relationshipList = new ArrayList<ObjRelationship>();
+        ObjRelationship[] relationships = new ObjRelationship[0];
+
+        String objRels = preferences.getObjRels();
+        if (!objRels.isEmpty()) {
+            String[] lastObjRels = objRels.split(",");
+            for (String objRelName : lastObjRels) {
+                relationshipList.add(objEntity.getRelationship(objRelName));
+            }
+        }
+
+        return relationshipList.toArray(relationships);
+    }
+
+    private static DbRelationship[] getLastDbEntityRelationships(DbEntity dbEntity) {
+        List<DbRelationship> relationshipList = new ArrayList<DbRelationship>();
+        DbRelationship[] relationships = new DbRelationship[0];
+
+        String dbRels = preferences.getDbRels();
+        if (!dbRels.isEmpty()) {
+            String[] lastDbRels = dbRels.split(",");
+            for (String dbRelName : lastDbRels) {
+                relationshipList.add(dbEntity.getRelationship(dbRelName));
+            }
+        }
+
+        return relationshipList.toArray(relationships);
+    }
+
+    private static EmbeddableAttribute[] getLastEmbeddableAttributes(Embeddable embeddable) {
+        List<EmbeddableAttribute> embeddableAttributeList = new ArrayList<EmbeddableAttribute>();
+        EmbeddableAttribute[] attributes = new EmbeddableAttribute[0];
+
+        String embAttrs = preferences.getEmbAttrs();
+        if (!embAttrs.isEmpty()) {
+            String[] lastEmbAttrs = embAttrs.split(",");
+            for (String embAttrName : lastEmbAttrs) {
+                embeddableAttributeList.add(embeddable.getAttribute(embAttrName));
+            }
+        }
+
+        return embeddableAttributeList.toArray(attributes);
+    }
+
+    private static ProcedureParameter[] getLastProcedureParameters(Procedure procedure) {
+        List<ProcedureParameter> procedureParameterList = new ArrayList<ProcedureParameter>();
+        ProcedureParameter[] parameters = new ProcedureParameter[0];
+
+        String procedureParams = preferences.getProcedureParams();
+        if (!procedureParams.isEmpty()) {
+            String[] lastProcedureParams = procedureParams.split(",");
+            for (String procedureParamName : lastProcedureParams) {
+                for (ProcedureParameter procedureParameter : procedure.getCallParameters()) {
+                    if (procedureParameter.getName().equals(procedureParamName)) {
+                        procedureParameterList.add(procedureParameter);
+                    }
+                }
+            }
+        }
+
+        return procedureParameterList.toArray(parameters);
+    }
+
+    private static ConfigurationNode[] getLastMultipleObjects(DataChannelDescriptor dataChannel) {
+        List<ConfigurationNode> configurationNodeList = new ArrayList<ConfigurationNode>();
+        ConfigurationNode[] nodes = new ConfigurationNode[0];
+
+        String multipleObjects = preferences.getMultipleObjects();
+        if (!multipleObjects.isEmpty()) {
+            String[] lastMultipleObjects = multipleObjects.split(",");
+
+            outer:
+            for (String objectName : lastMultipleObjects) {
+                if (dataChannel.getName().equals(objectName)) {
+                    configurationNodeList.add(dataChannel);
+                    continue outer;
+                }
+
+                for (DataNodeDescriptor dataNode : dataChannel.getNodeDescriptors()) {
+                    if (dataNode.getName().equals(objectName)) {
+                        configurationNodeList.add(dataNode);
+                        continue outer;
+                    }
+                }
+
+                for (DataMap dataMap : dataChannel.getDataMaps()) {
+                    if (dataMap.getName().equals(objectName)) {
+                        configurationNodeList.add(dataMap);
+                        continue outer;
+                    }
+                }
+            }
+        }
+
+        return configurationNodeList.toArray(nodes);
+    }
+
+    private static ConfigurationNode[] getLastMultipleObjects(DataNodeDescriptor dataNode) {
+        List<ConfigurationNode> configurationNodeList = new ArrayList<ConfigurationNode>();
+        ConfigurationNode[] nodes = new ConfigurationNode[0];
+
+        String multipleObjects = preferences.getMultipleObjects();
+        if (!multipleObjects.isEmpty()) {
+            String[] lastMultipleObjects = multipleObjects.split(",");
+            for (String objectName : lastMultipleObjects) {
+                if (dataNode.getDataMapNames().contains(objectName)) {
+                    configurationNodeList.add(dataNode.getDataChannelDescriptor().getDataMap(objectName));
+                }
+            }
+        }
+
+        return configurationNodeList.toArray(nodes);
+    }
+
+    private static ConfigurationNode[] getLastMultipleObjects(DataMap dataMap) {
+        List<ConfigurationNode> configurationNodeList = new ArrayList<ConfigurationNode>();
+        ConfigurationNode[] nodes = new ConfigurationNode[0];
+
+        String multipleObjects = preferences.getMultipleObjects();
+        if (!multipleObjects.isEmpty()) {
+            String[] lastMultipleObjects = multipleObjects.split(",");
+            for (String objectName : lastMultipleObjects) {
+                if (dataMap.getObjEntity(objectName) != null) {
+                    configurationNodeList.add(dataMap.getObjEntity(objectName));
+                } else if (dataMap.getDbEntity(objectName) != null) {
+                    configurationNodeList.add(dataMap.getDbEntity(objectName));
+                } else if (dataMap.getEmbeddable(objectName) != null) {
+                    configurationNodeList.add(dataMap.getEmbeddable(objectName));
+                } else if (dataMap.getProcedure(objectName) != null) {
+                    configurationNodeList.add(dataMap.getProcedure(objectName));
+                } else if (dataMap.getQuery(objectName) != null) {
+                    configurationNodeList.add(dataMap.getQuery(objectName));
+                }
+            }
+        }
+
+        return configurationNodeList.toArray(nodes);
+    }
+
+    private static String getObjectName(Object object) {
+        if (object instanceof CayenneMapEntry) {
+            return ((CayenneMapEntry) object).getName();
+        } else if (object instanceof DataChannelDescriptor) {
+            return ((DataChannelDescriptor) object).getName();
+        } else if (object instanceof DataNodeDescriptor) {
+            return ((DataNodeDescriptor) object).getName();
+        } else if (object instanceof DataMap) {
+            return ((DataMap) object).getName();
+        } else if (object instanceof Embeddable) {
+            return ((Embeddable) object).getClassName();
+        } else if (object instanceof Query) {
+            return ((Query) object).getName();
+        } else {
+            return "";
+        }
+    }
+
+    private static String parseToString(CayenneMapEntry[] array) {
+        if (array == null) {
+            return "";
+        }
+
+        StringBuilder sb = new StringBuilder();
+        for (CayenneMapEntry entry : array) {
+            sb.append(entry.getName()).append(",");
+        }
+
+        return sb.toString();
+    }
+
+}


Mime
View raw message