blob: d0dfa383d28709b5a0f8c798737283beee9f35c5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.sling.ide.eclipse.ui.wizards;
import static org.apache.sling.ide.eclipse.core.progress.ProgressUtils.advance;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.apache.sling.ide.eclipse.core.ConfigurationHelper;
import org.apache.sling.ide.eclipse.core.DefaultSlingLaunchpadConfiguration;
import org.apache.sling.ide.eclipse.core.ISlingLaunchpadConfiguration;
import org.apache.sling.ide.eclipse.ui.WhitelabelSupport;
import org.apache.sling.ide.eclipse.ui.internal.Activator;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
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.debug.core.ILaunchManager;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.IServerWorkingCopy;
import org.eclipse.wst.server.core.ServerUtil;
/**
* The <tt>AbstractNewSlingApplicationWizard</tt> is a support class for wizards which create Sling applications
*
*/
public abstract class AbstractNewSlingApplicationWizard extends Wizard implements INewWizard {
private SetupServerWizardPage setupServerWizardPage = new SetupServerWizardPage(this);
public void init(IWorkbench workbench, IStructuredSelection selection) {
}
/**
*
* @return the current wizard page, possibly null
*/
protected WizardPage getCurrentWizardPage() {
IWizardPage currentPage = getContainer().getCurrentPage();
if (currentPage instanceof WizardPage) {
return (WizardPage) currentPage;
}
return null;
}
public void reportError(CoreException e) {
WizardPage currentPage = getCurrentWizardPage();
if (currentPage != null) {
currentPage.setMessage(e.getMessage(), IMessageProvider.ERROR);
} else {
MessageDialog.openError(getShell(), "Unexpected error", e.getMessage());
}
Activator.getDefault().getLog().log(e.getStatus());
}
public void reportError(Throwable t) {
if (t instanceof CoreException) {
reportError((CoreException) t);
return;
}
IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, t.getMessage(), t);
reportError(new CoreException(status));
}
protected SetupServerWizardPage getSetupServerWizardPage() {
return setupServerWizardPage;
}
/**
* This method is called when 'Finish' button is pressed in the wizard. We will create an operation and run it using
* wizard as execution context.
*/
public boolean performFinish() {
try {
// create projects
final List<IProject> createdProjects = new ArrayList<>();
getContainer().run(false, true, new WorkspaceModifyOperation() {
@Override
protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException,
InterruptedException {
createdProjects.addAll(createProjects(monitor));
}
});
// configure projects
final Projects[] projects = new Projects[1];
getContainer().run(false, true, new WorkspaceModifyOperation() {
@Override
protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException,
InterruptedException {
projects[0] = configureCreatedProjects(createdProjects, monitor);
}
});
// deploy the projects on server
getContainer().run(false, true, new WorkspaceModifyOperation() {
@Override
protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException,
InterruptedException {
deployProjectsOnServer(projects[0], monitor);
}
});
// ensure server is started and all modules are published
getContainer().run(false, false, new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
publishModules(createdProjects, monitor);
} catch (CoreException e) {
throw new InvocationTargetException(e);
}
}
});
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
} catch (InvocationTargetException e) {
reportError(e.getTargetException());
return false;
}
return true;
}
protected abstract List<IProject> createProjects(IProgressMonitor monitor) throws CoreException;
protected abstract Projects configureCreatedProjects(List<IProject> createdProjects, IProgressMonitor monitor)
throws CoreException;
protected void deployProjectsOnServer(Projects projects, IProgressMonitor monitor) throws CoreException {
IServer server = setupServerWizardPage.getOrCreateServer(monitor);
if (server == null) {
monitor.done();
return;
}
advance(monitor, 1);
IServerWorkingCopy wc = server.createWorkingCopy();
// add the bundle and content projects, ie modules, to the server
List<IModule> modules = new LinkedList<>();
for (IProject project : projects.getBundleProjects()) {
IModule module = ServerUtil.getModule(project);
if (module != null && shouldDeploy(module)) {
modules.add(module);
}
}
for (IProject project : projects.getContentProjects()) {
IModule module = ServerUtil.getModule(project);
if (module != null && shouldDeploy(module)) {
modules.add(module);
}
}
wc.modifyModules(modules.toArray(new IModule[modules.size()]), new IModule[0], monitor);
wc.save(true, monitor);
advance(monitor, 2);
monitor.done();
}
/**
* Extension method to allow subclasses to deploy and publish specific modules created by the wizard
*
* <p>
* By default, all modules are deployed
*
* @param module the module
* @return true is the module should be deployed, false otherwise
*/
protected boolean shouldDeploy(IModule module) {
return true;
}
protected void publishModules(final List<IProject> createdProjects, IProgressMonitor monitor) throws CoreException {
IServer server = setupServerWizardPage.getOrCreateServer(monitor);
if (server == null) {
return;
}
if (setupServerWizardPage.getStartServer()) {
server.start(ILaunchManager.RUN_MODE, monitor);
}
List<IModule[]> modules = new ArrayList<>();
for (IProject project : createdProjects) {
IModule module = ServerUtil.getModule(project);
if (module != null && shouldDeploy(module)) {
modules.add(new IModule[] { module });
}
}
if (modules.size() > 0) {
server.publish(IServer.PUBLISH_CLEAN, modules, null, null);
}
}
protected void configureBundleProject(IProject aBundleProject, List<IProject> projects, IProgressMonitor monitor)
throws CoreException {
ConfigurationHelper.convertToBundleProject(aBundleProject);
}
protected void configureContentProject(IProject aContentProject, List<IProject> projects, IProgressMonitor monitor)
throws CoreException {
ConfigurationHelper.convertToContentPackageProject(aContentProject, monitor, new Path("src/main/content/jcr_root"));
}
protected void configureReactorProject(IProject reactorProject, IProgressMonitor monitor) throws CoreException {
// nothing to be done
}
protected void finishConfiguration(List<IProject> projects, IServer server, IProgressMonitor monitor)
throws CoreException {
// nothing to be done by default - hook for subclasses
}
public ImageDescriptor getLogo() {
return WhitelabelSupport.getProjectWizardBanner();
}
public abstract String doGetWindowTitle();
protected ISlingLaunchpadConfiguration getDefaultConfig() {
return DefaultSlingLaunchpadConfiguration.INSTANCE;
}
}