You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by sk...@apache.org on 2015/12/07 16:31:42 UTC
[3/8] cayenne git commit: add auto suggestion DbRelationshipPath .
add extra columns relationship table. reason : reduse DatabaseMapping dialog
add auto suggestion DbRelationshipPath . add extra columns relationship table. reason : reduse DatabaseMapping dialog
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/8367f77a
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/8367f77a
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/8367f77a
Branch: refs/heads/master
Commit: 8367f77a52c910a2dc56a49668b068edf402e713
Parents: 681a1fa
Author: AlexandrShestak <sh...@mail.ru>
Authored: Tue Nov 24 12:34:32 2015 +0300
Committer: Savva Kolbachev <s....@gmail.com>
Committed: Mon Dec 7 13:21:41 2015 +0300
----------------------------------------------------------------------
.../editor/ObjEntityRelationshipPanel.java | 535 ++++++++++++++++++-
.../editor/ObjRelationshipTableModel.java | 69 ++-
2 files changed, 586 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/8367f77a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipPanel.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipPanel.java
index 3b557e2..dffd96d 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipPanel.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipPanel.java
@@ -18,10 +18,15 @@
****************************************************************/
package org.apache.cayenne.modeler.editor;
+import org.apache.cayenne.map.Attribute;
import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbRelationship;
import org.apache.cayenne.map.DeleteRule;
+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.EntityEvent;
import org.apache.cayenne.map.event.ObjEntityListener;
import org.apache.cayenne.map.event.ObjRelationshipListener;
@@ -40,13 +45,17 @@ import org.apache.cayenne.modeler.event.TablePopupHandler;
import org.apache.cayenne.modeler.pref.TableColumnPreferences;
import org.apache.cayenne.modeler.util.CayenneTable;
import org.apache.cayenne.modeler.util.CellRenderers;
+import org.apache.cayenne.modeler.util.EntityTreeFilter;
+import org.apache.cayenne.modeler.util.EntityTreeModel;
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;
+import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import javax.swing.AbstractCellEditor;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.Icon;
@@ -62,14 +71,22 @@ import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
+import javax.swing.text.JTextComponent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
+import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.regex.Pattern;
/**
* Displays ObjRelationships for the edited ObjEntity.
@@ -86,6 +103,11 @@ public class ObjEntityRelationshipPanel extends JPanel implements ObjEntityDispl
DeleteRule.deleteRuleName(DeleteRule.DENY),
};
+ /* 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_COLLECTION_TYPE = "java.util.List";*/
+
protected ProjectController mediator;
protected CayenneTable table;
private TableColumnPreferences tablePreferences;
@@ -94,7 +116,7 @@ public class ObjEntityRelationshipPanel extends JPanel implements ObjEntityDispl
private boolean enabledResolve;//for JBottom "resolve" in ObjEntityAttrRelationshipTab
/**
- * By now popup menu item is made similiar to toolbar button. (i.e. all functionality
+ * By now popup menu item is made similar to toolbar button. (i.e. all functionality
* is here) This should be probably refactored as Action.
*/
protected JMenuItem resolveMenu;
@@ -112,7 +134,16 @@ public class ObjEntityRelationshipPanel extends JPanel implements ObjEntityDispl
ActionManager actionManager = Application.getInstance().getActionManager();
- table = new CayenneTable();
+ table = new CayenneTable(){
+ @Override
+ public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
+ Component component = super.prepareRenderer(renderer, row, column);
+ int rendererWidth = component.getPreferredSize().width;
+ TableColumn tableColumn = getColumnModel().getColumn(column);
+ tableColumn.setPreferredWidth(Math.max(rendererWidth + getIntercellSpacing().width, tableColumn.getPreferredWidth()));
+ return component;
+ }
+ };
table.setDefaultRenderer(String.class, new StringRenderer());
table.setDefaultRenderer(ObjEntity.class, new EntityRenderer());
tablePreferences = new TableColumnPreferences(
@@ -287,7 +318,8 @@ public class ObjEntityRelationshipPanel extends JPanel implements ObjEntityDispl
JComboBox combo = (JComboBox) editor.getComponent();
combo.setRenderer(CellRenderers.entityListRendererWithIcons(entity.getDataMap()));
- combo.setModel(new DefaultComboBoxModel(createObjEntityComboModel()));
+ //combo.setModel(new DefaultComboBoxModel(createObjEntityComboModel()));
+ //combo.setEnabled(false);
ObjRelationshipTableModel model = (ObjRelationshipTableModel) table.getModel();
model.fireTableDataChanged();
@@ -319,7 +351,7 @@ public class ObjEntityRelationshipPanel extends JPanel implements ObjEntityDispl
table.setRowMargin(3);
TableColumn col = table.getColumnModel().getColumn(
- ObjRelationshipTableModel.REL_TARGET);
+ ObjRelationshipTableModel.REL_TARGET_PATH);
JComboBox targetCombo = Application.getWidgetFactory().createComboBox(
createObjEntityComboModel(),
false);
@@ -328,9 +360,9 @@ public class ObjEntityRelationshipPanel extends JPanel implements ObjEntityDispl
targetCombo.setRenderer(CellRenderers.entityListRendererWithIcons(entity
.getDataMap()));
targetCombo.setSelectedIndex(-1);
- col.setCellEditor(Application.getWidgetFactory().createCellEditor(targetCombo));
+ col.setCellEditor(new JTableTargetComboBoxEditor());
- col = table.getColumnModel().getColumn(ObjRelationshipTableModel.REL_DELETERULE);
+ col = table.getColumnModel().getColumn(ObjRelationshipTableModel.REL_DELETE_RULE);
JComboBox deleteRulesCombo = Application.getWidgetFactory().createComboBox(
deleteRules,
false);
@@ -339,6 +371,15 @@ public class ObjEntityRelationshipPanel extends JPanel implements ObjEntityDispl
col.setCellEditor(Application.getWidgetFactory().createCellEditor(
deleteRulesCombo));
+ col = table.getColumnModel().getColumn(ObjRelationshipTableModel.REL_COLLECTION_TYPE);
+
+ col.setCellEditor(new JTableCollectionTypeComboBoxEditor());
+ col.setCellRenderer(new JTableCollectionTypeComboBoxRenderer());
+
+ col = table.getColumnModel().getColumn(ObjRelationshipTableModel.REL_MAP_KEY);
+ col.setCellEditor(new JTableMapKeyComboBoxEditor());
+ col.setCellRenderer(new JTableMapKeyComboBoxRenderer());
+
tablePreferences.bind(
table,
null,
@@ -469,4 +510,486 @@ public class ObjEntityRelationshipPanel extends JPanel implements ObjEntityDispl
public ActionListener getResolver() {
return resolver;
}
+
+ private final static class JTableCollectionTypeComboBoxEditor extends AbstractCellEditor implements TableCellEditor{
+
+ 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_COLLECTION_TYPE = "java.util.List";
+
+ private ObjRelationshipTableModel model;
+ private int row;
+ private int column;
+
+ public JTableCollectionTypeComboBoxEditor() {
+ }
+
+ @Override
+ public Component getTableCellEditorComponent(final JTable table, Object value, boolean isSelected, final int row, final int column) {
+ this.model = (ObjRelationshipTableModel) table.getModel();
+ this.row = row;
+ this.column = column;
+
+ final JComboBox collectionTypeCombo = Application.getWidgetFactory().createComboBox(
+ new Object[]{
+ COLLECTION_TYPE_MAP,
+ COLLECTION_TYPE_SET,
+ COLLECTION_TYPE_COLLECTION,
+ DEFAULT_COLLECTION_TYPE
+ },
+ false);
+ if(model.getRelationship(row).isToMany()){
+ collectionTypeCombo.setEnabled(true);
+ collectionTypeCombo.setSelectedItem( model.getRelationship(row).getCollectionType());
+ }else{
+ JLabel labelIfToOneRelationship = new JLabel();
+ labelIfToOneRelationship.setEnabled(false);
+ //collectionTypeCombo.setEnabled(false);
+ //collectionTypeCombo.setSelectedItem( model.getRelationship(row).getCollectionType());
+ return labelIfToOneRelationship;
+ }
+ collectionTypeCombo.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Object selected = collectionTypeCombo.getSelectedItem();
+ model.setUpdatedValueAt(selected,row,column);
+ table.repaint();
+ }
+ });
+ return collectionTypeCombo;
+ }
+
+ @Override
+ public Object getCellEditorValue() {
+ return model.getValueAt(row,column);
+ }
+ }
+
+ private final static class JTableCollectionTypeComboBoxRenderer implements TableCellRenderer {
+
+ private ObjRelationshipTableModel model;
+
+ public JTableCollectionTypeComboBoxRenderer() {
+ }
+
+ @Override
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ this.model = (ObjRelationshipTableModel) table.getModel();
+ JLabel labelIfToOneRelationship = new JLabel();
+ labelIfToOneRelationship.setEnabled(false);
+ JLabel labelIfToManyRelationship = new JLabel((String) value);
+ labelIfToManyRelationship.setEnabled(true);
+ labelIfToManyRelationship.setFont(new Font("Verdana", Font.PLAIN , 12));
+ if (value == null)
+ return labelIfToOneRelationship;
+
+ if (model.getRelationship(row).isToMany()) {
+ return labelIfToManyRelationship;
+ }else{
+ return labelIfToOneRelationship;
+ }
+
+ }
+ }
+
+ private final static class JTableMapKeyComboBoxEditor extends AbstractCellEditor implements TableCellEditor {
+
+ static final String DEFAULT_MAP_KEY = "ID (default)";
+ static final String COLLECTION_TYPE_MAP = "java.util.Map";
+
+ private List<String> mapKeys = new ArrayList<>() ;
+ private ObjRelationshipTableModel model;
+ private int row;
+ private int column;
+
+ private JTableMapKeyComboBoxEditor() {
+ }
+
+ private void initMapKeys() {
+ mapKeys.clear();
+ mapKeys.add(DEFAULT_MAP_KEY);
+ /**
+ * Object target can be null when selected target DbEntity has no
+ * ObjEntities
+ */
+ ObjEntity objectTarget = model.getRelationship(row).getTargetEntity();
+ if (objectTarget == null) {
+ return ;
+ }
+ for (ObjAttribute attribute : objectTarget.getAttributes()) {
+ mapKeys.add(attribute.getName());
+ }
+ }
+
+ @Override
+ public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, final int row, final int column) {
+ this.model = (ObjRelationshipTableModel) table.getModel();
+ this.row = row;
+ this.column = column;
+ initMapKeys();
+ final JComboBox mapKeysComboBox = Application.getWidgetFactory().createComboBox(
+ mapKeys,
+ false);
+ if ((model.getRelationship(row).getCollectionType() == null)
+ ||(!model.getRelationship(row).getCollectionType().equals(COLLECTION_TYPE_MAP))){
+ JComboBox jComboBox = new JComboBox();
+ jComboBox.setFocusable(false);
+ jComboBox.setEnabled(false);
+ return jComboBox;
+ }else{
+ mapKeysComboBox.setFocusable(true);
+ mapKeysComboBox.setEnabled(true);
+ }
+ mapKeysComboBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Object selected = mapKeysComboBox.getSelectedItem();
+ model.setUpdatedValueAt(selected,row,column);
+ }
+ });
+ mapKeysComboBox.setSelectedItem(model.getRelationship(row).getMapKey());
+ return mapKeysComboBox;
+ }
+
+ @Override
+ public Object getCellEditorValue() {
+ return model.getValueAt(row,column);
+ }
+ }
+
+ private final static class JTableMapKeyComboBoxRenderer implements TableCellRenderer{
+
+ static final String DEFAULT_MAP_KEY = "ID (default)";
+ static final String COLLECTION_TYPE_MAP = "java.util.Map";
+
+ private ObjRelationshipTableModel model;
+
+ public JTableMapKeyComboBoxRenderer() {
+ }
+
+ @Override
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ this.model = (ObjRelationshipTableModel) table.getModel();
+ if ( (model.getRelationship(row).getCollectionType() == null)
+ ||(!model.getRelationship(row).getCollectionType().equals(COLLECTION_TYPE_MAP))){
+ JComboBox jComboBox = new JComboBox();
+ jComboBox.setFocusable(false);
+ jComboBox.setEnabled(false);
+ return jComboBox;
+ }
+ if (model.getRelationship(row).getMapKey() == null){
+ model.getRelationship(row).setMapKey(DEFAULT_MAP_KEY);
+ }
+ JLabel jLabel = new JLabel(model.getRelationship(row).getMapKey());
+ jLabel.setFont(new Font("Verdana", Font.PLAIN , 12));
+ return jLabel;
+ }
+ }
+
+ private static final class JTableTargetComboBoxEditor extends AbstractCellEditor implements TableCellEditor, ActionListener {
+
+ private ObjRelationshipTableModel model;
+ private int row;
+ private int column;
+ private JComboBox dbRelationshipPathCombo;
+ private EntityTreeModel treeModel;
+ private int previousEmbededLevel = 0;
+ private static int enterPressedCount = 0;
+
+ public JTableTargetComboBoxEditor() {
+ }
+
+ @Override
+ public Object getCellEditorValue() {
+ return model.getValueAt(row,column);
+ }
+
+ @Override
+ public Component getTableCellEditorComponent(final JTable table, Object value, boolean isSelected, final int row, int column) {
+ this.model = (ObjRelationshipTableModel) table.getModel();
+ this.row = row;
+ this.column = column;
+ treeModel = createTreeModelForComboBoxBrowser(row);
+ if (treeModel == null)
+ return new JLabel("You need select table to this ObjectEntity");
+ initializeCombo(model , row);
+
+ String dbRelationshipPath = ((JTextComponent) (dbRelationshipPathCombo).
+ getEditor().getEditorComponent()).getText();
+ previousEmbededLevel = dbRelationshipPath.split(Pattern.quote(".")).length;
+
+ dbRelationshipPathCombo.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() {
+ private void enterPressed(){
+ String dbRelationshipPath = ((JTextComponent) (dbRelationshipPathCombo).
+ getEditor().getEditorComponent()).getText();
+ Object currentNode = getCurrentNode(dbRelationshipPath);
+ String[] pathStrings = dbRelationshipPath.split(Pattern.quote("."));
+ String lastStringInPath = pathStrings[pathStrings.length - 1];
+
+ if (lastStringInPath.equals(ModelerUtil.getObjectName(currentNode))) {
+ if (enterPressedCount == 1) {
+ //it is second time enter pressed.. so we will save input data
+ enterPressedCount = 0;
+ if (currentNode instanceof DbRelationship) {
+
+ if (table.getCellEditor() != null) {
+
+ table.getCellEditor().stopCellEditing();
+ model.getRelationship(row).setDbRelationshipPath(dbRelationshipPath);
+
+ //we need object target to save it in model
+ DbEntity lastEntity = ((DbRelationship) currentNode).getTargetEntity();
+ Collection<ObjEntity> objEntities = ((DbRelationship) currentNode).getTargetEntity().
+ getDataMap().getMappedEntities(lastEntity);
+ ObjEntity objectTarget = objEntities.size() == 0 ? null : objEntities.iterator().next();
+ model.getRelationship(row).setTargetEntityName(objectTarget);
+ }
+ }
+ table.repaint();
+ } else {
+ enterPressedCount = 1;
+ }
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent event) {
+ if (event.getKeyCode() == KeyEvent.VK_ENTER) {
+ enterPressed();
+ return;
+ }
+ parseDbRelationshipString(event.getKeyChar());
+ }
+ });
+ return dbRelationshipPathCombo;
+ }
+
+ private void initializeCombo(ObjRelationshipTableModel model , int row){
+ String dbRelationshipPath = model.getRelationship(row).getDbRelationshipPath();
+ Object currentNode;
+ if (dbRelationshipPath == null){
+ //case if it is new attribute or for some reason dbRelationshipPath is null
+ currentNode = getCurrentNode(dbRelationshipPath);
+ dbRelationshipPath = "";
+
+ }else{
+ //case if dbRelationshipPath isn't null and we must change it to find auto completion list
+ String[] pathStrings = dbRelationshipPath.split(Pattern.quote("."));
+ String lastStringInPath = pathStrings[pathStrings.length - 1];
+ dbRelationshipPath = dbRelationshipPath.replaceAll(lastStringInPath + "$", "");
+ currentNode = getCurrentNode(dbRelationshipPath);
+ }
+ List<String> nodeChildren = getChildren(currentNode , dbRelationshipPath);
+ dbRelationshipPathCombo = Application.getWidgetFactory().createComboBox(
+ nodeChildren,
+ false);
+ AutoCompletion.enable(dbRelationshipPathCombo, false, true);
+ dbRelationshipPathCombo.setEditable(true);
+ ((JTextComponent) (dbRelationshipPathCombo).
+ getEditor().getEditorComponent()).setText(model.getRelationship(row).getDbRelationshipPath());
+ dbRelationshipPathCombo.setSelectedItem(model.getRelationship(row).getDbRelationshipPath());
+ dbRelationshipPathCombo.addActionListener(this);
+ return;
+ }
+
+ /*
+ * chech if potential child is child for father
+ * @param father
+ * @param potentialChild
+ * @return
+ */
+ /*private boolean isChild(Object father , Object potentialChild){
+ List<Object> fatherChildren = new ArrayList<>();
+ for(int j = 0 ; j < treeModel.getChildCount(father) ; j++){
+ Object child = treeModel.getChild(father, j);
+ fatherChildren.add(child);
+ }
+ return fatherChildren.contains(potentialChild);
+ }*/
+
+ private void parseDbRelationshipString(char lastEnteredCharacter){
+ String dbRelationshipPath = ((JTextComponent) (dbRelationshipPathCombo).
+ getEditor().getEditorComponent()).getText();
+
+ enterPressedCount = 0;
+
+ if (dbRelationshipPath.equals("")){
+ List<String> currentNodeChildren = new ArrayList<>();
+ currentNodeChildren.add("");
+ currentNodeChildren.addAll(getChildren(getCurrentNode(dbRelationshipPath),""));
+ dbRelationshipPathCombo.setModel(new DefaultComboBoxModel(currentNodeChildren.toArray()));
+ dbRelationshipPathCombo.showPopup();
+ dbRelationshipPathCombo.setPopupVisible(true);
+ return;
+ }
+
+ if (lastEnteredCharacter == '.') {
+ processDotEntered();
+ previousEmbededLevel = StringUtils.countMatches(dbRelationshipPath,".");
+ return;
+ }
+
+ int currentEmbededLevel = StringUtils.countMatches(dbRelationshipPath,".");
+ if (previousEmbededLevel != currentEmbededLevel){
+ previousEmbededLevel = currentEmbededLevel;
+ List<String> currentNodeChildren = new ArrayList<>();
+ String[] pathStrings = dbRelationshipPath.split(Pattern.quote("."));
+ String lastStringInPath = pathStrings[pathStrings.length - 1];
+ String saveDbRelationshipPath = dbRelationshipPath;
+ dbRelationshipPath = dbRelationshipPath.replaceAll(lastStringInPath + "$", "");
+ currentNodeChildren.add("");
+ currentNodeChildren.addAll(getChildren(getCurrentNode(dbRelationshipPath), dbRelationshipPath));
+ dbRelationshipPathCombo.setModel(new DefaultComboBoxModel(currentNodeChildren.toArray()));
+ ((JTextComponent) (dbRelationshipPathCombo).
+ getEditor().getEditorComponent()).setText(saveDbRelationshipPath);
+
+ dbRelationshipPathCombo.showPopup();
+ dbRelationshipPathCombo.setPopupVisible(true);
+ return;
+ }
+ }
+
+ private void processDotEntered(){
+ String dbAttributePath = ((JTextComponent) (dbRelationshipPathCombo).
+ getEditor().getEditorComponent()).getText();
+ if (dbAttributePath.equals(".")){
+ List<String> currentNodeChildren = new ArrayList<>();
+ currentNodeChildren.add("");
+ currentNodeChildren.addAll(getChildren(getCurrentNode(""),""));
+ dbRelationshipPathCombo.setModel(new DefaultComboBoxModel(currentNodeChildren.toArray()));
+ dbRelationshipPathCombo.showPopup();
+ dbRelationshipPathCombo.setPopupVisible(true);
+ return;
+ }else {
+ char secondFromEndCharacter = dbAttributePath.charAt(dbAttributePath.length()-2);
+ if(secondFromEndCharacter == '.') {
+ // two dots entered one by one , we replace it by one dot
+ ((JTextComponent) (dbRelationshipPathCombo).
+ getEditor().getEditorComponent()).setText(dbAttributePath.substring(0,dbAttributePath.length()-1));
+ return;
+ }else{
+ String[] pathStrings = dbAttributePath.split(Pattern.quote("."));
+ String lastStringInPath = pathStrings[pathStrings.length - 1];
+
+ //we will check if lastStringInPath is correct name of DbAttribute or DbRelationship
+ //for appropriate previous node in path. if it is not we won't add entered dot to dbAttributePath
+ String dbAttributePathForPreviousNode;
+ if (pathStrings.length == 1){
+ dbAttributePathForPreviousNode = null;
+ }else {
+ dbAttributePathForPreviousNode = dbAttributePath.replace("."+lastStringInPath,"");
+ }
+ List<String> potentialVariantsToChoose = getChildren(getCurrentNode(dbAttributePathForPreviousNode),"");
+ if (potentialVariantsToChoose.contains(lastStringInPath)){
+ List<String> currentNodeChildren = new ArrayList<>();
+ currentNodeChildren.add(dbAttributePath + "");
+ currentNodeChildren.addAll(getChildren(getCurrentNode(dbAttributePath), dbAttributePath));
+ dbRelationshipPathCombo.setModel(new DefaultComboBoxModel(currentNodeChildren.toArray()));
+ dbRelationshipPathCombo.showPopup();
+ dbRelationshipPathCombo.setPopupVisible(true);
+ }else{
+ ((JTextComponent) (dbRelationshipPathCombo).
+ getEditor().getEditorComponent()).setText(dbAttributePath.substring(0,dbAttributePath.length()-1));
+ }
+ }
+ }
+ previousEmbededLevel = StringUtils.countMatches(dbAttributePath,".");
+ return;
+ }
+
+ /**
+ * find current node by dbRelationshipPath
+ * @param dbRelationshipPath
+ * @return last node in dbRelationshipPath which matches DbRelationship
+ */
+ private final Object getCurrentNode(String dbRelationshipPath) {
+ try {
+ //case for new relationship
+ if(dbRelationshipPath == null){
+ return treeModel.getRoot();
+ }
+ String[] pathStrings = dbRelationshipPath.split(Pattern.quote("."));
+ Object root = treeModel.getRoot();
+ for (int i = 0 ; i < pathStrings.length ; i ++) {
+ String rootChildText = pathStrings[i];
+ for (int j = 0; j < treeModel.getChildCount(root); j++) {
+ Object child = treeModel.getChild(root, j);
+ if (child instanceof DbRelationship) {
+ String relationshipName = ModelerUtil.getObjectName(child);
+ if (relationshipName.equals(rootChildText)) {
+ root = child;
+ break;
+ }
+ }
+ }
+ }
+ return root;
+ }catch (Exception e){
+ return treeModel.getRoot();
+ }
+ }
+
+ /**
+ * @param node for which we will find children
+ * @param dbRelationshipPath string which will be added to each child to make right autocomplete
+ * @return list with children , which will be used to autocomplete
+ */
+ private final List<String> getChildren(Object node , String dbRelationshipPath){
+ List<String> currentNodeChildren = new ArrayList<>();
+ for(int j = 0 ; j < treeModel.getChildCount(node) ; j++){
+ Object child = treeModel.getChild(node, j);
+ String relationshipName = ModelerUtil.getObjectName(child);
+ currentNodeChildren.add(dbRelationshipPath + relationshipName);
+ }
+ return currentNodeChildren;
+ }
+
+ /**
+ * @param relationshipIndexInTable index of attribute for which now we will create cell editor
+ * @return treeModel for nessesary for us attribute
+ */
+ private EntityTreeModel createTreeModelForComboBoxBrowser(int relationshipIndexInTable){
+ if (model.getRelationship(relationshipIndexInTable).
+ getSourceEntity().getDbEntity() == null)
+ return null;
+ EntityTreeModel treeModel = new EntityTreeModel(model.getRelationship(relationshipIndexInTable).
+ getSourceEntity().getDbEntity());
+ 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);
+ }
+
+ });
+ return treeModel;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ model.getRelationship(row).setMapKey(null);
+
+ //for some reason dbRelationshipPathCombo don't load selected item text, so we made it by hand
+ if (dbRelationshipPathCombo.getSelectedIndex() != (-1)){
+ ((JTextComponent) (dbRelationshipPathCombo).
+ getEditor().getEditorComponent()).setText(dbRelationshipPathCombo.getSelectedItem().toString());
+ }
+
+
+ }
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cayenne/blob/8367f77a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjRelationshipTableModel.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjRelationshipTableModel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjRelationshipTableModel.java
index 5dca446..91592f6 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjRelationshipTableModel.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjRelationshipTableModel.java
@@ -39,9 +39,14 @@ public class ObjRelationshipTableModel extends CayenneTableModel {
// Columns
static final int REL_NAME = 0;
static final int REL_TARGET = 1;
- static final int REL_SEMANTICS = 2;
- static final int REL_DELETERULE = 3;
- static final int REL_LOCKING = 4;
+ static final int REL_TARGET_PATH = 2;
+ static final int REL_COLLECTION_TYPE = 3;
+ static final int REL_MAP_KEY = 4;
+ static final int REL_SEMANTICS = 5;
+ static final int REL_DELETE_RULE = 6;
+ static final int REL_LOCKING = 7;
+
+ static final int COLUMN_COUNT = 8;
protected ObjEntity entity;
@@ -72,7 +77,7 @@ public class ObjRelationshipTableModel extends CayenneTableModel {
}
public int getColumnCount() {
- return 5;
+ return COLUMN_COUNT;
}
@Override
@@ -86,8 +91,14 @@ public class ObjRelationshipTableModel extends CayenneTableModel {
return "Used for Locking";
case REL_SEMANTICS:
return "Semantics";
- case REL_DELETERULE:
+ case REL_DELETE_RULE:
return "Delete Rule";
+ case REL_COLLECTION_TYPE:
+ return "Collection Type";
+ case REL_MAP_KEY:
+ return "Map key";
+ case REL_TARGET_PATH:
+ return "DbRelationshipPath";
default:
return null;
@@ -126,8 +137,16 @@ public class ObjRelationshipTableModel extends CayenneTableModel {
else if (column == REL_SEMANTICS) {
return getSemantics(relationship);
}
- else if (column == REL_DELETERULE) {
+ else if (column == REL_DELETE_RULE) {
return DeleteRule.deleteRuleName(relationship.getDeleteRule());
+ } else if (column == REL_COLLECTION_TYPE) {
+ if (!relationship.isToMany())
+ return null;
+ return relationship.getCollectionType();
+ } else if (column == REL_MAP_KEY){
+ return relationship.getMapKey();
+ } else if (column == REL_TARGET_PATH){
+ return relationship.getDbRelationshipPath();
}
else {
return null;
@@ -191,7 +210,7 @@ public class ObjRelationshipTableModel extends CayenneTableModel {
fireTableRowsUpdated(row, row);
}
- else if (column == REL_DELETERULE) {
+ else if (column == REL_DELETE_RULE) {
relationship.setDeleteRule(DeleteRule.deleteRuleForName((String) value));
fireTableCellUpdated(row, column);
}
@@ -200,6 +219,17 @@ public class ObjRelationshipTableModel extends CayenneTableModel {
&& ((Boolean) value).booleanValue());
fireTableCellUpdated(row, column);
}
+ else if (column == REL_COLLECTION_TYPE){
+ relationship.setCollectionType((String) value);
+ fireTableCellUpdated(row, column);
+ }else if (column == REL_MAP_KEY){
+ relationship.setMapKey((String) value);
+ fireTableCellUpdated(row, column);
+ }
+ else if (column == REL_TARGET_PATH){
+ relationship.setDbRelationshipPath((String) value);
+ fireTableCellUpdated(row, column);
+ }
mediator.fireObjRelationshipEvent(event);
}
@@ -223,7 +253,8 @@ public class ObjRelationshipTableModel extends CayenneTableModel {
@Override
public boolean isCellEditable(int row, int col) {
- return !isInherited(row) && col != REL_SEMANTICS;
+ return !isInherited(row) && col != REL_SEMANTICS
+ && col != REL_TARGET;
}
final class RelationshipComparator implements Comparator {
@@ -261,7 +292,10 @@ public class ObjRelationshipTableModel extends CayenneTableModel {
sortByElementProperty("usedForLocking", isAscent);
break;
case REL_SEMANTICS:
- case REL_DELETERULE:
+ case REL_COLLECTION_TYPE:
+ case REL_MAP_KEY:
+ case REL_DELETE_RULE:
+ case REL_TARGET_PATH:
Collections.sort(objectList, new Comparator<ObjRelationship>() {
public int compare(ObjRelationship o1, ObjRelationship o2) {
@@ -278,14 +312,25 @@ public class ObjRelationshipTableModel extends CayenneTableModel {
String valueToCompare1 = "";
String valueToCompare2 = "";
switch(sortCol){
+ case REL_COLLECTION_TYPE:
+ valueToCompare1 = o1.getCollectionType();
+ valueToCompare2 = o2.getCollectionType();
+ break;
+ case REL_MAP_KEY:
+ valueToCompare1 = o1.getMapKey();
+ valueToCompare2 = o2.getMapKey();
+ break;
case REL_SEMANTICS:
valueToCompare1 = getSemantics(o1);
valueToCompare2 = getSemantics(o2);
break;
- case REL_DELETERULE:
+ case REL_DELETE_RULE:
valueToCompare1 = DeleteRule.deleteRuleName(o1.getDeleteRule());
valueToCompare2 = DeleteRule.deleteRuleName(o2.getDeleteRule());
-
+ break;
+ case REL_TARGET_PATH:
+ valueToCompare1 = o1.getDbRelationshipPath();
+ valueToCompare2 = o2.getDbRelationshipPath();
break;
}
return (valueToCompare1 == null) ? -1 : (valueToCompare2 == null)
@@ -298,7 +343,7 @@ public class ObjRelationshipTableModel extends CayenneTableModel {
Collections.reverse(objectList);
}
break;
-
+
}
}