From e6ebf28517a07017df9eb64f508a3967b39a4254 Mon Sep 17 00:00:00 2001 From: Jesper Steen Møller Date: Wed, 24 Apr 2013 11:28:22 +0200 Subject: [405223] Processing and file name/type doesn't match output type from XSL --- .../xsl/internal/debug/ui/XSLLaunchShortcut.java | 35 ++++- .../internal/debug/ui/XslOutputMethodSniffer.java | 160 +++++++++++++++++++++ .../internal/debug/ui/tabs/main/XSLMainTab.java | 11 +- .../debug/ui/tabs/output/OutputFileBlock.java | 10 +- .../META-INF/MANIFEST.MF | 2 +- .../launching/XSLLaunchConfigurationConstants.java | 10 +- .../org/eclipse/wst/xsl/launching/XSLTRuntime.java | 21 ++- .../wst/xsl/launching/config/BaseLaunchHelper.java | 9 +- 8 files changed, 247 insertions(+), 11 deletions(-) create mode 100644 bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/XslOutputMethodSniffer.java diff --git a/bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/XSLLaunchShortcut.java b/bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/XSLLaunchShortcut.java index a852d7a..cebf156 100644 --- a/bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/XSLLaunchShortcut.java +++ b/bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/XSLLaunchShortcut.java @@ -11,11 +11,12 @@ *******************************************************************************/ package org.eclipse.wst.xsl.internal.debug.ui; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -393,10 +394,11 @@ public class XSLLaunchShortcut implements ILaunchShortcut { ILaunchConfiguration config = null; try { ILaunchConfigurationType configType = getConfigurationType(); + String lastSegment = xmlFile != null ? xmlFile.getName() : xmlFilePath != null ? xmlFilePath.lastSegment() : "XSLTransformation"; //$NON-NLS-1$ ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, getLaunchManager() .generateUniqueLaunchConfigurationNameFrom( - xmlFilePath.lastSegment())); + lastSegment)); if (xmlFile != null) wc .setAttribute( @@ -424,6 +426,16 @@ public class XSLLaunchShortcut implements ILaunchShortcut { pipeline.addTransformDef(new LaunchTransform(xslFilePath, LaunchTransform.EXTERNAL_TYPE)); } + if (! pipeline.getTransformDefs().isEmpty()) { + LaunchTransform lastDef = pipeline.getTransformDefs().get(pipeline.getTransformDefs().size()-1); + String outputFormat = guessOutputMethod(lastDef); + if (outputFormat != null) { + wc + .setAttribute( + XSLLaunchConfigurationConstants.ATTR_DEFAULT_OUTPUT_METHOD, + outputFormat); + } + } wc.setAttribute(XSLLaunchConfigurationConstants.ATTR_PIPELINE, pipeline.toXML()); if (xmlFile != null) @@ -436,6 +448,25 @@ public class XSLLaunchShortcut implements ILaunchShortcut { return config; } + private String guessOutputMethod(LaunchTransform lastDef) { + try { + XslOutputMethodSniffer xofs = new XslOutputMethodSniffer(); + xofs.parseContents(new InputSource(new FileInputStream(lastDef.getLocation().toFile()))); + return xofs.getOutputMethod(); + } catch (FileNotFoundException e) { + // It's OK + } catch (IOException e) { + // It's OK + } catch (ParserConfigurationException e) { + // It's OK + } catch (SAXException e) { + // It's OK + } catch (CoreException e) { + // It really is OK! + } + return null; + } + protected Shell getShell() { return XSLDebugUIPlugin.getActiveWorkbenchShell(); } diff --git a/bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/XslOutputMethodSniffer.java b/bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/XslOutputMethodSniffer.java new file mode 100644 index 0000000..4fd4908 --- /dev/null +++ b/bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/XslOutputMethodSniffer.java @@ -0,0 +1,160 @@ +/******************************************************************************* + * Copyright (c) 2013 Jesper Steen Moller and others + * 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: + * Jesper Steen Moller - initial API and implementation + *******************************************************************************/ + +package org.eclipse.wst.xsl.internal.debug.ui; + +import java.io.IOException; +import java.io.StringReader; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.DefaultHandler; + +/** + * @since 3.5 + */ +public final class XslOutputMethodSniffer extends DefaultHandler { + private static final String XSL_NAMESPACE = "http://www.w3.org/1999/XSL/Transform"; //$NON-NLS-1$ + private static final String OUTPUT_ELEMENT_NAME = "output"; //$NON-NLS-1$ + private static final String METHOD_ATTR_NAME = "method"; //$NON-NLS-1$ + + /** + * An exception indicating that the parsing should stop. This is usually + * triggered when the top-level element has been found. + */ + private class StopParsingException extends SAXException { + /** + * All serializable objects should have a stable serialVersionUID + */ + private static final long serialVersionUID = 1L; + + /** + * Constructs an instance of StopParsingException with a + * null detail message. + */ + public StopParsingException() { + super((String) null); + } + } + + private String outputMethod = null; + + public String getOutputMethod() { + return this.outputMethod; + } + + /** + * Creates a new SAX parser for use within this instance. + * + * @return The newly created parser. + * + * @throws ParserConfigurationException + * If a parser of the given configuration cannot be created. + * @throws SAXException + * If something in general goes wrong when creating the parser. + * @throws SAXNotRecognizedException + * If the XMLReader does not recognize the + * lexical handler configuration option. + * @throws SAXNotSupportedException + * If the XMLReader does not support the lexical + * handler configuration option. + */ + private final SAXParser createParser(SAXParserFactory parserFactory) throws ParserConfigurationException, SAXException, SAXNotRecognizedException, SAXNotSupportedException { + // Initialize the parser. + final SAXParser parser = parserFactory.newSAXParser(); + final XMLReader reader = parser.getXMLReader(); + try { + // be sure validation is "off" or the feature to ignore DTD's will not apply + reader.setFeature("http://xml.org/sax/features/validation", false); //$NON-NLS-1$ + reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); //$NON-NLS-1$ + } catch (SAXNotRecognizedException e) { + // not a big deal if the parser does not recognize the features + } catch (SAXNotSupportedException e) { + // not a big deal if the parser does not support the features + } + return parser; + } + + public boolean parseContents(InputSource contents) throws IOException, ParserConfigurationException, SAXException { + // Parse the file into we have what we need (or an error occurs). + + try { + SAXParserFactory parserFactory = SAXParserFactory.newInstance(); + parserFactory.setValidating(false); + parserFactory.setNamespaceAware(true); + final SAXParser parser = createParser(parserFactory); + // to support external entities specified as relative URIs (see bug 63298) + contents.setSystemId("/"); //$NON-NLS-1$ + parser.parse(contents, this); + } catch (StopParsingException e) { + // Abort the parsing normally. Fall through... + } + return true; + } + + /* + * Resolve external entity definitions to an empty string. This is to speed + * up processing of files with external DTDs. Not resolving the contents + * of the DTD is ok, as only the System ID of the DTD declaration is used. + * @see org.xml.sax.helpers.DefaultHandler#resolveEntity(java.lang.String, java.lang.String) + */ + public InputSource resolveEntity(String publicId, String systemId) throws SAXException { + return new InputSource(new StringReader("")); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see org.xml.sax.ContentHandler#startElement(java.lang.String, + * java.lang.String, java.lang.String, org.xml.sax.Attributes) + */ + public final void startElement(final String uri, final String elementName, final String qualifiedName, final Attributes attributes) throws SAXException { + if (XSL_NAMESPACE.equals(uri) && OUTPUT_ELEMENT_NAME.equals(elementName)) { + this.outputMethod = attributes.getValue(METHOD_ATTR_NAME); + throw new StopParsingException(); + } + } + + /* + * (non-Javadoc) + * + * @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String) + */ + public final void startEntity(final String name) { + // Not interested. + } + + @Override + public void processingInstruction(String target, String data) + throws SAXException { + } + +// public static void main(String[] args) throws IOException, ParserConfigurationException, SAXException { +// String xml = ""; //$NON-NLS-1$ +// XslOutputFormatSniffer sniffer = new XslOutputFormatSniffer(); +// sniffer.parseContents(new InputSource(new StringReader(xml))); +// System.out.println(sniffer.getOutputMethod()); +// } +} diff --git a/bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/tabs/main/XSLMainTab.java b/bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/tabs/main/XSLMainTab.java index a9db14f..98d5096 100644 --- a/bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/tabs/main/XSLMainTab.java +++ b/bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/tabs/main/XSLMainTab.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007,2008 Chase Technology Ltd - http://www.chasetechnology.co.uk and others + * Copyright (c) 2007,2013 Chase Technology Ltd - http://www.chasetechnology.co.uk and others * 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 @@ -8,6 +8,7 @@ * Contributors: * Doug Satchwell (Chase Technology Ltd) - initial API and implementation * David Carver - STAR - bug 223557 - Added Images contributed by Holger Voorman + * Jesper S Moller - 405223 - Processing and file name/type doesn't match output type from XSL *******************************************************************************/ package org.eclipse.wst.xsl.internal.debug.ui.tabs.main; @@ -124,6 +125,14 @@ public class XSLMainTab extends XSLLaunchConfigurationTab { configuration.setAttribute( XSLLaunchConfigurationConstants.ATTR_PIPELINE, pipeline .toXML()); + + String method = pipeline.getOutputProperties().getProperty("method", null); //$NON-NLS-1$ + + if (method != null) { + configuration.setAttribute( + XSLLaunchConfigurationConstants.ATTR_DEFAULT_OUTPUT_METHOD, + method); + } } catch (CoreException e) { XSLDebugUIPlugin.log(e); } diff --git a/bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/tabs/output/OutputFileBlock.java b/bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/tabs/output/OutputFileBlock.java index ff99b65..ee31db8 100644 --- a/bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/tabs/output/OutputFileBlock.java +++ b/bundles/org.eclipse.wst.xsl.debug.ui/src/org/eclipse/wst/xsl/internal/debug/ui/tabs/output/OutputFileBlock.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk + * Copyright (c) 2007, 2013 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 @@ -7,6 +7,7 @@ * * Contributors: * Doug Satchwell (Chase Technology Ltd) - initial API and implementation + * Jesper S Moller - 405223 - Processing and file name/type doesn't match output type from XSL *******************************************************************************/ package org.eclipse.wst.xsl.internal.debug.ui.tabs.output; @@ -39,6 +40,7 @@ public class OutputFileBlock extends ResourceSelectionBlock { private String inputFilename; private Text fileNameText; private String defaultOutputFileName; + private String defaultOutputFileMethod; private String outputFileName; public OutputFileBlock() { @@ -196,6 +198,10 @@ public class OutputFileBlock extends ResourceSelectionBlock { public void initializeFrom(ILaunchConfiguration configuration) { try { + defaultOutputFileMethod = configuration.getAttribute( + XSLLaunchConfigurationConstants.ATTR_DEFAULT_OUTPUT_METHOD, + "xml"); //$NON-NLS-1$ + inputFilename = configuration.getAttribute( XSLLaunchConfigurationConstants.ATTR_INPUT_FILE, ""); //$NON-NLS-1$ updateDefaultOutputFile(); @@ -284,7 +290,7 @@ public class OutputFileBlock extends ResourceSelectionBlock { private void updateDefaultOutputFile() { try { IPath path = XSLTRuntime - .defaultOutputFileForInputFile(inputFilename); + .defaultOutputFileForInputFile(inputFilename, defaultOutputFileMethod); // determine whether this path exists in the workspace IFile[] files = ResourcesPlugin.getWorkspace().getRoot() .findFilesForLocation(path); diff --git a/bundles/org.eclipse.wst.xsl.launching/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.xsl.launching/META-INF/MANIFEST.MF index 6e18cea..82c18ea 100644 --- a/bundles/org.eclipse.wst.xsl.launching/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.wst.xsl.launching/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name.0 Bundle-SymbolicName: org.eclipse.wst.xsl.launching;singleton:=true -Bundle-Version: 1.0.200.qualifier +Bundle-Version: 1.1.0.qualifier Bundle-Activator: org.eclipse.wst.xsl.internal.launching.LaunchingPlugin Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)", org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)", diff --git a/bundles/org.eclipse.wst.xsl.launching/src/org/eclipse/wst/xsl/launching/XSLLaunchConfigurationConstants.java b/bundles/org.eclipse.wst.xsl.launching/src/org/eclipse/wst/xsl/launching/XSLLaunchConfigurationConstants.java index 1c226a4..8cc3beb 100644 --- a/bundles/org.eclipse.wst.xsl.launching/src/org/eclipse/wst/xsl/launching/XSLLaunchConfigurationConstants.java +++ b/bundles/org.eclipse.wst.xsl.launching/src/org/eclipse/wst/xsl/launching/XSLLaunchConfigurationConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk + * Copyright (c) 2007, 2013 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 @@ -7,6 +7,7 @@ * * Contributors: * Doug Satchwell (Chase Technology Ltd) - initial API and implementation + * Jesper S Moller - 405223 - Processing and file name/type doesn't match output type from XSL *******************************************************************************/ package org.eclipse.wst.xsl.launching; @@ -38,4 +39,11 @@ public class XSLLaunchConfigurationConstants * @since 1.0 */ public static final String ATTR_WORKING_DIR = LaunchingPlugin.PLUGIN_ID + ".ATTR_WORKING_DIR"; //$NON-NLS-1$; + + /** + * @since 1.1 + */ + public static final String ATTR_DEFAULT_OUTPUT_METHOD = LaunchingPlugin.PLUGIN_ID + ".ATTR_DEFAULT_OUTPUT_METHOD"; //$NON-NLS-1$; + + } diff --git a/bundles/org.eclipse.wst.xsl.launching/src/org/eclipse/wst/xsl/launching/XSLTRuntime.java b/bundles/org.eclipse.wst.xsl.launching/src/org/eclipse/wst/xsl/launching/XSLTRuntime.java index 1164cbd..92bf426 100644 --- a/bundles/org.eclipse.wst.xsl.launching/src/org/eclipse/wst/xsl/launching/XSLTRuntime.java +++ b/bundles/org.eclipse.wst.xsl.launching/src/org/eclipse/wst/xsl/launching/XSLTRuntime.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Chase Technology Ltd - http://www.chasetechnology.co.uk + * Copyright (c) 2007, 2013 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 @@ -8,6 +8,7 @@ * Contributors: * Doug Satchwell (Chase Technology Ltd) - initial API and implementation * David Carver (Intalio) - clean up find bugs + * Jesper S Moller - 405223 - Processing and file name/type doesn't match output type from XSL *******************************************************************************/ package org.eclipse.wst.xsl.launching; @@ -35,11 +36,27 @@ public class XSLTRuntime { */ public static IPath defaultOutputFileForInputFile(String inputFileExpression) throws CoreException { + return defaultOutputFileForInputFile(inputFileExpression, "xml"); //$NON-NLS-1$ + } + + /** + * Creates a default Output File for the given input file string. + * + * @return Returns an IPath for the Output File. + * @since 1.0 + */ + public static IPath defaultOutputFileForInputFile(String inputFileExpression, String method) + throws CoreException { String file = VariablesPlugin.getDefault().getStringVariableManager() .performStringSubstitution(inputFileExpression); IPath inputFilePath = new Path(file); inputFilePath = inputFilePath.removeFileExtension(); - inputFilePath = inputFilePath.addFileExtension("out.xml"); //$NON-NLS-1$ + String extension = "xml"; //$NON-NLS-1$ + if ("text".equals(method)) extension = "txt"; //$NON-NLS-1$//$NON-NLS-2$ + else if ("html".equals(method)) extension = "html"; //$NON-NLS-1$ //$NON-NLS-2$ + else if ("xhtml".equals(method)) extension = "xhtml"; //$NON-NLS-1$ //$NON-NLS-2$ + + inputFilePath = inputFilePath.addFileExtension("out." + extension); //$NON-NLS-1$ return inputFilePath; } diff --git a/bundles/org.eclipse.wst.xsl.launching/src/org/eclipse/wst/xsl/launching/config/BaseLaunchHelper.java b/bundles/org.eclipse.wst.xsl.launching/src/org/eclipse/wst/xsl/launching/config/BaseLaunchHelper.java index 8c2eb6e..73b9ab7 100644 --- a/bundles/org.eclipse.wst.xsl.launching/src/org/eclipse/wst/xsl/launching/config/BaseLaunchHelper.java +++ b/bundles/org.eclipse.wst.xsl.launching/src/org/eclipse/wst/xsl/launching/config/BaseLaunchHelper.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk + * Copyright (c) 2007, 2013 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 @@ -7,6 +7,7 @@ * * Contributors: * Doug Satchwell (Chase Technology Ltd) - initial API and implementation + * Jesper S Moller - 405223 - Processing and file name/type doesn't match output type from XSL *******************************************************************************/ package org.eclipse.wst.xsl.launching.config; @@ -137,6 +138,10 @@ public class BaseLaunchHelper { public static File hydrateOutputFile(ILaunchConfiguration configuration) throws CoreException { IPath outputFile = null; + + String method = configuration.getAttribute( + XSLLaunchConfigurationConstants.ATTR_DEFAULT_OUTPUT_METHOD, "xml"); //$NON-NLS-1$ + boolean useDefaultOutputFile = configuration.getAttribute( XSLLaunchConfigurationConstants.ATTR_USE_DEFAULT_OUTPUT_FILE, true); @@ -153,7 +158,7 @@ public class BaseLaunchHelper { outputFile = XSLTRuntime .defaultOutputFileForInputFile(configuration.getAttribute( XSLLaunchConfigurationConstants.ATTR_INPUT_FILE, - (String) null)); + (String) null), method); } return outputFile.toFile(); } -- cgit v1.2.3