/**
* Copyright 2005 Open Cloud Ltd.
*
* 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
*
* 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.mobicents.eclipslee.servicecreation.wizards.deployable;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
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.jface.wizard.WizardPage;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.mobicents.eclipslee.servicecreation.util.FileUtil;
import org.mobicents.eclipslee.servicecreation.wizards.WizardChangeListener;
import org.mobicents.eclipslee.servicecreation.wizards.generic.FilenamePage;
import org.mobicents.eclipslee.util.slee.xml.ant.AntBuildTargetXML;
import org.mobicents.eclipslee.util.slee.xml.ant.AntCleanTargetXML;
import org.mobicents.eclipslee.util.slee.xml.ant.AntCopyXML;
import org.mobicents.eclipslee.util.slee.xml.ant.AntEventJarXML;
import org.mobicents.eclipslee.util.slee.xml.ant.AntFileSet;
import org.mobicents.eclipslee.util.slee.xml.ant.AntJarXML;
import org.mobicents.eclipslee.util.slee.xml.ant.AntProfileSpecJarXML;
import org.mobicents.eclipslee.util.slee.xml.ant.AntProjectXML;
import org.mobicents.eclipslee.util.slee.xml.ant.AntSbbJarXML;
import org.mobicents.eclipslee.util.slee.xml.ant.AntTargetXML;
import org.mobicents.eclipslee.xml.DeployableUnitXML;
/**
* @author cath
*/
public class DeployableUnitWizard extends Wizard implements INewWizard {
private static final String WIZARD_TITLE = "JAIN SLEE Deployable Unit Wizard";
private static final String ENDS = "-deployable-unit.xml";
public DeployableUnitWizard() {
super();
setNeedsProgressMonitor(true);
}
/**
* The worker method. It will find the container, create the
* file if missing or just replace its contents, and open
* the editor on the newly created file.
*/
public void doFinish(IProgressMonitor monitor) throws CoreException {
try {
monitor.beginTask("Creating JAIN SLEE DeployableUnit " + getFileName(), 2);
// The folder that will contain the Foo-deployable-unit.xml file.
IFolder folder = getSourceContainer().getFolder(new Path(this.getPackageName().replaceAll("\\.", "/")));
// Get the ant build file.
IPath antBuildPath = new Path("/build.xml");
IFile projectFile = getSourceContainer().getProject().getFile(antBuildPath);
AntProjectXML projectXML = new AntProjectXML(projectFile.getContents());
// Create the DU's all and clean targets.
AntBuildTargetXML buildXML = projectXML.addBuildTarget();
AntCleanTargetXML cleanXML = projectXML.addCleanTarget();
buildXML.setName("build-" + getBaseName() + "-DU");
cleanXML.setName("clean-" + getBaseName() + "-DU");
// Update the 'all' and 'clean' targets
AntTargetXML buildAllXML = projectXML.getTarget("all");
AntTargetXML cleanAllXML = projectXML.getTarget("clean");
buildAllXML.addAntTarget(buildXML);
cleanAllXML.addAntTarget(cleanXML);
// Configure the build target.
buildXML.addMkdir("classes/" + getBaseName() + "-DU");
// Create the copy target. This must be done before the jar target is created.
AntCopyXML copy = buildXML.addCopyTarget();
copy.setSourceFile(folder.getProjectRelativePath().toString() + "/" + getFileName());
copy.setDestFile("classes/" + getBaseName() + "-DU/deployable-unit.xml");
// Create a jar target for the buildXML.
AntJarXML jarXML = buildXML.addJar();
jarXML.setJarFile("jars/" + getBaseName() + "-DU.jar");
// Create a metainf element and add this deployable unit XML to it, but
// renamed as "deployable-unit.xml"
AntFileSet metaInf = jarXML.addMetaInf();
metaInf.setDir("classes/" + getBaseName() + "-DU");
metaInf.setIncludes(new String[] { "deployable-unit.xml" });
// Configure the clean target.
cleanXML.addFile("jars/" + getBaseName() + "-DU.jar");
cleanXML.addDir("classes/" + getBaseName() + "-DU");
// Create DU Jar
HashMap[] jars = getJars();
HashMap[] services = getServices();
DeployableUnitXML duXML = new DeployableUnitXML();
for (int i = 0; i < jars.length; i++) {
IPath workspaceRelativePath = new Path((String) jars[i].get("Jar"));
IPath projectPath = getProject().getFullPath();
// This is the path relative to the project
IPath path = workspaceRelativePath.removeFirstSegments(projectPath.segmentCount());
duXML.addJar(path.toString());
// Create a fileset and add this jar to it.
AntFileSet fileSet = jarXML.addFileSet();
fileSet.addInclude(path.toString());
fileSet.setDir("");
// Do any of the build targets in build.xml produce this jar, if
// so, depend on those targets.
String dependsOn = getDependsOn(projectXML, path.toString());
if (dependsOn != null)
buildXML.addDepends(dependsOn);
}
for (int i = 0; i < services.length; i++) {
IPath servicePath = new Path((String) services[i].get("Service XML"));
IPath path = servicePath.removeFirstSegments(getProject().getFullPath().segmentCount());
duXML.addService(path.toString());
// Create a fileset and add this service to it - standard fileset, NOT metainf
AntFileSet fileSet = jarXML.addFileSet();
fileSet.addInclude(path.toString());
fileSet.setDir(".");
}
// Save build.xml
projectFile.setContents(projectXML.getInputStreamFromXML(), true, true, monitor);
// Save DU XML
final IFile xmlFile = FileUtil.createFromInputStream(folder, new Path(getFileName()), duXML.getInputStreamFromXML(), monitor);
monitor.worked(1);
// Open...
monitor.setTaskName("Opening JAIN SLEE DeployableUnit XML for viewing...");
getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
IWorkbenchPage page =
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
try {
IDE.openEditor(page, xmlFile, true);
} catch (PartInitException e) {
}
}
});
monitor.worked(1);
monitor.done();
} catch (Exception e) {
e.printStackTrace();
throw newCoreException("Error", e);
}
}
/**
* If you override this method you must call super.addPages() if you want to use
* the standard Filename and Identity Pages provided in this abstract class.
*/
public void addPages() {
filenamePage = new FilenamePage(selection, WIZARD_TITLE, ENDS);
addPage(filenamePage);
jarPage = new DeployableUnitJarPage(WIZARD_TITLE);
addPage(jarPage);
servicePage = new DeployableUnitServicePage(WIZARD_TITLE);
addPage(servicePage);
}
/**
* When a page's contents change in a way that might impact other pages
* this method should be called so that other pages can react.
* @param page
*/
public void pageChanged(WizardPage page) {
IWizardPage pages[] = this.getPages();
for (int i= 0; i < pages.length; i++) {
if (pages[i] instanceof WizardChangeListener) {
((WizardChangeListener) pages[i]).onWizardPageChanged(page);
}
}
}
/**
* This method calls doFinish() in a new thread.
*/
public boolean performFinish() {
sourceContainer = filenamePage.getSourceContainer();
project = sourceContainer.getProject();
packageName = filenamePage.getPackageName();
filename = filenamePage.getFileName();
// Extract stuff from jarPage and servicePage
jars = jarPage.getSelectedJars();
services = servicePage.getSelectedServices();
IRunnableWithProgress op = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException {
try {
doFinish(monitor);
} catch (CoreException e) {
throw new InvocationTargetException(e);
} finally {
monitor.done();
}
}
};
try {
getContainer().run(true, false, op);
} catch (InterruptedException e) {
return false;
} catch (InvocationTargetException e) {
Throwable realException = e.getTargetException();
if (realException != null)
MessageDialog.openError(getShell(), "Error", realException.getMessage());
else
MessageDialog.openError(getShell(), "Error", e.getMessage());
return false;
}
return true;
}
public void init(IWorkbench workbench, IStructuredSelection selection) {
this.selection = selection;
}
protected CoreException newCoreException(String message, Exception cause) {
String stackTrace = message + "\n" + cause.toString() + ":" + cause.getMessage() + "\n";
StackTraceElement elements[] = cause.getStackTrace();
for (int i = 0; i < elements.length; i++) {
stackTrace = stackTrace + elements[i].toString() + "\n";
}
return newCoreException(stackTrace);
}
protected CoreException newCoreException(String message) {
IStatus status = new Status(IStatus.ERROR, "org.mobicents.eclipslee.servicecreation", IStatus.OK, message, null);
return new CoreException(status);
}
protected void throwCoreException(String message) throws CoreException {
throw newCoreException(message);
}
protected void throwCoreException(String message, Exception cause) throws CoreException {
throw newCoreException(message, cause);
}
public IContainer getSourceContainer() { return sourceContainer; }
public IProject getProject() { return project; }
public String getPackageName() { return packageName; }
public String getFileName() { return filename; }
public HashMap[] getJars() { return jars; }
public HashMap[] getServices() { return services; }
public String getBaseName() {
String filename = getFileName();
String basename = filename.substring(0, filename.indexOf(ENDS));
return basename;
}
private String getDependsOn(AntProjectXML projectXML, String jarPath) {
AntTargetXML targets[] = projectXML.getTargets();
for (int i = 0; i < targets.length; i++) {
// Only interested in build targets.
if (targets[i] instanceof AntBuildTargetXML) {
AntBuildTargetXML target = (AntBuildTargetXML) targets[i];
AntEventJarXML events[] = target.getEventJars();
for (int j = 0; j < events.length; j++)
if (events[j].getDestfile().equals(jarPath))
return target.getName();
AntSbbJarXML sbbs[] = target.getSbbJars();
for (int j = 0; j < sbbs.length; j++)
if (sbbs[j].getDestfile().equals(jarPath))
return target.getName();
AntProfileSpecJarXML profiles[] = target.getProfileSpecJars();
for (int j = 0; j < profiles.length; j++)
if (profiles[j].getDestfile().equals(jarPath))
return target.getName();
}
}
return null;
}
private IStructuredSelection selection;
private String filename;
private IContainer sourceContainer;
private IProject project;
private String packageName;
private HashMap[] jars;
private HashMap[] services;
private FilenamePage filenamePage;
private DeployableUnitJarPage jarPage;
private DeployableUnitServicePage servicePage;
}