drop saxon-based XSLT transformer
Change-Id: I2cd4e0965452c376df8c5e43353fbdd6f62fb27d
This commit is contained in:
parent
ca0ea73a4a
commit
bfc71eb03e
@ -1,18 +0,0 @@
|
||||
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
|
||||
#
|
||||
# This file is part of the LibreOffice project.
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
|
||||
$(eval $(call gb_Extension_Extension,xslt2-transformer,filter/source/xsltfilter))
|
||||
|
||||
$(eval $(call gb_Extension_add_files,xslt2-transformer,,\
|
||||
$(call gb_Jar_get_outdir_target,saxon9) \
|
||||
$(call gb_Jar_get_outdir_target,XSLTFilter) \
|
||||
$(SRCDIR)/filter/source/xsltfilter/components.rdb \
|
||||
))
|
||||
|
||||
# vim: set noet sw=4 ts=4:
|
@ -1,42 +0,0 @@
|
||||
#
|
||||
# This file is part of the LibreOffice project.
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# This file incorporates work covered by the following license notice:
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed
|
||||
# with this work for additional information regarding copyright
|
||||
# ownership. The ASF licenses this file to you 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 .
|
||||
#
|
||||
|
||||
$(eval $(call gb_Jar_Jar,XSLTFilter))
|
||||
|
||||
$(eval $(call gb_Jar_use_jars,XSLTFilter,\
|
||||
ridl \
|
||||
unoil \
|
||||
jurt \
|
||||
juh \
|
||||
))
|
||||
|
||||
$(eval $(call gb_Jar_use_externals,XSLTFilter,saxon))
|
||||
|
||||
$(eval $(call gb_Jar_set_componentfile,XSLTFilter,filter/source/xsltfilter/XSLTFilter.jar,OOO))
|
||||
|
||||
$(eval $(call gb_Jar_set_manifest,XSLTFilter,$(SRCDIR)/filter/source/xsltfilter/Manifest))
|
||||
|
||||
$(eval $(call gb_Jar_set_packageroot,XSLTFilter,com))
|
||||
|
||||
$(eval $(call gb_Jar_add_sourcefiles,XSLTFilter,\
|
||||
filter/source/xsltfilter/com/sun/star/comp/xsltfilter/Base64 \
|
||||
filter/source/xsltfilter/com/sun/star/comp/xsltfilter/XSLTFilterOLEExtracter \
|
||||
filter/source/xsltfilter/com/sun/star/comp/xsltfilter/XSLTransformer \
|
||||
))
|
||||
|
||||
# vim: set noet sw=4 ts=4:
|
@ -74,8 +74,6 @@ endif
|
||||
|
||||
ifneq ($(SOLAR_JAVA),)
|
||||
$(eval $(call gb_Module_add_targets,filter,\
|
||||
Extension_xslt2_transformer \
|
||||
Jar_XSLTFilter \
|
||||
Jar_XSLTValidate \
|
||||
))
|
||||
endif
|
||||
|
@ -1,2 +0,0 @@
|
||||
RegistrationClassName: com.sun.star.comp.xsltfilter.XSLTransformer
|
||||
UNO-Type-Path:
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* This file incorporates work covered by the following license notice:
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you 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 .
|
||||
-->
|
||||
|
||||
<component loader="com.sun.star.loader.Java2"
|
||||
xmlns="http://openoffice.org/2010/uno-components">
|
||||
<implementation name="XSLTransformer">
|
||||
<service name="com.sun.star.comp.JAXTHelper"/>
|
||||
</implementation>
|
||||
</component>
|
File diff suppressed because it is too large
Load Diff
@ -1,386 +0,0 @@
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* This file incorporates work covered by the following license notice:
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you 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 .
|
||||
*/
|
||||
|
||||
package com.sun.star.comp.xsltfilter;
|
||||
|
||||
// Standard Java classes
|
||||
import java.io.FileWriter;
|
||||
import java.util.zip.Inflater;
|
||||
import java.util.zip.Deflater;
|
||||
|
||||
// StarOffice Interfaces and UNO
|
||||
import com.sun.star.bridge.XBridgeFactory;
|
||||
import com.sun.star.bridge.XBridge;
|
||||
import com.sun.star.connection.XConnector;
|
||||
import com.sun.star.connection.XConnection;
|
||||
import com.sun.star.container.XNameContainer;
|
||||
import com.sun.star.embed.XTransactedObject;
|
||||
import com.sun.star.io.XStream;
|
||||
import com.sun.star.io.XSeekable;
|
||||
import com.sun.star.io.XInputStream;
|
||||
import com.sun.star.io.XOutputStream;
|
||||
import com.sun.star.lang.XMultiServiceFactory;
|
||||
import com.sun.star.lang.XComponent;
|
||||
import com.sun.star.uno.XComponentContext;
|
||||
import com.sun.star.uno.UnoRuntime;
|
||||
|
||||
/** This class is an xalan extension class. It provider 2 elements
|
||||
* and 2 functions to used in xslt script. With this elements and functions
|
||||
* we can convert between oledata between Wordml and OOo flat.
|
||||
* To use it, we need a running OOo. There are two ways to get the XMultiServiceFactory.
|
||||
* When called by OOo xslt filter, an XMultiServiceFactory will be add to the transformer
|
||||
* by setParameter(), then we can get it using getParameter(). Another way is using an
|
||||
* XConnection to connect to a running OOo. We connect to a running OOo, we need know the
|
||||
* uno url. It can be set in the xslt script. The default uno url is:
|
||||
* "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager"
|
||||
* see XSLTXalanOLEExtracter.java
|
||||
*/
|
||||
public class XSLTFilterOLEExtracter {
|
||||
|
||||
protected XMultiServiceFactory m_xMSF;
|
||||
protected XNameContainer m_Storage;
|
||||
protected XStream m_RootStream;
|
||||
protected XConnection m_Connection;
|
||||
protected String sConnectionString;
|
||||
private static final String UNO_URL = "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager";
|
||||
|
||||
public XSLTFilterOLEExtracter() {
|
||||
}
|
||||
|
||||
public void init(String unoUrl) {
|
||||
if (unoUrl == null || unoUrl.equals("")) {
|
||||
unoUrl = UNO_URL;
|
||||
}
|
||||
debugln("Init with uno url=" + unoUrl);
|
||||
if (null == m_xMSF) {
|
||||
try {
|
||||
m_xMSF = connectAwareGetServiceFactory();
|
||||
} catch (Exception ex) {
|
||||
System.err.println("Could not connect to the office '" + unoUrl + "'\n" + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void exit() {
|
||||
m_Storage = null;
|
||||
m_xMSF = null;
|
||||
if (null != m_Connection) {
|
||||
try {
|
||||
m_Connection.close();
|
||||
} catch (Exception ex) {
|
||||
System.err.println("Could not close connection to the office.\n" + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
//If aName = "oledata.mso" then we load the root storage from the given base64 string
|
||||
//Otherwise we compress the stream and add it to the root storage under the name of aName
|
||||
public void insertByName(String aName, String aBase64) {
|
||||
debugln("insertByName(" + aName + " : " + aBase64 + ")");
|
||||
if (aName.equals("oledata.mso")) {
|
||||
loadRootStorageFromBase64(aBase64);
|
||||
} else {
|
||||
ensureCreateRootStorage();
|
||||
insertSubStorage(aName, aBase64);
|
||||
}
|
||||
}
|
||||
//If aName = "oledata.mso" then we return the base64 encoded string of the root storage
|
||||
//Otherwise we return the base64 encoded string of the sub stream under the name of aName
|
||||
public String getByName(String aName) {
|
||||
if (aName.equals("oledata.mso")) {
|
||||
try {
|
||||
//get the length and seek to 0
|
||||
XSeekable xSeek = UnoRuntime.queryInterface(XSeekable.class, m_RootStream);
|
||||
int oleLength = (int) xSeek.getLength();
|
||||
xSeek.seek(0);
|
||||
xSeek = null;
|
||||
//read all bytes
|
||||
XInputStream xInput = m_RootStream.getInputStream();
|
||||
byte oledata[][] = new byte[1][oleLength];
|
||||
xInput.readBytes(oledata, oleLength);
|
||||
//return the base64 encoded string
|
||||
return Base64.encodeBytes(oledata[0]);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
return getEncodedSubStorage(aName);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
//get the sub stream which name = aName, decompress it and return the base64 encoded string
|
||||
public String getEncodedSubStorage(String aName) {
|
||||
debugln("getByName(" + aName + ")");
|
||||
try {
|
||||
if (!m_Storage.hasByName(aName)) {
|
||||
return "Not Found:" + aName;
|
||||
}
|
||||
Object oSubStream = m_Storage.getByName(aName);
|
||||
if (oSubStream == null) {
|
||||
return "Not Found:" + aName;
|
||||
}
|
||||
XInputStream xSubStream = UnoRuntime.queryInterface(XInputStream.class,
|
||||
oSubStream);
|
||||
if (xSubStream == null) {
|
||||
return "Not Found:" + aName;
|
||||
}
|
||||
//The first four byte are the length of the uncompressed data
|
||||
byte pLength[][] = new byte[1][4];
|
||||
XSeekable xSeek = UnoRuntime.queryInterface(XSeekable.class, xSubStream);
|
||||
xSeek.seek(0);
|
||||
xSeek = null;
|
||||
//Get the uncompressed length
|
||||
int readbytes = xSubStream.readBytes(pLength, 4);
|
||||
if (4 != readbytes) {
|
||||
System.out.println("readbytes:" + readbytes);
|
||||
return "Can not read the length.";
|
||||
}
|
||||
int oleLength = (pLength[0][0] << 0) + (pLength[0][1] << 8) + (pLength[0][2] << 16) + (pLength[0][3] << 24);
|
||||
byte pContents[][] = new byte[1][oleLength];
|
||||
//Read all bytes. The compressed length should less then the uncompressed length
|
||||
readbytes = xSubStream.readBytes(pContents, oleLength);
|
||||
if (oleLength < readbytes) {
|
||||
return "oleLength :" + oleLength + " readbytes: " + readbytes;
|
||||
}
|
||||
|
||||
// Decompress the bytes
|
||||
Inflater decompresser = new Inflater();
|
||||
decompresser.setInput(pContents[0], 0, readbytes);
|
||||
byte[] result = new byte[oleLength];
|
||||
int resultLength = decompresser.inflate(result);
|
||||
decompresser.end();
|
||||
|
||||
//return the base64 string of the uncompressed data
|
||||
return Base64.encodeBytes(result);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public XStream CreateTempFileStream(XMultiServiceFactory xMSF) {
|
||||
// try to get temporary file representation
|
||||
XStream xTempFileStream = null;
|
||||
try {
|
||||
Object oTempFile = xMSF.createInstance("com.sun.star.io.TempFile");
|
||||
xTempFileStream = UnoRuntime.queryInterface(XStream.class, oTempFile);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
if (xTempFileStream == null) {
|
||||
System.out.println("Can't create temporary file!");
|
||||
}
|
||||
|
||||
return xTempFileStream;
|
||||
}
|
||||
//decode the base64 string and create an com.sun.star.embed.OLESimpleStorage from it
|
||||
public void loadRootStorageFromBase64(String aBase64) {
|
||||
try {
|
||||
//Decode and write the data to an temp stream
|
||||
byte[] oledata = Base64.decode(aBase64);
|
||||
m_RootStream = CreateTempFileStream(m_xMSF);
|
||||
XOutputStream xOutput = m_RootStream.getOutputStream();
|
||||
xOutput.writeBytes(oledata);
|
||||
xOutput.flush();
|
||||
//Get the input stream and seek to begin
|
||||
XInputStream xInput = m_RootStream.getInputStream();
|
||||
XSeekable xSeek = UnoRuntime.queryInterface(XSeekable.class, xInput);
|
||||
xSeek.seek(0);
|
||||
oledata = null;
|
||||
xSeek = null;
|
||||
|
||||
//create an com.sun.star.embed.OLESimpleStorage from the temp stream
|
||||
Object pArgs[] = new Object[1];
|
||||
pArgs[0] = xInput;
|
||||
Object oTempStorage = m_xMSF.createInstanceWithArguments("com.sun.star.embed.OLESimpleStorage", pArgs);
|
||||
pArgs = null;
|
||||
|
||||
m_Storage = UnoRuntime.queryInterface(XNameContainer.class, oTempStorage);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//Create a empty OLESimpleStorage if there is not one
|
||||
public void ensureCreateRootStorage() {
|
||||
if (null == m_RootStream || null == m_Storage) {
|
||||
try {
|
||||
m_RootStream = CreateTempFileStream(m_xMSF);
|
||||
|
||||
Object pArgs[] = new Object[1];
|
||||
pArgs[0] = m_RootStream;
|
||||
Object oTempStorage = m_xMSF.createInstanceWithArguments("com.sun.star.embed.OLESimpleStorage", pArgs);
|
||||
pArgs = null;
|
||||
|
||||
m_Storage = UnoRuntime.queryInterface(XNameContainer.class, oTempStorage);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
//decode the base64 string and insert the length and the compressed data of it to
|
||||
//the root storage as a sub stream under aName
|
||||
public void insertSubStorage(String aName, String aBase64) {
|
||||
try {
|
||||
//decode the base64 string
|
||||
byte[] oledata = Base64.decode(aBase64);
|
||||
//create a temp stream to write data to
|
||||
XStream subStream = CreateTempFileStream(m_xMSF);
|
||||
XInputStream xInput = subStream.getInputStream();
|
||||
XOutputStream xOutput = subStream.getOutputStream();
|
||||
//write the length to the temp stream
|
||||
byte oleHead[] = new byte[4];
|
||||
oleHead[0] = (byte) ((oledata.length >>> 0) & 0xFF);
|
||||
oleHead[1] = (byte) ((oledata.length >>> 8) & 0xFF);
|
||||
oleHead[2] = (byte) ((oledata.length >>> 16) & 0xFF);
|
||||
oleHead[3] = (byte) ((oledata.length >>> 24) & 0xFF);
|
||||
xOutput.writeBytes(oleHead);
|
||||
|
||||
// Compress the bytes
|
||||
byte[] output = new byte[oledata.length];
|
||||
Deflater compresser = new Deflater();
|
||||
compresser.setInput(oledata);
|
||||
compresser.finish();
|
||||
int compressedDataLength = compresser.deflate(output);
|
||||
//realloc the data length
|
||||
byte[] compressedBytes = new byte[compressedDataLength];
|
||||
for (int i = 0; i < compressedDataLength; i++) {
|
||||
compressedBytes[i] = output[i];
|
||||
}
|
||||
|
||||
//write the compressed data to the temp stream
|
||||
xOutput.writeBytes(compressedBytes);
|
||||
//seek to 0
|
||||
XSeekable xSeek = UnoRuntime.queryInterface(XSeekable.class, xInput);
|
||||
xSeek.seek(0);
|
||||
xSeek = null;
|
||||
oledata = null;
|
||||
|
||||
//insert the temp stream as a sub stream and use an XTransactedObject to commit it immediately
|
||||
XTransactedObject xTransact = UnoRuntime.queryInterface(XTransactedObject.class, m_Storage);
|
||||
m_Storage.insertByName(aName, xInput);
|
||||
xTransact.commit();
|
||||
xTransact = null;
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/** separtates the uno-url into 3 different parts.
|
||||
*/
|
||||
protected static String[] parseUnoUrl(String url) {
|
||||
String[] aRet = new String[3];
|
||||
|
||||
if (!url.startsWith("uno:")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int semicolon = url.indexOf(';');
|
||||
if (semicolon == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
aRet[0] = url.substring(4, semicolon);
|
||||
int nextSemicolon = url.indexOf(';', semicolon + 1);
|
||||
|
||||
if (semicolon == -1) {
|
||||
return null;
|
||||
}
|
||||
aRet[1] = url.substring(semicolon + 1, nextSemicolon);
|
||||
|
||||
aRet[2] = url.substring(nextSemicolon + 1);
|
||||
return aRet;
|
||||
}
|
||||
//connect to running OOo and keep an XConnection object so that we can disconnect from OOo as we wish
|
||||
protected XMultiServiceFactory connectAwareGetServiceFactory() throws com.sun.star.uno.Exception,
|
||||
com.sun.star.uno.RuntimeException,
|
||||
Exception {
|
||||
|
||||
// Get component context
|
||||
XComponentContext xComponentContext =
|
||||
com.sun.star.comp.helper.Bootstrap.createInitialComponentContext(null);
|
||||
|
||||
// instantiate connector service
|
||||
Object x = xComponentContext.getServiceManager().createInstanceWithContext(
|
||||
"com.sun.star.connection.Connector", xComponentContext);
|
||||
|
||||
XConnector xConnector = UnoRuntime.queryInterface(XConnector.class, x);
|
||||
|
||||
String a[] = parseUnoUrl(sConnectionString);
|
||||
if (null == a) {
|
||||
throw new com.sun.star.uno.Exception("Couldn't parse uno-url " + sConnectionString);
|
||||
}
|
||||
|
||||
// connect using the connection string part of the uno-url only.
|
||||
m_Connection = xConnector.connect(a[0]);
|
||||
|
||||
x = xComponentContext.getServiceManager().createInstanceWithContext(
|
||||
"com.sun.star.bridge.BridgeFactory", xComponentContext);
|
||||
|
||||
XBridgeFactory xBridgeFactory = UnoRuntime.queryInterface(
|
||||
XBridgeFactory.class, x);
|
||||
|
||||
// create a nameless bridge with no instance provider
|
||||
// using the middle part of the uno-url
|
||||
XBridge bridge = xBridgeFactory.createBridge("", a[1], m_Connection, null);
|
||||
|
||||
// query for the XComponent interface and add this as event listener
|
||||
XComponent xComponent = UnoRuntime.queryInterface(
|
||||
XComponent.class, bridge);
|
||||
|
||||
// get the remote instance
|
||||
x = bridge.getInstance(a[2]);
|
||||
|
||||
// Did the remote server export this object ?
|
||||
if (null == x) {
|
||||
throw new com.sun.star.uno.Exception(
|
||||
"Server didn't provide an instance for" + a[2], null);
|
||||
}
|
||||
|
||||
XMultiServiceFactory xFac = UnoRuntime.queryInterface(XMultiServiceFactory.class, x);
|
||||
return xFac;
|
||||
}
|
||||
protected static boolean DEBUG = false;
|
||||
protected static boolean DEBUGCHK = false;
|
||||
protected static String debugfile;
|
||||
|
||||
protected static void debugln(String s) {
|
||||
debug(s + "\n");
|
||||
}
|
||||
|
||||
protected static void debug(String s) {
|
||||
if (!DEBUGCHK) {
|
||||
if (System.getProperty("xsltfilter.debug") == null) {
|
||||
DEBUGCHK = true;
|
||||
return;
|
||||
} else {
|
||||
debugfile = System.getProperty("xsltfilter.debug");
|
||||
DEBUG = true;
|
||||
}
|
||||
}
|
||||
if (!DEBUG) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
FileWriter dbgwriter = new FileWriter(debugfile, true);
|
||||
dbgwriter.write(s);
|
||||
dbgwriter.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,499 +0,0 @@
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* This file incorporates work covered by the following license notice:
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you 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 .
|
||||
*/
|
||||
|
||||
package com.sun.star.comp.xsltfilter;
|
||||
|
||||
// Standard Java classes
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.StringReader;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
|
||||
// Imported TraX classes
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.URIResolver;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
|
||||
//StarOffice Interfaces and UNO
|
||||
import com.sun.star.beans.NamedValue;
|
||||
import com.sun.star.comp.loader.FactoryHelper;
|
||||
import com.sun.star.io.XActiveDataControl;
|
||||
import com.sun.star.io.XActiveDataSink;
|
||||
import com.sun.star.io.XActiveDataSource;
|
||||
import com.sun.star.io.XInputStream;
|
||||
import com.sun.star.io.XOutputStream;
|
||||
import com.sun.star.io.XSeekable;
|
||||
import com.sun.star.io.XStreamListener;
|
||||
import com.sun.star.lang.XInitialization;
|
||||
import com.sun.star.lang.XMultiServiceFactory;
|
||||
import com.sun.star.lang.XServiceInfo;
|
||||
import com.sun.star.lang.XServiceName;
|
||||
import com.sun.star.lang.XSingleServiceFactory;
|
||||
import com.sun.star.lang.XTypeProvider;
|
||||
import com.sun.star.registry.XRegistryKey;
|
||||
import com.sun.star.uno.AnyConverter;
|
||||
import com.sun.star.uno.Type;
|
||||
import com.sun.star.uno.UnoRuntime;
|
||||
import com.sun.star.xml.xslt.XXSLTTransformer;
|
||||
|
||||
//Uno to java Adaptor
|
||||
import com.sun.star.lib.uno.adapter.XInputStreamToInputStreamAdapter;
|
||||
import com.sun.star.lib.uno.adapter.XOutputStreamToOutputStreamAdapter;
|
||||
import javax.xml.transform.Templates;
|
||||
|
||||
import net.sf.saxon.FeatureKeys;
|
||||
|
||||
/** This outer class provides an inner class to implement the service
|
||||
* description and a method to instantiate the
|
||||
* component on demand (__getServiceFactory()).
|
||||
*/
|
||||
public class XSLTransformer
|
||||
implements XTypeProvider, XServiceName, XServiceInfo, XXSLTTransformer,
|
||||
URIResolver, EntityResolver {
|
||||
|
||||
/**
|
||||
* This component provides java based XSL transformations
|
||||
* A SAX based interface is not feasible when crossing language bordes
|
||||
* since too much time would be wasted by bridging the events between environments
|
||||
* example: 190 pages document, 82000 events 8seconds transform 40(!) sec. bridging
|
||||
*
|
||||
*/
|
||||
private XInputStream m_xis;
|
||||
private XOutputStream m_xos; // private static HashMap templatecache;
|
||||
private static final String STATSPROP = "XSLTransformer.statsfile";
|
||||
private static PrintStream statsp;
|
||||
private String stylesheeturl;
|
||||
private String targeturl;
|
||||
private String targetbaseurl;
|
||||
private String sourceurl;
|
||||
private String sourcebaseurl;
|
||||
private String pubtype = new String();
|
||||
private String systype = new String(); // processing thread
|
||||
private Thread t; // listeners
|
||||
private ArrayList<XStreamListener> listeners = new ArrayList<XStreamListener>(); //
|
||||
private XMultiServiceFactory svcfactory; // cache for transformations by stylesheet
|
||||
private static Map<String,WeakReference<Transformation>> xsltReferences = new HashMap<String,WeakReference<Transformation>>();
|
||||
// struct for cached stylesheets
|
||||
private static class Transformation {
|
||||
|
||||
public Templates cachedXSLT;
|
||||
public long lastmod;
|
||||
}
|
||||
// Resolve URIs to an empty source
|
||||
public Source resolve(String href, String base) {
|
||||
return new StreamSource(new StringReader(""));
|
||||
}
|
||||
|
||||
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, java.io.IOException {
|
||||
return new InputSource(new StringReader(""));
|
||||
}
|
||||
// --- Initialization ---
|
||||
public XSLTransformer(XMultiServiceFactory msf) {
|
||||
svcfactory = msf;
|
||||
}
|
||||
|
||||
public void initialize(Object[] args) throws com.sun.star.uno.Exception {
|
||||
// some configurable debugging
|
||||
String statsfilepath = null;
|
||||
if ((statsfilepath = System.getProperty(STATSPROP)) != null) {
|
||||
try {
|
||||
File statsfile = new File(statsfilepath);
|
||||
statsp = new PrintStream(new FileOutputStream(statsfile.getPath(), false));
|
||||
} catch (java.lang.Exception e) {
|
||||
System.err.println("XSLTransformer: could not open statsfile'" + statsfilepath + "'");
|
||||
System.err.println(" " + e.getClass().getName() + ": " + e.getMessage());
|
||||
System.err.println(" output disabled");
|
||||
}
|
||||
}
|
||||
|
||||
Object[] values = (Object[]) args[0];
|
||||
|
||||
// reading the values
|
||||
NamedValue nv = null;
|
||||
debug("The transformation's parameters as 'name = value' pairs:\n");
|
||||
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
nv = (NamedValue) AnyConverter.toObject(new Type(NamedValue.class), values[i]);
|
||||
|
||||
if (nv.Name != null && !nv.Name.equals("")) {
|
||||
debug(nv.Name + " = " + nv.Value);
|
||||
}
|
||||
|
||||
if (nv.Name.equals("StylesheetURL")) {
|
||||
stylesheeturl = (String) AnyConverter.toObject(
|
||||
new Type(String.class), nv.Value);
|
||||
} else if (nv.Name.equals("SourceURL")) {
|
||||
sourceurl = (String) AnyConverter.toObject(
|
||||
new Type(String.class), nv.Value);
|
||||
} else if (nv.Name.equals("TargetURL")) {
|
||||
targeturl = (String) AnyConverter.toObject(
|
||||
new Type(String.class), nv.Value);
|
||||
} else if (nv.Name.equals("SourceBaseURL")) {
|
||||
sourcebaseurl = (String) AnyConverter.toObject(
|
||||
new Type(String.class), nv.Value);
|
||||
} else if (nv.Name.equals("TargetBaseURL")) {
|
||||
targetbaseurl = (String) AnyConverter.toObject(
|
||||
new Type(String.class), nv.Value);
|
||||
} else if (nv.Name.equals("SystemType")) {
|
||||
systype = (String) AnyConverter.toObject(
|
||||
new Type(String.class), nv.Value);
|
||||
} else if (nv.Name.equals("PublicType")) {
|
||||
pubtype = (String) AnyConverter.toObject(
|
||||
new Type(String.class), nv.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- XActiveDataSink xistream = aStream;
|
||||
public void setInputStream(XInputStream aStream) {
|
||||
m_xis = aStream;
|
||||
}
|
||||
|
||||
public com.sun.star.io.XInputStream getInputStream() {
|
||||
return m_xis;
|
||||
}
|
||||
|
||||
// --- XActiveDataSource
|
||||
public void setOutputStream(XOutputStream aStream) {
|
||||
m_xos = aStream;
|
||||
}
|
||||
|
||||
public com.sun.star.io.XOutputStream getOutputStream() {
|
||||
return m_xos;
|
||||
}
|
||||
|
||||
// --- XActiveDataControl
|
||||
public void addListener(XStreamListener aListener) {
|
||||
if (aListener != null && !listeners.contains(aListener)) {
|
||||
listeners.add(aListener);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeListener(XStreamListener aListener) {
|
||||
if (aListener != null) {
|
||||
listeners.remove(aListener);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void start() {
|
||||
// notify listeners
|
||||
t = new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
// Local variabes used outside try block in finally block
|
||||
InputStream is = null;
|
||||
Source source = null;
|
||||
BufferedOutputStream os = null;
|
||||
PrintStream origOut = System.out;
|
||||
PrintStream origErr = System.err;
|
||||
if (statsp != null) {
|
||||
System.setErr(statsp);
|
||||
System.setOut(statsp);
|
||||
}
|
||||
try {
|
||||
debug("\n\nStarting transformation...");
|
||||
|
||||
// Set up context class loader for SAXParserFactory and
|
||||
// TransformerFactory calls below:
|
||||
setContextClassLoader(this.getClass().getClassLoader());
|
||||
|
||||
for (Iterator<XStreamListener> e = listeners.iterator(); e.hasNext();) {
|
||||
XStreamListener l = e.next();
|
||||
l.started();
|
||||
}
|
||||
|
||||
XSeekable xseek = UnoRuntime.queryInterface(XSeekable.class, m_xis);
|
||||
if (xseek != null) {
|
||||
xseek.seek(0);
|
||||
}
|
||||
|
||||
is = new BufferedInputStream(
|
||||
new XInputStreamToInputStreamAdapter(m_xis));
|
||||
//Source xmlsource = new StreamSource(xmlinput);
|
||||
SAXParserFactory spf = SAXParserFactory.newInstance();
|
||||
spf.setValidating(false);
|
||||
spf.setNamespaceAware(true);
|
||||
XMLReader xmlReader = spf.newSAXParser().getXMLReader();
|
||||
xmlReader.setEntityResolver(XSLTransformer.this);
|
||||
source = new SAXSource(xmlReader, new InputSource(is));
|
||||
|
||||
// in order to help performance and to remedy a a possible memory
|
||||
// leak in xalan, where it seems, that Transformer instances cannot
|
||||
// be reclaimed though they are no longer referenced here, we use
|
||||
// a cache of weak references (ie. xsltReferences) created for specific
|
||||
// style sheet URLs see also #i48384#
|
||||
|
||||
Templates xsltTemplate = null;
|
||||
Transformer transformer = null;
|
||||
Transformation transformation = null;
|
||||
// File stylefile = new File(new URI(stylesheeturl));
|
||||
long lastmod = 0;
|
||||
try {
|
||||
URL uStyle = new URL(stylesheeturl);
|
||||
URLConnection c = uStyle.openConnection();
|
||||
lastmod = c.getLastModified();
|
||||
} catch (java.lang.Exception ex) {
|
||||
// lastmod will remain at 0;
|
||||
if (statsp != null) {
|
||||
statsp.println(ex.getClass().getName() + ": " + ex.getMessage());
|
||||
ex.printStackTrace(statsp);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (xsltReferences) {
|
||||
WeakReference<Transformation> ref = null;
|
||||
// try to get the xsltTemplate reference from the cache
|
||||
if ((ref = xsltReferences.get(stylesheeturl)) == null ||
|
||||
(transformation = ref.get()) == null ||
|
||||
ref.get().lastmod < lastmod) {
|
||||
// we cannot find a valid reference for this stylesheet
|
||||
// or the stylsheet was updated
|
||||
if (ref != null) {
|
||||
xsltReferences.remove(stylesheeturl);
|
||||
}
|
||||
// create new xsltTemplate for this stylesheet
|
||||
TransformerFactory tfactory = TransformerFactory.newInstance();
|
||||
debug("TransformerFactory is '" + tfactory.getClass().getName() + "'");
|
||||
// some external saxons (Debian, Ubuntu, ...) have this disabled
|
||||
// per default
|
||||
tfactory.setAttribute(FeatureKeys.ALLOW_EXTERNAL_FUNCTIONS, new Boolean(true));
|
||||
xsltTemplate = tfactory.newTemplates(new StreamSource(stylesheeturl));
|
||||
|
||||
// store the transformation into the cache
|
||||
transformation = new Transformation();
|
||||
transformation.lastmod = lastmod;
|
||||
transformation.cachedXSLT = xsltTemplate;
|
||||
ref = new WeakReference<Transformation>(transformation);
|
||||
xsltReferences.put(stylesheeturl, ref);
|
||||
}
|
||||
}
|
||||
xsltTemplate = transformation.cachedXSLT;
|
||||
transformer = xsltTemplate.newTransformer();
|
||||
transformer.setOutputProperty("encoding", "UTF-8");
|
||||
// transformer.setURIResolver(XSLTransformer.this);
|
||||
|
||||
// invalid to set 'null' as parameter as 'null' is not a valid Java object
|
||||
if (sourceurl != null) {
|
||||
transformer.setParameter("sourceURL", sourceurl);
|
||||
}
|
||||
if (sourcebaseurl != null) {
|
||||
transformer.setParameter("sourceBaseURL", sourcebaseurl);
|
||||
}
|
||||
if (targeturl != null) {
|
||||
transformer.setParameter("targetURL", targeturl);
|
||||
}
|
||||
if (targetbaseurl != null) {
|
||||
transformer.setParameter("targetBaseURL", targetbaseurl);
|
||||
}
|
||||
if (pubtype != null) {
|
||||
transformer.setParameter("publicType", pubtype);
|
||||
}
|
||||
if (systype != null) {
|
||||
transformer.setParameter("systemType", systype);
|
||||
}
|
||||
if (svcfactory != null) {
|
||||
transformer.setParameter("XMultiServiceFactory", svcfactory);
|
||||
}
|
||||
os = new BufferedOutputStream(
|
||||
new XOutputStreamToOutputStreamAdapter(m_xos));
|
||||
StreamResult sr = new StreamResult(os);
|
||||
long tstart = System.currentTimeMillis();
|
||||
transformer.transform(source, sr);
|
||||
debug("finished transformation in " + (System.currentTimeMillis() - tstart) + "ms");
|
||||
|
||||
} catch (java.lang.Throwable ex) {
|
||||
// notify any listeners about close
|
||||
for (Iterator<XStreamListener> e = listeners.iterator(); e.hasNext();) {
|
||||
|
||||
XStreamListener l = e.next();
|
||||
l.error(new com.sun.star.uno.Exception(ex.getClass().getName() + ": " + ex.getMessage()));
|
||||
}
|
||||
if (statsp != null) {
|
||||
statsp.println(ex.getClass().getName() + ": " + ex.getMessage());
|
||||
ex.printStackTrace(statsp);
|
||||
}
|
||||
} finally {
|
||||
// dereference input buffer
|
||||
source = null;
|
||||
try {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
} catch (java.lang.Throwable ex) {
|
||||
if (statsp != null) {
|
||||
statsp.println(ex.getClass().getName() + ": " + ex.getMessage());
|
||||
ex.printStackTrace(statsp);
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
} catch (java.lang.Throwable ex) {
|
||||
if (statsp != null) {
|
||||
statsp.println(ex.getClass().getName() + ": " + ex.getMessage());
|
||||
ex.printStackTrace(statsp);
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (m_xis != null) {
|
||||
m_xis.closeInput();
|
||||
}
|
||||
} catch (java.lang.Throwable ex) {
|
||||
if (statsp != null) {
|
||||
statsp.println(ex.getClass().getName() + ": " + ex.getMessage());
|
||||
ex.printStackTrace(statsp);
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (m_xos != null) {
|
||||
m_xos.closeOutput();
|
||||
}
|
||||
} catch (java.lang.Throwable ex) {
|
||||
if (statsp != null) {
|
||||
statsp.println(ex.getClass().getName() + ": " + ex.getMessage());
|
||||
ex.printStackTrace(statsp);
|
||||
}
|
||||
}
|
||||
|
||||
// resetting standard input/error streams from logfile to default
|
||||
if (statsp != null) {
|
||||
System.setErr(origErr);
|
||||
System.setOut(origOut);
|
||||
}
|
||||
// try to release references asap...
|
||||
m_xos = null;
|
||||
m_xis = null;
|
||||
is = null;
|
||||
os = null;
|
||||
// notify any listeners about close
|
||||
if (listeners != null) {
|
||||
for (Iterator<XStreamListener> e = listeners.iterator(); e.hasNext();) {
|
||||
XStreamListener l = e.next();
|
||||
l.closed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
} /* a statsfile have to be created as precondition to use this function */
|
||||
|
||||
|
||||
private static final void debug(String s) {
|
||||
if (statsp != null) {
|
||||
statsp.println(s);
|
||||
}
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
try {
|
||||
debug("terminate called");
|
||||
if (t.isAlive()) {
|
||||
t.interrupt();
|
||||
for (Iterator<XStreamListener> e = listeners.iterator(); e.hasNext();) {
|
||||
XStreamListener l = e.next();
|
||||
l.terminated();
|
||||
}
|
||||
}
|
||||
} catch (java.lang.Exception ex) {
|
||||
if (statsp != null) {
|
||||
statsp.println(ex.getClass().getName() + ": " + ex.getMessage());
|
||||
ex.printStackTrace(statsp);
|
||||
}
|
||||
}
|
||||
} // --- component management interfaces... ---
|
||||
private final static String _serviceName = "com.sun.star.xml.xslt.XSLT2Transformer";
|
||||
|
||||
// Implement methods from interface XTypeProvider
|
||||
public byte[] getImplementationId() {
|
||||
byte[] byteReturn = {};
|
||||
byteReturn = new String("" + this.hashCode()).getBytes();
|
||||
return (byteReturn);
|
||||
}
|
||||
|
||||
public com.sun.star.uno.Type[] getTypes() {
|
||||
Type[] typeReturn = {};
|
||||
try {
|
||||
typeReturn = new Type[]{
|
||||
new Type(XTypeProvider.class),
|
||||
new Type(XServiceName.class),
|
||||
new Type(XServiceInfo.class),
|
||||
new Type(XActiveDataSource.class),
|
||||
new Type(XActiveDataSink.class),
|
||||
new Type(XActiveDataControl.class),
|
||||
new Type(XInitialization.class)
|
||||
};
|
||||
} catch (java.lang.Exception exception) {
|
||||
}
|
||||
|
||||
return (typeReturn);
|
||||
}
|
||||
|
||||
// --- Implement method from interface XServiceName ---
|
||||
public String getServiceName() {
|
||||
return (_serviceName);
|
||||
}
|
||||
|
||||
// --- Implement methods from interface XServiceInfo ---
|
||||
public boolean supportsService(String stringServiceName) {
|
||||
return (stringServiceName.equals(_serviceName));
|
||||
}
|
||||
|
||||
public String getImplementationName() {
|
||||
return (XSLTransformer.class.getName());
|
||||
}
|
||||
|
||||
public String[] getSupportedServiceNames() {
|
||||
String[] stringSupportedServiceNames = {_serviceName};
|
||||
return stringSupportedServiceNames;
|
||||
}
|
||||
|
||||
// --- component registration methods ---
|
||||
public static XSingleServiceFactory __getServiceFactory(
|
||||
String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey) {
|
||||
XSingleServiceFactory xSingleServiceFactory = null;
|
||||
if (implName.equals(XSLTransformer.class.getName())) {
|
||||
xSingleServiceFactory = FactoryHelper.getServiceFactory(XSLTransformer.class,
|
||||
_serviceName, multiFactory, regKey);
|
||||
}
|
||||
return xSingleServiceFactory;
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<components xmlns="http://openoffice.org/2010/uno-components">
|
||||
<component loader="com.sun.star.loader.Java2" uri="./XSLTFilter.jar">
|
||||
<implementation name="com.sun.star.comp.xsltfilter.XSLTransformer">
|
||||
<service name="com.sun.star.xml.xslt.XSLT2Transformer"/>
|
||||
</implementation>
|
||||
</component>
|
||||
</components>
|
@ -1 +0,0 @@
|
||||
The xslt2-transformer implements a transformer for XSLT import/export filters with support for XSLT 2.0.
|
@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<description
|
||||
|
||||
xmlns="http://openoffice.org/extensions/description/2006"
|
||||
xmlns:dep="http://libreoffice.org/extensions/description/2011"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
<identifier value="org.libreoffice.JavaXSLT2Transformer"/>
|
||||
|
||||
<dependencies>
|
||||
<dep:LibreOffice-minimal-version value="3.7"/>
|
||||
</dependencies>
|
||||
|
||||
<version value="1.0.0"/>
|
||||
|
||||
<publisher>
|
||||
<name xlink:href="http://www.documentfoundation.org" lang="en-US">The Document Foundation</name>
|
||||
</publisher>
|
||||
|
||||
<display-name>
|
||||
<name lang="en-US">XSLT 2.0 transformer</name>
|
||||
</display-name>
|
||||
|
||||
<extension-description>
|
||||
<src xlink:href="description-en-US.txt" lang="en-US" />
|
||||
</extension-description>
|
||||
|
||||
</description>
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE manifest:manifest PUBLIC "-//OpenOffice.org//DTD Manifest 1.0//EN" "Manifest.dtd">
|
||||
<manifest:manifest xmlns:manifest="http://openoffice.org/2001/manifest">
|
||||
<manifest:file-entry manifest:media-type="application/vnd.sun.star.uno-components"
|
||||
manifest:full-path="components.rdb"/>
|
||||
</manifest:manifest>
|
Loading…
x
Reference in New Issue
Block a user