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

org.apache.cayenne.modeler.action.RemoveAction 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.action;

import org.apache.cayenne.configuration.ConfigurationNode;
import org.apache.cayenne.configuration.DataChannelDescriptor;
import org.apache.cayenne.configuration.DataNodeDescriptor;
import org.apache.cayenne.configuration.event.DataMapEvent;
import org.apache.cayenne.configuration.event.DataNodeEvent;
import org.apache.cayenne.configuration.event.ProcedureEvent;
import org.apache.cayenne.configuration.event.ProcedureParameterEvent;
import org.apache.cayenne.configuration.event.QueryEvent;
import org.apache.cayenne.map.Attribute;
import org.apache.cayenne.map.CallbackMap;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.DbRelationship;
import org.apache.cayenne.map.Embeddable;
import org.apache.cayenne.map.EmbeddableAttribute;
import org.apache.cayenne.map.Entity;
import org.apache.cayenne.map.ObjAttribute;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.ObjRelationship;
import org.apache.cayenne.map.Procedure;
import org.apache.cayenne.map.ProcedureParameter;
import org.apache.cayenne.map.Relationship;
import org.apache.cayenne.map.event.AttributeEvent;
import org.apache.cayenne.map.event.EmbeddableAttributeEvent;
import org.apache.cayenne.map.event.EmbeddableEvent;
import org.apache.cayenne.map.event.EntityEvent;
import org.apache.cayenne.map.event.MapEvent;
import org.apache.cayenne.map.event.RelationshipEvent;
import org.apache.cayenne.modeler.Application;
import org.apache.cayenne.modeler.ProjectController;
import org.apache.cayenne.modeler.dialog.ConfirmRemoveDialog;
import org.apache.cayenne.modeler.editor.CallbackType;
import org.apache.cayenne.modeler.editor.ObjCallbackMethod;
import org.apache.cayenne.modeler.event.CallbackMethodEvent;
import org.apache.cayenne.modeler.undo.RemoveAttributeUndoableEdit;
import org.apache.cayenne.modeler.undo.RemoveCallbackMethodUndoableEdit;
import org.apache.cayenne.modeler.undo.RemoveCompoundUndoableEdit;
import org.apache.cayenne.modeler.undo.RemoveRelationshipUndoableEdit;
import org.apache.cayenne.modeler.undo.RemoveUndoableEdit;
import org.apache.cayenne.modeler.util.CayenneAction;
import org.apache.cayenne.modeler.util.ProjectUtil;
import org.apache.cayenne.query.Query;
import org.apache.cayenne.map.QueryDescriptor;

import javax.swing.KeyStroke;
import javax.swing.undo.CompoundEdit;
import javax.swing.undo.UndoableEdit;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * Removes currently selected object from the project. This can be Domain, DataNode,
 * Entity, Attribute or Relationship.
 */
public class RemoveAction extends CayenneAction {

    public static String getActionName() {
        return "Remove";
    }

    public RemoveAction(Application application) {
        super(getActionName(), application);
    }

    protected RemoveAction(String actionName, Application application) {
        super(actionName, application);
    }

    @Override
    public String getIconName() {
        return "icon-trash.png";
    }

    @Override
    public KeyStroke getAcceleratorKey() {
        return KeyStroke.getKeyStroke(KeyEvent.VK_D, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
    }

    /**
     * Creates and returns dialog for delete prompt
     * 
     * @param allowAsking If false, no question will be asked no matter what settings are
     */
    public ConfirmRemoveDialog getConfirmDeleteDialog(boolean allowAsking) {
        return new ConfirmRemoveDialog(allowAsking);
    }

    @Override
    public void performAction(ActionEvent e) {
        performAction(e, true);
    }

    /**
     * Performs delete action
     * 
     * @param allowAsking If false, no question will be asked no matter what settings are
     */
    public void performAction(ActionEvent e, boolean allowAsking) {

        ProjectController mediator = getProjectController();
        ConfirmRemoveDialog dialog = getConfirmDeleteDialog(allowAsking);
        
        if (mediator.getCurrentObjEntity() != null) {
            if (dialog.shouldDelete("ObjEntity", mediator.getCurrentObjEntity().getName())) {

                application.getUndoManager()
                        .addEdit(new RemoveUndoableEdit(mediator.getCurrentDataMap(), mediator.getCurrentObjEntity()));
                removeObjEntity(mediator.getCurrentDataMap(), mediator.getCurrentObjEntity());
            }
        } else if (mediator.getCurrentDbEntity() != null) {
            if (dialog.shouldDelete("DbEntity", mediator.getCurrentDbEntity().getName())) {

                application.getUndoManager()
                        .addEdit(new RemoveUndoableEdit(mediator.getCurrentDataMap(), mediator.getCurrentDbEntity()));
                removeDbEntity(mediator.getCurrentDataMap(), mediator.getCurrentDbEntity());
            }
        } else if (mediator.getCurrentQuery() != null) {
            if (dialog.shouldDelete("query", mediator.getCurrentQuery().getName())) {

                application.getUndoManager()
                        .addEdit(new RemoveUndoableEdit(mediator.getCurrentDataMap(), mediator.getCurrentQuery()));
                removeQuery(mediator.getCurrentDataMap(), mediator.getCurrentQuery());
            }
        } else if (mediator.getCurrentProcedure() != null) {
            if (dialog.shouldDelete("procedure", mediator.getCurrentProcedure().getName())) {

                application.getUndoManager()
                        .addEdit(new RemoveUndoableEdit(mediator.getCurrentDataMap(), mediator.getCurrentProcedure()));
                removeProcedure(mediator.getCurrentDataMap(), mediator.getCurrentProcedure());
            }
        } else if (mediator.getCurrentEmbeddable() != null) {
            if (dialog.shouldDelete("embeddable", mediator.getCurrentEmbeddable().getClassName())) {

                application.getUndoManager()
                        .addEdit(new RemoveUndoableEdit(mediator.getCurrentDataMap(), mediator.getCurrentEmbeddable()));
                removeEmbeddable(mediator.getCurrentDataMap(), mediator.getCurrentEmbeddable());
            }
        } else if (mediator.getCurrentDataMap() != null) {
            if (dialog.shouldDelete("data map", mediator.getCurrentDataMap().getName())) {

                // In context of Data node just remove from Data Node
                if (mediator.getCurrentDataNode() != null) {
                    application.getUndoManager()
                            .addEdit(new RemoveUndoableEdit(application, mediator.getCurrentDataNode(),
                                    mediator.getCurrentDataMap()));
                    removeDataMapFromDataNode(mediator.getCurrentDataNode(), mediator.getCurrentDataMap());
                } else {
                    // Not under Data Node, remove completely
                    application.getUndoManager()
                            .addEdit(new RemoveUndoableEdit(application, mediator.getCurrentDataMap()));
                    removeDataMap(mediator.getCurrentDataMap());
                }
            }
        } else if (mediator.getCurrentDataNode() != null) {
            if (dialog.shouldDelete("data node", mediator.getCurrentDataNode().getName())) {

                application.getUndoManager()
                        .addEdit(new RemoveUndoableEdit(application, mediator.getCurrentDataNode()));
                removeDataNode(mediator.getCurrentDataNode());
            }
        } else if (mediator.getCurrentPaths() != null) { // multiple deletion
            if (dialog.shouldDelete("selected objects")) {

                ConfigurationNode[] paths = mediator.getCurrentPaths();
                ConfigurationNode parentPath = mediator.getCurrentParentPath();

                CompoundEdit compoundEdit = new RemoveCompoundUndoableEdit();
                for (ConfigurationNode path : paths) {
                    compoundEdit.addEdit(removeLastPathComponent(path, parentPath));
                }
                compoundEdit.end();

                application.getUndoManager().addEdit(compoundEdit);
            }
        } else if(mediator.getCurrentCallbackMethods().length > 0) {
            removeMethods(mediator, dialog, getProjectController().getCurrentCallbackMethods());
        } else if(mediator.getCurrentObjRelationships().length > 0) {
      		removeObjRelationships(mediator, dialog, getProjectController().getCurrentObjRelationships());
        } else if(mediator.getCurrentDbRelationships().length > 0) {
      		removeDBRelationships(mediator, dialog, getProjectController().getCurrentDbRelationships());
        } else if(mediator.getCurrentObjAttributes().length > 0) {
      		removeObjAttributes(mediator, dialog, getProjectController().getCurrentObjAttributes());
        } else if(mediator.getCurrentEmbAttributes().length > 0) {
      		removeEmbAttributes(mediator, dialog, getProjectController().getCurrentEmbAttributes());
        } else if(mediator.getCurrentDbAttributes().length > 0) {
        	removeDbAttributes(mediator, dialog, getProjectController().getCurrentDbAttributes());
        } else if(mediator.getCurrentProcedureParameters().length > 0) {
        	removeProcedureParameters(mediator.getCurrentProcedure(), mediator.getCurrentProcedureParameters());
        }

    }

    private void removeProcedureParameters(Procedure procedure, ProcedureParameter[] parameters) {
        ProjectController mediator = getProjectController();
        for (ProcedureParameter parameter : parameters) {
            procedure.removeCallParameter(parameter.getName());
            ProcedureParameterEvent e = new ProcedureParameterEvent(Application.getFrame(), parameter, MapEvent.REMOVE);
            mediator.fireProcedureParameterEvent(e);
        }
    }
    
    private void removeEmbAttributes(ProjectController mediator, ConfirmRemoveDialog dialog,
                                     EmbeddableAttribute[] embAttrs) {
    	if (embAttrs != null && embAttrs.length > 0) {
        	if ((embAttrs.length == 1 && dialog.shouldDelete("DbAttribute", embAttrs[0].getName()))
                    || (embAttrs.length > 1 && dialog.shouldDelete("selected DbAttributes"))) {

        		Embeddable embeddable = mediator.getCurrentEmbeddable();

                application.getUndoManager()
                        .addEdit(new RemoveAttributeUndoableEdit(embeddable, embAttrs));

                for (EmbeddableAttribute attrib : embAttrs) {
                    embeddable.removeAttribute(attrib.getName());
                    EmbeddableAttributeEvent e = new EmbeddableAttributeEvent(Application.getFrame(),
                            attrib, embeddable, MapEvent.REMOVE);
                    mediator.fireEmbeddableAttributeEvent(e);
                }

                ProjectUtil.cleanObjMappings(mediator.getCurrentDataMap());
        	}
    	}
	}

	private void removeObjAttributes(ProjectController mediator,
			ConfirmRemoveDialog dialog, ObjAttribute[] objAttrs) {
    	if (objAttrs != null && objAttrs.length > 0) {
        	if ((objAttrs.length == 1 && dialog.shouldDelete("DbAttribute", objAttrs[0].getName()))
                    || (objAttrs.length > 1 && dialog.shouldDelete("selected DbAttributes"))) {

        		ObjEntity entity = mediator.getCurrentObjEntity();

                application.getUndoManager()
                        .addEdit(new RemoveAttributeUndoableEdit(entity, objAttrs));

                for (ObjAttribute attrib : objAttrs) {
                    entity.removeAttribute(attrib.getName());
                    AttributeEvent e = new AttributeEvent(Application.getFrame(), attrib, entity, MapEvent.REMOVE);
                    mediator.fireObjAttributeEvent(e);
                }

                ProjectUtil.cleanObjMappings(mediator.getCurrentDataMap());
        	}
    	}
	}

	private void removeDbAttributes(ProjectController mediator, ConfirmRemoveDialog dialog, DbAttribute[] dbAttrs) {
    	if (dbAttrs != null && dbAttrs.length > 0) {
        	if ((dbAttrs.length == 1 && dialog.shouldDelete("DbAttribute", dbAttrs[0].getName()))
                    || (dbAttrs.length > 1 && dialog.shouldDelete("selected DbAttributes"))) {

        		DbEntity entity = mediator.getCurrentDbEntity();

                application.getUndoManager()
                        .addEdit(new RemoveAttributeUndoableEdit(entity, dbAttrs));

                for (DbAttribute attrib : dbAttrs) {
                    entity.removeAttribute(attrib.getName());
                    AttributeEvent e = new AttributeEvent(Application.getFrame(), attrib, entity, MapEvent.REMOVE);
                    mediator.fireDbAttributeEvent(e);
                }

                ProjectUtil.cleanObjMappings(mediator.getCurrentDataMap());
        	}
    	}
    }
    
    private void removeDBRelationships(ProjectController mediator, ConfirmRemoveDialog dialog,
                                       DbRelationship[] dbRels) {
		if (dbRels != null && dbRels.length > 0) {
			if ((dbRels.length == 1 && dialog.shouldDelete("DbRelationship", dbRels[0].getName()))
					|| (dbRels.length > 1 && dialog.shouldDelete("selected DbRelationships"))) {
				DbEntity entity = mediator.getCurrentDbEntity();
				
				for (DbRelationship rel : dbRels) {
					entity.removeRelationship(rel.getName());
					RelationshipEvent e = new RelationshipEvent(Application.getFrame(), rel, entity, MapEvent.REMOVE);
					mediator.fireDbRelationshipEvent(e);
				}

				ProjectUtil.cleanObjMappings(mediator.getCurrentDataMap());
				Application.getInstance().getUndoManager().addEdit(new RemoveRelationshipUndoableEdit(entity, dbRels));
			}
		}
	}

	private void removeObjRelationships(ProjectController mediator, ConfirmRemoveDialog dialog,
                                        ObjRelationship[] rels) {
		if ((rels.length == 1 && dialog.shouldDelete("ObjRelationship", rels[0].getName()))
				|| (rels.length > 1 && dialog.shouldDelete("selected ObjRelationships"))) {
			ObjEntity entity = mediator.getCurrentObjEntity();
			for (ObjRelationship rel : rels) {
				entity.removeRelationship(rel.getName());
				RelationshipEvent e = new RelationshipEvent(Application.getFrame(), rel, entity, MapEvent.REMOVE);
				mediator.fireObjRelationshipEvent(e);
			}
			Application.getInstance().getUndoManager().addEdit(new RemoveRelationshipUndoableEdit(entity, rels));
		}		
	}

	private void removeMethods(ProjectController mediator, ConfirmRemoveDialog dialog, ObjCallbackMethod[] methods) {
    	CallbackMap callbackMap = mediator.getCurrentObjEntity().getCallbackMap();
    	CallbackType callbackType = mediator.getCurrentCallbackType();

        if ((methods.length == 1 && dialog.shouldDelete("callback method", methods[0].getName()))
        	|| (methods.length > 1 && dialog.shouldDelete("selected callback methods"))) {
            for (ObjCallbackMethod callbackMethod : methods) {
            	callbackMap.getCallbackDescriptor(callbackType.getType()).removeCallbackMethod(callbackMethod.getName());
                    
                CallbackMethodEvent ce = new CallbackMethodEvent(this, null,
                        callbackMethod.getName(),
                        MapEvent.REMOVE);
                    
                mediator.fireCallbackMethodEvent(ce);
            }
            
            Application.getInstance().getUndoManager()
                    .addEdit(new RemoveCallbackMethodUndoableEdit(callbackType, methods));
        }		
	}

	public void removeDataMap(DataMap map) {
        ProjectController mediator = getProjectController();
        DataChannelDescriptor domain = (DataChannelDescriptor) mediator.getProject().getRootNode();
        DataMapEvent e = new DataMapEvent(Application.getFrame(), map, MapEvent.REMOVE);
        e.setDomain((DataChannelDescriptor) mediator.getProject().getRootNode());

        domain.getDataMaps().remove(map);
        if (map.getConfigurationSource() != null) {
            URL mapURL = map.getConfigurationSource().getURL();
            Collection unusedResources = getCurrentProject().getUnusedResources();
            unusedResources.add(mapURL);
        }

        for (DataNodeDescriptor node : domain.getNodeDescriptors()) {
            if (node.getDataMapNames().contains(map.getName())) {
                removeDataMapFromDataNode(node, map);
            }
        }
       
        mediator.fireDataMapEvent(e);
    }

    public void removeDataNode(DataNodeDescriptor node) {
        ProjectController mediator = getProjectController();
        DataChannelDescriptor domain = (DataChannelDescriptor) mediator.getProject().getRootNode();
        DataNodeEvent e = new DataNodeEvent(Application.getFrame(), node, MapEvent.REMOVE);
        e.setDomain((DataChannelDescriptor) mediator.getProject().getRootNode());

        domain.getNodeDescriptors().remove(node);
        mediator.fireDataNodeEvent(e);
    }

    /**
     * Removes current DbEntity from its DataMap and fires "remove" EntityEvent.
     */
    public void removeDbEntity(DataMap map, DbEntity ent) {
        ProjectController mediator = getProjectController();

        EntityEvent e = new EntityEvent(Application.getFrame(), ent, MapEvent.REMOVE);
        e.setDomain((DataChannelDescriptor) mediator.getProject().getRootNode());

        map.removeDbEntity(ent.getName(), true);
        mediator.fireDbEntityEvent(e);
    }

    /**
     * Removes current Query from its DataMap and fires "remove" QueryEvent.
     */
    public void removeQuery(DataMap map, QueryDescriptor query) {
        ProjectController mediator = getProjectController();

        QueryEvent e = new QueryEvent(Application.getFrame(), query, MapEvent.REMOVE, map);
        e.setDomain((DataChannelDescriptor) mediator.getProject().getRootNode());

        map.removeQueryDescriptor(query.getName());
        mediator.fireQueryEvent(e);
    }

    /**
     * Removes current Procedure from its DataMap and fires "remove" ProcedureEvent.
     */
    public void removeProcedure(DataMap map, Procedure procedure) {
        ProjectController mediator = getProjectController();

        ProcedureEvent e = new ProcedureEvent(Application.getFrame(), procedure, MapEvent.REMOVE);
        e.setDomain((DataChannelDescriptor) mediator.getProject().getRootNode());

        map.removeProcedure(procedure.getName());
        mediator.fireProcedureEvent(e);
    }

    /**
     * Removes current object entity from its DataMap.
     */
    public void removeObjEntity(DataMap map, ObjEntity entity) {
        ProjectController mediator = getProjectController();

        EntityEvent e = new EntityEvent(Application.getFrame(), entity, MapEvent.REMOVE);
        e.setDomain((DataChannelDescriptor) mediator.getProject().getRootNode());

        map.removeObjEntity(entity.getName(), true);
        mediator.fireObjEntityEvent(e);

        // remove queries that depend on entity
        // TODO: (Andrus, 09/09/2005) show warning dialog?

        // clone to be able to remove within iterator...
        for (QueryDescriptor query : new ArrayList<>(map.getQueryDescriptors())) {
            if (!QueryDescriptor.EJBQL_QUERY.equals(query.getType())) {
                Object root = query.getRoot();

                if (root == entity || (root instanceof String && root.toString().equals(entity.getName()))) {
                    removeQuery(map, query);
                }
            }
        }
    }

    public void removeEmbeddable(DataMap map, Embeddable embeddable) {
        ProjectController mediator = getProjectController();

        EmbeddableEvent e = new EmbeddableEvent(Application.getFrame(), embeddable, MapEvent.REMOVE);
        e.setDomain((DataChannelDescriptor) mediator.getProject().getRootNode());

        map.removeEmbeddable(embeddable.getClassName());
        mediator.fireEmbeddableEvent(e, map);
    }

    public void removeDataMapFromDataNode(DataNodeDescriptor node, DataMap map) {
        ProjectController mediator = getProjectController();

        DataNodeEvent e = new DataNodeEvent(Application.getFrame(), node);
        e.setDomain((DataChannelDescriptor) mediator.getProject().getRootNode());

        node.getDataMapNames().remove(map.getName());

        // Force reloading of the data node in the browse view
        mediator.fireDataNodeEvent(e);
    }

    /**
     * Returns true if last object in the path contains a removable object.
     */
    @Override
    public boolean enableForPath(ConfigurationNode object) {
        return (object instanceof DataChannelDescriptor)
                || (object instanceof DataMap)
                || (object instanceof DataNodeDescriptor)
                || (object instanceof Entity)
                || (object instanceof Attribute)
                || (object instanceof Relationship)
                || (object instanceof Procedure)
                || (object instanceof ProcedureParameter)
                || (object instanceof QueryDescriptor)
                || (object instanceof Embeddable)
                || (object instanceof EmbeddableAttribute);
    }

    /**
     * Removes an object, depending on its type
     */
    private UndoableEdit removeLastPathComponent(ConfigurationNode object, ConfigurationNode parentObject) {

        UndoableEdit undo = null;

        if (object instanceof DataMap) {
            if (parentObject != null && parentObject instanceof DataNodeDescriptor) {
                undo = new RemoveUndoableEdit(application, (DataNodeDescriptor) parentObject, (DataMap) object);
                removeDataMapFromDataNode((DataNodeDescriptor) parentObject, (DataMap) object);
            } else {
                // Not under Data Node, remove completely
                undo = new RemoveUndoableEdit(application, (DataMap) object);
                removeDataMap((DataMap) object);
            }
        } else if (object instanceof DataNodeDescriptor) {
            undo = new RemoveUndoableEdit(application, (DataNodeDescriptor) object);
            removeDataNode((DataNodeDescriptor) object);
        } else if (object instanceof DbEntity) {
            undo = new RemoveUndoableEdit(((DbEntity) object).getDataMap(), (DbEntity) object);
            removeDbEntity(((DbEntity) object).getDataMap(), (DbEntity) object);
        } else if (object instanceof ObjEntity) {
            undo = new RemoveUndoableEdit(((ObjEntity) object).getDataMap(), (ObjEntity) object);
            removeObjEntity(((ObjEntity) object).getDataMap(), (ObjEntity) object);
        } else if (object instanceof QueryDescriptor) {
            undo = new RemoveUndoableEdit(((QueryDescriptor) object).getDataMap(), (QueryDescriptor) object);
            removeQuery(((QueryDescriptor) object).getDataMap(), (QueryDescriptor) object);
        } else if (object instanceof Procedure) {
            undo = new RemoveUndoableEdit(((Procedure) object).getDataMap(), (Procedure) object);
            removeProcedure(((Procedure) object).getDataMap(), (Procedure) object);
        } else if (object instanceof Embeddable) {
            undo = new RemoveUndoableEdit(((Embeddable) object).getDataMap(), (Embeddable) object);
            removeEmbeddable(((Embeddable) object).getDataMap(), (Embeddable) object);
        }

        return undo;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy