/*******************************************************************************
* 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.services.ui.wizards;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.ebayopensource.turmeric.eclipse.buildsystem.utils.ActionUtil;
import org.ebayopensource.turmeric.eclipse.core.logging.SOALogger;
import org.ebayopensource.turmeric.eclipse.core.model.services.ServiceFromTemplateWsdlParamModel;
import org.ebayopensource.turmeric.eclipse.core.model.services.ServiceFromWsdlParamModel;
import org.ebayopensource.turmeric.eclipse.core.resources.constants.SOAProjectConstants;
import org.ebayopensource.turmeric.eclipse.exception.resources.projects.SOAServiceCreationFailedException;
import org.ebayopensource.turmeric.eclipse.registry.ExtensionPointFactory;
import org.ebayopensource.turmeric.eclipse.registry.intf.IArtifactValidator;
import org.ebayopensource.turmeric.eclipse.registry.intf.IRegistryProvider;
import org.ebayopensource.turmeric.eclipse.registry.intf.IValidationStatus;
import org.ebayopensource.turmeric.eclipse.registry.models.SimpleAssetModel;
import org.ebayopensource.turmeric.eclipse.registry.util.RegistryStatusUtil;
import org.ebayopensource.turmeric.eclipse.repositorysystem.core.GlobalRepositorySystem;
import org.ebayopensource.turmeric.eclipse.repositorysystem.core.ISOAOrganizationProvider;
import org.ebayopensource.turmeric.eclipse.repositorysystem.core.TrackingEvent;
import org.ebayopensource.turmeric.eclipse.resources.util.SOAServiceUtil;
import org.ebayopensource.turmeric.eclipse.services.buildsystem.ServiceCreator;
import org.ebayopensource.turmeric.eclipse.services.ui.SOAMessages;
import org.ebayopensource.turmeric.eclipse.services.ui.wizards.pages.ChooseWSDLSourcePage;
import org.ebayopensource.turmeric.eclipse.services.ui.wizards.pages.DependenciesWizardPage;
import org.ebayopensource.turmeric.eclipse.services.ui.wizards.pages.ServiceFromExistingWSDLWizardPage;
import org.ebayopensource.turmeric.eclipse.services.ui.wizards.pages.ServiceFromNewWSDLAddBindingWizardPage;
import org.ebayopensource.turmeric.eclipse.services.ui.wizards.pages.ServiceFromNewWSDLAddOperationWizardPage;
import org.ebayopensource.turmeric.eclipse.services.ui.wizards.pages.ServiceFromNewWSDLPage;
import org.ebayopensource.turmeric.eclipse.services.ui.wizards.pages.ServiceProtocolSelectionWizardPage;
import org.ebayopensource.turmeric.eclipse.template.wsdl.processors.WSDLTemplateProcessor;
import org.ebayopensource.turmeric.eclipse.ui.AbstractSOADomainWizard;
import org.ebayopensource.turmeric.eclipse.ui.SOABasePage;
import org.ebayopensource.turmeric.eclipse.ui.actions.SOAStatusReportingRunnable;
import org.ebayopensource.turmeric.eclipse.ui.wizards.pages.AbstractNewServiceFromWSDLWizardPage;
import org.ebayopensource.turmeric.eclipse.utils.lang.StringUtil;
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.core.ISOAPreValidator;
import org.eclipse.core.resources.IFile;
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.window.Window;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.ide.IDE;
/**
* The Wizard represents service from new and from existing WSDL both. It stages
* all the wizard pages and finally formulates the UI model and pass it to the
* back end for processing. It has the wizard page navigation logic as the next
* wizard is mostly controlled by the current pages inputs.Even if there are
* some code in the UI component, it does not have many SOA specific logic
* except for some inevitable UI validations and selection responses. The
* principle here is to make the UI as dumb as possible to enable non UI testing
* possible to the maximum extent.
*
* @author smathew
*/
public class ServiceFromWSDLWizard extends AbstractSOADomainWizard {
private static final SOALogger logger = SOALogger.getLogger();
private ChooseWSDLSourcePage chooseWsdlSource = null;
private ServiceFromNewWSDLPage serviceFromNewWSDL = null;
private DependenciesWizardPage intfDependenciesPage = null;
private DependenciesWizardPage implDependenciesPage = null;
private ServiceFromExistingWSDLWizardPage serviceFromExsitingWSDL = null;
private ServiceFromNewWSDLAddOperationWizardPage addOperationPage = null;
private ServiceFromNewWSDLAddBindingWizardPage addBindingPage = null;
private ServiceProtocolSelectionWizardPage protocolPage = null;
/**
* Instantiates a new service from wsdl wizard.
*/
public ServiceFromWSDLWizard() {
super();
}
/**
* {@inheritDoc}
*/
@Override
public boolean canFinish() {
if (chooseWsdlSource == null || serviceFromExsitingWSDL == null
|| serviceFromNewWSDL == null) {
logger.warning(StringUtil.formatString(SOAMessages.INITIALIZE_ERR,
chooseWsdlSource, serviceFromExsitingWSDL,
serviceFromNewWSDL));
return false;
}
final boolean fromExistingWsdl = chooseWsdlSource
.isStartFromExistingWSDL();
if (fromExistingWsdl) {
return serviceFromExsitingWSDL.isPageComplete()
&& getContainer().getCurrentPage() != chooseWsdlSource;
} else {
return serviceFromNewWSDL.isPageComplete()
&& getContainer().getCurrentPage() != chooseWsdlSource
&& addOperationPage.getOperations().size() > 0;
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean performFinish() {
if (SOALogger.DEBUG)
logger.entering();
final boolean fromExistingWsdl = chooseWsdlSource
.isStartFromExistingWSDL();
final AbstractNewServiceFromWSDLWizardPage wizardPage = fromExistingWsdl ? serviceFromExsitingWSDL
: serviceFromNewWSDL;
// saving the user selected project dir
final boolean overrideWorkspaceRoot = wizardPage
.isOverrideProjectRootDirectory();
final String workspaceRootDirectory = wizardPage
.getProjectRootDirectory();
if (overrideWorkspaceRoot)
SOABasePage.saveWorkspaceRoot(workspaceRootDirectory);
final String adminName = wizardPage.getAdminName();
final String servicePackage = wizardPage.getServicePackage();
final String serviceInterface = SOAServiceUtil
.generateInterfaceClassName(adminName, servicePackage);
final String implProjectName = adminName
+ SOAProjectConstants.IMPL_PROJECT_SUFFIX;
final ServiceFromWsdlParamModel uiModel = fromExistingWsdl ? new ServiceFromWsdlParamModel()
: new ServiceFromTemplateWsdlParamModel();
uiModel.setServiceName(adminName);
uiModel.setPublicServiceName(wizardPage.getPublicServiceName());
uiModel.setServiceInterface(serviceInterface);
uiModel.setOverrideWorkspaceRoot(overrideWorkspaceRoot);
uiModel.setWorkspaceRootDirectory(workspaceRootDirectory);
uiModel.setServiceImpl(wizardPage
.getFullyQualifiedServiceImplementation());
uiModel.setServiceVersion(wizardPage.getServiceVersion());
uiModel.setServiceImplType(wizardPage.getServiceImplType());
if (!wizardPage.getTypeFolding())
uiModel.setTypeNamespace(wizardPage.getTypeNamespace());
uiModel.setTypeFolding(wizardPage.getTypeFolding());
uiModel.setServiceLayer(wizardPage.getServiceLayer());
uiModel.setInterfaceLibs(intfDependenciesPage.getLibraries());
uiModel.setInterfaceProjects(intfDependenciesPage.getProjects());
uiModel.setImplLibs(implDependenciesPage.getLibraries());
uiModel.setImplProjects(implDependenciesPage.getProjects());
uiModel.setImplName(implProjectName);
uiModel.setServiceDomain(wizardPage.getServiceDomain());
uiModel.setNamespacePart(wizardPage.getDomainClassifier());
uiModel.setServiceNonXSDProtocols(protocolPage.getNonXSDProtocolString());
uiModel.setNamespaceToPacakgeMappings(wizardPage
.getNamespaceToPackageMappings());
try {
if (fromExistingWsdl) {
uiModel
.setWSDLSourceType(SOAProjectConstants.InterfaceWsdlSourceType.EXISTIING);
uiModel.setOriginalWsdlUrl(new URL(serviceFromExsitingWSDL
.getWSDLURL()));
} else {
final ServiceFromTemplateWsdlParamModel tempModel = (ServiceFromTemplateWsdlParamModel) uiModel;
tempModel.setTemplateFile(serviceFromNewWSDL.getTemplateFile());
uiModel.setTargetNamespace(serviceFromNewWSDL
.getTargetNamespace());
uiModel
.setWSDLSourceType(SOAProjectConstants.InterfaceWsdlSourceType.NEW);
tempModel.setOperations(addOperationPage.getOperations());
tempModel.setBindings(addBindingPage.getBindings());
}
final ISOAOrganizationProvider provider = GlobalRepositorySystem
.instanceOf().getActiveRepositorySystem()
.getActiveOrganizationProvider();
// registry validation
SOAStatusReportingRunnable validationRunnable = new SOAStatusReportingRunnable() {
@Override
public IStatus execute(IProgressMonitor monitor)
throws Exception {
monitor.beginTask("Checking existence for service->"
+ uiModel.getServiceName(),
ProgressUtil.PROGRESS_STEP * 30);
final List<IStatus> statuses = new ArrayList<IStatus>();
IRegistryProvider regProvider = ExtensionPointFactory
.getSOARegistryProvider();
if (regProvider == null) {
// could not find a reg provider
logger
.warning(SOAMessages.WARNING_MISSING_REGISTRY_PROVIDER);
} else {
ProgressUtil.progressOneStep(monitor);
final SimpleAssetModel assetModel = new SimpleAssetModel();
assetModel.setAssetAdminName(uiModel.getServiceName());
assetModel.setAssetName(uiModel.getPublicServiceName());
assetModel.setAssetVersion(uiModel.getServiceVersion());
assetModel.setDomainName(uiModel.getServiceDomain());
assetModel.setNamespacePart(uiModel.getNamespacePart());
logger.info("Checking asset name existence ->",
assetModel);
IStatus nameCheckStatus = regProvider.assetNameExists(
assetModel, monitor);
logger.info("Asset name existence checking result->",
nameCheckStatus);
if (RegistryStatusUtil
.isLoginFailStatus(nameCheckStatus)) {
if (SOALogger.DEBUG)
logger.debug("Asset Repository login failed.");
} else if (nameCheckStatus.getSeverity() == IStatus.CANCEL) {
if (SOALogger.DEBUG)
logger
.debug("Asset Repository login canceled. Service Name duplication check is skipped.");
} else if (nameCheckStatus.isOK() == false) {
statuses.add(nameCheckStatus);
}
ProgressUtil.progressOneStep(monitor);
}
final List<IArtifactValidator> validators = ExtensionPointFactory
.getArtifactValidators();
if (validators.isEmpty() == true) {
logger
.warning(SOAMessages.WARNING_MISSING_ARTIFACT_VALIDATOR);
}
ProgressUtil.progressOneStep(monitor);
URL wsdlURL = null;
if (fromExistingWsdl == true) {
wsdlURL = uiModel.getOriginalWsdlUrl();
} else {
WSDLTemplateProcessor wsdlTemplateProcessor = new WSDLTemplateProcessor(
(ServiceFromTemplateWsdlParamModel) uiModel);
wsdlURL = wsdlTemplateProcessor.getWSDLFileURL(monitor);
}
IStatus validationStatuses = ActionUtil
.validateServiceWSDL(null, wsdlURL, provider
.supportAssertionServiceIntegration(),
false, monitor);
if (validationStatuses != null) {
if (validationStatuses.isMultiStatus() == true) {
Collections.addAll(statuses, validationStatuses
.getChildren());
} else {
statuses.add(validationStatuses);
}
}
if (statuses.isEmpty() == false) {
return EclipseMessageUtils
.createErrorMultiStatus(
statuses,
SOAMessages.ERROR_SERVICE_WSDL_VALIDATION_FAILED);
}
monitor.done();
return Status.OK_STATUS;
}
};
// we only do the validation if and only if the underlying
// organization support it.
if (provider != null
&& (provider.supportAssetRepositoryIntegration() || provider
.supportAssertionServiceIntegration())) {
try {
getContainer().run(false, false, validationRunnable);
} catch (Exception arExp) {
logger.error(arExp);
IStatus status = UIUtil
.getDetailedExceptionStackTrace(arExp);
if (UIUtil.showErrorDialog(getShell(), "Error occured",
SOAMessages.ERROR_ASSET_REPOSITORY, status, false,
false, true, true) == Window.CANCEL) {
if (SOALogger.DEBUG)
logger.exiting(false);
return false;
}
}
IStatus regStatus = validationRunnable.getStatus();
if (regStatus.isOK() == false) {
int errorCount = 0, warningCount = 0, mayCount = 0;
final StringBuffer msg = new StringBuffer();
if ((regStatus instanceof NameValidationStatus)
&& regStatus.getSeverity() == IStatus.WARNING) {
// could be connection issue
msg.append("Problems occured.");
} else {
msg.append(SOAMessages.ISSUES_DIALOG_OPENING);
}
if (regStatus.isMultiStatus() == true) {
for (IStatus status : regStatus.getChildren()) {
switch (status.getSeverity()) {
case IStatus.WARNING:
if (status.getCode() == IValidationStatus.CODE_MAY)
mayCount++;
else
warningCount++;
break;
case IStatus.ERROR:
errorCount++;
break;
}
}
}
if (errorCount > 0) {
msg.append("\n");
msg.append(SOAMessages.ISSUES_DIALOG_MUST_FIX);
msg.append(errorCount);
}
if (warningCount > 0) {
msg.append("\n");
msg.append(SOAMessages.ISSUES_DIALOG_SHOULD_FIX);
msg.append(warningCount);
}
if (mayCount > 0) {
msg.append("\n");
msg.append(SOAMessages.ISSUES_DIALOG_MAY_FIX);
msg.append(mayCount);
}
boolean isNameValidationError = (regStatus instanceof NameValidationStatus)
&& regStatus.getSeverity() == IStatus.ERROR;
if (isNameValidationError == true) {
regStatus = ((NameValidationStatus) regStatus)
.getNestedStatus();
msg.append("\n\n");
msg
.append(SOAMessages.ISSUES_DIALOG_FIX_IN_DETAILS_PAGE);
} else {
msg.append("\n\n");
msg.append(SOAMessages.ISSUES_DIALOG_OK_OR_CONTINUE);
}
if (regStatus.getException() != null
|| regStatus.isMultiStatus() == true) {
msg.append("\n\n");
msg.append(SOAMessages.ISSUES_DIALOG_COPY_TO_CLIPBOARD);
}
String title = regStatus.getSeverity() == IStatus.WARNING ? "Problems Occured"
: "Validation Failed";
logger.warning(msg);
logger.warning(regStatus);
int ret = UIUtil.showErrorDialog(getShell(), title, msg
.toString(), regStatus, true, true,
isNameValidationError == false,
isNameValidationError == false);
if (ret == Window.CANCEL || isNameValidationError == true) {
if (SOALogger.DEBUG)
logger.exiting(false);
return false;
}
}
}
final WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
@Override
protected void execute(IProgressMonitor monitor)
throws CoreException, InvocationTargetException,
InterruptedException {
final long startTime = System.currentTimeMillis();
final int totalWork = ProgressUtil.PROGRESS_STEP * 50;
monitor.beginTask(StringUtil.formatString(
SOAMessages.SVC_CREATE, adminName), totalWork);
ProgressUtil.progressOneStep(monitor);
try {
String wsdlSource = "Existing";
if (fromExistingWsdl) {
ServiceCreator.createServiceFromExistingWSDL(
uiModel, monitor);
} else {
wsdlSource = "Blank";
ServiceCreator
.createServiceFromBlankWSDL(
(ServiceFromTemplateWsdlParamModel) uiModel,
monitor);
}
// we should open the wsdl file for any successful
// creation of an interface project.
final IFile wsdlFile = SOAServiceUtil
.getWsdlFile(adminName);
WorkspaceUtil.refresh(wsdlFile, monitor);
if (wsdlFile.exists()) {
IDE.openEditor(
UIUtil.getWorkbench()
.getActiveWorkbenchWindow()
.getActivePage(), wsdlFile);
}
final TrackingEvent event = new TrackingEvent(
StringUtil.formatString(SOAMessages.NEW_SVC,
wsdlSource), new Date(startTime),
System.currentTimeMillis() - startTime);
GlobalRepositorySystem.instanceOf()
.getActiveRepositorySystem().trackingUsage(
event);
} catch (Exception e) {
logger.error(e);
throw new SOAServiceCreationFailedException(StringUtil
.formatString(SOAMessages.SVC_CREATE_FAILED,
adminName), e);
} finally {
monitor.done();
}
}
};
getContainer().run(false, true, operation);
changePerspective();
} catch (Exception e) {
logger.error(e);
UIUtil.showErrorDialog(getShell(), SOAMessages.ERR_SVC_CREATE,
null, e);
if (SOALogger.DEBUG)
logger.exiting(false);
return false;
}
if (SOALogger.DEBUG)
logger.exiting(true);
return true;
}
/**
* {@inheritDoc}
*/
@Override
public IWizardPage getNextPage(IWizardPage page) {
if (page instanceof ChooseWSDLSourcePage) {
if (((ChooseWSDLSourcePage) page).isStartFromNewWSDL()) {
protocolPage.setWizardPage(serviceFromNewWSDL);
return serviceFromNewWSDL;
} else {
protocolPage.setWizardPage(serviceFromExsitingWSDL);
return serviceFromExsitingWSDL;
}
}
// avoiding service from wsdl page coming up two times
else if (page == serviceFromNewWSDL) {
return addOperationPage;
} else if (page == serviceFromExsitingWSDL) {
return intfDependenciesPage;
} else if (page == addOperationPage) {
return addBindingPage;
} else if (page == addBindingPage) {
return intfDependenciesPage;
} else if (page == intfDependenciesPage) {
return implDependenciesPage;
} else if (page == implDependenciesPage) {
return protocolPage;
}
return null;
}
/**
* {@inheritDoc}
*/
@Override
public IWizardPage[] getContentPages() {
chooseWsdlSource = new ChooseWSDLSourcePage();
serviceFromNewWSDL = new ServiceFromNewWSDLPage();
serviceFromExsitingWSDL = new ServiceFromExistingWSDLWizardPage();
intfDependenciesPage = new DependenciesWizardPage(SOAMessages.SVC_INTF);
implDependenciesPage = new DependenciesWizardPage(
"Service Implementation");
addOperationPage = new ServiceFromNewWSDLAddOperationWizardPage();
addBindingPage = new ServiceFromNewWSDLAddBindingWizardPage();
protocolPage = new ServiceProtocolSelectionWizardPage();
List<IWizardPage> pages = new ArrayList<IWizardPage>();
pages.add(chooseWsdlSource);
pages.add(serviceFromNewWSDL);
pages.add(serviceFromExsitingWSDL);
pages.add(addOperationPage);
pages.add(addBindingPage);
pages.add(intfDependenciesPage);
pages.add(implDependenciesPage);
pages.add(protocolPage);
return pages.toArray(new IWizardPage[pages.size()]);
}
/**
* {@inheritDoc}
*/
@Override
protected Object getCreatingType() {
return ISOAPreValidator.SERVICE;
}
/**
* {@inheritDoc}
*/
@Override
public int getMinimumHeight() {
return super.getMinimumHeight() + 50;
}
private static class NameValidationStatus extends Status {
private IStatus nestedStatus;
public NameValidationStatus(IStatus status) {
super(status.getSeverity(), status.getPlugin(), status.getCode(),
status.getMessage(), status.getException());
this.nestedStatus = status;
}
public IStatus getNestedStatus() {
return nestedStatus;
}
}
}