org.eclipse.jubula.client.ui.rcp.handlers.project.DeleteProjectHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.jubula.client.ui.rcp.handlers.project.DeleteProjectHandler.java

Source

/*******************************************************************************
 * Copyright (c) 2004, 2010 BREDEX GmbH.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     BREDEX GmbH - initial API and implementation and/or initial documentation
 *******************************************************************************/
package org.eclipse.jubula.client.ui.rcp.handlers.project;

import java.lang.reflect.InvocationTargetException;
import java.util.List;

import javax.persistence.EntityManager;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.window.Window;
import org.eclipse.jubula.client.core.businessprocess.progress.ProgressMonitorTracker;
import org.eclipse.jubula.client.core.events.DataEventDispatcher;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.DataState;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.TestresultState;
import org.eclipse.jubula.client.core.events.DataEventDispatcher.UpdateState;
import org.eclipse.jubula.client.core.model.IProjectPO;
import org.eclipse.jubula.client.core.model.IReusedProjectPO;
import org.eclipse.jubula.client.core.model.ProjectVersion;
import org.eclipse.jubula.client.core.persistence.GeneralStorage;
import org.eclipse.jubula.client.core.persistence.NodePM;
import org.eclipse.jubula.client.core.persistence.PMException;
import org.eclipse.jubula.client.core.persistence.Persistor;
import org.eclipse.jubula.client.core.persistence.ProjectPM;
import org.eclipse.jubula.client.core.persistence.TestResultSummaryPM;
import org.eclipse.jubula.client.ui.constants.ContextHelpIds;
import org.eclipse.jubula.client.ui.constants.IconConstants;
import org.eclipse.jubula.client.ui.handlers.project.AbstractProjectHandler;
import org.eclipse.jubula.client.ui.rcp.Plugin;
import org.eclipse.jubula.client.ui.rcp.controllers.PMExceptionHandler;
import org.eclipse.jubula.client.ui.rcp.dialogs.ProjectDialog;
import org.eclipse.jubula.client.ui.rcp.i18n.Messages;
import org.eclipse.jubula.client.ui.rcp.utils.Utils;
import org.eclipse.jubula.client.ui.utils.DialogUtils;
import org.eclipse.jubula.client.ui.utils.ErrorHandlingUtil;
import org.eclipse.jubula.tools.internal.exception.JBException;
import org.eclipse.jubula.tools.internal.exception.ProjectDeletedException;
import org.eclipse.jubula.tools.internal.messagehandling.MessageIDs;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.PlatformUI;

/**
 * @author BREDEX GmbH
 * @created 06.07.2005
 */
public class DeleteProjectHandler extends AbstractProjectHandler {

    /** number of Persistence (JPA / EclipseLink) event types with progress listeners */
    // Event types:
    // postRemove
    private static final int NUM_HBM_PROGRESS_EVENT_TYPES = 1;

    /**
     * Operation for deleting a project.
     * 
     * @author BREDEX GmbH
     * @created Jan 7, 2008
     */
    private class DeleteProjectOperation implements IRunnableWithProgress {

        /** the project to delete */
        private IProjectPO m_project;

        /** whether the currently opened project is the project to delete */
        private boolean m_deleteCurrentProject;

        /** true, if test result summary of project should not be deleted */
        private boolean m_keepTestresultSummary = false;

        /**
         * Constructor
         * 
         * @param project The project to delete.
         * @param deleteCurrentProject <code>true</code> if the project to 
         *                             delete is the currently opened project.
         *                             Otherwise, <code>false</code>.
         * @param keepTestresultSummary true, if test result summary should not be deleted
         */
        public DeleteProjectOperation(IProjectPO project, boolean deleteCurrentProject,
                boolean keepTestresultSummary) {

            m_project = project;
            m_deleteCurrentProject = deleteCurrentProject;
            m_keepTestresultSummary = keepTestresultSummary;
        }

        /**
         * {@inheritDoc}
         */
        public void run(IProgressMonitor monitor) throws InterruptedException {
            final ProjectVersion version = m_project.getProjectVersion();
            monitor.beginTask(
                    NLS.bind(Messages.DeleteProjectActionDeleting, new Object[] { m_project.getName(), version }),
                    getTotalWork());
            ProgressMonitorTracker instance = ProgressMonitorTracker.SINGLETON;
            try {
                boolean isRefreshRequired = false;
                final String guid = m_project.getGuid();
                if (!m_deleteCurrentProject) {
                    isRefreshRequired = isRefreshRequired(guid, version);
                }
                if (m_deleteCurrentProject) {
                    Plugin.getDisplay().syncExec(new Runnable() {
                        public void run() {
                            Plugin.closeAllOpenedJubulaEditors(false);
                        }
                    });
                }

                // Register Persistence (JPA / EclipseLink) progress listeners
                instance.setProgressMonitor(monitor);
                ProjectPM.deleteProject(m_project, m_deleteCurrentProject);
                final String jobName = Messages.UIJobDeletingTestResultDetails;
                final DataEventDispatcher ded = DataEventDispatcher.getInstance();
                Job job = new Job(jobName) {
                    public IStatus run(IProgressMonitor mon) {
                        mon.beginTask(jobName, IProgressMonitor.UNKNOWN);
                        TestResultSummaryPM.deleteTestrunsByProject(guid, version, m_keepTestresultSummary);
                        mon.done();
                        ded.fireTestresultChanged(TestresultState.Refresh);
                        return Status.OK_STATUS;
                    }
                };
                if (m_deleteCurrentProject) {
                    Utils.clearClient();
                    GeneralStorage.getInstance().nullProject();
                    ded.fireDataChangedListener(m_project, DataState.Deleted, UpdateState.all);
                } else if (isRefreshRequired) {
                    GeneralStorage.getInstance().reloadMasterSession(new NullProgressMonitor());
                }
                job.schedule();
            } catch (PMException e) {
                PMExceptionHandler.handlePMExceptionForMasterSession(e);
                return;
            } catch (ProjectDeletedException e) {
                PMExceptionHandler.handleProjectDeletedException();
                return;
            } catch (JBException e) {
                ErrorHandlingUtil.createMessageDialog(e, null, null);
            } finally {
                // Remove JPA progress listeners
                instance.setProgressMonitor(null);
                monitor.done();
                Plugin.stopLongRunning();
            }
        }

        /**
         * 
         * @return the total units of work required for this operation.
         */
        private int getTotalWork() {
            int totalWork = 0;

            // (project_node=1)
            totalWork++;
            EntityManager getNumNodesSession = Persistor.instance().openSession();
            totalWork += NodePM.getNumNodes(m_project.getId(), getNumNodesSession);
            Persistor.instance().dropSessionWithoutLockRelease(getNumNodesSession);

            totalWork *= NUM_HBM_PROGRESS_EVENT_TYPES;

            return totalWork;
        }
    }

    /**
     * Opens a dialog to select a project to delete.
     */
    void selectProject() {
        boolean deleteCurrentProject = false;
        List<IProjectPO> projList;
        try {
            projList = ProjectPM.findAllProjects();
            if (projList.isEmpty()) {
                ErrorHandlingUtil.createMessageDialog(MessageIDs.I_NO_PROJECT_IN_DB);
                return;
            }
            ProjectDialog dialog = getComboSelectionDialog(projList);
            if (dialog.getReturnCode() == Window.CANCEL) {
                return;
            }
            ProjectDialog.ProjectData project = dialog.getSelection();
            IProjectPO projectToDelete = null;
            for (IProjectPO projToDelete : projList) {
                if (projToDelete.getGuid().equals(project.getGUID())
                        && projToDelete.getVersionString().equals(project.getVersionString())) {
                    projectToDelete = projToDelete;
                }
            }
            if (projectToDelete == null) {
                Plugin.stopLongRunning();
                return;
            }
            boolean keepTestresults = dialog.keepTestresultSummary();
            Integer questionID = null;
            Object[] param = null;
            IProjectPO actProj = GeneralStorage.getInstance().getProject();
            if (actProj != null && actProj.getId().equals(projectToDelete.getId())) {
                questionID = MessageIDs.Q_DELETE_ACTUAL_PROJECT;
                deleteCurrentProject = true;
            } else {
                questionID = MessageIDs.Q_DELETE_PROJECT;
                param = new Object[] { projectToDelete.getName() };
            }
            Plugin.startLongRunning(Messages.DeleteProjectActionWaitWhileDeleting);
            Dialog qDialog = ErrorHandlingUtil.createMessageDialog(questionID, param, null);
            if (qDialog.getReturnCode() == 0) {
                try {
                    PlatformUI.getWorkbench().getProgressService().busyCursorWhile(
                            new DeleteProjectOperation(projectToDelete, deleteCurrentProject, keepTestresults));
                } catch (InvocationTargetException e) {
                    // Exception occurred during the operation.
                    // The exception was already handled by the operation.
                    // Do nothing.
                } catch (InterruptedException e) {
                    // Operation was canceled.
                    // Do nothing.
                }
            }
        } catch (JBException e) {
            ErrorHandlingUtil.createMessageDialog(e, null, null);
        } finally {
            Plugin.stopLongRunning();
        }
    }

    /**
     * Returns <code>true</code> if deletion of the project with the given 
     * attributes will require a refresh of the current project in order to 
     * see changes in the reused project set.
     * 
     * @param deletedGuid The GUID of the deleted project.
     * @param version the {@link ProjectVersion}  of the deleted project.
     * @return <code>true</code> if the deleted GUID and major and minor version
     *         numbers are present in the current project's set of reused
     *         projects. Otherwise <code>false</code>.
     */
    private boolean isRefreshRequired(String deletedGuid, ProjectVersion version) {

        IProjectPO currentProject = GeneralStorage.getInstance().getProject();

        if (currentProject == null) {
            return false;
        }

        for (IReusedProjectPO reused : currentProject.getUsedProjects()) {

            String guid = reused.getProjectGuid();
            ProjectVersion reusedVersion = reused.getProjectVersion();
            if (deletedGuid.equals(guid) && version.equals(reusedVersion)) {
                return true;
            }
        }

        return false;
    }

    /**
     * @param projList
     *            The input list.
     * @return The dialog when closed.
     */
    private ProjectDialog getComboSelectionDialog(List<IProjectPO> projList) {
        ProjectDialog dialog = new ProjectDialog(getActiveShell(), projList, Messages.DeleteProjectActionMessage,
                Messages.OpenProjectActionTitle, IconConstants.DELETE_PROJECT_DIALOG_IMAGE,
                Messages.DeleteProjectActionCaption, true);
        // set up help for the dialog
        dialog.setHelpAvailable(true);
        dialog.create();
        DialogUtils.setWidgetNameForModalDialog(dialog);
        Plugin.getHelpSystem().setHelp(dialog.getShell(), ContextHelpIds.DELETE_PROJECT);
        dialog.open();
        return dialog;
    }

    /**
     * {@inheritDoc}
     */
    public Object executeImpl(ExecutionEvent event) {
        selectProject();
        return null;
    }
}