/*******************************************************************************
* Copyright (c) 2009, 2010 Innovation Gate 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:
* Innovation Gate GmbH - initial API and implementation
******************************************************************************/
package de.innovationgate.eclipse.wgadesigner.wizards.export.webapp;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeoutException;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.IExportWizard;
import org.eclipse.ui.IWorkbench;
import de.innovationgate.eclipse.utils.WorkbenchUtils;
import de.innovationgate.eclipse.utils.ui.SingleStructuredSelection;
import de.innovationgate.eclipse.utils.ui.ValidatedMultiPageWizard;
import de.innovationgate.eclipse.utils.ui.ValidatedWizardPage;
import de.innovationgate.eclipse.utils.wga.WGADesignStructureHelper;
import de.innovationgate.eclipse.wgadesigner.WGADesignerPlugin;
import de.innovationgate.eclipse.wgadesigner.actions.StartWGARuntime;
import de.innovationgate.eclipse.wgadesigner.models.WGARemoteServer;
import de.innovationgate.eclipse.wgadesigner.models.WGARuntimeConfigurationModel;
import de.innovationgate.eclipse.wgadesigner.models.WebApplication;
import de.innovationgate.eclipse.wgadesigner.natures.IncompatibleWGAConfigVersion;
import de.innovationgate.eclipse.wgadesigner.natures.WGARuntime;
import de.innovationgate.eclipse.wgadesigner.team.ChooseWGARuntimePage;
import de.innovationgate.eclipse.wgadesigner.team.RemoteLocationPage;
import de.innovationgate.eclipse.wgadesigner.tomcat.TomcatUtils;
import de.innovationgate.utils.WGUtils;
import de.innovationgate.utils.io.ByteArrayDataSource;
import de.innovationgate.wga.config.ContentStore;
import de.innovationgate.wga.config.Domain;
import de.innovationgate.wga.config.WGAConfiguration;
import de.innovationgate.wgaservices.WGAServiceException;
import de.innovationgate.wgaservices.types.DatabaseInformation;
import de.innovationgate.wgaservices.types.DatabaseServerInfo;
public class ExportWGAApplication extends ValidatedMultiPageWizard implements IExportWizard {
public static final String CS_PATH_OPTION_NAME = "Path";
/**
* necessary infos for export
*/
private WGARuntime _runtime = null;
private String _webApplication = null;
private WGARemoteServer _remoteServer;
private DatabaseServerInfo _remoteDatabaseServer;
private String _remoteDatabaseName;
private boolean _copyContent;
private boolean _includeACL;
private RemoteLocationPage _remoteLocationPage;
private ChooseRuntimePage _chooseRuntimePage;
private ChooseWebApplicationPage _chooseWebApplicationPage;
private CheckWebApplicationExportPreconditionsPage _checkWebApplicationExportPreconditionsPage;
private ChooseDBServerPage _chooseDBServerPage;
private WebApplicationExportSummaryPage _exportSummaryPage;
private WGAConfiguration _remoteWGAConfiguration;
public ExportWGAApplication() {
super();
setNeedsProgressMonitor(true);
setWindowTitle("Export WGA Web Application");
}
@Override
public boolean performFinish() {
try {
// save location in runtime config
try {
WGARuntimeConfigurationModel model = new WGARuntimeConfigurationModel();
model.init(_runtime);
if (model.getRemoteLocation() == null || !model.getRemoteLocation().equals(_remoteLocationPage.getLocation())) {
model.setRemoteLocation(_remoteLocationPage.getLocation());
model.saveChanges();
}
} catch (Exception e) {
// ignore
}
getContainer().run(true, false, new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) {
try {
int totalWork = 6;
if (isCopyContent()) {
totalWork += 2;
}
monitor.beginTask("Export web application", totalWork);
monitor.setTaskName("connecting to remote server");
// use infinte read timeout here ... bc. db dumps can be large
_remoteServer.connectToServer(5*1000, 0);
monitor.worked(1);
monitor.setTaskName("creating database on remote server");
Map<String, String> pathOptions = new HashMap<String, String>();
pathOptions.put(CS_PATH_OPTION_NAME, _remoteDatabaseName);
_remoteServer.getServices().createDatabase(_remoteServer.getSession(), _remoteDatabaseServer, _remoteDatabaseServer.getCreateableContentStoreImplemenations().get(0),
pathOptions);
monitor.worked(1);
monitor.setTaskName("transfering design");
IContainer designContainer = _runtime.getConnectedDesignContainers().get(_webApplication);
designContainer.accept(new IResourceVisitor() {
public boolean visit(IResource resource) throws CoreException {
IPath remotePathObj = resource.getLocation();
int count = remotePathObj.matchingFirstSegments(_runtime.getDesignRoot().getLocation());
remotePathObj = remotePathObj.removeFirstSegments(count);
String remotePath = remotePathObj.toString();
if (resource.getType() == IResource.FILE) {
DataSource content = new FileDataSource(((IFile) resource).getLocation().toFile());
try {
_remoteServer.getServices().updateFSDesignResource(_remoteServer.getSession(), remotePath, content, resource.getLocalTimeStamp());
}
catch (WGAServiceException e) {
throw new CoreException(new Status(IStatus.ERROR, WGADesignerPlugin.PLUGIN_ID, "Creating design file failed.", e));
}
}
else if (resource.getType() == IResource.FOLDER) {
try {
_remoteServer.getServices().mkFSDesignDir(_remoteServer.getSession(), remotePath);
}
catch (WGAServiceException e) {
throw new CoreException(new Status(IStatus.ERROR, WGADesignerPlugin.PLUGIN_ID, "Creating design folder failed.", e));
}
}
return true;
}
});
monitor.worked(1);
monitor.setTaskName("configuring content store");
WGAConfiguration localConfig = _runtime.retrieveWGAConfig(false);
ContentStore cs = localConfig.getContentStore(_webApplication);
cs.getDatabaseOptions().put(CS_PATH_OPTION_NAME, _remoteDatabaseName);
cs.setDbServer(_remoteDatabaseServer.getUid());
cs.setImplClassName(_remoteDatabaseServer.getCreateableContentStoreImplemenations().get(0));
String remoteDomainUID = null;
if (cs.getDomain().equals("default")) {
remoteDomainUID = "default";
} else {
String localDomainName = localConfig.getDomain(cs.getDomain()).getName();
remoteDomainUID = getDomainUID(_remoteWGAConfiguration, localDomainName);
}
cs.setDomain(remoteDomainUID);
_remoteWGAConfiguration.add(cs);
monitor.worked(1);
monitor.setTaskName("updating remote server configuration");
ByteArrayOutputStream out = new ByteArrayOutputStream();
WGAConfiguration.write(_remoteWGAConfiguration, out);
DataSource configDataSource = new ByteArrayDataSource(out.toByteArray(), "WGAConfiguration", "text/xml");
_remoteServer.getServices().updateWGAConfiguration(_remoteServer.getSession(), configDataSource);
monitor.worked(1);
monitor.setTaskName("waiting for remote content store to get available");
List<String> dbkeys = new ArrayList<String>();
long startTime = System.currentTimeMillis();
while (!dbkeys.contains(_webApplication)) {
if ((System.currentTimeMillis() - startTime) > 1000 * 60) {
throw new TimeoutException("Timeout waiting for remote content store.");
}
Thread.sleep(2000);
dbkeys = _remoteServer.getServices().getConnectedContentDatabases(_remoteServer.getSession());
}
monitor.worked(1);
if (isCopyContent()) {
// create local database dump
monitor.setTaskName("creating content store dump");
WGARemoteServer server = new WGARemoteServer("local", _runtime.getRootURL(), "unused", "unused");
server.connectToServer(5*1000, 0);
DataSource csDump = server.getServices().createContentStoreDump(server.getSession(), _webApplication, isIncludeACL(), true);
monitor.worked(1);
// import dump on remote db
monitor.setTaskName("importing content store dump in remote database");
_remoteServer.getServices().importContentStoreDump(_remoteServer.getSession(), csDump, _webApplication, isIncludeACL(), true);
monitor.worked(1);
}
}
catch (Exception e) {
WorkbenchUtils.showErrorDialog(WGADesignerPlugin.getDefault(), getShell(), "Export failed.", e.getMessage(), e);
}
finally {
monitor.done();
}
}
});
MessageDialog.openInformation(getShell(), "Export WGA Application", "Export of web application successfully finshed.");
return true;
}
catch (InvocationTargetException e) {
WorkbenchUtils.showErrorDialog(getShell(), "Export failed.", e.getMessage(), e);
}
catch (InterruptedException e) {
WorkbenchUtils.showErrorDialog(getShell(), "Export failed.", e.getMessage(), e);
}
return false;
}
public void init(IWorkbench workbench, IStructuredSelection selection) {
WGARuntime runtime = null;
if (selection.getFirstElement() instanceof WebApplication) {
WebApplication app = (WebApplication) selection.getFirstElement();
runtime = app.getRuntime();
_webApplication = app.getContentStore().getKey();
} else {
runtime = WGARuntime.fromSelection(selection);
}
if (runtime != null) {
// validate runtime state
List<IStatus> errors = new ArrayList<IStatus>();
ChooseRuntimePage.validateWGARuntimeVersion(errors, runtime);
if (!errors.isEmpty()) {
MessageDialog.openWarning(getShell(), "Invalid runtime", errors.get(0).getMessage());
} else {
if (!TomcatUtils.getInstance().isRunning(runtime)) {
boolean start = MessageDialog.openConfirm(getShell(), "Start WGA Runtime", "To export a web application the selected runtime '" + runtime.getName() + "' must be started. Start runtime now?");
if (start) {
StartWGARuntime.call(runtime, true);
_runtime = runtime;
}
} else {
_runtime = runtime;
}
}
}
if (_runtime != null && _webApplication == null) {
IContainer designContainer = WGADesignStructureHelper.retrieveDesignContainerFromSelection(selection);
if (designContainer != null) {
try {
Map<String,IContainer> connectedDesigns = _runtime.getConnectedDesignContainers();
Iterator<String> dbkeys = connectedDesigns.keySet().iterator();
while (dbkeys.hasNext()) {
String dbkey = dbkeys.next();
IContainer container = connectedDesigns.get(dbkey);
if (container != null && container.equals(designContainer)) {
if (_webApplication == null) {
_webApplication = dbkey;
} else {
// more than one cs with this design - user must choose one
_webApplication = null;
break;
}
}
}
}
catch (IncompatibleWGAConfigVersion e) {
}
catch (IOException e) {
}
}
}
}
@Override
public void addPages() {
_chooseRuntimePage = new ChooseRuntimePage();
if (_runtime == null) {
addPage(_chooseRuntimePage);
}
_chooseWebApplicationPage = new ChooseWebApplicationPage();
if (_webApplication == null) {
addPage(_chooseWebApplicationPage);
}
_remoteLocationPage = new RemoteLocationPage("Server connection for export");
_remoteLocationPage.setRuntime(_runtime);
addPage(_remoteLocationPage);
_checkWebApplicationExportPreconditionsPage = new CheckWebApplicationExportPreconditionsPage();
addPage(_checkWebApplicationExportPreconditionsPage);
_chooseDBServerPage = new ChooseDBServerPage();
addPage(_chooseDBServerPage);
_exportSummaryPage = new WebApplicationExportSummaryPage();
addPage(_exportSummaryPage);
}
@Override
public IWizardPage getNextPage(IWizardPage page) {
IWizardPage nextPage = super.getNextPage(page);
System.out.println(page + "|" + nextPage);
if (page == _remoteLocationPage) {
_remoteServer = _remoteLocationPage.getRemoteServer();
}
if (nextPage == _remoteLocationPage) {
_remoteLocationPage.setRuntime(_runtime);
}
if (nextPage == _chooseDBServerPage) {
_chooseDBServerPage.init(_checkWebApplicationExportPreconditionsPage.getAvailableDatabaseServers());
}
return nextPage;
}
public WGARuntime getRuntime() {
return _runtime;
}
public void setRuntime(WGARuntime runtime) {
_runtime = runtime;
}
public String getWebApplication() {
return _webApplication;
}
public void setWebApplication(String webApplication) {
_webApplication = webApplication;
}
public WGARemoteServer getRemoteServer() {
return _remoteServer;
}
public void setRemoteServer(WGARemoteServer remoteServer) {
_remoteServer = remoteServer;
}
public DatabaseServerInfo getRemoteDatabaseServer() {
return _remoteDatabaseServer;
}
public void setRemoteDatabaseServer(DatabaseServerInfo remoteDatabaseServer) {
_remoteDatabaseServer = remoteDatabaseServer;
}
public String getRemoteDatabaseName() {
return _remoteDatabaseName;
}
public void setRemoteDatabaseName(String remoteDatabaseName) {
_remoteDatabaseName = remoteDatabaseName;
}
public boolean isCopyContent() {
return _copyContent;
}
public void setCopyContent(boolean copyContent) {
_copyContent = copyContent;
}
public boolean isIncludeACL() {
return _includeACL;
}
public void setIncludeACL(boolean includeACL) {
_includeACL = includeACL;
}
public WGAConfiguration getRemoteWGAConfiguration() {
return _remoteWGAConfiguration;
}
public void setRemoteWGAConfiguration(WGAConfiguration remoteWGAConfiguration) {
_remoteWGAConfiguration = remoteWGAConfiguration;
}
private String getDomainUID(WGAConfiguration config, String domainName) {
if (domainName != null && domainName.equalsIgnoreCase("default")) {
return "default";
}
String remoteDomainUID = null;
List<Domain> domains = config.getDomains();
for (Domain domain : domains) {
if (domain.getName().equals(domainName)) {
return domain.getUid();
}
}
return null;
}
}