All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.cayenne.modeler.editor.ObjRelationshipTableModel Maven / Gradle / Ivy

There is a newer version: 5.0-M1
Show newest version
/*****************************************************************
 *   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
 *
 *    https://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 ****************************************************************/

package org.apache.cayenne.modeler.editor;

import org.apache.cayenne.map.*;
import org.apache.cayenne.map.event.RelationshipEvent;
import org.apache.cayenne.modeler.ProjectController;
import org.apache.cayenne.modeler.util.CayenneTableModel;
import org.apache.cayenne.modeler.util.ProjectUtil;
import org.apache.cayenne.project.extension.info.ObjectInfo;
import org.apache.cayenne.util.Util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 * Table model to display ObjRelationships.
 * 
 */
public class ObjRelationshipTableModel extends CayenneTableModel {

    // Columns
    public static final int REL_NAME = 0;
    public static final int REL_TARGET = 1;
    public static final int REL_TARGET_PATH = 2;
    public static final int REL_SEMANTICS = 3;
    public static final int REL_DELETE_RULE = 4;
    public static final int REL_LOCKING = 5;
    public static final int REL_COMMENT = 6;
    public static final int COLUMN_COUNT = 7;

    private ObjEntity entity;

    public ObjRelationshipTableModel(ObjEntity entity, ProjectController mediator, Object eventSource) {
        super(mediator, eventSource, new ArrayList<>(entity.getRelationships()));
        this.entity = entity;

        // order using local comparator
        objectList.sort(new RelationshipComparator());
    }

    public ObjEntity getEntity() {
        return entity;
    }

    /**
     * Returns ObjRelationship class.
     */
    @Override
    public Class getElementsClass() {
        return ObjRelationship.class;
    }

    public int getColumnCount() {
        return COLUMN_COUNT;
    }

    @Override
    public String getColumnName(int column) {
        switch (column) {
            case REL_NAME:
                return "Name";
            case REL_TARGET:
                return "Target";
            case REL_LOCKING:
                return "Used for Locking";
            case REL_SEMANTICS:
                return "Semantics";
            case REL_DELETE_RULE:
                return "Delete Rule";
            case REL_TARGET_PATH:
                return "DbRelationship Path";
            case REL_COMMENT:
                return "Comment";
            default:
                return null;
        }
    }

    @Override
    public Class getColumnClass(int col) {
        switch (col) {
            case REL_TARGET:
                return ObjEntity.class;
            case REL_LOCKING:
                return Boolean.class;
            default:
                return String.class;
        }
    }

    public ObjRelationship getRelationship(int row) {
        return (row >= 0 && row < objectList.size()) ?  objectList.get(row) : null;
    }

    public Object getValueAt(int row, int column) {
        ObjRelationship relationship = getRelationship(row);

        switch (column) {
            case REL_NAME:
                return relationship.getName();
            case REL_TARGET:
                return relationship.getTargetEntity();
            case REL_LOCKING:
                return relationship.isUsedForLocking() ? Boolean.TRUE : Boolean.FALSE;
            case REL_SEMANTICS:
                return getSemantics(relationship);
            case REL_DELETE_RULE:
                return DeleteRule.deleteRuleName(relationship.getDeleteRule());
            case REL_TARGET_PATH:
                return relationship.getDbRelationshipPath();
            case REL_COMMENT:
                return getComment(relationship);
            default:
                return null;
        }
    }

    private static String getSemantics(ObjRelationship relationship) {
        StringBuilder semantics =  new StringBuilder(20);
        semantics.append(relationship.isToMany() ? "to many" : "to one");
        if (relationship.isReadOnly()) {
            semantics.append(", read-only");
        }
        if (relationship.isToMany()) {
            String collection = "list";
            if (relationship.getCollectionType() != null) {
                int dot = relationship.getCollectionType().lastIndexOf('.');
                collection = relationship
                        .getCollectionType()
                        .substring(dot + 1)
                        .toLowerCase();
            }

            semantics.append(", ").append(collection);
        }
        return semantics.toString();
    }

    @Override
    public void setUpdatedValueAt(Object value, int row, int column) {
        ObjRelationship relationship = getRelationship(row);
        RelationshipEvent event = new RelationshipEvent(eventSource, relationship, entity);

        switch (column) {
            case REL_NAME:
                String text = (String) value;
                event.setOldName(relationship.getName());
                ProjectUtil.setRelationshipName(entity, relationship, text);
                fireTableCellUpdated(row, column);
                break;
            case REL_TARGET:
                ObjEntity target = (ObjEntity) value;
                relationship.setTargetEntityName(target);

                // Clear existing relationships, otherwise addDbRelationship() might fail
                relationship.clearDbRelationships();

                // now try to connect DbEntities if we can do it in one step
                if (target != null) {
                    DbEntity srcDB = relationship.getSourceEntity()
                            .getDbEntity();
                    DbEntity targetDB = target.getDbEntity();
                    if (srcDB != null && targetDB != null) {
                        Relationship anyConnector = srcDB.getAnyRelationship(targetDB);
                        if (anyConnector != null) {
                            relationship.addDbRelationship((DbRelationship) anyConnector);
                        }
                    }
                }

                fireTableRowsUpdated(row, row);
                break;
            case REL_DELETE_RULE:
                relationship.setDeleteRule(DeleteRule.deleteRuleForName((String) value));
                fireTableCellUpdated(row, column);
                break;
            case REL_LOCKING:
                relationship.setUsedForLocking((value instanceof Boolean) && (Boolean) value);
                fireTableCellUpdated(row, column);
                break;
            case REL_TARGET_PATH:
                relationship.setDbRelationshipPath((String) value);
                fireTableCellUpdated(row, column);
                break;
            case REL_COMMENT:
                setComment((String)value, relationship);
                fireTableRowsUpdated(row, row);
                break;
        }

        mediator.fireObjRelationshipEvent(event);
    }

    public void removeRow(int row) {
        if (row < 0) {
            return;
        }
        Relationship rel = getRelationship(row);
        RelationshipEvent e;
        e = new RelationshipEvent(eventSource, rel, entity, RelationshipEvent.REMOVE);
        mediator.fireObjRelationshipEvent(e);
        objectList.remove(row);
        entity.removeRelationship(rel.getName());
        fireTableRowsDeleted(row, row);
    }

    private boolean isInherited(int row) {
        ObjRelationship relationship = getRelationship(row);
        return (relationship != null) && relationship.getSourceEntity() != entity;
    }

    @Override
    public boolean isCellEditable(int row, int col) {
        return !isInherited(row) && col != REL_SEMANTICS && col != REL_TARGET;
    }

    final class RelationshipComparator implements Comparator {
        public int compare(ObjRelationship o1, ObjRelationship o2) {
            int delta = getWeight(o1) - getWeight(o2);
            return (delta != 0) ? delta : Util.nullSafeCompare(true, o1.getName(), o2.getName());
        }

        private int getWeight(ObjRelationship r) {
            return r.getSourceEntity() == entity ? 1 : -1;
        }
    }

    @Override
    public boolean isColumnSortable(int sortCol) {
        return true;
    }

    @Override
    public void sortByColumn(final int sortCol, boolean isAscent) {
        switch (sortCol) {
            case REL_NAME:
                sortByElementProperty("name", isAscent);
                break;
            case REL_TARGET:
                sortByElementProperty("targetEntityName", isAscent);
                break;
            case REL_LOCKING:
                sortByElementProperty("usedForLocking", isAscent);
                break;
            case REL_SEMANTICS:
            case REL_DELETE_RULE:
            case REL_TARGET_PATH:
                objectList.sort(new ObjRelationshipTableComparator(sortCol));
                if (!isAscent) {
                    Collections.reverse(objectList);
                }
                break;
            default:
                break;
        }
    }

    private static class ObjRelationshipTableComparator implements Comparator{

        private int sortCol;

        ObjRelationshipTableComparator(int sortCol) {
            this.sortCol = sortCol;
        }

        public int compare(ObjRelationship o1, ObjRelationship o2) {
            if (o1 == o2) {
                return 0;
            } else if (o1 == null) {
                return -1;
            } else if (o2 == null) {
                return 1;
            }

            switch(sortCol) {
                case REL_SEMANTICS:
                    return compareColumnsData(getSemantics(o1), getSemantics(o2));
                case REL_DELETE_RULE:
                    return compareColumnsData(DeleteRule.deleteRuleName(o1.getDeleteRule()),
                                    DeleteRule.deleteRuleName(o2.getDeleteRule()));
                case REL_TARGET_PATH:
                    return compareColumnsData(o1.getDbRelationshipPath(), o2.getDbRelationshipPath());
                default:
                    return compareColumnsData("", "");
            }
        }
    }

    private static int compareColumnsData(String value1, String value2) {
        if (value1 == null) {
            return -1;
        } else if (value2 == null) {
            return 1;
        } else {
            return value1.compareTo(value2);
        }
    }

    private String getComment(ObjRelationship rel) {
        return ObjectInfo.getFromMetaData(mediator.getApplication().getMetaData(), rel, ObjectInfo.COMMENT);
    }

    private void setComment(String newVal, ObjRelationship rel) {
        ObjectInfo.putToMetaData(mediator.getApplication().getMetaData(), rel, ObjectInfo.COMMENT, newVal);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy