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 2009/09/02 10:52:40 UTC

svn commit: r810422 [2/3] - in /cayenne/main/trunk/framework: cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/event/ cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/project/ cayenne-modeler/src/main/java/org/apache/cayenne/m...

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java?rev=810422&r1=810421&r2=810422&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java Wed Sep  2 08:52:39 2009
@@ -37,6 +37,8 @@
 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.ObjAttribute;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.ObjRelationship;
@@ -56,8 +58,9 @@
  * Action for pasting entities, queries etc. from the system buffer
  */
 public class PasteAction extends CayenneAction implements FlavorListener {
+
     private static final String COPY_PREFIX = "Copy of ";
-    
+
     public static String getActionName() {
         return "Paste";
     }
@@ -67,8 +70,9 @@
      */
     public PasteAction(Application application) {
         super(getActionName(), application);
-        
-        //add listener, so that button state would update event if clipboard was filled by other app
+
+        // add listener, so that button state would update event if clipboard was filled
+        // by other app
         Toolkit.getDefaultToolkit().getSystemClipboard().addFlavorListener(this);
     }
 
@@ -76,10 +80,12 @@
     public String getIconName() {
         return "icon-paste.gif";
     }
-    
+
     @Override
     public KeyStroke getAcceleratorKey() {
-        return KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
+        return KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit
+                .getDefaultToolkit()
+                .getMenuShortcutKeyMask());
     }
 
     /**
@@ -88,11 +94,11 @@
     @Override
     public void performAction(ActionEvent e) {
         try {
-            Object content = Toolkit.getDefaultToolkit().getSystemClipboard()
-                .getData(CayenneTransferable.CAYENNE_FLAVOR);
-            
+            Object content = Toolkit.getDefaultToolkit().getSystemClipboard().getData(
+                    CayenneTransferable.CAYENNE_FLAVOR);
+
             Object currentObject = getProjectController().getCurrentObject();
-            
+
             if (content != null && currentObject != null) {
                 if (content instanceof List) {
                     for (Object o : (List) content) {
@@ -105,7 +111,7 @@
             }
         }
         catch (UnsupportedFlavorException ufe) {
-            //do nothing
+            // do nothing
         }
         catch (Exception ex) {
             ErrorDebugDialog.guiException(ex);
@@ -118,108 +124,155 @@
     protected void paste(Object where, Object content) {
         final ProjectController mediator = getProjectController();
         final DataDomain domain = mediator.getCurrentDataDomain();
-        
+
         /**
-         * Add a little intelligence - if a tree leaf is selected, we can paste to a parent datamap
+         * Add a little intelligence - if a tree leaf is selected, we can paste to a
+         * parent datamap
          */
         if (isTreeLeaf(where) && isTreeLeaf(content)) {
             where = mediator.getCurrentDataMap();
         }
-        
-        if ((where instanceof DataDomain || where instanceof DataNode) && content instanceof DataMap) {
-            //paste DataMap to DataDomain or DataNode
+
+        if ((where instanceof DataDomain || where instanceof DataNode)
+                && content instanceof DataMap) {
+            // paste DataMap to DataDomain or DataNode
             DataMap dataMap = ((DataMap) content);
-            
-            dataMap.setName(getFreeName(
-                    new DataMapNameChecker(domain), dataMap.getName()));
-         
+
+            dataMap
+                    .setName(getFreeName(new DataMapNameChecker(domain), dataMap
+                            .getName()));
+
             /**
-             * Update all names in the new DataMap, so that they would not conflict with names from
-             * other datamaps of this domain
+             * Update all names in the new DataMap, so that they would not conflict with
+             * names from other datamaps of this domain
              */
-            
-            //add some intelligence - if we rename an entity, we should rename all links to it as well
+
+            // add some intelligence - if we rename an entity, we should rename all links
+            // to it as well
             Map<String, String> renamedDbEntities = new HashMap<String, String>();
             Map<String, String> renamedObjEntities = new HashMap<String, String>();
-            
+
+            Map<String, String> renamedEmbeddables = new HashMap<String, String>();
+
             for (DbEntity dbEntity : dataMap.getDbEntities()) {
                 String oldName = dbEntity.getName();
-                dbEntity.setName(getFreeName(new DbEntityNameChecker(domain), dbEntity.getName()));
-                
+                dbEntity.setName(getFreeName(new DbEntityNameChecker(domain), dbEntity
+                        .getName()));
+
                 if (!oldName.equals(dbEntity.getName())) {
                     renamedDbEntities.put(oldName, dbEntity.getName());
                 }
             }
             for (ObjEntity objEntity : dataMap.getObjEntities()) {
                 String oldName = objEntity.getName();
-                objEntity.setName(getFreeName(new ObjEntityNameChecker(domain), objEntity.getName()));
-                
+                objEntity.setName(getFreeName(new ObjEntityNameChecker(domain), objEntity
+                        .getName()));
+
                 if (!oldName.equals(objEntity.getName())) {
                     renamedObjEntities.put(oldName, objEntity.getName());
                 }
             }
+
+            for (Embeddable embeddable : dataMap.getEmbeddables()) {
+                String oldName = embeddable.getClassName();
+                embeddable.setClassName(getFreeName(
+                        new EmbeddableNameChecker(domain),
+                        embeddable.getClassName()));
+
+                if (!oldName.equals(embeddable.getClassName())) {
+                    renamedEmbeddables.put(oldName, embeddable.getClassName());
+                }
+            }
+
             for (Procedure procedure : dataMap.getProcedures()) {
-                procedure.setName(getFreeName(new ProcedureNameChecker(domain), procedure.getName()));
+                procedure.setName(getFreeName(new ProcedureNameChecker(domain), procedure
+                        .getName()));
             }
             for (Query query : dataMap.getQueries()) {
-                ((AbstractQuery) query).setName(getFreeName(new QueryNameChecker(domain), query.getName()));
+                ((AbstractQuery) query).setName(getFreeName(
+                        new QueryNameChecker(domain),
+                        query.getName()));
             }
-            
+
             // if an entity was renamed, we rename all links to it too
             for (DbEntity dbEntity : dataMap.getDbEntities()) {
                 for (DbRelationship rel : dbEntity.getRelationships()) {
                     if (renamedDbEntities.containsKey(rel.getTargetEntityName())) {
-                        rel.setTargetEntityName(renamedDbEntities.get(rel.getTargetEntityName()));
+                        rel.setTargetEntityName(renamedDbEntities.get(rel
+                                .getTargetEntityName()));
                     }
                 }
             }
             for (ObjEntity objEntity : dataMap.getObjEntities()) {
                 if (renamedDbEntities.containsKey(objEntity.getDbEntityName())) {
-                    objEntity.setDbEntityName(renamedDbEntities.get(objEntity.getDbEntityName()));
+                    objEntity.setDbEntityName(renamedDbEntities.get(objEntity
+                            .getDbEntityName()));
                 }
-                
+
                 if (renamedObjEntities.containsKey(objEntity.getSuperEntityName())) {
-                    objEntity.setSuperEntityName(renamedDbEntities.get(objEntity.getSuperEntityName()));
+                    objEntity.setSuperEntityName(renamedDbEntities.get(objEntity
+                            .getSuperEntityName()));
                 }
-                
+
                 for (ObjRelationship rel : objEntity.getRelationships()) {
                     if (renamedObjEntities.containsKey(rel.getTargetEntityName())) {
-                        rel.setTargetEntityName(renamedObjEntities.get(rel.getTargetEntityName()));
+                        rel.setTargetEntityName(renamedObjEntities.get(rel
+                                .getTargetEntityName()));
                     }
                 }
             }
-            
+
             mediator.addDataMap(this, dataMap);
         }
         else if (where instanceof DataMap) {
-            //paste DbEntity to DataMap
-            final DataMap dataMap = ((DataMap) where); 
-            
+            // paste DbEntity to DataMap
+            final DataMap dataMap = ((DataMap) where);
+
             if (content instanceof DbEntity) {
                 DbEntity dbEntity = (DbEntity) content;
-                dbEntity.setName(getFreeName(new DbEntityNameChecker(domain), dbEntity.getName()));
-                
+                dbEntity.setName(getFreeName(new DbEntityNameChecker(domain), dbEntity
+                        .getName()));
+
                 dataMap.addDbEntity(dbEntity);
                 CreateDbEntityAction.fireDbEntityEvent(this, mediator, dbEntity);
             }
             else if (content instanceof ObjEntity) {
-                //paste ObjEntity to DataMap
+                // paste ObjEntity to DataMap
                 ObjEntity objEntity = (ObjEntity) content;
-                objEntity.setName(getFreeName(new ObjEntityNameChecker(domain), objEntity.getName()));
-                
+                objEntity.setName(getFreeName(new ObjEntityNameChecker(domain), objEntity
+                        .getName()));
+
                 dataMap.addObjEntity(objEntity);
-                CreateObjEntityAction.fireObjEntityEvent(this, mediator, dataMap, objEntity);
-            }           
+                CreateObjEntityAction.fireObjEntityEvent(
+                        this,
+                        mediator,
+                        dataMap,
+                        objEntity);
+            }
+            else if (content instanceof Embeddable) {
+                // paste Embeddable to DataMap
+                Embeddable embeddable = (Embeddable) content;
+                embeddable.setClassName(getFreeName(
+                        new EmbeddableNameChecker(domain),
+                        embeddable.getClassName()));
+
+                dataMap.addEmbeddable(embeddable);
+                CreateEmbeddableAction.fireEmbeddableEvent(
+                        this,
+                        mediator,
+                        dataMap,
+                        embeddable);
+            }
             else if (content instanceof Query) {
-                //paste Query to DataMap
+                // paste Query to DataMap
                 AbstractQuery query = (AbstractQuery) content;
-                
+
                 /**
                  * Change Query root do current datamap's
                  */
                 Object root = query.getRoot();
                 Object newRoot = root;
-                
+
                 if (root instanceof ObjEntity) {
                     newRoot = dataMap.getObjEntity(((ObjEntity) root).getName());
                 }
@@ -229,125 +282,176 @@
                 else if (root instanceof Procedure) {
                     newRoot = dataMap.getProcedure(((Procedure) root).getName());
                 }
-                
+
                 if (newRoot == null) {
-                    JOptionPane.showMessageDialog(
-                            Application.getFrame(),
-                            "Query root cannot be resolved. Pasting has not been performed.",
-                            "Warning",
-                            JOptionPane.WARNING_MESSAGE);
+                    JOptionPane
+                            .showMessageDialog(
+                                    Application.getFrame(),
+                                    "Query root cannot be resolved. Pasting has not been performed.",
+                                    "Warning",
+                                    JOptionPane.WARNING_MESSAGE);
                     return;
                 }
-                    
+
                 query.setName(getFreeName(new QueryNameChecker(domain), query.getName()));
-                    
+
                 dataMap.addQuery(query);
-                QueryTypeController.fireQueryEvent(this, mediator, mediator.getCurrentDataDomain(), 
-                        dataMap, query);
+                QueryTypeController.fireQueryEvent(this, mediator, mediator
+                        .getCurrentDataDomain(), dataMap, query);
             }
             else if (content instanceof Procedure) {
-                //paste Procedure to DataMap
+                // paste Procedure to DataMap
                 Procedure procedure = (Procedure) content;
-                procedure.setName(getFreeName(new ProcedureNameChecker(domain), procedure.getName()));
-                
+                procedure.setName(getFreeName(new ProcedureNameChecker(domain), procedure
+                        .getName()));
+
                 dataMap.addProcedure(procedure);
-                CreateProcedureAction.fireProcedureEvent(this, mediator, dataMap, procedure);
+                CreateProcedureAction.fireProcedureEvent(
+                        this,
+                        mediator,
+                        dataMap,
+                        procedure);
             }
         }
         else if (where instanceof DbEntity) {
             final DbEntity dbEntity = (DbEntity) where;
-            
-            //attrs and rels must be unique in entity namespace
-            FreeNameChecker checker = 
-                new FreeNameChecker() {
-                    public boolean isNameFree(String name) {
-                        return dbEntity.getAttribute(name) == null 
+
+            // attrs and rels must be unique in entity namespace
+            FreeNameChecker checker = new FreeNameChecker() {
+
+                public boolean isNameFree(String name) {
+                    return dbEntity.getAttribute(name) == null
                             && dbEntity.getRelationship(name) == null;
-                    }
-                };
-            
+                }
+            };
+
             if (content instanceof DbAttribute) {
-                DbAttribute attr = (DbAttribute) content; 
-                attr.setName(getFreeName(checker, attr.getName()));          
-                
+                DbAttribute attr = (DbAttribute) content;
+                attr.setName(getFreeName(checker, attr.getName()));
+
                 dbEntity.addAttribute(attr);
-                CreateAttributeAction.fireDbAttributeEvent(this, mediator, dbEntity, attr);
+                CreateAttributeAction
+                        .fireDbAttributeEvent(this, mediator, dbEntity, attr);
             }
             else if (content instanceof DbRelationship) {
-                DbRelationship rel = (DbRelationship) content; 
-                rel.setName(getFreeName(checker, rel.getName()));          
-                
+                DbRelationship rel = (DbRelationship) content;
+                rel.setName(getFreeName(checker, rel.getName()));
+
                 dbEntity.addRelationship(rel);
-                CreateRelationshipAction.fireDbRelationshipEvent(this, mediator, dbEntity, rel);
+                CreateRelationshipAction.fireDbRelationshipEvent(
+                        this,
+                        mediator,
+                        dbEntity,
+                        rel);
             }
         }
         else if (where instanceof ObjEntity) {
             final ObjEntity objEntity = (ObjEntity) where;
-            
-            //attrs and rels must be unique in entity namespace
-            FreeNameChecker checker = 
-                new FreeNameChecker() {
-                    public boolean isNameFree(String name) {
-                        return objEntity.getAttribute(name) == null 
+
+            // attrs and rels must be unique in entity namespace
+            FreeNameChecker checker = new FreeNameChecker() {
+
+                public boolean isNameFree(String name) {
+                    return objEntity.getAttribute(name) == null
                             && objEntity.getRelationship(name) == null;
-                    }
-                };
-            
+                }
+            };
+
             if (content instanceof ObjAttribute) {
-                ObjAttribute attr = (ObjAttribute) content; 
-                attr.setName(getFreeName(checker, attr.getName()));          
-                
+                ObjAttribute attr = (ObjAttribute) content;
+                attr.setName(getFreeName(checker, attr.getName()));
+
                 objEntity.addAttribute(attr);
-                CreateAttributeAction.fireObjAttributeEvent(this, mediator, objEntity, attr);
+                CreateAttributeAction.fireObjAttributeEvent(
+                        this,
+                        mediator,
+                        objEntity,
+                        attr);
             }
             else if (content instanceof ObjRelationship) {
-                ObjRelationship rel = (ObjRelationship) content; 
-                rel.setName(getFreeName(checker, rel.getName()));          
-                
+                ObjRelationship rel = (ObjRelationship) content;
+                rel.setName(getFreeName(checker, rel.getName()));
+
                 objEntity.addRelationship(rel);
-                CreateRelationshipAction.fireObjRelationshipEvent(this, mediator, objEntity, rel);
+                CreateRelationshipAction.fireObjRelationshipEvent(
+                        this,
+                        mediator,
+                        objEntity,
+                        rel);
             }
         }
+
+        else if (where instanceof Embeddable) {
+            final Embeddable embeddable = (Embeddable) where;
+
+            // attrs and rels must be unique in entity namespace
+            FreeNameChecker checker = new FreeNameChecker() {
+
+                public boolean isNameFree(String name) {
+                    return embeddable.getAttribute(name) == null;
+                }
+            };
+
+            if (content instanceof EmbeddableAttribute) {
+                EmbeddableAttribute attr = (EmbeddableAttribute) content;
+                attr.setName(getFreeName(checker, attr.getName()));
+
+                embeddable.addAttribute(attr);
+                CreateAttributeAction.fireEmbeddableAttributeEvent(
+                        this,
+                        mediator,
+                        embeddable,
+                        attr);
+            }
+
+        }
+
         else if (where instanceof Procedure) {
-            //paste param to procedure
+            // paste param to procedure
             final Procedure procedure = (Procedure) where;
-            
+
             if (content instanceof ProcedureParameter) {
                 ProcedureParameter param = (ProcedureParameter) content;
-                
-                param.setName(getFreeName(
-                        new FreeNameChecker()
-                        {
-                            public boolean isNameFree(String name) {
-                                for (ProcedureParameter existingParam : procedure.getCallParameters()) {
-                                    if (name.equals(existingParam.getName())) {
-                                        return false;
-                                    }
-                                }
-                                
-                                return true;
+
+                param.setName(getFreeName(new FreeNameChecker() {
+
+                    public boolean isNameFree(String name) {
+                        for (ProcedureParameter existingParam : procedure
+                                .getCallParameters()) {
+                            if (name.equals(existingParam.getName())) {
+                                return false;
                             }
-                        }, param.getName()));
-                
+                        }
+
+                        return true;
+                    }
+                }, param.getName()));
+
                 procedure.addCallParameter(param);
-                CreateProcedureParameterAction.fireProcedureParameterEvent(this, mediator, procedure, param);
+                CreateProcedureParameterAction.fireProcedureParameterEvent(
+                        this,
+                        mediator,
+                        procedure,
+                        param);
             }
-            
+
         }
     }
-    
+
     /**
      * Finds avaliable name for an object
      */
     private String getFreeName(FreeNameChecker checker, String defName) {
         String name = defName;
-        
-        for (int i = 0; !checker.isNameFree(name); 
-            name = COPY_PREFIX + defName + (i == 0 ? "" : " (" + i + ")"), i++);
-        
+
+        for (int i = 0; !checker.isNameFree(name); name = COPY_PREFIX
+                + defName
+                + (i == 0 ? "" : " (" + i + ")"), i++)
+            ;
+
         return name;
     }
-    
+
     /**
      * Returns <code>true</code> if last object in the path contains a removable object.
      */
@@ -356,108 +460,117 @@
         if (path == null) {
             return false;
         }
-        
+
         return getState();
     }
-    
+
     /**
      * Enables or disables the action, judging last selected component
      */
     public void updateState() {
         setEnabled(getState());
     }
-    
+
     /**
      * Returns desired enable state for this action
      */
     private boolean getState() {
         try {
-            Object content = Toolkit.getDefaultToolkit().getSystemClipboard()
-                .getData(CayenneTransferable.CAYENNE_FLAVOR);
-            
+            Object content = Toolkit.getDefaultToolkit().getSystemClipboard().getData(
+                    CayenneTransferable.CAYENNE_FLAVOR);
+
             if (content instanceof List) {
                 content = ((List) content).get(0);
             }
-            
+
             Object currentObject = getProjectController().getCurrentObject();
-            
+
             if (currentObject == null) {
-                return false; 
+                return false;
             }
-            
+
             /**
-             * Checking all avaliable pairs source-pasting object 
+             * Checking all avaliable pairs source-pasting object
              */
-            
-            return (
-                    (currentObject instanceof DataDomain || currentObject instanceof DataNode) && 
-                    content instanceof DataMap) ||
-                    
-                    (currentObject instanceof DataMap && isTreeLeaf(content)) ||
-                        
-                    (currentObject instanceof DbEntity && (
-                        content instanceof DbAttribute || content instanceof DbRelationship
-                        || isTreeLeaf(content))) ||
-                        
-                    (currentObject instanceof ObjEntity && (
-                        content instanceof ObjAttribute || content instanceof ObjRelationship
-                        || isTreeLeaf(content))) ||
-                        
-                    (currentObject instanceof Procedure && (content instanceof ProcedureParameter
-                        || isTreeLeaf(content)) ||
-            
+
+            return ((currentObject instanceof DataDomain || currentObject instanceof DataNode) && content instanceof DataMap)
+                    ||
+
+                    (currentObject instanceof DataMap && isTreeLeaf(content))
+                    ||
+
+                    (currentObject instanceof DbEntity && (content instanceof DbAttribute
+                            || content instanceof DbRelationship || isTreeLeaf(content)))
+                    ||
+
+                    (currentObject instanceof ObjEntity && (content instanceof ObjAttribute
+                            || content instanceof ObjRelationship || isTreeLeaf(content)))
+                    ||
+
+                    (currentObject instanceof Embeddable 
+                            && (content instanceof EmbeddableAttribute || isTreeLeaf(content))) ||
+
+                    (currentObject instanceof Procedure
+                            && (content instanceof ProcedureParameter || isTreeLeaf(content)) ||
+
                     (currentObject instanceof Query && isTreeLeaf(content)));
         }
         catch (Exception ex) {
             return false;
         }
     }
-    
+
     /**
      * @return true if the object is in a lowest level of the tree
      */
     private boolean isTreeLeaf(Object content) {
-        return content instanceof DbEntity || content instanceof ObjEntity || 
-            content instanceof Procedure || content instanceof Query;  
+        return content instanceof DbEntity
+                || content instanceof ObjEntity
+                || content instanceof Embeddable
+                || content instanceof Procedure
+                || content instanceof Query;
     }
-    
+
     public void flavorsChanged(FlavorEvent e) {
         updateState();
     }
-    
+
     /**
-     * Interface for checking that specified name is free in superior DataMap, Entity etc. and
-     * therefore can be used for new object 
+     * Interface for checking that specified name is free in superior DataMap, Entity etc.
+     * and therefore can be used for new object
      */
     interface FreeNameChecker {
+
         boolean isNameFree(String name);
     }
-    
+
     /**
-     * FreeNameChecker implementation for choosing DataMap names 
+     * FreeNameChecker implementation for choosing DataMap names
      */
     class DataMapNameChecker implements FreeNameChecker {
+
         DataDomain domain;
-        
+
         public DataMapNameChecker(DataDomain domain) {
             this.domain = domain;
         }
-        
+
         public boolean isNameFree(String name) {
             return domain.getMap(name) == null;
         }
     }
-    
+
     /**
-     * FreeNameChecker implementation for choosing DbEntity names 
+     * FreeNameChecker implementation for choosing DbEntity names
      */
     class DbEntityNameChecker implements FreeNameChecker {
+
         DataDomain domain;
-        
+
         public DbEntityNameChecker(DataDomain domain) {
             this.domain = domain;
         }
-        
+
         public boolean isNameFree(String name) {
             /**
              * Name mast be unique through all DataDomain, for EntityResolver to work
@@ -468,21 +581,22 @@
                     return false;
                 }
             }
-            
+
             return true;
         }
     }
-    
+
     /**
-     * FreeNameChecker implementation for choosing ObjEntity names 
+     * FreeNameChecker implementation for choosing ObjEntity names
      */
     class ObjEntityNameChecker implements FreeNameChecker {
+
         DataDomain domain;
-        
+
         public ObjEntityNameChecker(DataDomain domain) {
             this.domain = domain;
         }
-        
+
         public boolean isNameFree(String name) {
             /**
              * Name mast be unique through all DataDomain, for EntityResolver to work
@@ -493,21 +607,45 @@
                     return false;
                 }
             }
-            
+
             return true;
         }
     }
-    
+
+    class EmbeddableNameChecker implements FreeNameChecker {
+
+        DataDomain domain;
+
+        public EmbeddableNameChecker(DataDomain domain) {
+            this.domain = domain;
+        }
+
+        public boolean isNameFree(String name) {
+            /**
+             * Name mast be unique through all DataDomain, for EntityResolver to work
+             * correctly
+             */
+            for (DataMap map : domain.getDataMaps()) {
+                if (map.getEmbeddable(name) != null) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+    }
+
     /**
-     * FreeNameChecker implementation for choosing Procedure names 
+     * FreeNameChecker implementation for choosing Procedure names
      */
     class ProcedureNameChecker implements FreeNameChecker {
+
         DataDomain domain;
-        
+
         public ProcedureNameChecker(DataDomain domain) {
             this.domain = domain;
         }
-        
+
         public boolean isNameFree(String name) {
             /**
              * Name mast be unique through all DataDomain, for EntityResolver to work
@@ -518,21 +656,22 @@
                     return false;
                 }
             }
-            
+
             return true;
         }
     }
-    
+
     /**
-     * FreeNameChecker implementation for choosing Query names 
+     * FreeNameChecker implementation for choosing Query names
      */
     class QueryNameChecker implements FreeNameChecker {
+
         DataDomain domain;
-        
+
         public QueryNameChecker(DataDomain domain) {
             this.domain = domain;
         }
-        
+
         public boolean isNameFree(String name) {
             /**
              * Name mast be unique through all DataDomain, for EntityResolver to work
@@ -543,7 +682,7 @@
                     return false;
                 }
             }
-            
+
             return true;
         }
     }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAction.java?rev=810422&r1=810421&r2=810422&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAction.java Wed Sep  2 08:52:39 2009
@@ -31,6 +31,8 @@
 import org.apache.cayenne.map.Attribute;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.Embeddable;
+import org.apache.cayenne.map.EmbeddableAttribute;
 import org.apache.cayenne.map.Entity;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.Procedure;
@@ -39,6 +41,7 @@
 import org.apache.cayenne.map.event.DataMapEvent;
 import org.apache.cayenne.map.event.DataNodeEvent;
 import org.apache.cayenne.map.event.DomainEvent;
+import org.apache.cayenne.map.event.EmbeddableEvent;
 import org.apache.cayenne.map.event.EntityEvent;
 import org.apache.cayenne.map.event.MapEvent;
 import org.apache.cayenne.map.event.ProcedureEvent;
@@ -131,6 +134,12 @@
                 removeProcedure(mediator.getCurrentDataMap(), mediator
                         .getCurrentProcedure());
             }
+        } 
+        else if (mediator.getCurrentEmbeddable() != null) {
+            if (dialog.shouldDelete("embeddable", mediator.getCurrentEmbeddable().getClassName())) {
+                removeEmbeddable(mediator.getCurrentDataMap(), mediator
+                        .getCurrentEmbeddable());
+            }
         }
         else if (mediator.getCurrentDataMap() != null) {
             if (dialog.shouldDelete("data map", mediator.getCurrentDataMap().getName())) {
@@ -168,6 +177,7 @@
                 }
             }
         }
+        
     }
 
     private void removeDomain(DataDomain domain) {
@@ -272,6 +282,16 @@
         }
     }
 
+    private void removeEmbeddable(DataMap map, Embeddable embeddable) {
+        ProjectController mediator = getProjectController();
+
+        EmbeddableEvent e = new EmbeddableEvent(Application.getFrame(), embeddable, MapEvent.REMOVE);
+        e.setDomain(mediator.findDomain(map));
+        
+        map.removeEmbeddable(embeddable.getClassName());
+        mediator.fireEmbeddableEvent(e, map);
+    }
+    
     private void removeDataMapFromDataNode(DataNode node, DataMap map) {
         ProjectController mediator = getProjectController();
 
@@ -319,6 +339,12 @@
         else if (lastObject instanceof ProcedureParameter) {
             return true;
         }
+        else if (lastObject instanceof Embeddable) {
+            return true;
+        }
+        else if (lastObject instanceof EmbeddableAttribute) {
+            return true;
+        }
         else {
             return false;
         }
@@ -328,6 +354,7 @@
      * Removes an object, depending on its type
      */
     private void removeLastPathComponent(ProjectPath path) {
+        
         Object lastObject = path.getObject();
 
         if (lastObject instanceof DataDomain) {
@@ -357,5 +384,8 @@
         else if (lastObject instanceof Procedure) {
             removeProcedure((DataMap) path.getObjectParent(), (Procedure) lastObject);
         }
+        else if (lastObject instanceof Embeddable) {
+            removeEmbeddable((DataMap) path.getObjectParent(), (Embeddable) lastObject);
+        }
     }
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAttributeAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAttributeAction.java?rev=810422&r1=810421&r2=810422&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAttributeAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAttributeAction.java Wed Sep  2 08:52:39 2009
@@ -17,7 +17,6 @@
  *  under the License.
  ****************************************************************/
 
-
 package org.apache.cayenne.modeler.action;
 
 import java.awt.event.ActionEvent;
@@ -25,9 +24,12 @@
 import org.apache.cayenne.map.Attribute;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.Embeddable;
+import org.apache.cayenne.map.EmbeddableAttribute;
 import org.apache.cayenne.map.ObjAttribute;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.event.AttributeEvent;
+import org.apache.cayenne.map.event.EmbeddableAttributeEvent;
 import org.apache.cayenne.map.event.MapEvent;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
@@ -42,7 +44,7 @@
 public class RemoveAttributeAction extends RemoveAction implements MultipleObjectsAction {
 
     private final static String ACTION_NAME = "Remove Attribute";
-    
+
     /**
      * Name of action if multiple rels are selected
      */
@@ -51,7 +53,7 @@
     public static String getActionName() {
         return ACTION_NAME;
     }
-    
+
     public String getActionName(boolean multiple) {
         return multiple ? ACTION_NAME_MULTIPLE : ACTION_NAME;
     }
@@ -77,21 +79,35 @@
     public void performAction(ActionEvent e, boolean allowAsking) {
         ConfirmRemoveDialog dialog = getConfirmDeleteDialog(allowAsking);
 
+        EmbeddableAttribute[] embAttrs = getProjectController().getCurrentEmbAttrs();
         ObjAttribute[] attrs = getProjectController().getCurrentObjAttributes();
-        if (attrs != null && attrs.length > 0) {
-            if ((attrs.length == 1 && dialog.shouldDelete("ObjAttribute", attrs[0].getName()))
-                || (attrs.length > 1 && dialog.shouldDelete("selected ObjAttributes"))) {
+
+        if (embAttrs != null && embAttrs.length > 0) {
+            if ((embAttrs.length == 1 && dialog.shouldDelete(
+                    "Embeddable Attribute",
+                    embAttrs[0].getName()))
+                    || (embAttrs.length > 1 && dialog
+                            .shouldDelete("selected EmbAttributes"))) {
+                removeEmbeddableAttributes();
+            }
+        }
+        else if (attrs != null && attrs.length > 0) {
+            if ((attrs.length == 1 && dialog.shouldDelete("ObjAttribute", attrs[0]
+                    .getName()))
+                    || (attrs.length > 1 && dialog.shouldDelete("selected ObjAttributes"))) {
                 removeObjAttributes();
             }
         }
         else {
             DbAttribute[] dbAttrs = getProjectController().getCurrentDbAttributes();
             if (dbAttrs != null && dbAttrs.length > 0) {
-                if ((dbAttrs.length == 1 && dialog.shouldDelete("DbAttribute", dbAttrs[0].getName()))
-                    || (dbAttrs.length > 1 && dialog.shouldDelete("selected DbAttributes"))) {
+                if ((dbAttrs.length == 1 && dialog.shouldDelete("DbAttribute", dbAttrs[0]
+                        .getName()))
+                        || (dbAttrs.length > 1 && dialog
+                                .shouldDelete("selected DbAttributes"))) {
                     removeDbAttributes();
                 }
-            }            
+            }
         }
     }
 
@@ -117,7 +133,7 @@
     protected void removeObjAttributes() {
         ProjectController mediator = getProjectController();
         ObjEntity entity = mediator.getCurrentObjEntity();
-        
+
         ObjAttribute[] attribs = mediator.getCurrentObjAttributes();
 
         for (ObjAttribute attrib : attribs) {
@@ -130,4 +146,18 @@
             mediator.fireObjAttributeEvent(e);
         }
     }
+
+    protected void removeEmbeddableAttributes() {
+        ProjectController mediator = getProjectController();
+        Embeddable embeddable = mediator.getCurrentEmbeddable();
+
+        EmbeddableAttribute[] attrs = getProjectController().getCurrentEmbAttrs();
+
+        for (EmbeddableAttribute attrib : attrs) {
+            embeddable.removeAttribute(attrib.getName());
+            EmbeddableAttributeEvent e = new EmbeddableAttributeEvent(Application
+                    .getFrame(), attrib, embeddable, MapEvent.REMOVE);
+            mediator.fireEmbeddableAttributeEvent(e);
+        }
+    }
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EditorView.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EditorView.java?rev=810422&r1=810421&r2=810422&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EditorView.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EditorView.java Wed Sep  2 08:52:39 2009
@@ -40,6 +40,8 @@
 import org.apache.cayenne.modeler.event.DbEntityDisplayListener;
 import org.apache.cayenne.modeler.event.DomainDisplayEvent;
 import org.apache.cayenne.modeler.event.DomainDisplayListener;
+import org.apache.cayenne.modeler.event.EmbeddableDisplayEvent;
+import org.apache.cayenne.modeler.event.EmbeddableDisplayListener;
 import org.apache.cayenne.modeler.event.EntityDisplayEvent;
 import org.apache.cayenne.modeler.event.MultipleObjectsDisplayEvent;
 import org.apache.cayenne.modeler.event.MultipleObjectsDisplayListener;
@@ -64,7 +66,7 @@
 public class EditorView extends JPanel implements ObjEntityDisplayListener,
         DbEntityDisplayListener, DomainDisplayListener, DataMapDisplayListener,
         DataNodeDisplayListener, ProcedureDisplayListener, QueryDisplayListener,
-        MultipleObjectsDisplayListener {
+        MultipleObjectsDisplayListener, EmbeddableDisplayListener {
 
     private static final String EMPTY_VIEW = "Empty";
     private static final String DOMAIN_VIEW = "Domain";
@@ -72,6 +74,7 @@
     private static final String DATA_MAP_VIEW = "DataMap";
     private static final String OBJ_VIEW = "ObjView";
     private static final String DB_VIEW = "DbView";
+    private static final String EMBEDDABLE_VIEW = "EmbeddableView";
     private static final String PROCEDURE_VIEW = "ProcedureView";
     private static final String SELECT_QUERY_VIEW = "SelectQueryView";
     private static final String SQL_TEMPLATE_VIEW = "SQLTemplateView";
@@ -82,18 +85,20 @@
     protected JSplitPane splitPane;
     protected Container detailPanel;
     protected CardLayout detailLayout;
-    private ProjectTreeView treePanel;    
-    
+    private ProjectTreeView treePanel;
+
     public ProjectTreeView getProjectTreeView() {
         return treePanel;
     }
 
     private DbEntityTabbedView dbDetailView;
+
     public DbEntityTabbedView getDbDetailView() {
         return dbDetailView;
     }
 
     private ObjEntityTabbedView objDetailView;
+
     public ObjEntityTabbedView getObjDetailView() {
         return objDetailView;
     }
@@ -128,7 +133,7 @@
         detailPanel.add(new JScrollPane(domainView), DOMAIN_VIEW);
 
         DataNodeEditor nodeController = new DataNodeEditor(eventController);
-        detailPanel.add(nodeController.getView(), NODE_VIEW); 
+        detailPanel.add(nodeController.getView(), NODE_VIEW);
 
         Component dataMapView = new DataMapTabbedView(eventController);
         detailPanel.add(dataMapView, DATA_MAP_VIEW);
@@ -144,10 +149,13 @@
 
         Component procedureQueryView = new ProcedureQueryView(eventController);
         detailPanel.add(new JScrollPane(procedureQueryView), PROCEDURE_QUERY_VIEW);
-       
+
         Component ejbqlQueryView = new EjbqlTabbedView(eventController);
         detailPanel.add(ejbqlQueryView, EJBQL_QUERY_VIEW);
 
+        Component embeddableView = new EmbeddableTabbedView(eventController);
+        detailPanel.add(new JScrollPane(embeddableView), EMBEDDABLE_VIEW);
+
         objDetailView = new ObjEntityTabbedView(eventController);
         detailPanel.add(objDetailView, OBJ_VIEW);
 
@@ -170,20 +178,22 @@
         eventController.addProcedureDisplayListener(this);
         eventController.addQueryDisplayListener(this);
         eventController.addMultipleObjectsDisplayListener(this);
+        eventController.addEmbeddableDisplayListener(this);
 
         /**
-         * Moving this to try-catch block per CAY-940.
-         * Exception will be stack-traced  
+         * Moving this to try-catch block per CAY-940. Exception will be stack-traced
          */
         try {
-            Domain domain = eventController.getApplicationPreferenceDomain().getSubdomain(
-                 this.getClass());
+            Domain domain = eventController
+                    .getApplicationPreferenceDomain()
+                    .getSubdomain(this.getClass());
             ComponentGeometry geometry = (ComponentGeometry) domain.getDetail(
-                "splitPane.divider",
-                ComponentGeometry.class,
-                true);
+                    "splitPane.divider",
+                    ComponentGeometry.class,
+                    true);
 
-            geometry.bindIntProperty(splitPane, JSplitPane.DIVIDER_LOCATION_PROPERTY, 150);
+            geometry
+                    .bindIntProperty(splitPane, JSplitPane.DIVIDER_LOCATION_PROPERTY, 150);
         }
         catch (Exception ex) {
             LogFactory.getLog(getClass()).error("Cannot bind divider property", ex);
@@ -255,4 +265,11 @@
     public void currentObjectsChanged(MultipleObjectsDisplayEvent e) {
         detailLayout.show(detailPanel, EMPTY_VIEW);
     }
+
+    public void currentEmbeddableChanged(EmbeddableDisplayEvent e) {
+        if (e.getEmbeddable() == null)
+            detailLayout.show(detailPanel, EMPTY_VIEW);
+        else
+            detailLayout.show(detailPanel, EMBEDDABLE_VIEW);
+    }
 }

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTab.java?rev=810422&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTab.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTab.java Wed Sep  2 08:52:39 2009
@@ -0,0 +1,311 @@
+/*****************************************************************
+ *   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.editor;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.util.EventObject;
+import java.util.List;
+
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JTable;
+import javax.swing.JToolBar;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableColumn;
+
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.Embeddable;
+import org.apache.cayenne.map.EmbeddableAttribute;
+import org.apache.cayenne.map.event.EmbeddableAttributeEvent;
+import org.apache.cayenne.map.event.EmbeddableAttributeListener;
+import org.apache.cayenne.map.event.EmbeddableEvent;
+import org.apache.cayenne.map.event.EmbeddableListener;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.action.CopyAttributeAction;
+import org.apache.cayenne.modeler.action.CreateAttributeAction;
+import org.apache.cayenne.modeler.action.CutAttributeAction;
+import org.apache.cayenne.modeler.action.PasteAction;
+import org.apache.cayenne.modeler.action.RemoveAttributeAction;
+import org.apache.cayenne.modeler.event.EmbeddableAttributeDisplayEvent;
+import org.apache.cayenne.modeler.event.EmbeddableDisplayEvent;
+import org.apache.cayenne.modeler.event.EmbeddableDisplayListener;
+import org.apache.cayenne.modeler.event.TablePopupHandler;
+import org.apache.cayenne.modeler.util.CayenneTable;
+import org.apache.cayenne.modeler.util.CayenneWidgetFactory;
+import org.apache.cayenne.modeler.util.ModelerUtil;
+import org.apache.cayenne.modeler.util.PanelFactory;
+import org.apache.cayenne.modeler.util.UIUtil;
+import org.apache.cayenne.modeler.util.combo.AutoCompletion;
+
+public class EmbeddableAttributeTab extends JPanel implements
+        EmbeddableAttributeListener, EmbeddableDisplayListener, EmbeddableListener,
+        ExistingSelectionProcessor {
+
+    protected ProjectController mediator;
+    protected CayenneTable table;
+
+    JButton resolve;
+
+    public EmbeddableAttributeTab(ProjectController mediator) {
+        this.mediator = mediator;
+        init();
+        initController();
+    }
+
+    private void init() {
+        this.setLayout(new BorderLayout());
+
+        JToolBar toolBar = new JToolBar();
+        Application app = Application.getInstance();
+
+        toolBar.add(app.getAction(CreateAttributeAction.getActionName()).buildButton());
+        toolBar.addSeparator();
+
+        toolBar.add(app.getAction(RemoveAttributeAction.getActionName()).buildButton());
+        toolBar.addSeparator();
+
+        toolBar.add(app.getAction(CutAttributeAction.getActionName()).buildButton());
+        toolBar.add(app.getAction(CopyAttributeAction.getActionName()).buildButton());
+        toolBar.add(app.getAction(PasteAction.getActionName()).buildButton());
+
+        add(toolBar, BorderLayout.NORTH);
+
+        table = new CayenneTable();
+        table.setDefaultRenderer(String.class, new CellRenderer());
+
+        /**
+         * Create and install a popup
+         */
+        JPopupMenu popup = new JPopupMenu();
+        popup.add(app.getAction(RemoveAttributeAction.getActionName()).buildMenu());
+
+        popup.addSeparator();
+
+        popup.add(app.getAction(CutAttributeAction.getActionName()).buildMenu());
+        popup.add(app.getAction(CopyAttributeAction.getActionName()).buildMenu());
+        popup.add(app.getAction(PasteAction.getActionName()).buildMenu());
+
+        TablePopupHandler.install(table, popup);
+        add(PanelFactory.createTablePanel(table, null), BorderLayout.CENTER);
+    }
+
+    private void initController() {
+        mediator.addEmbeddableAttributeListener(this);
+        mediator.addEmbeddableDisplayListener(this);
+        mediator.addEmbeddableListener(this);
+
+        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+
+            public void valueChanged(ListSelectionEvent e) {
+                processExistingSelection(e);
+            }
+        });
+
+        mediator.getApplication().getActionManager().setupCCP(
+                table,
+                CutAttributeAction.getActionName(),
+                CopyAttributeAction.getActionName());
+    }
+
+    public void processExistingSelection(EventObject e) {
+
+        if (e instanceof ChangeEvent) {
+            table.clearSelection();
+        }
+
+        EmbeddableAttribute[] attrs = new EmbeddableAttribute[0];
+        if (table.getSelectedRow() >= 0) {
+            EmbeddableAttributeTableModel model = (EmbeddableAttributeTableModel) table
+                    .getModel();
+
+            int[] sel = table.getSelectedRows();
+            attrs = new EmbeddableAttribute[sel.length];
+
+            for (int i = 0; i < sel.length; i++) {
+                attrs[i] = model.getEmbeddableAttribute(sel[i]);
+            }
+
+            if (sel.length == 1) {
+                UIUtil.scrollToSelectedRow(table);
+            }
+        }
+
+        EmbeddableAttributeDisplayEvent ev = new EmbeddableAttributeDisplayEvent(
+                this,
+                mediator.getCurrentEmbeddable(),
+                attrs,
+                mediator.getCurrentDataMap(),
+                mediator.getCurrentDataDomain());
+
+        mediator.fireEmbeddableAttributeDisplayEvent(ev);
+    }
+
+    private void rebuildTable(Embeddable emb) {
+        EmbeddableAttributeTableModel model = new EmbeddableAttributeTableModel(
+                emb,
+                mediator,
+                this);
+        table.setModel(model);
+        table.setRowHeight(25);
+        table.setRowMargin(3);
+        setUpTableStructure(model);
+    }
+
+    private void setUpTableStructure(EmbeddableAttributeTableModel model) {
+        TableColumn inheritanceColumn = table.getColumnModel().getColumn(
+                EmbeddableAttributeTableModel.INHERITED);
+        inheritanceColumn.setMinWidth(20);
+        inheritanceColumn.setMaxWidth(20);
+
+        TableColumn nameColumn = table.getColumnModel().getColumn(
+                EmbeddableAttributeTableModel.OBJ_ATTRIBUTE);
+        nameColumn.setMinWidth(150);
+
+        TableColumn typeColumn = table.getColumnModel().getColumn(
+                EmbeddableAttributeTableModel.OBJ_ATTRIBUTE_TYPE);
+        typeColumn.setMinWidth(150);
+
+        JComboBox javaTypesCombo = CayenneWidgetFactory.createComboBox(ModelerUtil
+                .getRegisteredTypeNames(), false);
+        AutoCompletion.enable(javaTypesCombo, false, true);
+        typeColumn.setCellEditor(CayenneWidgetFactory.createCellEditor(javaTypesCombo));
+
+        TableColumn dbAttrColumn = table.getColumnModel().getColumn(
+                EmbeddableAttributeTableModel.DB_ATTRIBUTE);
+        dbAttrColumn.setMinWidth(150);
+
+    }
+
+    /**
+     * Selects a specified attribute.
+     */
+    public void selectAttributes(EmbeddableAttribute[] embAttrs) {
+        ModelerUtil.updateActions(
+                embAttrs.length,
+                RemoveAttributeAction.getActionName(),
+                CopyAttributeAction.getActionName(),
+                CutAttributeAction.getActionName());
+
+        EmbeddableAttributeTableModel model = (EmbeddableAttributeTableModel) table
+                .getModel();
+
+        List listAttrs = model.getObjectList();
+        int[] newSel = new int[embAttrs.length];
+
+        for (int i = 0; i < embAttrs.length; i++) {
+            newSel[i] = listAttrs.indexOf(embAttrs[i]);
+        }
+
+        table.select(newSel);
+    }
+
+    public void embeddableAttributeAdded(EmbeddableAttributeEvent e) {
+        rebuildTable((Embeddable) e.getEmbeddable());
+        table.select(e.getEmbeddableAttribute());
+    }
+
+    public void embeddableAttributeChanged(EmbeddableAttributeEvent e) {
+        table.select(e.getEmbeddableAttribute());
+    }
+
+    public void embeddableAttributeRemoved(EmbeddableAttributeEvent e) {
+
+        EmbeddableAttributeTableModel model = (EmbeddableAttributeTableModel) table
+                .getModel();
+        int ind = model.getObjectList().indexOf(e.getEmbeddableAttribute());
+        model.removeRow(e.getEmbeddableAttribute());
+        table.select(ind);
+    }
+
+    public void currentEmbeddableChanged(EmbeddableDisplayEvent e) {
+        if (e.getSource() == this) {
+            return;
+        }
+
+        Embeddable embeddable = (Embeddable) e.getEmbeddable();
+        if (embeddable != null) {
+            rebuildTable(embeddable);
+        }
+
+    }
+
+    public void embeddableAdded(EmbeddableEvent e, DataMap map) {
+    }
+
+    public void embeddableChanged(EmbeddableEvent e, DataMap map) {
+    }
+
+    public void embeddableRemoved(EmbeddableEvent e, DataMap map) {
+    }
+
+    // custom renderer used for inherited attributes highlighting
+    final class CellRenderer extends DefaultTableCellRenderer {
+
+        @Override
+        public Component getTableCellRendererComponent(
+                JTable table,
+                Object value,
+                boolean isSelected,
+                boolean hasFocus,
+                int row,
+                int column) {
+
+            super.getTableCellRendererComponent(
+                    table,
+                    value,
+                    isSelected,
+                    hasFocus,
+                    row,
+                    column);
+
+            EmbeddableAttributeTableModel model = (EmbeddableAttributeTableModel) table
+                    .getModel();
+            EmbeddableAttribute attribute = model.getEmbeddableAttribute(row);
+            if (column != EmbeddableAttributeTableModel.INHERITED) {
+
+                if (!model.isCellEditable(row, column)) {
+                    setForeground(Color.GRAY);
+                }
+                else {
+                    setForeground(isSelected && !hasFocus ? table
+                            .getSelectionForeground() : table.getForeground());
+                }
+
+                setIcon(null);
+            }
+            else {
+                setText("");
+            }
+            setBackground(isSelected && !hasFocus
+                    ? table.getSelectionBackground()
+                    : table.getBackground());
+
+            return this;
+        }
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTableModel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTableModel.java?rev=810422&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTableModel.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTableModel.java Wed Sep  2 08:52:39 2009
@@ -0,0 +1,260 @@
+/*****************************************************************
+ *   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.editor;
+
+import java.awt.Component;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.EventObject;
+import java.util.Hashtable;
+
+import javax.swing.DefaultCellEditor;
+import javax.swing.JComboBox;
+import javax.swing.JTable;
+import javax.swing.event.CellEditorListener;
+import javax.swing.table.TableCellEditor;
+
+import org.apache.cayenne.map.Embeddable;
+import org.apache.cayenne.map.EmbeddableAttribute;
+import org.apache.cayenne.map.event.EmbeddableAttributeEvent;
+import org.apache.cayenne.modeler.ProjectController;
+
+import org.apache.cayenne.modeler.util.CayenneTable;
+import org.apache.cayenne.modeler.util.CayenneTableModel;
+import org.apache.cayenne.modeler.util.CayenneWidgetFactory;
+import org.apache.cayenne.modeler.util.ProjectUtil;
+import org.apache.cayenne.util.Util;
+
+public class EmbeddableAttributeTableModel extends CayenneTableModel {
+
+    private Embeddable embeddable;
+
+    // Columns
+    static final int INHERITED = 0;
+    static final int OBJ_ATTRIBUTE = 1;
+    static final int OBJ_ATTRIBUTE_TYPE = 2;
+    static final int DB_ATTRIBUTE = 3;
+
+    private CellEditor cellEditor;
+
+    private CayenneTable table;
+
+    public EmbeddableAttributeTableModel(Embeddable embeddable,
+            ProjectController mediator, Object eventSource) {
+        super(mediator, eventSource, new ArrayList<EmbeddableAttribute>(embeddable
+                .getAttributes()));
+        this.embeddable = embeddable;
+
+        // order using local comparator
+        Collections.sort(objectList, new EmbeddableAttributeComparator());
+    }
+
+    public EmbeddableAttribute getEmbeddableAttribute(int row) {
+        return (row >= 0 && row < objectList.size()) ? (EmbeddableAttribute) objectList
+                .get(row) : null;
+    }
+
+    @Override
+    public Class<?> getElementsClass() {
+        return EmbeddableAttribute.class;
+    }
+
+    @Override
+    public void setUpdatedValueAt(Object value, int row, int col) {
+        EmbeddableAttribute attribute = getEmbeddableAttribute(row);
+        EmbeddableAttributeEvent event = new EmbeddableAttributeEvent(eventSource, embeddable, attribute);
+        String path = null;
+        Collection<String> nameAttr = null;
+        
+        if (col == OBJ_ATTRIBUTE) {
+            event.setOldName(attribute.getName());
+            ProjectUtil.setEmbeddableAttributeName(attribute, value != null ? value
+             .toString()
+             .trim() : null);
+
+            fireTableCellUpdated(row, col);
+        }
+        else if (col == OBJ_ATTRIBUTE_TYPE) {
+            attribute.setType(value != null ? value.toString() : null);
+            fireTableCellUpdated(row, col);
+        }
+        else if (col == DB_ATTRIBUTE) {
+            attribute.setDbAttributeName(value != null ? value.toString() : null);
+            fireTableCellUpdated(row, col);
+        }
+        
+        mediator.fireEmbeddableAttributeEvent(event);
+    }
+
+    public int getColumnCount() {
+        return 4;
+    }
+
+    public String getColumnName(int column) {
+        switch (column) {
+            case INHERITED:
+                return "In";
+            case OBJ_ATTRIBUTE:
+                return "ObjAttribute";
+            case OBJ_ATTRIBUTE_TYPE:
+                return "Java Type";
+            case DB_ATTRIBUTE:
+                return "DbAttribute";
+            default:
+                return "";
+        }
+    }
+
+    public Object getValueAt(int row, int column) {
+        EmbeddableAttribute attribute = getEmbeddableAttribute(row);
+
+        if (column == INHERITED) {
+            return null;
+        }
+        else if (column == OBJ_ATTRIBUTE) {
+            return attribute.getName();
+        }
+        else if (column == OBJ_ATTRIBUTE_TYPE) {
+            return attribute.getType();
+        }
+        else if (column == DB_ATTRIBUTE) {
+            return attribute.getDbAttributeName();
+        }
+        else {
+            return null;
+        }
+    }
+
+    public CellEditor setCellEditor(Collection<String> nameAttr, CayenneTable table) {
+        this.cellEditor = new CellEditor(table, CayenneWidgetFactory.createComboBox(
+                nameAttr,
+                true));
+        this.table = table;
+        return cellEditor;
+    }
+
+    public CellEditor getCellEditor() {
+        return cellEditor;
+    }
+
+    public boolean isCellEditable(int row, int col) {
+        return true;
+    }
+
+    final class EmbeddableAttributeComparator implements Comparator {
+
+        public int compare(Object o1, Object o2) {
+            EmbeddableAttribute a1 = (EmbeddableAttribute) o1;
+            EmbeddableAttribute a2 = (EmbeddableAttribute) o2;
+
+            int delta = getWeight(a1) - getWeight(a2);
+
+            return (delta != 0) ? delta : Util.nullSafeCompare(true, a1.getName(), a2
+                    .getName());
+        }
+
+        private int getWeight(EmbeddableAttribute a) {
+            return a.getEmbeddable() == embeddable ? 1 : -1;
+        }
+    }
+
+    final class CellEditor implements TableCellEditor {
+
+        protected Hashtable editors;
+        protected TableCellEditor editor, defaultEditor;
+        JTable table;
+
+        public CellEditor(JTable table, JComboBox combo) {
+            this.table = table;
+            editors = new Hashtable();
+            if (combo != null) {
+                defaultEditor = new DefaultCellEditor(combo);
+            }
+            else {
+                defaultEditor = new DefaultCellEditor(new JComboBox());
+            }
+        }
+
+        public void setEditorAt(int row, TableCellEditor editor) {
+            editors.put(new Integer(row), editor);
+        }
+
+        public Component getTableCellEditorComponent(
+                JTable table,
+                Object value,
+                boolean isSelected,
+                int row,
+                int column) {
+
+            return editor.getTableCellEditorComponent(
+                    table,
+                    value,
+                    isSelected,
+                    row,
+                    column);
+        }
+
+        public Object getCellEditorValue() {
+            return editor.getCellEditorValue();
+        }
+
+        public boolean stopCellEditing() {
+            return editor.stopCellEditing();
+        }
+
+        public void cancelCellEditing() {
+            editor.cancelCellEditing();
+        }
+
+        public boolean isCellEditable(EventObject anEvent) {
+            selectEditor((MouseEvent) anEvent);
+            return editor.isCellEditable(anEvent);
+        }
+
+        public void addCellEditorListener(CellEditorListener l) {
+            editor.addCellEditorListener(l);
+        }
+
+        public void removeCellEditorListener(CellEditorListener l) {
+            editor.removeCellEditorListener(l);
+        }
+
+        public boolean shouldSelectCell(EventObject anEvent) {
+            selectEditor((MouseEvent) anEvent);
+            return editor.shouldSelectCell(anEvent);
+        }
+
+        protected void selectEditor(MouseEvent e) {
+            int row;
+            if (e == null) {
+                row = table.getSelectionModel().getAnchorSelectionIndex();
+            }
+            else {
+                row = table.rowAtPoint(e.getPoint());
+            }
+            editor = (TableCellEditor) editors.get(new Integer(row));
+            if (editor == null) {
+                editor = defaultEditor;
+            }
+        }
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableTab.java?rev=810422&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableTab.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableTab.java Wed Sep  2 08:52:39 2009
@@ -0,0 +1,124 @@
+/*****************************************************************
+ *   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.editor;
+
+import java.awt.BorderLayout;
+import java.util.EventObject;
+
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.JToolBar;
+
+import org.apache.cayenne.map.Embeddable;
+import org.apache.cayenne.map.event.EmbeddableEvent;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.action.CreateAttributeAction;
+import org.apache.cayenne.modeler.event.EmbeddableDisplayEvent;
+import org.apache.cayenne.modeler.event.EmbeddableDisplayListener;
+import org.apache.cayenne.modeler.util.TextAdapter;
+import org.apache.cayenne.util.Util;
+
+import com.jgoodies.forms.builder.DefaultFormBuilder;
+import com.jgoodies.forms.layout.FormLayout;
+
+public class EmbeddableTab extends JPanel implements EmbeddableDisplayListener {
+
+    protected ProjectController mediator;
+    protected TextAdapter className;
+
+    public EmbeddableTab(ProjectController mediator) {
+        this.mediator = mediator;
+        initView();
+        initController();
+    }
+
+    private void initController() {
+        mediator.addEmbeddableDisplayListener(this);
+
+    }
+
+    private void initView() {
+        this.setLayout(new BorderLayout());
+
+        JToolBar toolBar = new JToolBar();
+        Application app = Application.getInstance();
+        toolBar.add(app.getAction(CreateAttributeAction.getActionName()).buildButton());
+
+        add(toolBar, BorderLayout.NORTH);
+
+        className = new TextAdapter(new JTextField()) {
+
+            @Override
+            protected void updateModel(String text) {
+                setClassName(text);
+            }
+        };
+
+        FormLayout layout = new FormLayout(
+                "right:50dlu, 3dlu, fill:150dlu, 3dlu, fill:100",
+                "");
+        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
+        builder.setDefaultDialogBorder();
+        builder.append("Class Name:", className.getComponent(), 3);
+
+        add(builder.getPanel(), BorderLayout.CENTER);
+    }
+
+    public void processExistingSelection(EventObject e) {
+        EmbeddableDisplayEvent ede = new EmbeddableDisplayEvent(this, mediator
+                .getCurrentEmbeddable(), mediator.getCurrentDataMap(), mediator
+                .getCurrentDataDomain());
+        mediator.fireEmbeddableDisplayEvent(ede);
+    }
+
+    void setClassName(String newClassName) {
+        if (newClassName != null && newClassName.trim().length() == 0) {
+            newClassName = null;
+        }
+
+        Embeddable embeddable = mediator.getCurrentEmbeddable();
+        
+        if (embeddable == null) {
+            return;
+        }
+        
+        if (Util.nullSafeEquals(newClassName, embeddable.getClassName())) {
+            return;
+        }
+
+        // completely new name, set new name for entity
+        EmbeddableEvent e = new EmbeddableEvent(this, embeddable, embeddable.getClassName());
+        embeddable.setClassName(newClassName);
+        
+        mediator.fireEmbeddableEvent(e, mediator.getCurrentDataMap());
+    }
+
+    public void currentEmbeddableChanged(EmbeddableDisplayEvent e) {
+        Embeddable embeddable = e.getEmbeddable();
+        if (embeddable == null || !e.isEmbeddableChanged()) {
+            return;
+        }
+        initFromModel(embeddable);
+    }
+
+    private void initFromModel(Embeddable embeddable) {
+        className.setText(embeddable.getClassName());
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableTabbedView.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableTabbedView.java?rev=810422&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableTabbedView.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableTabbedView.java Wed Sep  2 08:52:39 2009
@@ -0,0 +1,125 @@
+/*****************************************************************
+ *   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.editor;
+
+import java.awt.Component;
+
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import org.apache.cayenne.map.Embeddable;
+import org.apache.cayenne.map.EmbeddableAttribute;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.action.RemoveAttributeAction;
+import org.apache.cayenne.modeler.action.RemoveCallbackMethodAction;
+import org.apache.cayenne.modeler.event.EmbeddableAttributeDisplayEvent;
+import org.apache.cayenne.modeler.event.EmbeddableAttributeDisplayListener;
+import org.apache.cayenne.modeler.event.EmbeddableDisplayEvent;
+import org.apache.cayenne.modeler.event.EmbeddableDisplayListener;
+
+public class EmbeddableTabbedView extends JTabbedPane implements
+        EmbeddableAttributeDisplayListener, EmbeddableDisplayListener {
+
+    protected ProjectController mediator;
+
+    protected JScrollPane embeddablePanel;
+    protected EmbeddableAttributeTab attributesPanel;
+
+    protected JPanel listenersPanel;
+
+    public EmbeddableTabbedView(ProjectController mediator) {
+        this.mediator = mediator;
+
+        initView();
+        initController();
+    }
+
+    private void initView() {
+        setTabPlacement(JTabbedPane.TOP);
+
+        embeddablePanel = new JScrollPane(new EmbeddableTab(mediator));
+        addTab("Embeddable", embeddablePanel);
+
+        attributesPanel = new EmbeddableAttributeTab(mediator);
+        addTab("Attributes", attributesPanel);
+    }
+
+    private void initController() {
+
+        mediator.addEmbeddableAttributeDisplayListener(this);
+        mediator.addEmbeddableDisplayListener(this);
+
+        addChangeListener(new ChangeListener() {
+
+            public void stateChanged(ChangeEvent e) {
+                resetRemoveButtons();
+                Component selected = getSelectedComponent();
+                while (selected instanceof JScrollPane) {
+                    selected = ((JScrollPane) selected).getViewport().getView();
+                }
+
+                if (selected instanceof ExistingSelectionProcessor) {
+                    ((ExistingSelectionProcessor) selected).processExistingSelection(e);
+                }
+            }
+        });
+    }
+
+    /** Reset the remove buttons */
+    private void resetRemoveButtons() {
+        Application app = Application.getInstance();
+        app.getAction(RemoveAttributeAction.getActionName()).setEnabled(false);
+        app.getAction(RemoveCallbackMethodAction.getActionName()).setEnabled(false);
+    }
+
+    public void currentEmbeddableChanged(EmbeddableDisplayEvent e) {
+        Embeddable emb = e.getEmbeddable();
+        if (e.isMainTabFocus() && emb instanceof Embeddable) {
+            
+            if (getSelectedComponent() != embeddablePanel) {
+                setSelectedComponent(embeddablePanel);
+                embeddablePanel.setVisible(true);
+            }
+        }
+
+        resetRemoveButtons();
+        setVisible(e.getEmbeddable() != null);
+    }
+
+    public void currentEmbeddableAttributeChanged(EmbeddableAttributeDisplayEvent e) {
+        if (e.getEmbeddable() == null)
+            return;
+
+        EmbeddableAttribute[] attrs = e.getEmbeddableAttributes();
+        EmbeddableAttribute[] embAttrs = new EmbeddableAttribute[attrs.length];
+
+        System.arraycopy(attrs, 0, embAttrs, 0, attrs.length);
+
+        if (getSelectedComponent() != attributesPanel && embAttrs.length > 0) {
+            setSelectedComponent(attributesPanel);
+            attributesPanel.setVisible(true);
+        }
+
+        attributesPanel.selectAttributes(embAttrs);
+    }
+}

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityTabbedView.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityTabbedView.java?rev=810422&r1=810421&r2=810422&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityTabbedView.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityTabbedView.java Wed Sep  2 08:52:39 2009
@@ -82,7 +82,7 @@
 
         entityPanel = new JScrollPane(new ObjEntityTab(mediator));
         addTab("Entity", entityPanel);
-        
+
         attributesPanel = new ObjEntityAttributeTab(mediator);
         addTab("Attributes", attributesPanel);
 
@@ -118,7 +118,7 @@
     }
 
     /** Reset the remove buttons */
-    private void resetRemoveButtons(){
+    private void resetRemoveButtons() {
         Application app = Application.getInstance();
         app.getAction(RemoveAttributeAction.getActionName()).setEnabled(false);
         app.getAction(RemoveRelationshipAction.getActionName()).setEnabled(false);
@@ -127,6 +127,7 @@
 
     public void currentObjEntityChanged(EntityDisplayEvent e) {
         Entity entity = e.getEntity();
+
         if (e.isMainTabFocus() && entity instanceof ObjEntity) {
             if (getSelectedComponent() != entityPanel) {
                 setSelectedComponent(entityPanel);
@@ -146,14 +147,14 @@
         // update relationship selection
         Relationship[] rels = e.getRelationships();
         ObjRelationship[] objRels = new ObjRelationship[rels.length];
-        
+
         System.arraycopy(rels, 0, objRels, 0, rels.length);
-        
+
         if (getSelectedComponent() != relationshipsPanel && objRels.length > 0) {
             setSelectedComponent(relationshipsPanel);
             relationshipsPanel.setVisible(true);
         }
-        
+
         relationshipsPanel.selectRelationships(objRels);
     }
 
@@ -164,14 +165,14 @@
         // update relationship selection
         Attribute[] attrs = e.getAttributes();
         ObjAttribute[] objAttrs = new ObjAttribute[attrs.length];
-        
+
         System.arraycopy(attrs, 0, objAttrs, 0, attrs.length);
-        
+
         if (getSelectedComponent() != attributesPanel && objAttrs.length > 0) {
             setSelectedComponent(attributesPanel);
             attributesPanel.setVisible(true);
         }
-        
+
         attributesPanel.selectAttributes(objAttrs);
     }
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/AttributeDisplayEvent.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/AttributeDisplayEvent.java?rev=810422&r1=810421&r2=810422&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/AttributeDisplayEvent.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/AttributeDisplayEvent.java Wed Sep  2 08:52:39 2009
@@ -27,6 +27,7 @@
 /** 
   */
 public class AttributeDisplayEvent extends EntityDisplayEvent {
+   
     protected Attribute[] attributes;
     
     public AttributeDisplayEvent(

Copied: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/EmbeddableAttributeDisplayEvent.java (from r809002, cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/AttributeDisplayEvent.java)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/EmbeddableAttributeDisplayEvent.java?p2=cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/EmbeddableAttributeDisplayEvent.java&p1=cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/AttributeDisplayEvent.java&r1=809002&r2=810422&rev=810422&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/AttributeDisplayEvent.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/EmbeddableAttributeDisplayEvent.java Wed Sep  2 08:52:39 2009
@@ -1,4 +1,3 @@
-package org.apache.cayenne.modeler.event;
 /*****************************************************************
  *   Licensed to the Apache Software Foundation (ASF) under one
  *  or more contributor license agreements.  See the NOTICE file
@@ -17,41 +16,40 @@
  *  specific language governing permissions and limitations
  *  under the License.
  ****************************************************************/
-
+package org.apache.cayenne.modeler.event;
 
 import org.apache.cayenne.access.DataDomain;
-import org.apache.cayenne.map.Attribute;
 import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.Entity;
+import org.apache.cayenne.map.Embeddable;
+import org.apache.cayenne.map.EmbeddableAttribute;
+
+public class EmbeddableAttributeDisplayEvent extends EmbeddableDisplayEvent {
+
+    protected EmbeddableAttribute[] embeddableAttributes;
 
-/** 
-  */
-public class AttributeDisplayEvent extends EntityDisplayEvent {
-    protected Attribute[] attributes;
-    
-    public AttributeDisplayEvent(
-            Object src,
-            Attribute attribute,
-            Entity entity,
-            DataMap dataMap,
-            DataDomain domain) {
-        
-            super(src, entity, dataMap, domain);
-            attributes = new Attribute[] { attribute };
+    public EmbeddableAttributeDisplayEvent(Object src, Embeddable embeddable,
+            EmbeddableAttribute attr, DataMap dataMap, DataDomain domain) {
+
+        super(src, embeddable, dataMap, domain);
+        embeddableAttributes = new EmbeddableAttribute[] {
+            attr
+        };
     }
 
-    public AttributeDisplayEvent(
-        Object src,
-        Attribute[] attributes,
-        Entity entity,
-        DataMap dataMap,
-        DataDomain domain) {
+    public EmbeddableAttributeDisplayEvent(Object src, Embeddable embeddable,
+            EmbeddableAttribute[] attr, DataMap dataMap, DataDomain domain) {
+        super(src, embeddable, dataMap, domain);
+        this.embeddableAttributes = attr;
+    }
 
-        super(src, entity, dataMap, domain);
-        this.attributes = attributes;
+    public EmbeddableAttributeDisplayEvent(Object src, Embeddable embeddable,
+            EmbeddableAttribute[] attr) {
+        super(src, embeddable, null, null);
+        this.embeddableAttributes = attr;
     }
-    
-    public Attribute[] getAttributes() {
-        return attributes;
+
+    public EmbeddableAttribute[] getEmbeddableAttributes() {
+        return embeddableAttributes;
     }
+
 }

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/EmbeddableAttributeDisplayListener.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/EmbeddableAttributeDisplayListener.java?rev=810422&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/EmbeddableAttributeDisplayListener.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/EmbeddableAttributeDisplayListener.java Wed Sep  2 08:52:39 2009
@@ -0,0 +1,27 @@
+/*****************************************************************
+ *   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.event;
+
+import java.util.EventListener;
+
+
+public interface EmbeddableAttributeDisplayListener extends EventListener{
+   
+    public void currentEmbeddableAttributeChanged(EmbeddableAttributeDisplayEvent e);
+}

Copied: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/EmbeddableDisplayEvent.java (from r809002, cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/AttributeDisplayEvent.java)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/EmbeddableDisplayEvent.java?p2=cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/EmbeddableDisplayEvent.java&p1=cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/AttributeDisplayEvent.java&r1=809002&r2=810422&rev=810422&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/AttributeDisplayEvent.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/event/EmbeddableDisplayEvent.java Wed Sep  2 08:52:39 2009
@@ -1,4 +1,3 @@
-package org.apache.cayenne.modeler.event;
 /*****************************************************************
  *   Licensed to the Apache Software Foundation (ASF) under one
  *  or more contributor license agreements.  See the NOTICE file
@@ -17,41 +16,43 @@
  *  specific language governing permissions and limitations
  *  under the License.
  ****************************************************************/
-
+package org.apache.cayenne.modeler.event;
 
 import org.apache.cayenne.access.DataDomain;
-import org.apache.cayenne.map.Attribute;
 import org.apache.cayenne.map.DataMap;
-import org.apache.cayenne.map.Entity;
+import org.apache.cayenne.map.Embeddable;
+
+public class EmbeddableDisplayEvent extends DataMapDisplayEvent {
+
+    protected Embeddable embeddable;
+    protected boolean embeddableChanged = true;
+
+    protected boolean mainTabFocus;
+
+    public EmbeddableDisplayEvent(Object src, Embeddable embeddable, DataMap dataMap,
+            DataDomain dataDomain) {
+        super(src, dataMap, dataDomain);
+        this.embeddable = embeddable;
+        setDataMapChanged(false);
+    }
+
+    public Embeddable getEmbeddable() {
+        return embeddable;
+    }
+
+    public boolean isMainTabFocus() {
+        return mainTabFocus;
+    }
+
+    public void setMainTabFocus(boolean mainTabFocus) {
+        this.mainTabFocus = mainTabFocus;
+    }
+
+    public boolean isEmbeddableChanged() {
+        return embeddableChanged;
+    }
 
-/** 
-  */
-public class AttributeDisplayEvent extends EntityDisplayEvent {
-    protected Attribute[] attributes;
-    
-    public AttributeDisplayEvent(
-            Object src,
-            Attribute attribute,
-            Entity entity,
-            DataMap dataMap,
-            DataDomain domain) {
-        
-            super(src, entity, dataMap, domain);
-            attributes = new Attribute[] { attribute };
-    }
-
-    public AttributeDisplayEvent(
-        Object src,
-        Attribute[] attributes,
-        Entity entity,
-        DataMap dataMap,
-        DataDomain domain) {
-
-        super(src, entity, dataMap, domain);
-        this.attributes = attributes;
-    }
-    
-    public Attribute[] getAttributes() {
-        return attributes;
+    public void setEmbeddableChanged(boolean temp) {
+        this.embeddableChanged = temp;
     }
 }