/******************************************************************************* * 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; } }