| /******************************************************************************* |
| * 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); |
| } |
| } |
| } |
| } |
| } |