blob: cfb19de101f406e4a6c6cdb98eb6a2c95fae35a9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 Jesper Steen Moeller 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 Moeller - XSL core plugin
* Doug Satchwell - bug 225304
*******************************************************************************/
package org.eclipse.wst.xsl.core.resolver;
import java.io.IOException;
import java.net.URL;
import javax.xml.parsers.ParserConfigurationException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverExtension;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xsl.core.Messages;
import org.eclipse.wst.xsl.core.XSLCore;
import org.eclipse.wst.xsl.core.internal.XSLCorePlugin;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* TODO: Javadoc
*
* @author Jesper Steen Moeller
*
*/
public class ResolverExtension implements URIResolverExtension
{
private static final Double DEFAULT_XSLT_VERSION = 1.0;
private static final String XSLT_STYLESHEET = "stylesheet"; //$NON-NLS-1$
private static final String XSLT_TEMPLATE = "template"; //$NON-NLS-1$
private static final String XSLT_VERSION = "version"; //$NON-NLS-1$
private boolean initialised;
private String xslt_1_0_fileURL;
private String xslt_2_0_fileURL;
public String resolve(IFile file, String baseLocation, String publicId, String systemId)
{
// Is someone looking for "our" schema?
if (!XSLCore.XSL_NAMESPACE_URI.equals(publicId))
{
// Not this time, return right away
return null;
}
String version = null;
if (file != null)
version = peekVersionAttributeFromSSE(file);
if (version == null)
version = peekVersionFromFile(file, baseLocation);
if (version == null)
return null;
Double versionNumber = null;
try
{
versionNumber = Double.valueOf(version);
}
catch (Throwable t)
{
// Not interested
}
if (versionNumber == null)
{
versionNumber = DEFAULT_XSLT_VERSION;
}
// We carelessly ditch the fraction part
int intVersion = versionNumber.intValue();
checkInitialised();
if (intVersion == 1)
{
return xslt_1_0_fileURL;
}
else if (intVersion == 2)
{
return xslt_2_0_fileURL;
}
else
return null;
}
private void checkInitialised()
{
if (!initialised)
{
initialised = true;
try
{
URL pluginURL = FileLocator.find(XSLCorePlugin.getDefault().getBundle(), new Path("/xslt-schemas/xslt-1.0.xsd"), null); //$NON-NLS-1$
xslt_1_0_fileURL = FileLocator.toFileURL(pluginURL).toExternalForm();
pluginURL = FileLocator.find(XSLCorePlugin.getDefault().getBundle(), new Path("/xslt-schemas/xslt-2.0.xsd"), null); //$NON-NLS-1$
xslt_2_0_fileURL = FileLocator.toFileURL(pluginURL).toExternalForm();
}
catch (IOException e)
{
XSLCorePlugin.log(e);
}
}
}
private String peekVersionFromFile(IFile file, String baseLocation)
{
XSLVersionHandler handler = new XSLVersionHandler();
try
{
handler.parseContents(file != null ? createInputSource(file) : createInputSource(baseLocation));
}
catch (SAXException se)
{
XSLCorePlugin.log(se);
// drop through, since this is almost to be expected
}
catch (IOException ioe)
{
XSLCorePlugin.log(new CoreException(XSLCorePlugin.newErrorStatus("Can't parse XSL document", ioe))); //$NON-NLS-1$
// drop through, since this is not really a show-stopper
}
catch (ParserConfigurationException pce)
{
// some bad thing happened - force this describer to be disabled
String message = Messages.XSLCorePlugin_parserConfiguration;
XSLCorePlugin.log(new Status(IStatus.ERROR, XSLCorePlugin.PLUGIN_ID, 0, message, pce));
throw new RuntimeException(message);
// drop through, since this is not really a show-stopper
}
catch (CoreException ce)
{
XSLCorePlugin.log(ce);
// drop through, since this is not really a show-stopper
}
String versionX = handler.getVersionAttribute();
return versionX;
}
private String peekVersionAttributeFromSSE(IFile file)
{
IModelManager manager = StructuredModelManager.getModelManager();
if (manager != null)
{
String id = manager.calculateId(file);
IStructuredModel model = manager.getExistingModelForRead(id);
try
{
if (model instanceof IDOMModel)
{
Document doc = ((IDOMModel) model).getDocument();
if (doc != null && doc.getDocumentElement() != null)
{
Element documentElement = doc.getDocumentElement();
if (XSLT_STYLESHEET.equals(documentElement.getLocalName()) || XSLT_TEMPLATE.equals(documentElement.getLocalName()))
{
return documentElement.getAttribute(XSLT_VERSION);
}
else
return ""; //$NON-NLS-1$
}
}
}
finally
{
// bug 225304
if (model != null)
model.releaseFromRead();
}
}
return null;
}
private InputSource createInputSource(String systemId) throws CoreException
{
return new InputSource(systemId);
}
private InputSource createInputSource(IFile file) throws CoreException
{
InputSource src = new InputSource(file.getContents());
src.setSystemId(file.getLocationURI().toString());
return src;
}
}