/*******************************************************************************
* Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
* Licensed 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*******************************************************************************/
package org.ebayopensource.turmeric.eclipse.typelibrary.ui.actions;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.ebayopensource.turmeric.common.config.LibraryType;
import org.ebayopensource.turmeric.eclipse.buildsystem.SynchronizeWsdlAndDepXML;
import org.ebayopensource.turmeric.eclipse.codegen.utils.CodegenInvoker;
import org.ebayopensource.turmeric.eclipse.core.logging.SOALogger;
import org.ebayopensource.turmeric.eclipse.repositorysystem.core.SOAGlobalRegistryAdapter;
import org.ebayopensource.turmeric.eclipse.typelibrary.builders.TypeLibraryBuilderUtils;
import org.ebayopensource.turmeric.eclipse.typelibrary.codegen.model.GenTypeDeleteType;
import org.ebayopensource.turmeric.eclipse.typelibrary.resources.SOAMessages;
import org.ebayopensource.turmeric.eclipse.typelibrary.utils.TypeLibraryUtil;
import org.ebayopensource.turmeric.eclipse.utils.collections.CollectionUtil;
import org.ebayopensource.turmeric.eclipse.utils.plugin.EclipseMessageUtils;
import org.ebayopensource.turmeric.eclipse.utils.plugin.ProgressUtil;
import org.ebayopensource.turmeric.eclipse.utils.plugin.WorkspaceUtil;
import org.ebayopensource.turmeric.eclipse.utils.ui.UIUtil;
import org.ebayopensource.turmeric.eclipse.validator.utils.ValidateUtil;
import org.ebayopensource.turmeric.tools.library.SOATypeRegistry;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.progress.IProgressConstants;
/**
* The Class DeleteTypeAction.
*
* @author smathew
*
* Delete Action in the context menu. This menu is an Object Delegate and would
* be hanging down in any I File object which is an XSD.
*
* Steps in delete. Validate XSD file for accessibility Validate the Type
* Dep/Info for writability. Delete the type from registry Delete The file from
* disk Call Codegen. Synchronize dependency.
*/
public class DeleteTypeAction implements IObjectActionDelegate {
private IStructuredSelection selection;
private static final SOALogger logger = SOALogger.getLogger();
/**
* {@inheritDoc}
*/
@Override
public void setActivePart(final IAction action,
final IWorkbenchPart targetPart) {
}
/**
* {@inheritDoc}
*/
@Override
public void run(final IAction action) {
if (SOALogger.DEBUG)
logger.entering(action, selection);
try {
if (selection == null) {
showErrorDialog();
return;
}
if (!UIUtil.openChoiceDialog("Confirm Type Delete",
"Are you sure you want to delete this type?",
MessageDialog.QUESTION))
return;
if (TypeLibraryUtil.isValidXSDFile(selection.getFirstElement())) {
final IFile xsdFile = (IFile) selection.getFirstElement();
final IProject project = xsdFile.getProject();
final String fileName = StringUtils.substringBeforeLast(xsdFile.getName(),
"." + xsdFile.getFileExtension());
final IFile episodeFile = project.getFile(
"gen-meta-src/META-INF/"
+ project.getName() + "/"
+ fileName
+ ".episode");
final IStatus status = ActionUtil
.validateTypeDependencyAndProjectConfigFile(project, episodeFile);
final String messages = ValidateUtil
.getFormattedStatusMessagesForAction(status);
if (messages != null) {
UIUtil.showErrorDialog(UIUtil.getActiveShell(), "Error",
messages, (Throwable) null);
return;
}
File eFile = episodeFile.getLocation().toFile();
if (eFile.exists() == true) {
File tmpFile = new File(eFile.getCanonicalPath() + ".bak");
try {
if (tmpFile.exists()) {
tmpFile.delete();
}
if (eFile.renameTo(tmpFile) == false) {
UIUtil.showErrorDialog(UIUtil.getActiveShell(), "Error",
SOAMessages.ERR_DELETE_TYPE
+ eFile);
return;
}
} catch (Exception e) {
//the file could not be deleted, warn the user
UIUtil.showErrorDialog(UIUtil.getActiveShell(), "Error",
SOAMessages.ERR_DELETE_TYPE
+ eFile);
return;
} finally {
if (tmpFile.exists()) {
tmpFile.renameTo(eFile);
}
}
}
DeleteTypeAction.executeTypeDeletionTask((IFile) selection.getFirstElement());
} else {
showErrorDialog();
return;
}
} catch (Exception e) {
logger.error(e);
UIUtil.showErrorDialog(e);
} finally {
if (SOALogger.DEBUG)
logger.exiting();
}
}
/**
* {@inheritDoc}
*/
@Override
public void selectionChanged(final IAction action,
final ISelection selection) {
this.selection = (IStructuredSelection) selection;
}
/**
* Execute type deletion task.
*
* @param file the file
* @throws CoreException the core exception
* @throws Exception This is being used from the test apis. So please dont make it private
*/
public static void executeTypeDeletionTask(final IFile file) throws CoreException, Exception {
LibraryType libraryType;
SOAGlobalRegistryAdapter registryAdaptor = SOAGlobalRegistryAdapter.getInstance();
try {
SOATypeRegistry typeRegistry = registryAdaptor.getGlobalRegistry();
libraryType = typeRegistry.getType(TypeLibraryUtil.toQName(file));
final List<LibraryType> childTypes = typeRegistry.getDependentChildTypeFiles(libraryType);
if (!CollectionUtil.isEmpty(childTypes)) {
StringBuilder msg = new StringBuilder("SOA governance found the following types depending on this type: ");
for (LibraryType libType : childTypes) {
msg.append(libType.getName());
msg.append(", ");
}
String smsg = msg.toString();
smsg = StringUtils.substringBeforeLast(smsg, ",");
UIUtil.showErrorDialog(null, "File cannot be deleted",
"Type cannot be deleted", smsg);
return;
} else {
WorkspaceJob job = new WorkspaceJob("Deleting type->" + file.getLocation()) {
@Override
public IStatus runInWorkspace(IProgressMonitor monitor)
throws CoreException {
SOAGlobalRegistryAdapter registryAdaptor = SOAGlobalRegistryAdapter.getInstance();
try {
SOATypeRegistry typeRegistry = registryAdaptor.getGlobalRegistry();
monitor.beginTask("Deleting type->" + file.getLocation(),
ProgressUtil.PROGRESS_STEP * 50);
IProject project = file.getProject();
LibraryType libraryType = typeRegistry.getType(
TypeLibraryUtil.toQName(file));
ProgressUtil.progressOneStep(monitor);
typeRegistry.removeTypeFromRegistry(libraryType);
ProgressUtil.progressOneStep(monitor);
// file.delete(true, ProgressUtil
// .getDefaultMonitor(null));
DeleteTypeAction.callCodegen(project, file, monitor);
ProgressUtil.progressOneStep(monitor);
WorkspaceUtil.refresh(monitor, project);
registryAdaptor.populateRegistry(project
.getName());
ProgressUtil.progressOneStep(monitor);
SynchronizeWsdlAndDepXML synch = new SynchronizeWsdlAndDepXML(project);
synch.syncronizeAllXSDsandDepXml();
ProgressUtil.progressOneStep(monitor);
synch.synchronizeTypeDepandProjectDep(monitor);
WorkspaceUtil.refresh(monitor, project);
} catch (Exception e) {
logger.error(e);
throw new CoreException(EclipseMessageUtils.createErrorStatus(e));
}
setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE);
return Status.OK_STATUS;
}
};
job.setUser(true);
job.schedule();
}
} catch (Exception e) {
WorkspaceUtil.refresh(file.getProject());
UIUtil.showErrorDialog(e);
}
}
private static void callCodegen(IProject project, IFile file, IProgressMonitor monitor) throws Exception {
GenTypeDeleteType genTypeDeleteType = new GenTypeDeleteType();
genTypeDeleteType.setProjectRoot(project.getLocation().toString());
genTypeDeleteType.setLibraryName(project.getName());
ArrayList<String> types = new ArrayList<String>();
types.add(file.getName());
genTypeDeleteType.setTypes(types);
CodegenInvoker codegenInvoker = TypeLibraryBuilderUtils
.initForTypeLib(project);
ProgressUtil.progressOneStep(monitor);
codegenInvoker.execute(genTypeDeleteType);
}
private void showErrorDialog() {
UIUtil
.showErrorDialog(
null,
"This action is not available for this selection.",
"Action not available",
"Please check if the project is a TypeLibrary project and the seleted file is a valid Type.");
}
}