blob: 30df9999c026abcc485b35894d6a148a829c590d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
* 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:
* Doug Satchwell (Chase Technology Ltd) - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.xsl.jaxp.launching.internal;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
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.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.jdt.launching.IVMRunner;
import org.eclipse.jdt.launching.JavaLaunchDelegate;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.xsl.jaxp.launching.IDebugger;
import org.eclipse.wst.xsl.jaxp.launching.IProcessorInstall;
import org.eclipse.wst.xsl.jaxp.launching.IProcessorInvoker;
import org.eclipse.wst.xsl.jaxp.launching.IProcessorJar;
import org.eclipse.wst.xsl.jaxp.launching.ITransformerFactory;
import org.eclipse.wst.xsl.jaxp.launching.JAXPLaunchConfigurationConstants;
import org.eclipse.wst.xsl.jaxp.launching.JAXPRuntime;
import org.eclipse.wst.xsl.jaxp.launching.model.JAXPDebugTarget;
import org.eclipse.wst.xsl.launching.model.IXSLConstants;
public class JAXPJavaLaunchConfigurationDelegate extends JavaLaunchDelegate implements IDebugEventSetListener
{
private String mode;
LaunchHelper launchHelper;
@Override
public synchronized void launch(ILaunchConfiguration configuration, final String mode, final ILaunch launch, IProgressMonitor monitor) throws CoreException
{
this.mode = mode;
launchHelper.save(getLaunchConfigFile());
// set the launch name
IProcessorInstall install = getProcessorInstall(configuration, mode);
String tfactory = getTransformerFactory(install);
String name = install.getName();
if (tfactory != null)
name += "[" + tfactory + "]";
launch.setAttribute("launchName", name);
// the super.launch will add a Java source director if we set it to null here
final ISourceLocator configuredLocator = launch.getSourceLocator();
launch.setSourceLocator(null);
super.launch(configuration, mode, launch, monitor);
// now get the java source locator
final ISourceLocator javaSourceLookupDirector = (ISourceLocator)launch.getSourceLocator();
// now add our own participant to the java director
launch.setSourceLocator(new ISourceLocator(){
public Object getSourceElement(IStackFrame stackFrame)
{
// simply look at one and then the other
Object sourceElement = javaSourceLookupDirector.getSourceElement(stackFrame);
if (sourceElement == null)
sourceElement = configuredLocator.getSourceElement(stackFrame);
return sourceElement;
}});
// IJavaDebugTarget javaTarget = (IJavaDebugTarget)launch.getDebugTarget();
// launch.removeDebugTarget(javaTarget);
IDebugTarget javaTarget = launch.getDebugTarget();
IDebugTarget xslTarget = new JAXPDebugTarget(launch, launch.getProcesses()[0], launchHelper);
// remove java as the primary target and make xsl the primary target
launch.removeDebugTarget(javaTarget);
launch.addDebugTarget(xslTarget);
// add this here to make java the non-primary target
// launch.addDebugTarget(javaTarget);
// launch.addDebugTarget(new JavaXSLDebugTarget(launch, launch.getProcesses()[0], launchHelper, javaTarget));
}
/**
* Get the Java breakpoint and the XSL breakpoints
*/
@Override
protected IBreakpoint[] getBreakpoints(ILaunchConfiguration configuration)
{
IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
if (!breakpointManager.isEnabled())
return null;
IBreakpoint[] javaBreakpoints = super.getBreakpoints(configuration);
IBreakpoint[] xslBreakpoints = breakpointManager.getBreakpoints(IXSLConstants.ID_XSL_DEBUG_MODEL);
IBreakpoint[] breakpoints = new IBreakpoint[javaBreakpoints.length+xslBreakpoints.length];
System.arraycopy(javaBreakpoints, 0, breakpoints, 0, javaBreakpoints.length);
System.arraycopy(xslBreakpoints, 0, breakpoints, javaBreakpoints.length, xslBreakpoints.length);
return breakpoints;
}
@Override
public boolean preLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException
{
this.launchHelper = new LaunchHelper(configuration);
if (mode.equals(ILaunchManager.DEBUG_MODE))
{
// TODO don't like having UI code in the launching plugin...where else can it go?
final IProcessorInstall install = getProcessorInstall(configuration, ILaunchManager.RUN_MODE);
if (install.getDebugger() == null)
{
final boolean[] result = new boolean[]
{ false };
// open a dialog for choosing a different install that does have
// an associated debugger
PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable()
{
public void run()
{
String debuggingInstallId = JAXPLaunchingPlugin.getDefault().getPluginPreferences().getString(JAXPLaunchConfigurationConstants.ATTR_DEFAULT_DEBUGGING_INSTALL_ID);
IProcessorInstall processor = JAXPRuntime.getProcessor(debuggingInstallId);
IWorkbenchWindow dw = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
String title = Messages.getString("XSLTLaunchConfigurationDelegate.0"); //$NON-NLS-1$
String message = Messages.getString("XSLTLaunchConfigurationDelegate.1") + install.getName() + Messages.getString("XSLTLaunchConfigurationDelegate.2") //$NON-NLS-1$ //$NON-NLS-2$
+ Messages.getString("XSLTLaunchConfigurationDelegate.3") + processor.getName() + Messages.getString("XSLTLaunchConfigurationDelegate.4");//$NON-NLS-1$ //$NON-NLS-2$
MessageDialog dialog = new MessageDialog(dw.getShell(), title, null, message, MessageDialog.QUESTION,
new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL }, 0); // yes is the default
result[0] = dialog.open() == 0;
}
});
return result[0];
}
else
{
String debuggerTF = install.getDebugger().getTransformerFactory();
String installTF = launchHelper.getTransformerFactory() == null ? null : launchHelper.getTransformerFactory().getFactoryClass();
if (!debuggerTF.equals(installTF))
{
PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable()
{
public void run()
{
IWorkbenchWindow dw = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
String title = Messages.getString("Change Transformer Factory");
String message = install.getName() + " must use the " + launchHelper.getTransformerFactory().getName() + " transformer factory when debugging.\n"
+ "Be aware that this may give different results to the " + launchHelper.getTransformerFactory().getName() + " transformer factory configured for this launch configuration.";
MessageDialog dialog = new MessageDialog(dw.getShell(), title, null, message, MessageDialog.WARNING,
new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL }, 0); // yes is the default
dialog.open();
}
});
}
}
}
return super.preLaunchCheck(configuration, mode, monitor);
}
@Override
public IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode) throws CoreException
{
// comment this out in order to get java debugging as well as XSL debugging
// if (ILaunchManager.DEBUG_MODE.equals(mode))
// return super.getVMRunner(configuration, ILaunchManager.RUN_MODE);
return super.getVMRunner(configuration, mode);
}
private File getLaunchConfigFile()
{
IPath launchPath = Platform.getStateLocation(JAXPLaunchingPlugin.getDefault().getBundle()).append("launch"); //$NON-NLS-1$
File launchDir = launchPath.toFile();
if (!launchDir.exists())
launchDir.mkdir();
File file = new File(launchDir, "launch.xml"); //$NON-NLS-1$
return file;
}
@Override
public IPath getWorkingDirectoryPath(ILaunchConfiguration configuration) throws CoreException
{
// TODO changes are afoot so that working directory can be gotten from the Common launch tab
// String path = configuration.getAttribute(JAXPLaunchConfigurationConstants.ATTR_PROCESSOR_WORKING_DIR, (String) null);
// if (path != null)
// {
// path = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(path);
// return new Path(path);
// }
return null;
}
private IProcessorInvoker getProcessorInvokerDescriptor(ILaunchConfiguration configuration) throws CoreException
{
String invokerId = configuration.getAttribute(JAXPLaunchConfigurationConstants.INVOKER_DESCRIPTOR, "org.eclipse.wst.xsl.launching.jaxp.invoke");
return JAXPRuntime.getProcessorInvoker(invokerId);
}
public static IProcessorInstall getProcessorInstall(ILaunchConfiguration configuration, String mode) throws CoreException
{
IProcessorInstall install = LaunchHelper.getProcessorInstall(configuration);
if (mode.equals(ILaunchManager.DEBUG_MODE) && install.getDebugger() == null)
{
String debuggingInstallId = JAXPLaunchingPlugin.getDefault().getPluginPreferences().getString(JAXPLaunchConfigurationConstants.ATTR_DEFAULT_DEBUGGING_INSTALL_ID);
install = JAXPRuntime.getProcessor(debuggingInstallId);
}
return install;
}
@Override
public String getMainTypeName(ILaunchConfiguration configuration) throws CoreException
{
if (ILaunchManager.DEBUG_MODE.equals(mode))
return "org.eclipse.wst.xsl.jaxp.debug.debugger.DebugRunner"; //$NON-NLS-1$
return "org.eclipse.wst.xsl.jaxp.debug.invoker.internal.Main"; //$NON-NLS-1$
}
@Override
public String getProgramArguments(ILaunchConfiguration configuration) throws CoreException
{
// classname, sourceurl, output file
IProcessorInvoker invoker = getProcessorInvokerDescriptor(configuration);
String clazz = invoker.getInvokerClassName();
StringBuffer sb = new StringBuffer();
sb.append(clazz);
sb.append(" "); //$NON-NLS-1$
sb.append("\"" + getLaunchConfigFile().getAbsolutePath() + "\""); //$NON-NLS-1$ //$NON-NLS-2$
sb.append(" "); //$NON-NLS-1$
sb.append("\"" + launchHelper.getSource() + "\""); //$NON-NLS-1$ //$NON-NLS-2$
sb.append(" "); //$NON-NLS-1$
sb.append("\"" + launchHelper.getTarget().getAbsolutePath() + "\""); //$NON-NLS-1$ //$NON-NLS-2$
if (ILaunchManager.DEBUG_MODE.equals(mode))
{
IProcessorInstall install = getProcessorInstall(configuration, mode);
if (install.getDebugger() != null)
{
IDebugger debugger = install.getDebugger();
String className = debugger.getClassName();
sb.append(" -debug ").append(className).append(" "); //$NON-NLS-1$ //$NON-NLS-2$
sb.append(launchHelper.getRequestPort());
sb.append(" ").append(launchHelper.getEventPort()); //$NON-NLS-1$
sb.append(" ").append(launchHelper.getGeneratePort()); //$NON-NLS-1$
}
}
return sb.toString();
}
@Override
public String[] getClasspath(ILaunchConfiguration configuration) throws CoreException
{
// get the classpath defined by the user
String[] userClasspath = super.getClasspath(configuration);
// get the classpath required for the transformation
IProcessorInvoker invoker = getProcessorInvokerDescriptor(configuration);
List<String> invokerCP = new ArrayList<String>();
for (String entry : invoker.getClasspathEntries())
{
invokerCP.add(entry);
}
// add the debugger...
IProcessorInstall install = getProcessorInstall(configuration, mode);
if (ILaunchManager.DEBUG_MODE.equals(mode) && install.getDebugger() != null)
{
String[] jars = install.getDebugger().getClassPath();
for (String jar : jars)
{
invokerCP.add(jar);
}
}
String[] invokerClasspath = (String[]) invokerCP.toArray(new String[0]);
// add them together
String[] classpath = new String[userClasspath.length + invokerClasspath.length];
System.arraycopy(invokerClasspath, 0, classpath, 0, invokerClasspath.length);
System.arraycopy(userClasspath, 0, classpath, invokerClasspath.length, userClasspath.length);
return classpath;
}
@Override
public String getVMArguments(ILaunchConfiguration configuration) throws CoreException
{
String vmargs = super.getVMArguments(configuration);
IProcessorInstall install = getProcessorInstall(configuration, mode);
if (install != null && !install.getProcessorType().isJREDefault())
{
// clear the endorsed dir
File tempDir = getEndorsedDir();
if (tempDir.exists())
{
File[] children = tempDir.listFiles();
for (File child : children)
{
child.delete();
}
tempDir.delete();
}
tempDir.mkdir();
// move the required jars to the endorsed dir
IProcessorJar[] jars = install.getProcessorJars();
for (int i = 0; i < jars.length; i++)
{
URL entry = jars[i].asURL();
if (entry == null)
throw new CoreException(new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, IStatus.ERROR, Messages.getString("XSLTLaunchConfigurationDelegate.23") + jars[i], null)); //$NON-NLS-1$
File file = new File(tempDir, "END_" + i + ".jar"); //$NON-NLS-1$ //$NON-NLS-2$
moveFile(entry, file);
}
// add the endorsed dir
vmargs += " -Djava.endorsed.dirs=\"" + tempDir.getAbsolutePath() + "\""; //$NON-NLS-1$ //$NON-NLS-2$
String tfactory = getTransformerFactory(install);
if (tfactory != null)
vmargs += " -Djavax.xml.transform.TransformerFactory=" + tfactory; //$NON-NLS-1$
// if (ILaunchManager.DEBUG_MODE.equals(mode))
// {
// // in debug mode, set the logging to ERROR. This prevents the console from popping up on top of the result view!
// try
// {
// URL url = FileLocator.resolve(FileLocator.find(Platform.getBundle(JAXPLaunchingPlugin.PLUGIN_ID), new Path("/log4j.debug.properties"), null));
// vmargs += " -Dlog4j.configuration=\""+url.toExternalForm()+"\""; //$NON-NLS-1$
// }
// catch (IOException e)
// {
// JAXPLaunchingPlugin.log(e);
// }
// }
}
return vmargs;
}
private String getTransformerFactory(IProcessorInstall install)
{
String tfactory = null;
if (ILaunchManager.DEBUG_MODE.equals(mode))
tfactory = install.getDebugger().getTransformerFactory();
else
{
ITransformerFactory t = launchHelper.getTransformerFactory();
if (t != null)
tfactory = t.getFactoryClass();
}
return tfactory;
}
private File getEndorsedDir()
{
IPath tempLocation = Platform.getStateLocation(JAXPLaunchingPlugin.getDefault().getBundle()).append("endorsed"); //$NON-NLS-1$
return tempLocation.toFile();
}
private static void moveFile(URL src, File target) throws CoreException
{
BufferedOutputStream bos = null;
BufferedInputStream bis = null;
try
{
bos = new BufferedOutputStream(new FileOutputStream(target));
bis = new BufferedInputStream(src.openStream());
while (bis.available() > 0)
{
int size = bis.available();
if (size > 1024)
size = 1024;
byte[] b = new byte[size];
bis.read(b, 0, b.length);
bos.write(b);
}
}
catch (IOException e)
{
throw new CoreException(new Status(IStatus.ERROR, JAXPLaunchingPlugin.PLUGIN_ID, IStatus.ERROR, Messages.getString("XSLTLaunchConfigurationDelegate.7") + src + Messages.getString("XSLTLaunchConfigurationDelegate.31") + target, e)); //$NON-NLS-1$ //$NON-NLS-2$
}
finally
{
if (bis != null)
{
try
{
bis.close();
}
catch (IOException e)
{
JAXPLaunchingPlugin.log(e);
}
}
if (bos != null)
{
try
{
bos.close();
}
catch (IOException e)
{
JAXPLaunchingPlugin.log(e);
}
}
}
}
}