cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dkazimirc...@apache.org
Subject svn commit: r1141850 - in /cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler: dialog/objentity/ editor/
Date Fri, 01 Jul 2011 07:36:43 GMT
Author: dkazimirchyk
Date: Fri Jul  1 07:36:43 2011
New Revision: 1141850

URL: http://svn.apache.org/viewvc?rev=1141850&view=rev
Log:
CAY-1461 CayenneModeler: remove ScopeMVC dependency - ObjRelationshipInfoDialog

patches by Rostislav with some edits
removed scopemvc dependencies from ObjRelationshipInfo and DbRelationshipTarget dialogs

Added:
    cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/DbRelationshipTarget.java
    cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/DbRelationshipTargetView.java
    cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfo.java
    cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfoView.java
Removed:
    cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/DbRelationshipTargetController.java
    cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/DbRelationshipTargetDialog.java
    cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/DbRelationshipTargetModel.java
    cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfoController.java
    cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfoDialog.java
    cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfoModel.java
Modified:
    cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipTab.java

Added: cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/DbRelationshipTarget.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/DbRelationshipTarget.java?rev=1141850&view=auto
==============================================================================
--- cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/DbRelationshipTarget.java
(added)
+++ cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/DbRelationshipTarget.java
Fri Jul  1 07:36:43 2011
@@ -0,0 +1,171 @@
+/*****************************************************************
+ *   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.objentity;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.swing.JOptionPane;
+import javax.swing.WindowConstants;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.util.CayenneController;
+import org.apache.cayenne.modeler.util.Comparators;
+
+public class DbRelationshipTarget extends CayenneController{
+    
+    private DbEntity source1;
+    private DbEntity source2;
+    protected DbEntity relTarget;
+    protected List<DbEntity> relTargets;
+    
+    protected DbEntity source;
+    protected ProjectController mediator;
+    protected boolean source1Selected;
+    protected DbRelationshipTargetView view;
+    protected boolean toMany;
+    protected boolean savePressed;
+    
+    @SuppressWarnings("unchecked")
+    public DbRelationshipTarget(ProjectController mediator,DbEntity source1, DbEntity source2)
{
+        super(mediator);
+        view = new DbRelationshipTargetView(source1, source2);
+        initController();
+        view.getSource1Button().setSelected(true);
+        view.getToManyCheckBox().setSelected(false);
+        setSource(source1, true);
+        this.mediator = mediator;
+        this.source1 = source1;
+        this.source2 = source2;
+        this.relTargets = new ArrayList<DbEntity>(source1.getDataMap().getDbEntities());
+        Collections.sort(relTargets, Comparators.getNamedObjectComparator());
+        view.targetCombo.removeAllItems();
+        for (DbEntity d : relTargets) {
+            view.targetCombo.addItem(d.getName());
+        }
+    }
+        
+    private void initController() {
+        view.getCancelButton().addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                view.dispose();
+            }
+        });
+        view.getSaveButton().addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                save();
+            }
+        });
+        view.getSource1Button().addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                setSource(source1, true);
+            }
+        });     
+        view.getSource2Button().addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                setSource(source2, false);
+            }
+        });   
+        view.getToManyCheckBox().addChangeListener(new ChangeListener() {
+            
+            public void stateChanged(ChangeEvent e) {
+                if (view.getToManyCheckBox().isSelected()) {
+                    toMany = true;
+                }
+                else {
+                    toMany = false;
+                }
+            }
+        });
+    }
+    
+    @Override
+    public Component getView() {
+        return view;
+    }
+    
+    protected void save() {
+             
+        this.relTarget = relTargets.get(view.targetCombo.getSelectedIndex());   
+        DbEntity target = getTarget();
+             
+        if (target == null) {
+            JOptionPane.showMessageDialog((Component) getView(), "Please select target entity
first.",
+                    "Warning", JOptionPane.WARNING_MESSAGE);
+            return;
+        }
+        
+        savePressed = true;
+        view.dispose();
+    }
+    
+    /**
+     * Creates and runs the dialog.
+     */
+    public void startupAction() {
+        view.pack();
+        view.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+        view.setModal(true);
+        makeCloseableOnEscape();
+        centerView();
+        view.setVisible(true);
+    }
+    
+    boolean isSavePressed() {
+        return savePressed;
+    }
+    
+    public List<DbEntity> getTargets() {
+        return relTargets;
+    }
+    
+    public DbEntity getTarget() {
+        return relTarget;
+    }
+    
+    public void setTarget(DbEntity newRelTarget) {
+        this.relTarget = newRelTarget;
+    }
+    
+    public boolean isSource1Selected() {
+        return source1Selected;
+    }
+    
+    public DbEntity getSource() {
+        return source;
+    }
+    
+    public void setSource(DbEntity source, boolean source1) {
+        this.source = source;
+        this.source1Selected = source1;
+    }
+    
+    public boolean isToMany() {
+        return toMany;
+    }
+}

Added: cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/DbRelationshipTargetView.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/DbRelationshipTargetView.java?rev=1141850&view=auto
==============================================================================
--- cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/DbRelationshipTargetView.java
(added)
+++ cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/DbRelationshipTargetView.java
Fri Jul  1 07:36:43 2011
@@ -0,0 +1,122 @@
+/*****************************************************************
+ *   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.objentity;
+
+import java.awt.BorderLayout;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JRadioButton;
+
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.modeler.util.DefaultWidgetFactory;
+import org.apache.cayenne.modeler.util.PanelFactory;
+import org.apache.cayenne.modeler.util.WidgetFactory;
+
+import com.jgoodies.forms.builder.PanelBuilder;
+import com.jgoodies.forms.layout.CellConstraints;
+import com.jgoodies.forms.layout.FormLayout;
+
+public class DbRelationshipTargetView extends JDialog {
+    
+    protected WidgetFactory widgetFactory;
+    protected JCheckBox toManyCheckBox ;
+    protected JButton saveButton;
+    protected JButton cancelButton ;
+    protected JRadioButton source1Button;
+    protected JRadioButton source2Button;
+    protected JComboBox targetCombo;
+    
+    public DbRelationshipTargetView(DbEntity source1, DbEntity source2) {
+        
+        widgetFactory = new DefaultWidgetFactory();
+        
+        // create widgets
+        saveButton = new JButton("Continue");
+        saveButton.setEnabled(true);
+
+        cancelButton = new JButton("Cancel");
+        cancelButton.setEnabled(true);
+                
+        targetCombo = widgetFactory.createComboBox();
+        targetCombo.setVisible(true);
+              
+        source1Button = new JRadioButton();
+        source2Button = new JRadioButton();
+        source2Button.setEnabled(source2 != null);
+        
+        ButtonGroup bg = new ButtonGroup();
+        bg.add(source1Button);
+        bg.add(source2Button);
+        
+        toManyCheckBox = new JCheckBox();
+        
+        setTitle("Create New DbRelationship");
+        setLayout(new BorderLayout());
+
+        CellConstraints cc = new CellConstraints();
+        PanelBuilder builder = new PanelBuilder(
+                new FormLayout(
+                        "right:max(100dlu;pref), 3dlu, fill:min(150dlu;pref)",
+                        "p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, top:p:grow"));
+        builder.setDefaultDialogBorder();
+        
+        builder.addLabel("Source: " + source1.getName(), cc.xy(1, 1));
+        builder.add(source1Button, cc.xy(3, 1));
+        
+        builder.addLabel("Source: " + (source2 == null ? "" : source2.getName()), cc.xy(1,
3));
+        builder.add(source2Button, cc.xy(3, 3));
+        
+        builder.addLabel("Target:", cc.xy(1, 5));
+        builder.add(targetCombo, cc.xywh(3, 5, 1, 1));
+        
+        builder.addLabel("To Many:", cc.xy(1, 7));
+        builder.add(toManyCheckBox, cc.xywh(3, 7, 1, 1));
+        
+        add(builder.getPanel(), BorderLayout.CENTER);
+        add(PanelFactory.createButtonPanel(new JButton[] {
+                saveButton, cancelButton
+            }), BorderLayout.SOUTH);
+    }
+    
+    public JRadioButton getSource1Button() {
+        return source1Button;
+    }
+    
+    public JRadioButton getSource2Button() {
+        return source2Button;
+    }
+    
+    public JButton getSaveButton()
+    {
+        return saveButton;
+    }
+    
+    public JButton getCancelButton()
+    {
+        return cancelButton;
+    }
+    
+    public JCheckBox getToManyCheckBox() {
+        return toManyCheckBox;
+    }
+}

Added: cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfo.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfo.java?rev=1141850&view=auto
==============================================================================
--- cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfo.java
(added)
+++ cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfo.java
Fri Jul  1 07:36:43 2011
@@ -0,0 +1,747 @@
+/*****************************************************************
+ *   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.objentity;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Vector;
+
+import javax.swing.JOptionPane;
+import javax.swing.WindowConstants;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.TreePath;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.map.Attribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.Entity;
+import org.apache.cayenne.map.ObjAttribute;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.map.Relationship;
+import org.apache.cayenne.map.event.RelationshipEvent;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.dialog.ResolveDbRelationshipDialog;
+import org.apache.cayenne.modeler.util.CayenneController;
+import org.apache.cayenne.modeler.util.Comparators;
+import org.apache.cayenne.modeler.util.EntityTreeFilter;
+import org.apache.cayenne.modeler.util.EntityTreeModel;
+import org.apache.cayenne.modeler.util.MultiColumnBrowser;
+import org.apache.cayenne.util.DeleteRuleUpdater;
+import org.apache.cayenne.util.NamedObjectFactory;
+import org.apache.cayenne.util.Util;
+
+public class ObjRelationshipInfo extends CayenneController implements
+    TreeSelectionListener {
+    
+    static final String COLLECTION_TYPE_MAP = "java.util.Map";
+    static final String COLLECTION_TYPE_SET = "java.util.Set";
+    static final String COLLECTION_TYPE_COLLECTION = "java.util.Collection";
+    static final String DEFAULT_MAP_KEY = "ID (default)";
+    
+    protected ObjRelationship relationship;
+    
+    protected List<DbRelationship> dbRelationships;
+
+    protected List<DbRelationship> savedDbRelationships;
+    protected ObjEntity objectTarget;
+    protected List<ObjEntity> objectTargets;
+    protected List<String> targetCollections;
+    protected List<String> mapKeys;
+    protected String relationshipName;
+    protected String targetCollection;
+    protected String mapKey;
+    protected ObjRelationshipInfoView view;
+    protected String currentPath;
+    protected ProjectController mediator;
+    
+    /**
+     * Starts options dialog.
+     */
+    public void startupAction() {
+        view.pack();
+        view.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+        view.setModal(true);
+        makeCloseableOnEscape();
+        centerView();
+        view.setVisible(true);
+    }
+   
+    public ObjRelationshipInfo(ProjectController mediator,ObjRelationship relationship) {
+        super(mediator);
+        this.view = new ObjRelationshipInfoView(mediator);
+        initController();
+        this.mediator=mediator;
+        ObjEntity target = getObjectTarget();
+        getPathBrowser().addTreeSelectionListener(this);
+        setObjectTarget(target);
+        view.sourceEntityLabel.setText(relationship.getSourceEntity().getName());    
+        this.relationship = relationship;
+        this.relationshipName = relationship.getName();
+        view.relationshipName.setText(relationshipName);
+        this.mapKey = relationship.getMapKey();
+        this.targetCollection = relationship.getCollectionType();
+        if (targetCollection == null) {
+            targetCollection = ObjRelationship.DEFAULT_COLLECTION_TYPE;
+        }
+
+        this.objectTarget = (ObjEntity) relationship.getTargetEntity();
+        if (objectTarget != null) {
+            updateTargetCombo(objectTarget.getDbEntity());
+        }
+
+        // validate -
+        // current limitation is that an ObjRelationship must have source
+        // and target entities present, with DbEntities chosen.
+        validateCanMap();
+
+        this.targetCollections = new ArrayList<String>(4);
+        targetCollections.add(COLLECTION_TYPE_COLLECTION);
+        targetCollections.add(ObjRelationship.DEFAULT_COLLECTION_TYPE);
+        targetCollections.add(COLLECTION_TYPE_MAP);
+        targetCollections.add(COLLECTION_TYPE_SET);
+        
+        for( ObjEntity s : objectTargets) {
+            view.targetCombo.addItem(s.getName());
+        }
+        
+        for( String s : targetCollections) {
+            view.collectionTypeCombo.addItem(s);
+        }
+       
+        this.mapKeys = new ArrayList<String>();
+        initMapKeys();
+        
+     
+        for(String s : mapKeys) {
+            view.mapKeysCombo.addItem(s);
+        }
+        view.collectionTypeCombo.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent action) {
+                updateCollectionChoosers();
+            }
+        });
+      
+        // setup path
+        dbRelationships = new ArrayList<DbRelationship>(relationship.getDbRelationships());
+        selectPath();
+       
+        // add dummy last relationship if we are not connected
+        connectEnds();
+        initFromModel();
+    }
+    
+    private void initController() {
+        view.getCancelButton().addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                view.dispose();
+            }
+        });
+        view.getSaveButton().addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                saveMapping();
+            }
+        });
+        view.getNewRelButton().addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                createRelationship();
+            }
+        });
+        view.getSelectPathButton().addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                selectPath();
+            }
+        });  
+    }
+    
+    void initFromModel() {
+        // called too early in the cycle...
+        if (!updateCollectionChoosers()) {
+            return;
+        }
+
+        if (view.pathBrowser.getModel() == null) {
+            EntityTreeModel treeModel = new EntityTreeModel(getStartEntity());
+            treeModel.setFilter(new EntityTreeFilter() {
+
+                public boolean attributeMatch(Object node, Attribute attr) {
+                    // attrs not allowed here
+                    return false;
+                }
+
+                public boolean relationshipMatch(Object node, Relationship rel) {
+                    if (!(node instanceof Relationship)) {
+                        return true;
+                    }
+
+                    /**
+                     * We do not allow A->B->A chains, where relationships are to-one
+                     */
+                    DbRelationship prev = (DbRelationship) node;
+                    return !(!rel.isToMany() && prev.getReverseRelationship() ==
rel);
+                }
+
+            });
+
+            view.pathBrowser.setModel(treeModel);
+
+            setSelectionPath(getSavedDbRelationships());
+        }
+    }
+    
+    /**
+     * Selects path in browser
+     */
+    void setSelectionPath(List<DbRelationship> rels) {
+        Object[] path = new Object[rels.size() + 1];
+        path[0] = getStartEntity();
+
+        System.arraycopy(rels.toArray(), 0, path, 1, rels.size());
+
+        view.pathBrowser.setSelectionPath(new TreePath(path));
+    }
+
+    @Override
+    public Component getView() {
+        return view;
+    }
+ 
+    public void setSavedDbRelationships(List<DbRelationship> rels) {
+        this.savedDbRelationships = rels;
+
+        String currPath = "";
+        for (DbRelationship rel : rels) {
+            currPath = "->" + rel.getName();
+        }
+
+        if (rels.size() > 0) {
+            currPath = currPath.substring(2);
+        }
+
+        currentPath = currPath;
+        view.currentPathLabel.setText(currPath);   
+    }
+    
+    public void selectPath() {
+        setSavedDbRelationships(new ArrayList<DbRelationship>(dbRelationships));
+    }
+
+    /**
+     * Reverts current path to saved path
+     */
+    protected void revertPath() {
+        setSelectionPath(getSavedDbRelationships());
+        setDbRelationships(getSavedDbRelationships());
+    }
+    
+    /**
+     * Updates 'collection type' and 'map keys' comboboxes
+     */
+    boolean updateCollectionChoosers() {
+        boolean collectionTypeEnabled = isToMany();
+        view.collectionTypeCombo.setEnabled(collectionTypeEnabled);
+        view.collectionTypeLabel.setEnabled(collectionTypeEnabled);
+
+        boolean mapKeysEnabled = collectionTypeEnabled
+                && ObjRelationshipInfo.COLLECTION_TYPE_MAP
+                        .equals(view.collectionTypeCombo.getSelectedItem());
+        view.mapKeysCombo.setEnabled(mapKeysEnabled);
+        view.mapKeysLabel.setEnabled(mapKeysEnabled);
+
+        return true;
+    }
+    
+    /**
+     * Clears paths and selections in browser
+     */
+    protected void clearPath() {
+        getPathBrowser().clearSelection();
+        setDbRelationships(new ArrayList<DbRelationship>());
+    }
+
+    protected void saveMapping() {
+        if (!getDbRelationships().equals(getSavedDbRelationships())) {
+            if (JOptionPane.showConfirmDialog(
+                    (Component) getView(),
+                    "You have changed Db Relationship path. Do you want it to be saved?",
+                    "Save ObjRelationship",
+                    JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
+                selectPath();
+            }
+        }
+
+        if (savePath()) {
+            mediator.fireObjRelationshipEvent(new RelationshipEvent(Application
+                    .getFrame(), getRelationship(), getRelationship()
+                    .getSourceEntity()));
+        }
+        view.sourceEntityLabel.setText(relationship.getSourceEntity().getName()); 
+        view.dispose();
+    }
+    
+    /**
+     * @return relationship path browser
+     */
+    public MultiColumnBrowser getPathBrowser() {
+        return view.pathBrowser;
+    }
+    
+    /**
+     * Creates a new relationship connecting currently selected source entity with
+     * ObjRelationship target entity. User is allowed to edit the relationship, change its
+     * name, and create joins.
+     */
+    protected void createRelationship() {
+      
+        DbRelationship dbRel = getLastRelationship();
+        DbEntity source = dbRel != null ? (DbEntity) dbRel.getTargetEntity() : null;
+
+        DbRelationshipTarget targetModel = new DbRelationshipTarget(mediator,
+                getStartEntity(),
+                source);
+        targetModel.startupAction();
+
+        if (!targetModel.isSavePressed()) {
+            return;
+        }
+
+        DbRelationship dbRelationship = (DbRelationship) NamedObjectFactory
+                .createRelationship(
+                        targetModel.getSource(),
+                        targetModel.getTarget(),
+                        targetModel.isToMany());
+
+        // note: NamedObjectFactory doesn't set source or target, just the name
+        dbRelationship.setSourceEntity(targetModel.getSource());
+        dbRelationship.setTargetEntity(targetModel.getTarget());
+        dbRelationship.setToMany(targetModel.isToMany());
+        targetModel.getSource().addRelationship(dbRelationship);
+
+        // TODO: creating relationship outside of ResolveDbRelationshipDialog confuses it
+        // to send incorrect event - CHANGE instead of ADD
+        ResolveDbRelationshipDialog dialog = new ResolveDbRelationshipDialog(
+                dbRelationship);
+
+        dialog.setVisible(true);
+        if (dialog.isCancelPressed()) {
+            targetModel.getSource().removeRelationship(dbRelationship.getName());
+        }
+        else {
+            MultiColumnBrowser pathBrowser = getPathBrowser();
+            Object[] oldPath = targetModel.isSource1Selected() ? new Object[] {
+                    getStartEntity()
+                } : pathBrowser.getSelectionPath().getPath();
+
+            /**
+             * Update the view
+             */
+            EntityTreeModel treeModel = (EntityTreeModel) pathBrowser.getModel();
+            treeModel.invalidate();
+
+            pathBrowser.setSelectionPath(new TreePath(new Object[] {
+                getStartEntity()
+            }));
+            pathBrowser.repaint();
+
+            Object[] path = new Object[oldPath.length + 1];
+            System.arraycopy(oldPath, 0, path, 0, path.length - 1);
+
+            path[path.length - 1] = dbRelationship;
+            pathBrowser.setSelectionPath(new TreePath(path));
+        }
+
+        dialog.dispose();
+    }
+    
+    /**
+     * Sets list of DB Relationships current ObjRelationship is mapped to
+     */
+    public void valueChanged(TreeSelectionEvent e) {
+        TreePath selectedPath = e.getPath();
+
+        // first item in the path is Entity, so we must have
+        // at least two elements to constitute a valid ordering path
+        if (selectedPath == null || selectedPath.getPathCount() < 2) {
+            return;
+        }
+
+        Relationship rel = (Relationship) selectedPath.getLastPathComponent();
+        DbEntity target = (DbEntity) rel.getTargetEntity();
+         /**
+         * Initialize root with one of mapped ObjEntities.
+         */
+        Collection<ObjEntity> objEntities = target.getDataMap().getMappedEntities(target);
+
+        List<DbRelationship> relPath = new Vector<DbRelationship>(selectedPath
+                .getPathCount() - 1);
+        for (int i = 1; i < selectedPath.getPathCount(); i++) {
+            relPath.add((DbRelationship) selectedPath.getPathComponent(i));
+        }
+        setDbRelationships(relPath);
+        setObjectTarget(objEntities.size() == 0 ? null : objEntities
+                .iterator()
+                .next());
+
+        updateCollectionChoosers();
+    }
+    public void setObjectTarget(ObjEntity objectTarget) {
+        if (this.objectTarget != objectTarget) {
+             this.objectTarget = objectTarget;
+             view.targetCombo.setSelectedItem(objectTarget);
+
+            // init available map keys
+            initMapKeys();
+        }
+    }
+    private void initMapKeys() {
+        this.mapKeys.clear();
+
+        mapKeys.add(DEFAULT_MAP_KEY);
+
+        /**
+         * Object target can be null when selected target DbEntity has no ObjEntities
+         */
+        if (objectTarget == null) {
+            return;
+        }
+
+        for (ObjAttribute attribute : this.objectTarget.getAttributes()) {
+            mapKeys.add(attribute.getName());
+        }
+        view.mapKeysCombo.removeAllItems();
+        for(String s :mapKeys)
+            view.mapKeysCombo.addItem(s);
+        
+        if (mapKey != null && !mapKeys.contains(mapKey)) {
+            mapKey = DEFAULT_MAP_KEY;
+            view.mapKeysCombo.setSelectedItem(mapKey);
+        }
+    }
+    
+    /**
+     * Places in objectTargets list all ObjEntities for specified DbEntity
+     */
+    @SuppressWarnings("unchecked")
+    protected void updateTargetCombo(DbEntity dbTarget) {
+        // copy those that have DbEntities mapped to dbTarget, and then sort
+
+        this.objectTargets = new ArrayList<ObjEntity>();
+
+        if (dbTarget != null) {
+            objectTargets.addAll(dbTarget.getDataMap().getMappedEntities(dbTarget));
+            Collections.sort(objectTargets, Comparators.getNamedObjectComparator());
+        }
+        view.targetCombo.removeAllItems();
+        for( ObjEntity s :objectTargets) {
+           view.targetCombo.addItem(s.getName());
+        }
+    }
+
+    public ObjRelationship getRelationship() {
+        return relationship;
+    }
+
+    /**
+     * @return list of DB Relationships current ObjRelationship is mapped to
+     */
+    public List<DbRelationship> getDbRelationships() {
+        return dbRelationships;
+    }
+
+    /**
+     * @return list of saved DB Relationships
+     */
+    public List<DbRelationship> getSavedDbRelationships() {
+        return savedDbRelationships;
+    }
+
+    /**
+     * @return last relationship in the path, or <code>null</code> if path is
empty
+     */
+    public DbRelationship getLastRelationship() {
+        return dbRelationships.size() == 0 ? null : dbRelationships.get(dbRelationships
+                .size() - 1);
+    }
+
+    /**
+     * Sets list of DB Relationships current ObjRelationship is mapped to
+     */
+    public void setDbRelationships(List<DbRelationship> rels) {
+        this.dbRelationships = rels;
+
+        updateTargetCombo(rels.size() > 0 ? (DbEntity) rels
+                .get(rels.size() - 1)
+                .getTargetEntity() : null);
+    }
+    
+    /**
+     * Returns currently selected target of the ObjRelationship.
+     */
+    public ObjEntity getObjectTarget() {
+        return objectTarget;
+    }
+
+    /**
+     * Returns a list of ObjEntities available for target mapping.
+     */
+    public List<ObjEntity> getObjectTargets() {
+        return objectTargets;
+    }
+
+    public String getRelationshipName() {
+        return relationshipName;
+    }
+
+    public void setRelationshipName(String relationshipName) {
+        view.relationshipName.setText(relationshipName);
+        this.relationshipName = relationshipName;
+    }
+
+    /**
+     * Processes relationship path when path component at index was changed.
+     */
+    public synchronized void relationshipChanged(int index) {
+        // strip everything starting from the index
+        breakChain(index);
+
+        // connect the ends
+        connectEnds();
+    }
+
+    public boolean isToMany() {
+        // copied algorithm from ObjRelationship.calculateToMany(), only iterating through
+        // the unsaved dbrels selection.
+
+        for (DbRelationship relationship : dbRelationships) {
+            if (relationship != null && relationship.isToMany()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+    
+    /**
+     * Stores current state of the model in the internal ObjRelationship.
+     */
+    public synchronized boolean savePath() {
+        boolean hasChanges = false;
+
+        boolean oldToMany = relationship.isToMany();
+
+        if (!Util.nullSafeEquals(relationship.getName(), relationshipName)) {
+            hasChanges = true;
+            relationship.setName(relationshipName);
+        }
+
+        if (savedDbRelationships.size() > 0) {
+            DbEntity lastEntity = (DbEntity) savedDbRelationships.get(
+                    savedDbRelationships.size() - 1).getTargetEntity();
+
+            if (objectTarget == null || objectTarget.getDbEntity() != lastEntity) {
+                /**
+                 * Entities in combobox and path browser do not match. In this case, we
+                 * rely on the browser and automatically select one of lastEntity's
+                 * ObjEntities
+                 */
+                Collection<ObjEntity> objEntities = lastEntity
+                        .getDataMap()
+                        .getMappedEntities(lastEntity);
+                objectTarget = objEntities.size() == 0 ? null : objEntities
+                        .iterator()
+                        .next();
+            }
+        }
+
+        if (objectTarget == null
+                || !Util.nullSafeEquals(objectTarget.getName(), relationship
+                        .getTargetEntityName())) {
+            hasChanges = true;
+
+            // note on events notification - this needs to be propagated
+            // via old modeler events, but we leave this to the controller
+            // since model knows nothing about Modeler mediator.
+            relationship.setTargetEntity(objectTarget);
+        }
+
+        // check for path modifications
+        List<DbRelationship> oldPath = relationship.getDbRelationships();
+        if (oldPath.size() != savedDbRelationships.size()) {
+            hasChanges = true;
+            updatePath();
+        }
+        else {
+            for (int i = 0; i < oldPath.size(); i++) {
+                DbRelationship next = savedDbRelationships.get(i);
+
+                if (oldPath.get(i) != next) {
+                    hasChanges = true;
+                    updatePath();
+                    break;
+                }
+            }
+        }
+
+        String collectionType = ObjRelationship.DEFAULT_COLLECTION_TYPE
+                .equals(targetCollection)
+                || !relationship.isToMany() ? null : targetCollection;
+        if (!Util.nullSafeEquals(collectionType, relationship.getCollectionType())) {
+            hasChanges = true;
+            relationship.setCollectionType(collectionType);
+        }
+
+        // map key only makes sense for Map relationships
+        String mapKey = COLLECTION_TYPE_MAP.equals(collectionType)
+                && !DEFAULT_MAP_KEY.equals(this.mapKey) ? this.mapKey : null;
+        if (!Util.nullSafeEquals(mapKey, relationship.getMapKey())) {
+            hasChanges = true;
+            relationship.setMapKey(mapKey);
+        }
+
+        /**
+         * As of CAY-436 here we check if to-many property has changed during the editing,
+         * and if so, delete rule must be reset to default value
+         */
+        if (hasChanges && relationship.isToMany() != oldToMany) {
+            DeleteRuleUpdater.updateObjRelationship(relationship);
+        }
+
+        return hasChanges;
+    }
+
+    private void updatePath() {
+        relationship.clearDbRelationships();
+
+        for (DbRelationship nextPathComponent : dbRelationships) {
+            if (nextPathComponent == null) {
+                break;
+            }
+
+            relationship.addDbRelationship(nextPathComponent);
+        }
+    }
+
+    private void breakChain(int index) {
+        // strip everything starting from the index
+
+        while (dbRelationships.size() > (index + 1)) {
+            // remove last
+            dbRelationships.remove(dbRelationships.size() - 1);
+        }
+    }
+    // Connects last selected DbRelationship in the path to the
+    // last DbEntity, creating a dummy relationship if needed.
+    private void connectEnds() {
+        Relationship last = null;
+
+        int size = dbRelationships.size();
+        if (size > 0) {
+            last = dbRelationships.get(size - 1);
+        }
+
+        Entity target = getEndEntity();
+
+        if (target != null && (last == null || last.getTargetEntity() != target))
{
+            // try to connect automatically, if we can't use dummy connector
+
+            Entity source = (last == null) ? getStartEntity() : last.getTargetEntity();
+            if (source != null) {
+
+                Relationship anyConnector = source != null ? source
+                        .getAnyRelationship(target) : null;
+
+                if (anyConnector != null) {
+                    dbRelationships.add((DbRelationship) anyConnector);
+                }
+            }
+        }
+    }
+
+    /**
+     * Checks if the entity can be edited with this inspector. NOTE: As of CAY-1077,
+     * relationship inspector can be opened even if no target entity was set.
+     */
+    private void validateCanMap() {
+        if (relationship.getSourceEntity() == null) {
+            throw new CayenneRuntimeException(
+                    "Can't map relationship without source entity.");
+        }
+
+        if (getStartEntity() == null) {
+            throw new CayenneRuntimeException(
+                    "Can't map relationship without source DbEntity.");
+        }
+    }
+
+    public DbEntity getStartEntity() {
+        return ((ObjEntity) relationship.getSourceEntity()).getDbEntity();
+    }
+
+    public DbEntity getEndEntity() {
+        /**
+         * Object target can be null when selected target DbEntity has no ObjEntities
+         */
+        if (objectTarget == null) {
+            return null;
+        }
+
+        return objectTarget.getDbEntity();
+    }
+
+    public String getMapKey() {
+        return mapKey;
+    }
+
+    public void setMapKey(String mapKey) {
+        this.mapKey = mapKey;
+    }
+
+    public String getCurrentPath() {
+        return currentPath;
+    }
+
+    public String getTargetCollection() {
+        return targetCollection;
+    }
+
+    public void setTargetCollection(String targetCollection) {
+        this.targetCollection = targetCollection;
+    }
+
+    public List getMapKeys() {
+        return mapKeys;
+    }
+
+    public List<String> getTargetCollections() {
+        return targetCollections;
+    }
+}

Added: cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfoView.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfoView.java?rev=1141850&view=auto
==============================================================================
--- cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfoView.java
(added)
+++ cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjRelationshipInfoView.java
Fri Jul  1 07:36:43 2011
@@ -0,0 +1,179 @@
+/*****************************************************************
+ *   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.objentity;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.util.DefaultWidgetFactory;
+import org.apache.cayenne.modeler.util.MultiColumnBrowser;
+import org.apache.cayenne.modeler.util.PanelFactory;
+import org.apache.cayenne.modeler.util.WidgetFactory;
+
+import com.jgoodies.forms.builder.PanelBuilder;
+import com.jgoodies.forms.layout.CellConstraints;
+import com.jgoodies.forms.layout.FormLayout;
+
+public class ObjRelationshipInfoView extends JDialog{
+    
+    static final Dimension BROWSER_CELL_DIM = new Dimension(130, 200);
+    
+    protected MultiColumnBrowser pathBrowser;
+    
+    protected WidgetFactory widgetFactory;
+
+    protected Component collectionTypeLabel;
+    protected JComboBox collectionTypeCombo;
+    protected Component mapKeysLabel;
+    protected JComboBox mapKeysCombo;
+
+    protected JButton saveButton;
+    protected JButton cancelButton;
+    protected JButton newRelButton;
+    protected JButton selectPathButton;
+    
+    protected JTextField relationshipName;
+    protected JLabel currentPathLabel;
+    protected JLabel sourceEntityLabel;
+    protected JComboBox targetCombo;
+    
+    ProjectController mediator;
+    
+    public ObjRelationshipInfoView(final ProjectController mediator) {
+
+        this.mediator = mediator;
+        
+        this.widgetFactory = new DefaultWidgetFactory();
+        
+        this.cancelButton = new JButton("Cancel");
+        this.saveButton = new JButton("Done");
+        this.newRelButton = new JButton("New DbRelationship");
+        this.selectPathButton = new JButton("Select Path");
+        this.relationshipName= new JTextField(25);
+        this.currentPathLabel=new JLabel();
+        this.sourceEntityLabel=new JLabel();
+        
+        cancelButton.setEnabled(true);
+        saveButton.setEnabled(true);
+        newRelButton.setEnabled(true);
+        collectionTypeCombo = widgetFactory.createComboBox();
+        collectionTypeCombo.setVisible(true);
+        this.targetCombo = widgetFactory.createComboBox();
+        targetCombo.setVisible(true);
+        
+        this.mapKeysCombo  = widgetFactory.createComboBox();
+        mapKeysCombo.setVisible(true);
+      
+        
+        pathBrowser = new ObjRelationshipPathBrowser();
+        pathBrowser.setPreferredColumnSize(BROWSER_CELL_DIM);
+        pathBrowser.setDefaultRenderer();
+        
+        setTitle("ObjAttribute Inspector");
+        setLayout(new BorderLayout());
+        CellConstraints cc = new CellConstraints();
+        PanelBuilder builder = new PanelBuilder(
+                new FormLayout(
+                        "right:max(50dlu;pref), 3dlu, fill:min(150dlu;pref), 3dlu, 300dlu,
3dlu, fill:min(120dlu;pref)",
+                        "p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p, 3dlu, p,
3dlu, p, 3dlu, top:14dlu, 3dlu, top:p:grow"));
+        builder.setDefaultDialogBorder();
+
+        builder.addSeparator("ObjRelationship Information", cc.xywh(1, 1, 5, 1));
+        builder.addLabel("Relationship:", cc.xy(1, 3));
+        builder.add(relationshipName, cc.xywh(3, 3, 1, 1));
+
+        builder.addLabel("Current Db Path:", cc.xy(1, 5));
+        builder.add(currentPathLabel, cc.xywh(3, 5, 5, 1));
+
+        builder.addLabel("Source:", cc.xy(1, 7));
+        builder.add(sourceEntityLabel, cc.xywh(3, 7, 1, 1));
+        builder.addLabel("Target:", cc.xy(1, 9));
+        builder.add(targetCombo, cc.xywh(3, 9, 1, 1));
+        collectionTypeLabel = builder.addLabel("Collection Type:", cc.xy(1, 11));
+        builder.add(collectionTypeCombo, cc.xywh(3, 11, 1, 1));
+        mapKeysLabel = builder.addLabel("Map Key:", cc.xy(1, 13));
+        builder.add(mapKeysCombo, cc.xywh(3, 13, 1, 1));
+
+        builder.addSeparator("Mapping to DbRelationships", cc.xywh(1, 15, 5, 1));
+
+        JPanel buttonsPane = new JPanel(new FlowLayout(FlowLayout.LEADING));
+        buttonsPane.add(selectPathButton);
+        buttonsPane.add(newRelButton);
+
+        builder.add(buttonsPane, cc.xywh(1, 17, 5, 1));
+        builder.add(new JScrollPane(
+                pathBrowser,
+                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED), cc.xywh(1, 19, 5, 3));
+
+        add(builder.getPanel(), BorderLayout.CENTER);
+        add(PanelFactory.createButtonPanel(new JButton[] {
+                saveButton, cancelButton
+            }), BorderLayout.SOUTH);        
+    }
+
+    public JButton getSaveButton()
+    {
+        return saveButton;
+    }
+    
+    public JButton getCancelButton()
+    {
+        return cancelButton;
+    }
+    
+    public JButton getNewRelButton()
+    {
+        return newRelButton;
+    }
+    
+    public JButton getSelectPathButton()
+    {
+        return selectPathButton;
+    }
+    
+    public JTextField getRelationshipName()
+    {
+        return relationshipName;
+    }
+    
+    public JLabel getCurrentPathLabel()
+    {
+        return currentPathLabel;
+    }
+    
+    public JLabel getSourceEntityLabel()
+    {
+        return sourceEntityLabel;
+    }
+    
+    public JComboBox getTargetCombo()
+    {
+        return targetCombo;
+    }
+}

Modified: cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipTab.java?rev=1141850&r1=1141849&r2=1141850&view=diff
==============================================================================
--- cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipTab.java
(original)
+++ cayenne/main/trunk/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipTab.java
Fri Jul  1 07:36:43 2011
@@ -65,7 +65,7 @@ import org.apache.cayenne.modeler.action
 import org.apache.cayenne.modeler.action.ObjEntitySyncAction;
 import org.apache.cayenne.modeler.action.PasteAction;
 import org.apache.cayenne.modeler.action.RemoveRelationshipAction;
-import org.apache.cayenne.modeler.dialog.objentity.ObjRelationshipInfoController;
+import org.apache.cayenne.modeler.dialog.objentity.ObjRelationshipInfo;
 import org.apache.cayenne.modeler.event.EntityDisplayEvent;
 import org.apache.cayenne.modeler.event.ObjEntityDisplayListener;
 import org.apache.cayenne.modeler.event.RelationshipDisplayEvent;
@@ -191,8 +191,7 @@ public class ObjEntityRelationshipTab ex
 
                 ObjRelationshipTableModel model = (ObjRelationshipTableModel) table
                         .getModel();
-                new ObjRelationshipInfoController(mediator, model.getRelationship(row))
-                        .startup();
+                new ObjRelationshipInfo(mediator, model.getRelationship(row)).startupAction();
 
                 /**
                  * This is required for a table to be updated properly



Mime
View raw message