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/06/17 09:40:55 UTC

svn commit: r785495 - in /cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler: ./ action/ dialog/autorelationship/

Author: aadamchik
Date: Wed Jun 17 07:40:55 2009
New Revision: 785495

URL: http://svn.apache.org/viewvc?rev=785495&view=rev
Log:
CAY-1220 A function to auto-map the DB relationships

patch by Dima Loiko InferRelationships_2.1.txt

Added:
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/InferRelationshipsAction.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationships.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsControllerBase.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsDialog.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsPanel.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsTabController.java
Modified:
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ActionManager.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerFrame.java

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ActionManager.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ActionManager.java?rev=785495&r1=785494&r2=785495&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ActionManager.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ActionManager.java Wed Jun 17 07:40:55 2009
@@ -65,6 +65,7 @@
 import org.apache.cayenne.modeler.action.ImportDBAction;
 import org.apache.cayenne.modeler.action.ImportDataMapAction;
 import org.apache.cayenne.modeler.action.ImportEOModelAction;
+import org.apache.cayenne.modeler.action.InferRelationshipsAction;
 import org.apache.cayenne.modeler.action.MigrateAction;
 import org.apache.cayenne.modeler.action.NavigateBackwardAction;
 import org.apache.cayenne.modeler.action.NavigateForwardAction;
@@ -128,7 +129,7 @@
                 CreateProcedureAction.getActionName(),
                 GenerateDBAction.getActionName(),
                 MigrateAction.getActionName(),
-                
+                InferRelationshipsAction.getActionName(),
                 CutAction.getActionName(),
                 CopyAction.getActionName()));
     }
@@ -212,6 +213,7 @@
         registerAction(new DbEntitySyncAction(application));
         registerAction(new ObjEntitySyncAction(application));
         registerAction(new ImportDBAction(application));
+        registerAction(new InferRelationshipsAction(application));
         registerAction(new ImportEOModelAction(application));
         registerAction(new GenerateDBAction(application));
         registerAction(new MigrateAction(application));

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerFrame.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerFrame.java?rev=785495&r1=785494&r2=785495&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerFrame.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerFrame.java Wed Jun 17 07:40:55 2009
@@ -64,6 +64,7 @@
 import org.apache.cayenne.modeler.action.ImportDBAction;
 import org.apache.cayenne.modeler.action.ImportDataMapAction;
 import org.apache.cayenne.modeler.action.ImportEOModelAction;
+import org.apache.cayenne.modeler.action.InferRelationshipsAction;
 import org.apache.cayenne.modeler.action.MigrateAction;
 import org.apache.cayenne.modeler.action.NavigateBackwardAction;
 import org.apache.cayenne.modeler.action.NavigateForwardAction;
@@ -222,6 +223,7 @@
         projectMenu.add(getAction(RemoveAction.getActionName()).buildMenu());
 
         toolMenu.add(getAction(ImportDBAction.getActionName()).buildMenu());
+        toolMenu.add(getAction(InferRelationshipsAction.getActionName()).buildMenu());
         toolMenu.add(getAction(ImportEOModelAction.getActionName()).buildMenu());
         toolMenu.addSeparator();
         toolMenu.add(getAction(GenerateCodeAction.getActionName()).buildMenu());

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/InferRelationshipsAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/InferRelationshipsAction.java?rev=785495&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/InferRelationshipsAction.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/InferRelationshipsAction.java Wed Jun 17 07:40:55 2009
@@ -0,0 +1,61 @@
+/*****************************************************************
+ *   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.action;
+
+import java.awt.event.ActionEvent;
+
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.dialog.autorelationship.InferRelationshipsController;
+import org.apache.cayenne.modeler.dialog.codegen.CodeGeneratorController;
+import org.apache.cayenne.modeler.util.CayenneAction;
+import org.apache.cayenne.project.ProjectPath;
+
+
+public class InferRelationshipsAction extends CayenneAction {
+
+    public static final String getActionName() {
+        return "Infer Relationships";
+    }
+    
+    /**
+     * Constructor for ShowLogConsoleAction.
+     */
+    public InferRelationshipsAction(Application application) {
+        super(getActionName(), application);
+    }
+    
+    @Override
+    public void performAction(ActionEvent e) {
+        DataMap dataMap = getProjectController().getCurrentDataMap();
+        if (dataMap != null) {
+            new InferRelationshipsController(getApplication().getFrameController(), dataMap)
+                    .startup();
+        }
+    }
+    
+    public boolean enableForPath(ProjectPath path) {
+        if (path == null) {
+            return false;
+        }
+
+        return path.firstInstanceOf(DataMap.class) != null;
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationships.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationships.java?rev=785495&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationships.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationships.java Wed Jun 17 07:40:55 2009
@@ -0,0 +1,83 @@
+/*****************************************************************
+ *   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.dialog.autorelationship;
+
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+
+
+public class InferRelationships {
+    private DbEntity source;
+    private DbEntity target;
+    private DbAttribute joinSource;
+    private DbAttribute joinTarget;
+    private String name;
+    private boolean toMany;
+    
+    
+    public boolean isToMany() {
+        return toMany;
+    }
+
+    
+    public void setToMany(boolean toMany) {
+        this.toMany = toMany;
+    }
+
+    public DbEntity getSource() {
+        return source;
+    }
+    
+    public void setSource(DbEntity source) {
+        this.source = source;
+    }
+    
+    public DbEntity getTarget() {
+        return target;
+    }
+    
+    public void setTarget(DbEntity target) {
+        this.target = target;
+    }
+    
+    public DbAttribute getJoinSource() {
+        return joinSource;
+    }
+    
+    public void setJoinSource(DbAttribute joinSource) {
+        this.joinSource = joinSource;
+    }
+    
+    public DbAttribute getJoinTarget() {
+        return joinTarget;
+    }
+    
+    public void setJoinTarget(DbAttribute joinTarget) {
+        this.joinTarget = joinTarget;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java?rev=785495&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java Wed Jun 17 07:40:55 2009
@@ -0,0 +1,144 @@
+/*****************************************************************
+ *   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.dialog.autorelationship;
+
+import java.awt.Component;
+
+import org.apache.cayenne.access.DbLoader;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbJoin;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.Entity;
+import org.apache.cayenne.map.event.MapEvent;
+import org.apache.cayenne.map.event.RelationshipEvent;
+import org.apache.cayenne.map.naming.BasicNamingStrategy;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.CayenneModelerController;
+import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.action.CreateRelationshipAction;
+import org.apache.cayenne.modeler.dialog.ErrorDebugDialog;
+import org.apache.cayenne.modeler.util.CayenneController;
+import org.apache.cayenne.modeler.util.ProjectUtil;
+import org.apache.cayenne.project.NamedObjectFactory;
+import org.apache.cayenne.swing.BindingBuilder;
+import org.apache.cayenne.util.Util;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class InferRelationshipsController extends InferRelationshipsControllerBase {
+
+    private static Log logObj = LogFactory.getLog(ErrorDebugDialog.class);
+
+    protected InferRelationshipsDialog view;
+
+    protected InferRelationshipsTabController entitySelector;
+
+    public InferRelationshipsController(CayenneController parent, DataMap dataMap) {
+        super(parent, dataMap);
+
+        this.entitySelector = new InferRelationshipsTabController(this);
+    }
+
+    @Override
+    public Component getView() {
+        return view;
+    }
+
+    public void startup() {
+        // show dialog even on empty DataMap, as custom generation may still take
+        // advantage of it
+
+        view = new InferRelationshipsDialog(entitySelector.getView());
+        initBindings();
+
+        view.pack();
+        view.setModal(true);
+        centerView();
+        makeCloseableOnEscape();
+        view.setVisible(true);
+    }
+
+    protected void initBindings() {
+        BindingBuilder builder = new BindingBuilder(
+                getApplication().getBindingFactory(),
+                this);
+
+        builder.bindToAction(view.getCancelButton(), "cancelAction()");
+        builder.bindToAction(view.getGenerateButton(), "generateAction()");
+        builder.bindToAction(this, "entitySelectedAction()", SELECTED_PROPERTY);
+    }
+
+    public void entitySelectedAction() {
+        int size = getSelectedEntitiesSize();
+        String label;
+
+        if (size == 0) {
+            label = "No entities selected";
+        }
+        else if (size == 1) {
+            label = "One entity selected";
+        }
+        else {
+            label = size + " entities selected";
+        }
+
+        view.getEntityCount().setText(label);
+    }
+
+    public void cancelAction() {
+        view.dispose();
+    }
+
+    public void generateAction() {
+        ProjectController mediator = application
+                .getFrameController()
+                .getProjectController();
+        for (InferRelationships temp : selectedEntities) {
+            DbRelationship rel = new DbRelationship(uniqueRelName(temp.getSource(), temp
+                    .getName()));
+
+            RelationshipEvent e = new RelationshipEvent(Application.getFrame(), rel, temp
+                    .getSource(), MapEvent.ADD);
+            mediator.fireDbRelationshipEvent(e);
+
+            rel.setSourceEntity(temp.getSource());
+            rel.setTargetEntity(temp.getTarget());
+            DbJoin join = new DbJoin(rel, temp.getJoinSource().getName(), temp
+                    .getJoinTarget()
+                    .getName());
+            rel.addJoin(join);
+            rel.setToMany(temp.isToMany());
+            temp.getSource().addRelationship(rel);
+        }
+    }
+
+    private String uniqueRelName(Entity entity, String preferredName) {
+        int currentSuffix = 1;
+        String relName = preferredName;
+
+        while (entity.getRelationship(relName) != null
+                || entity.getAttribute(relName) != null) {
+            relName = preferredName + currentSuffix;
+            currentSuffix++;
+        }
+        return relName;
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsControllerBase.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsControllerBase.java?rev=785495&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsControllerBase.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsControllerBase.java Wed Jun 17 07:40:55 2009
@@ -0,0 +1,253 @@
+/*****************************************************************
+ *   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.dialog.autorelationship;
+
+import java.awt.Component;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbJoin;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.Relationship;
+import org.apache.cayenne.map.naming.BasicNamingStrategy;
+import org.apache.cayenne.map.naming.ExportedKey;
+import org.apache.cayenne.map.naming.NamingStrategy;
+import org.apache.cayenne.modeler.util.CayenneController;
+import org.apache.cayenne.project.NamedObjectFactory;
+import org.apache.cayenne.validation.ValidationFailure;
+import org.apache.cayenne.validation.ValidationResult;
+import org.apache.commons.collections.Predicate;
+
+public class InferRelationshipsControllerBase extends CayenneController {
+
+    public static final String SELECTED_PROPERTY = "selected";
+
+    protected DataMap dataMap;
+
+    protected List<InferRelationships> ir;
+
+    protected List<DbEntity> entities;
+    protected Set<InferRelationships> selectedEntities;
+    protected int index = 0;
+    protected BasicNamingStrategy strategy;
+
+    protected transient InferRelationships currentEntity;
+    protected transient Integer entityNumber;
+
+    public InferRelationshipsControllerBase(CayenneController parent, DataMap dataMap) {
+        super(parent);
+
+        this.dataMap = dataMap;
+        this.entities = new ArrayList(dataMap.getDbEntities());
+        this.selectedEntities = new HashSet();
+        setRelationships();
+        createJoin();
+        createName();
+
+    }
+
+    public void setRelationships() {
+        ir = new ArrayList<InferRelationships>();
+        strategy = new BasicNamingStrategy();
+        for (DbEntity entity : entities) {
+            createRelationships(entity);
+        }
+    }
+
+    public void createRelationships(DbEntity entity) {
+        Collection<DbAttribute> attr = entity.getAttributes();
+
+        for (DbAttribute attribute : attr) {
+
+            for (DbEntity myEntity : entities) {
+                if ((attribute.getName().equalsIgnoreCase(myEntity.getName() + "_ID"))
+                        && (!attribute.isPrimaryKey())
+                        && (myEntity.getAttributes().size() != 0)) {
+                    if (!attribute.isForeignKey()) {
+                        InferRelationships myir = new InferRelationships();
+                        myir.setSource(entity);
+                        myir.setTarget(myEntity);
+                        ir.add(myir);
+                    }
+                    createReversRelationship(myEntity, entity);
+                }
+            }
+
+        }
+    }
+
+    public void createReversRelationship(DbEntity eSourse, DbEntity eTarget) {
+        InferRelationships myir = new InferRelationships();
+        for (Relationship relationship : eSourse.getRelationships()) {
+            for (DbJoin join : ((DbRelationship) relationship).getJoins()) {
+                if (((DbEntity) join.getSource().getEntity()).equals(eSourse)
+                        && ((DbEntity) join.getTarget().getEntity()).equals(eTarget)) {
+                    return;
+                }
+            }
+        }
+        myir.setSource(eSourse);
+        myir.setTarget(eTarget);
+        ir.add(myir);
+    }
+
+    public String getJoin(InferRelationships irItem) {
+        return irItem.getJoinSource().getName()
+                + " : "
+                + irItem.getJoinTarget().getName();
+    }
+
+    public DbAttribute getJoinAttribute(DbEntity sEntity, DbEntity tEntity) {
+        if (sEntity.getAttributes().size() == 1) {
+            return sEntity.getAttributes().iterator().next();
+        }
+        else {
+            for (DbAttribute attr : sEntity.getAttributes()) {
+                if (attr.getName().equalsIgnoreCase(tEntity.getName() + "_ID")) {
+                    return attr;
+                }
+            }
+
+            for(DbAttribute attr : sEntity.getAttributes()){
+                if(attr.isPrimaryKey()){
+                    return attr;
+                }
+            }
+        }
+        return null;
+    }
+
+    public void createJoin() {
+        for (InferRelationships myir : ir) {
+            DbAttribute temp = getJoinAttribute(myir.getSource(), myir.getTarget());
+            myir.setJoinSource(temp);
+            if (temp.isPrimaryKey()) {
+                myir.setToMany(true);
+            }
+            myir.setJoinTarget(getJoinAttribute(myir.getTarget(), myir.getSource()));
+        }
+
+    }
+
+    public void createName() {
+        for (InferRelationships myir : ir) {
+            ExportedKey key = new ExportedKey(myir.getSource().getName(), myir
+                    .getJoinSource()
+                    .getName(), null, myir.getTarget().getName(), myir
+                    .getJoinTarget()
+                    .getName(), null);
+            myir.setName(strategy.createDbRelationshipName(key, myir.isToMany()));
+        }
+    }
+
+    public List<InferRelationships> getSelectedEntities() {
+        List<InferRelationships> selected = new ArrayList<InferRelationships>(
+                selectedEntities.size());
+
+        for (InferRelationships entity : ir) {
+            if (selectedEntities.contains(entity)) {
+                selected.add(entity);
+            }
+        }
+
+        return selected;
+    }
+
+    public boolean updateSelection(Predicate predicate) {
+        boolean modified = false;
+
+        for (InferRelationships entity : ir) {
+            boolean select = predicate.evaluate(entity);
+
+            if (select) {
+                if (selectedEntities.add(entity)) {
+                    modified = true;
+                }
+            }
+            else {
+                if (selectedEntities.remove(entity)) {
+                    modified = true;
+                }
+            }
+        }
+
+        if (modified) {
+            firePropertyChange(SELECTED_PROPERTY, null, null);
+        }
+
+        return modified;
+    }
+
+    public boolean isSelected() {
+        return currentEntity != null ? selectedEntities.contains(currentEntity) : false;
+    }
+
+    public void setSelected(boolean selectedFlag) {
+        if (currentEntity == null) {
+            return;
+        }
+
+        if (selectedFlag) {
+            if (selectedEntities.add(currentEntity)) {
+                firePropertyChange(SELECTED_PROPERTY, null, null);
+            }
+        }
+        else {
+            if (selectedEntities.remove(currentEntity)) {
+                firePropertyChange(SELECTED_PROPERTY, null, null);
+            }
+        }
+    }
+
+    public int getSelectedEntitiesSize() {
+        return selectedEntities.size();
+    }
+
+    public List getEntities() {
+        return ir;
+    }
+
+    public InferRelationships getCurrentEntity() {
+        return currentEntity;
+    }
+
+    public void setCurrentEntity(InferRelationships currentEntity) {
+        this.currentEntity = currentEntity;
+    }
+
+    public DataMap getDataMap() {
+        return dataMap;
+    }
+
+    @Override
+    public Component getView() {
+        return null;
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsDialog.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsDialog.java?rev=785495&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsDialog.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsDialog.java Wed Jun 17 07:40:55 2009
@@ -0,0 +1,81 @@
+/*****************************************************************
+ *   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.dialog.autorelationship;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.FlowLayout;
+
+import javax.swing.Box;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import javax.swing.SwingConstants;
+
+import org.apache.cayenne.modeler.Application;
+
+
+public class InferRelationshipsDialog extends JDialog {
+
+    protected JButton generateButton;
+    protected JButton cancelButton;
+    protected JLabel entityCount;
+    
+    public InferRelationshipsDialog(Component entitySelectorPanel) {
+        super(Application.getFrame());
+        this.generateButton = new JButton("Generate");
+        this.cancelButton = new JButton("Cancel");
+        this.entityCount = new JLabel("No Relationships selected");
+        entityCount.setFont(entityCount.getFont().deriveFont(10f));
+
+        // assemble
+       
+
+        JPanel messages = new JPanel(new BorderLayout());
+        messages.add(entityCount, BorderLayout.WEST);
+
+        JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+        buttons.add(entityCount);
+        buttons.add(Box.createHorizontalStrut(50));
+        buttons.add(cancelButton);
+        buttons.add(generateButton);
+
+        Container contentPane = getContentPane();
+        contentPane.setLayout(new BorderLayout());
+        contentPane.add(entitySelectorPanel, BorderLayout.CENTER);
+        contentPane.add(buttons, BorderLayout.SOUTH);
+
+        setTitle("Infer Relationships");
+    }
+    
+    public JButton getCancelButton() {
+        return cancelButton;
+    }
+
+    public JButton getGenerateButton() {
+        return generateButton;
+    }
+
+    public JLabel getEntityCount() {
+        return entityCount;
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsPanel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsPanel.java?rev=785495&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsPanel.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsPanel.java Wed Jun 17 07:40:55 2009
@@ -0,0 +1,90 @@
+/*****************************************************************
+ *   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.dialog.autorelationship;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+
+import javax.swing.AbstractButton;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.ScrollPaneConstants;
+
+
+public class InferRelationshipsPanel extends JPanel {
+    
+    protected JTable table;
+    protected JCheckBox checkAll;
+    protected JLabel checkAllLabel;
+    
+    public InferRelationshipsPanel() {
+        this.table = new JTable();
+
+        // TODO: andrus 04/07/2006 - is there an easy way to stick that checkbox in the
+        // table header????
+        this.checkAll = new JCheckBox();
+        this.checkAllLabel = new JLabel("Check All DBRelationships");
+
+        checkAll.addItemListener(new ItemListener() {
+
+            public void itemStateChanged(ItemEvent event) {
+                if (checkAll.isSelected()) {
+                    checkAllLabel.setText("Uncheck All DBRelationships");
+                }
+                else {
+                    checkAllLabel.setText("Check All DBRelationships");
+                }
+            }
+        });
+
+        // assemble
+        JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
+        topPanel.add(checkAll);
+        topPanel.add(checkAllLabel);
+
+        JScrollPane tablePanel = new JScrollPane(
+                table,
+                ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
+                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
+
+        // set some minimal preferred size, so that it is smaller than other forms used in
+        // the dialog... this way we get the right automated overall size
+        tablePanel.setPreferredSize(new Dimension(600, 400));
+
+        setLayout(new BorderLayout());
+        add(topPanel, BorderLayout.NORTH);
+        add(tablePanel, BorderLayout.CENTER);
+        
+    }
+
+    public JTable getTable() {
+        return table;
+    }
+
+    public JCheckBox getCheckAll() {
+        return checkAll;
+    }
+
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsTabController.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsTabController.java?rev=785495&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsTabController.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsTabController.java Wed Jun 17 07:40:55 2009
@@ -0,0 +1,136 @@
+/*****************************************************************
+ *   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.dialog.autorelationship;
+
+import java.awt.Component;
+
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.table.TableColumn;
+
+import org.apache.cayenne.modeler.util.CayenneController;
+import org.apache.cayenne.swing.BindingBuilder;
+import org.apache.cayenne.swing.ObjectBinding;
+import org.apache.cayenne.swing.TableBindingBuilder;
+import org.apache.commons.collections.Predicate;
+import org.apache.commons.collections.PredicateUtils;
+
+
+public class InferRelationshipsTabController extends CayenneController{
+    public static final String GENERATE_PROPERTY = "generate";
+
+    protected InferRelationshipsPanel view;
+    protected ObjectBinding tableBinding;
+
+    public InferRelationshipsTabController(InferRelationshipsControllerBase parent) {
+        super(parent);
+
+        this.view = new InferRelationshipsPanel();
+        initBindings();
+    }
+
+    protected InferRelationshipsControllerBase getParentController() {
+        return (InferRelationshipsControllerBase) getParent();
+    }
+
+    public Component getView() {
+        return view;
+    }
+
+    protected void initBindings() {
+
+        BindingBuilder builder = new BindingBuilder(
+                getApplication().getBindingFactory(),
+                this);
+        builder.bindToAction(view.getCheckAll(), "checkAllAction()");
+
+        TableBindingBuilder tableBuilder = new TableBindingBuilder(builder);
+        
+        tableBuilder.addColumn(
+                "",
+                "parent.setCurrentEntity(#item), selected",
+                Boolean.class,
+                true,
+                Boolean.TRUE);
+        tableBuilder.addColumn(
+                "Source",
+                "#item.getSource().getName()",
+                String.class,
+                false,
+                "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+
+        tableBuilder.addColumn(
+                "Target",
+                "#item.getTarget().getName()",
+                String.class,
+                false,
+                "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+        tableBuilder.addColumn(
+                "Join",
+                "parent.getJoin(#item)",
+                String.class,
+                false,
+                "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+        tableBuilder.addColumn(
+                "Name",
+                "#item.getName()",
+                String.class,
+                false,
+                "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+        this.tableBinding = tableBuilder.bindToTable(view.getTable(), "parent.entities");
+    }
+
+    public boolean isSelected() {
+        return getParentController().isSelected();
+    }
+
+    public void setSelected(boolean selected) {
+        getParentController().setSelected(selected);
+        entitySelectedAction();
+    }
+
+    /**
+     * A callback action that updates the state of Select All checkbox.
+     */
+    public void entitySelectedAction() {
+        int selectedCount = getParentController().getSelectedEntitiesSize();
+
+        if (selectedCount == 0) {
+            view.getCheckAll().setSelected(false);
+        }
+        else if (selectedCount == getParentController().getEntities().size()) {
+            view.getCheckAll().setSelected(true);
+        }
+    }
+
+    /**
+     * An action that updates entity check boxes in response to the Select All state
+     * change.
+     */
+    public void checkAllAction() {
+
+        Predicate predicate = view.getCheckAll().isSelected() ? PredicateUtils
+                .truePredicate() : PredicateUtils.falsePredicate();
+
+        if (getParentController().updateSelection(predicate)) {
+            tableBinding.updateView();
+        }
+    }
+}
+