Hi,
I now have a first working implementation of the XSLT extension
functions which currently prevent the Office 2003 ML filters from using
the libxslt based transformation service.
The patch affects 3 modules:
solenv: new PACKAGE2LIB variable defined in libs.mk
components/package: made Inflater/Deflater classes (needed by the
extension functions) available as DLL imports.
filters/filter: added extenstion function impl., changed XSLT
stylesheets to work with that and changed configuration of Word 2003 ML
filters to no longer use the JAXT transformation service.
I'm afraid the OleHandler class still needs a lot of love, esp.
w/regards to exception handling, but as of now it even works somewhat
better than the java based impl. which is currently completely broken
(in both OOo and LibO, at least under Ubuntu 10.10).
Also, I feel that the extension function integration could be improved
upon.
If the patch and the general approach taken here are alright, I could
try to fix the Excel ML import problem here:
https://bugs.freedesktop.org/show_bug.cgi?id=35543
by providing yet another extension function that allows for a
non-recursive transformation of rows and columns.
As ever, I hope I got it right with git :-)
Best regards,
Peter
From 91e57060f94d884d5c146af03b45c8a1c8f7320a Mon Sep 17 00:00:00 2001
From: Peter Jentsch <pjotr@guineapics.de>
Date: Sat, 26 Mar 2011 13:57:21 +0100
Subject: [PATCH] added package2 linker flag constant to libs.mk
---
solenv/inc/libs.mk | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/solenv/inc/libs.mk b/solenv/inc/libs.mk
index 14678b7..6c0a7a4 100644
--- a/solenv/inc/libs.mk
+++ b/solenv/inc/libs.mk
@@ -252,6 +252,7 @@ SCHLIB=-lysch
SMLIB=-lysm
OFALIB=-lofa$(DLLPOSTFIX)
PRXLIB=-llprx2$(DLLPOSTFIX)
+PACKAGE2LIB=-lpackage2
PAPILIB=-lpap$(DLLPOSTFIX)
SCLIB=-lsclib
SDLIB=-lsdlib
--
1.7.1
From db3ad58407e7ae805445e542ba5c9d67621bb58d Mon Sep 17 00:00:00 2001
From: Peter Jentsch <pjotr@guineapics.de>
Date: Sat, 26 Mar 2011 14:14:51 +0100
Subject: [PATCH] make Inflater and Deflater classes available for other packages to use
Currently, those are used within an extension function used by the
Word 2003 ML XSLT filters
---
package/inc/Deflater.hxx | 3 ++-
package/inc/Inflater.hxx | 3 ++-
package/inc/packagedllapi.hxx | 15 +++++++++++++++
package/prj/d.lst | 3 +++
package/source/zipapi/makefile.mk | 2 ++
package/util/makefile.mk | 1 -
package/util/package.pmk | 2 ++
7 files changed, 26 insertions(+), 3 deletions(-)
create mode 100644 package/inc/packagedllapi.hxx
create mode 100644 package/util/package.pmk
diff --git a/package/inc/Deflater.hxx b/package/inc/Deflater.hxx
index 3f2c1fc..d866f7b 100644
--- a/package/inc/Deflater.hxx
+++ b/package/inc/Deflater.hxx
@@ -29,13 +29,14 @@
#define _DEFLATER_HXX_
#include <com/sun/star/uno/Sequence.hxx>
+#include "packagedllapi.hxx"
extern "C"
{
typedef struct z_stream_s z_stream;
}
-class Deflater
+class OOO_DLLPUBLIC_PACKAGE Deflater
{
protected:
com::sun::star::uno::Sequence< sal_Int8 > sInBuffer;
diff --git a/package/inc/Inflater.hxx b/package/inc/Inflater.hxx
index ee7efec..84dd3a4 100644
--- a/package/inc/Inflater.hxx
+++ b/package/inc/Inflater.hxx
@@ -29,12 +29,13 @@
#define _INFLATER_HXX_
#include <com/sun/star/uno/Sequence.hxx>
+#include "packagedllapi.hxx"
extern "C"
{
typedef struct z_stream_s z_stream;
}
-class Inflater
+class OOO_DLLPUBLIC_PACKAGE Inflater
{
protected:
sal_Bool bFinish, bFinished, bSetParams, bNeedDict;
diff --git a/package/inc/packagedllapi.hxx b/package/inc/packagedllapi.hxx
new file mode 100644
index 0000000..f4351d2
--- /dev/null
+++ b/package/inc/packagedllapi.hxx
@@ -0,0 +1,15 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+#ifndef INCLUDED_PACKAGEDLLAPI_H
+#define INCLUDED_PACKAGEDLLAPI_H
+
+#include "sal/types.h"
+
+#if defined(OOO_DLLIMPLEMENTATION_PACKAGE)
+#define OOO_DLLPUBLIC_PACKAGE SAL_DLLPUBLIC_EXPORT
+#else
+#define OOO_DLLPUBLIC_PACKAGE SAL_DLLPUBLIC_IMPORT
+#endif
+
+#endif /* INCLUDED_PACKAGEDLLAPI_H */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/package/prj/d.lst b/package/prj/d.lst
index 919a171..85f8c19 100644
--- a/package/prj/d.lst
+++ b/package/prj/d.lst
@@ -5,3 +5,6 @@
..\dtd\*.dtd %_DEST%\bin%_EXT%\*.*
..\%__SRC%\misc\package2.component %_DEST%\xml%_EXT%\package2.component
..\%__SRC%\misc\xstor.component %_DEST%\xml%_EXT%\xstor.component
+..\inc\Inflater.hxx %_DEST%\inc%_EXT%\package\Inflater.hxx
+..\inc\Deflater.hxx %_DEST%\inc%_EXT%\package\Deflater.hxx
+..\inc\packagedllapi.hxx %_DEST%\inc%_EXT%\package\packagedllapi.hxx
diff --git a/package/source/zipapi/makefile.mk b/package/source/zipapi/makefile.mk
index 1b941fa..ec8d636 100644
--- a/package/source/zipapi/makefile.mk
+++ b/package/source/zipapi/makefile.mk
@@ -34,12 +34,14 @@ ENABLE_EXCEPTIONS=TRUE
# --- Settings -----------------------------------------------------
.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/package.pmk
# --- Files --------------------------------------------------------
.IF "$(L10N_framework)"==""
.IF "$(SYSTEM_ZLIB)" == "YES"
CFLAGS+=-DSYSTEM_ZLIB
.ENDIF
+
SLOFILES= \
$(SLO)$/CRC32.obj \
$(SLO)$/ByteChucker.obj \
diff --git a/package/util/makefile.mk b/package/util/makefile.mk
index 344b2cf..827060a 100644
--- a/package/util/makefile.mk
+++ b/package/util/makefile.mk
@@ -55,7 +55,6 @@ LIB1FILES= \
SHL1TARGET=$(TARGET)$(MAJOR_VERSION)
SHL1IMPLIB=i$(TARGET)
-SHL1VERSIONMAP=$(SOLARENV)$/src$/component.map
SHL1STDLIBS=\
$(CPPULIB) \
diff --git a/package/util/package.pmk b/package/util/package.pmk
new file mode 100644
index 0000000..68c8df4
--- /dev/null
+++ b/package/util/package.pmk
@@ -0,0 +1,2 @@
+VISIBILITY_HIDDEN = TRUE
+CDEFS += -DOOO_DLLIMPLEMENTATION_PACKAGE
\ No newline at end of file
--
1.7.1
From 1e203e47e57071089f4dc5365c1fe099be9786c4 Mon Sep 17 00:00:00 2001
From: Peter Jentsch <pjotr@guineapics.de>
Date: Sat, 26 Mar 2011 14:24:41 +0100
Subject: [PATCH 3/3] replaced saxon/j extension functions with libxslt/cxx impl in XSLTFilter
---
.../config/fragments/filters/MS_Excel_2003_XML.xcu | 2 +-
.../config/fragments/filters/MS_Word_2003_XML.xcu | 2 +-
filter/source/xslt/common/measure_conversion.xsl | 101 ++++++++
filter/source/xslt/export/common/ooo2ms_docpr.xsl | 4 +-
.../source/xslt/export/wordml/ooo2wordml_draw.xsl | 126 +----------
filter/source/xslt/import/wordml/wordml2ooo.xsl | 83 -------
.../source/xslt/import/wordml/wordml2ooo_draw.xsl | 41 +---
filter/source/xsltfilter/LibXSLTTransformer.cxx | 125 ++++++++++-
filter/source/xsltfilter/LibXSLTTransformer.hxx | 10 +
filter/source/xsltfilter/OleHandler.cxx | 249 ++++++++++++++++++++
filter/source/xsltfilter/OleHandler.hxx | 111 +++++++++
filter/source/xsltfilter/makefile.mk | 5 +-
12 files changed, 610 insertions(+), 249 deletions(-)
create mode 100644 filter/source/xsltfilter/OleHandler.cxx
create mode 100644 filter/source/xsltfilter/OleHandler.hxx
diff --git a/filter/source/config/fragments/filters/MS_Excel_2003_XML.xcu
b/filter/source/config/fragments/filters/MS_Excel_2003_XML.xcu
index a0bb672..d0d2b13 100644
--- a/filter/source/config/fragments/filters/MS_Excel_2003_XML.xcu
+++ b/filter/source/config/fragments/filters/MS_Excel_2003_XML.xcu
@@ -2,7 +2,7 @@
<prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop>
<prop oor:name="UIComponent"/>
<prop
oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop>
- <prop oor:name="UserData"><value
oor:separator=",">com.sun.star.documentconversion.XSLTFilter,com.sun.star.comp.JAXTHelper,com.sun.star.comp.Calc.XMLOasisImporter,com.sun.star.comp.Calc.XMLOasisExporter,../share/xslt/import/spreadsheetml/spreadsheetml2ooo.xsl,../share/xslt/export/spreadsheetml/ooo2spreadsheetml.xsl</value></prop>
+ <prop oor:name="UserData"><value
oor:separator=",">com.sun.star.documentconversion.XSLTFilter,,com.sun.star.comp.Calc.XMLOasisImporter,com.sun.star.comp.Calc.XMLOasisExporter,../share/xslt/import/spreadsheetml/spreadsheetml2ooo.xsl,../share/xslt/export/spreadsheetml/ooo2spreadsheetml.xsl</value></prop>
<prop oor:name="FileFormatVersion"><value>0</value></prop>
<prop oor:name="Type"><value>calc_MS_Excel_2003_XML</value></prop>
<prop oor:name="TemplateName"/>
diff --git a/filter/source/config/fragments/filters/MS_Word_2003_XML.xcu
b/filter/source/config/fragments/filters/MS_Word_2003_XML.xcu
index 4568910..c953598 100644
--- a/filter/source/config/fragments/filters/MS_Word_2003_XML.xcu
+++ b/filter/source/config/fragments/filters/MS_Word_2003_XML.xcu
@@ -2,7 +2,7 @@
<prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER</value></prop>
<prop oor:name="UIComponent"/>
<prop
oor:name="FilterService"><value>com.sun.star.comp.Writer.XmlFilterAdaptor</value></prop>
- <prop oor:name="UserData"><value
oor:separator=",">com.sun.star.documentconversion.XSLTFilter,com.sun.star.comp.JAXTHelper,com.sun.star.comp.Writer.XMLOasisImporter,com.sun.star.comp.Writer.XMLOasisExporter,../share/xslt/import/wordml/wordml2ooo.xsl,../share/xslt/export/wordml/ooo2wordml.xsl</value></prop>
+ <prop oor:name="UserData"><value
oor:separator=",">com.sun.star.documentconversion.XSLTFilter,,com.sun.star.comp.Writer.XMLOasisImporter,com.sun.star.comp.Writer.XMLOasisExporter,../share/xslt/import/wordml/wordml2ooo.xsl,../share/xslt/export/wordml/ooo2wordml.xsl</value></prop>
<prop oor:name="FileFormatVersion"><value>0</value></prop>
<prop oor:name="Type"><value>writer_MS_Word_2003_XML</value></prop>
<prop oor:name="TemplateName"/>
diff --git a/filter/source/xslt/common/measure_conversion.xsl
b/filter/source/xslt/common/measure_conversion.xsl
index 4533013..6ad52e0 100644
--- a/filter/source/xslt/common/measure_conversion.xsl
+++ b/filter/source/xslt/common/measure_conversion.xsl
@@ -384,4 +384,105 @@
</xsl:otherwise>
</xsl:choose>
</xsl:template>
+ <xsl:template name="ConvertMeasure">
+ <xsl:param name="TargetMeasure" select="'cm'"/>
+ <xsl:param name="TargetTruncate" select=" 'all' "/>
+ <xsl:param name="value"/>
+ <!-- When TargetTruncate ='all' it returns the number whichsoever the return value
is negative or positive
+ When TargetTruncate ='nonNegative' it only returns nonNegative number, all
negative number to be returned as 0
+ When TargetTruncate ='positive" it only returns positive number, all
nonPositive number to be returned as 1 -->
+ <xsl:variable name="return_value">
+ <xsl:choose>
+ <!-- remove the measure mark, if the value is null, the result
should be 0. Must be the first case -->
+ <xsl:when
test="string-length(translate(string($value),'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
','')) = 0">0</xsl:when>
+ <xsl:when test="string-length(translate(string($value),'-
.0123456789','')) = 0">
+ <xsl:value-of select="$value"/>
+ </xsl:when>
+ <xsl:when test="$TargetMeasure = 'cm'">
+ <xsl:call-template name="convert2cm">
+ <xsl:with-param name="value" select="$value"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="$TargetMeasure = 'pt'">
+ <xsl:call-template name="convert2pt">
+ <xsl:with-param name="value" select="$value"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="$TargetMeasure = 'twip'">
+ <xsl:call-template name="convert2twip">
+ <xsl:with-param name="value" select="$value"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="$TargetMeasure = 'in'">
+ <xsl:call-template name="convert2in">
+ <xsl:with-param name="value" select="$value"/>
+ </xsl:call-template>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$TargetTruncate = 'all' ">
+ <xsl:choose>
+ <xsl:when test="string(number($TargetMeasure)) = 'NaN' ">
+ <xsl:value-of select=" '0' "/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$return_value"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="$TargetTruncate = 'nonNegative' ">
+ <xsl:choose>
+ <xsl:when test="string(number($TargetMeasure)) = 'NaN' ">
+ <xsl:value-of select=" '0' "/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test=" $return_value < 0 ">
+ <xsl:value-of select=" '0' "/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of
select="$return_value"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="$TargetTruncate = 'positive' ">
+ <xsl:choose>
+ <xsl:when test="string(number($TargetMeasure)) = 'NaN' ">
+ <xsl:value-of select=" '1' "/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test=" $return_value <= 0 ">
+ <xsl:value-of select=" '1' "/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of
select="$return_value"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:template>
+ <xsl:template name="Add-With-Measure">
+ <xsl:param name="value1"/>
+ <xsl:param name="value2"/>
+ <xsl:param name="TargetMeasure" select="'in'"/>
+ <xsl:variable name="number-value1">
+ <xsl:call-template name="ConvertMeasure">
+ <xsl:with-param name="value" select="$value1"/>
+ <xsl:with-param name="TargetMeasure" select="$TargetMeasure"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="number-value2">
+ <xsl:call-template name="ConvertMeasure">
+ <xsl:with-param name="value" select="$value2"/>
+ <xsl:with-param name="TargetMeasure" select="$TargetMeasure"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select="$number-value1 + $number-value2"/>
+ </xsl:template>
</xsl:stylesheet>
diff --git a/filter/source/xslt/export/common/ooo2ms_docpr.xsl
b/filter/source/xslt/export/common/ooo2ms_docpr.xsl
index cdf5ed9..69f6192 100644
--- a/filter/source/xslt/export/common/ooo2ms_docpr.xsl
+++ b/filter/source/xslt/export/common/ooo2ms_docpr.xsl
@@ -127,7 +127,9 @@
</o:Language>
<xsl:for-each select="meta:user-defined">
<!-- transfer strings to XML QName, necessary to convert several characters -->
- <xsl:element name="{concat( 'o:', translate(@meta:name,'.,|
~`!@#$%^&<>*()+=[]{};:"/\?','_'))}">
+ <!-- {} -->
+ <xsl:variable name="foo">.,|
~`!@#$%^*()&<>+=[];:"/\?{}'</xsl:variable>
+ <xsl:element name="{concat( 'o:', translate(@meta:name,string($foo),'_'))}">
<xsl:attribute name="dt:dt">string</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
diff --git a/filter/source/xslt/export/wordml/ooo2wordml_draw.xsl
b/filter/source/xslt/export/wordml/ooo2wordml_draw.xsl
index 2badb7c..b978e99 100644
--- a/filter/source/xslt/export/wordml/ooo2wordml_draw.xsl
+++ b/filter/source/xslt/export/wordml/ooo2wordml_draw.xsl
@@ -25,11 +25,9 @@
for a copy of the LGPLv3 License.
-->
-<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"
xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:aml="http://schemas.microsoft.com/aml/2001/core"
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
xmlns:math="http://www.w3.org/1998/Math/MathML"
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer"
xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events"
xmlns:xalan="http://xml.apache.org/xalan" xmlns:oleextracter="MyOleExtracter"
xmlns:ole="java:XSLTFilterOLEExtracter" xmlns:java="http://saxon.sf.net/java-type"
exclude-result-prefixes="office table style text draw svg dc config xlink meta oooc dom ooo chart
math dr3d form script ooow draw xalan ole oleextracter java"
extension-element-prefixes="oleextracter">
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"
xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:aml="http://schemas.microsoft.com/aml/2001/core"
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
xmlns:math="http://www.w3.org/1998/Math/MathML"
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer"
xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events"
xmlns:ole="http://libreoffice.org/2011/xslt/ole" exclude-result-prefixes="office table style text
draw svg dc config xlink meta oooc dom ooo chart math dr3d form script ooow ole">
<xsl:include href="ooo2wordml_custom_draw.xsl"/>
- <xsl:param name="oleExtractor"
as="java:com.sun.star.comp.xsltfilter.XSLTFilterOLEExtracter" select="ole:new()"/>
- <xsl:param name="XMultiServiceFactory" as="java:com.sun.star.lang.XMultiServiceFactory"
select="ole:init($oleExtractor,
'uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager')"/>
-
+
<xsl:key name="stroke-dash-style" match="draw:stroke-dash" use="@draw:name"/>
<xsl:key name="fill-image" match="draw:fill-image" use="@draw:name"/>
<xsl:key name="draw-gradient" match="draw:gradient " use="@draw:name"/>
@@ -1738,135 +1736,24 @@
<xsl:when test="$arrow-size > 0">Narrow</xsl:when>
</xsl:choose>
</xsl:template>
- <xsl:template name="ConvertMeasure">
- <xsl:param name="TargetMeasure" select="'cm'"/>
- <xsl:param name="TargetTruncate" select=" 'all' "/>
- <xsl:param name="value"/>
- <!-- When TargetTruncate ='all' it returns the number whichsoever the return value
is negative or positive
- When TargetTruncate ='nonNegative' it only returns nonNegative number,
all negative number to be returned as 0
- When TargetTruncate ='positive" it only returns positive number, all
nonPositive number to be returned as 1 -->
- <xsl:variable name="return_value">
- <xsl:choose>
- <!-- remove the measure mark, if the value is null, the result
should be 0. Must be the first case -->
- <xsl:when
test="string-length(translate(string($value),'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
','')) = 0">0</xsl:when>
- <xsl:when test="string-length(translate(string($value),'-
.0123456789','')) = 0">
- <xsl:value-of select="$value"/>
- </xsl:when>
- <xsl:when test="$TargetMeasure = 'cm'">
- <xsl:call-template name="convert2cm">
- <xsl:with-param name="value" select="$value"/>
- </xsl:call-template>
- </xsl:when>
- <xsl:when test="$TargetMeasure = 'pt'">
- <xsl:call-template name="convert2pt">
- <xsl:with-param name="value" select="$value"/>
- </xsl:call-template>
- </xsl:when>
- <xsl:when test="$TargetMeasure = 'twip'">
- <xsl:call-template name="convert2twip">
- <xsl:with-param name="value" select="$value"/>
- </xsl:call-template>
- </xsl:when>
- <xsl:when test="$TargetMeasure = 'in'">
- <xsl:call-template name="convert2in">
- <xsl:with-param name="value" select="$value"/>
- </xsl:call-template>
- </xsl:when>
- </xsl:choose>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$TargetTruncate = 'all' ">
- <xsl:choose>
- <xsl:when test="string(number($TargetMeasure)) = 'NaN' ">
- <xsl:value-of select=" '0' "/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$return_value"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:when test="$TargetTruncate = 'nonNegative' ">
- <xsl:choose>
- <xsl:when test="string(number($TargetMeasure)) = 'NaN' ">
- <xsl:value-of select=" '0' "/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:choose>
- <xsl:when test=" $return_value < 0 ">
- <xsl:value-of select=" '0' "/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of
select="$return_value"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:when test="$TargetTruncate = 'positive' ">
- <xsl:choose>
- <xsl:when test="string(number($TargetMeasure)) = 'NaN' ">
- <xsl:value-of select=" '1' "/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:choose>
- <xsl:when test=" $return_value <= 0 ">
- <xsl:value-of select=" '1' "/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of
select="$return_value"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- </xsl:choose>
- </xsl:template>
- <xsl:template name="Add-With-Measure">
- <xsl:param name="value1"/>
- <xsl:param name="value2"/>
- <xsl:param name="TargetMeasure" select="'in'"/>
- <xsl:variable name="number-value1">
- <xsl:call-template name="ConvertMeasure">
- <xsl:with-param name="value" select="$value1"/>
- <xsl:with-param name="TargetMeasure" select="$TargetMeasure"/>
- </xsl:call-template>
- </xsl:variable>
- <xsl:variable name="number-value2">
- <xsl:call-template name="ConvertMeasure">
- <xsl:with-param name="value" select="$value2"/>
- <xsl:with-param name="TargetMeasure" select="$TargetMeasure"/>
- </xsl:call-template>
- </xsl:variable>
- <xsl:value-of select="$number-value1 + $number-value2"/>
- </xsl:template>
+
<xsl:template name="export-oledata">
<xsl:if test="//draw:object-ole[1]">
- <xsl:choose>
- <xsl:when test="element-available('oleextracter:init')">
- <oleextracter:init
UNOURL="uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="ole:init($XMultiServiceFactory,
'uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager')"/>
- </xsl:otherwise>
- </xsl:choose>
<xsl:apply-templates select="//draw:object-ole" mode="oledata.mso"/>
<w:docOleData>
<w:binData w:name="oledata.mso">
<xsl:if test="function-available('ole:getByName')">
- <xsl:value-of
select="translate(ole:getByName($oleExtractor, 'oledata.mso'),'  ','')"/>
+ <xsl:value-of
select="translate(ole:getByName('oledata.mso'),'  ','')"/>
</xsl:if>
</w:binData>
</w:docOleData>
- <xsl:if test="function-available('ole:exit')">
- <xsl:value-of select="ole:exit($oleExtractor)"/>
- </xsl:if>
</xsl:if>
</xsl:template>
<xsl:template match="draw:object-ole" mode="oledata.mso">
<xsl:variable name="stream-name">
<xsl:apply-templates select="." mode="get-number"/>
</xsl:variable>
- <xsl:variable name="tmp" select="ole:insertByName($oleExtractor, $stream-name,
translate(office:binary-data/text(),'  ','' ) )"/>
+ <xsl:variable name="tmp" select="ole:insertByName($stream-name,
translate(office:binary-data/text(),'  ','' ) )"/>
</xsl:template>
<xsl:template match="draw:object-ole" mode="output">
<xsl:param name="ShapeID"/>
@@ -1879,7 +1766,4 @@
<xsl:number from="/office:document" level="any" count="draw:object-ole" format="1"/>
</xsl:template>
<xsl:template match="draw:object-ole"/>
- <xalan:component prefix="oleextracter" elements="init exit" functions="getByName
insertByName">
- <xalan:script lang="javaclass"
src="xalan://com.sun.star.comp.xsltfilter.XSLTFilterOLEExtracter"/>
- </xalan:component>
</xsl:stylesheet>
diff --git a/filter/source/xslt/import/wordml/wordml2ooo.xsl
b/filter/source/xslt/import/wordml/wordml2ooo.xsl
index 1f36f19..849e4a7 100644
--- a/filter/source/xslt/import/wordml/wordml2ooo.xsl
+++ b/filter/source/xslt/import/wordml/wordml2ooo.xsl
@@ -262,87 +262,4 @@
<style:graphic-properties text:anchor-type="paragraph" svg:x="0in" svg:y="0in"
style:wrap="parallel" style:number-wrapped-paragraphs="no-limit" style:wrap-contour="false"
style:vertical-pos="top" style:vertical-rel="paragraph-content" style:horizontal-pos="center"
style:horizontal-rel="paragraph-content"/>
</style:style>
</xsl:template>
- <xsl:template name="ConvertMeasure">
- <xsl:param name="TargetMeasure" select="'cm'"/>
- <xsl:param name="TargetTruncate" select=" 'all' "/>
- <xsl:param name="value"/>
- <!-- When TargetTruncate ='all' it returns the number whichsoever the return value is
negative or positive
- When TargetTruncate ='nonNegative' it only returns nonNegative number, all negative
number to be returned as 0
- When TargetTruncate ='positive" it only returns positive number, all nonPositive
number to be returned as 1 -->
- <xsl:variable name="return_value">
- <xsl:choose>
- <!-- remove the measure mark, if the value is null, the result should be 0. Must
be the first case -->
- <xsl:when
test="string-length(translate($value,'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ','')) =
0">0</xsl:when>
- <xsl:when test="string-length(translate($value,'-.0123456789 ','')) = 0">
- <xsl:value-of select="$value"/>
- </xsl:when>
- <xsl:when test="$TargetMeasure = 'cm'">
- <xsl:call-template name="convert2cm">
- <xsl:with-param name="value" select="$value"/>
- </xsl:call-template>
- </xsl:when>
- <xsl:when test="$TargetMeasure = 'pt'">
- <xsl:call-template name="convert2pt">
- <xsl:with-param name="value" select="$value"/>
- </xsl:call-template>
- </xsl:when>
- <xsl:when test="$TargetMeasure = 'twip'">
- <xsl:call-template name="convert2twip">
- <xsl:with-param name="value" select="$value"/>
- </xsl:call-template>
- </xsl:when>
- <xsl:when test="$TargetMeasure = 'in'">
- <xsl:call-template name="convert2in">
- <xsl:with-param name="value" select="$value"/>
- </xsl:call-template>
- </xsl:when>
- </xsl:choose>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$TargetTruncate = 'all' ">
- <xsl:choose>
- <xsl:when test="number($TargetMeasure) = 'NaN' ">
- <xsl:value-of select=" '0' "/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$return_value"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:when test="$TargetTruncate = 'nonNegative' ">
- <xsl:choose>
- <xsl:when test="number($TargetMeasure) = 'NaN' ">
- <xsl:value-of select=" '0' "/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:choose>
- <xsl:when test=" $return_value < 0 ">
- <xsl:value-of select=" '0' "/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$return_value"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:when test="$TargetTruncate = 'positive' ">
- <xsl:choose>
- <xsl:when test="number($TargetMeasure) = 'NaN' ">
- <xsl:value-of select=" '1' "/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:choose>
- <xsl:when test=" $return_value <= 0 ">
- <xsl:value-of select=" '1' "/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$return_value"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- </xsl:choose>
- </xsl:template>
</xsl:stylesheet>
diff --git a/filter/source/xslt/import/wordml/wordml2ooo_draw.xsl
b/filter/source/xslt/import/wordml/wordml2ooo_draw.xsl
index 0a12287..448923f 100644
--- a/filter/source/xslt/import/wordml/wordml2ooo_draw.xsl
+++ b/filter/source/xslt/import/wordml/wordml2ooo_draw.xsl
@@ -25,12 +25,8 @@
for a copy of the LGPLv3 License.
-->
-<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"
xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:aml="http://schemas.microsoft.com/aml/2001/core"
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
xmlns:math="http://www.w3.org/1998/Math/MathML"
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer"
xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events"
xmlns:xalan="http://xml.apache.org/xalan" xmlns:oleextracter="MyOleExtracter"
xmlns:ole="java:XSLTFilterOLEExtracter" xmlns:java="http://saxon.sf.net/java-type"
exclude-result-prefixes="w wx aml o dt v xalan ole oleextracter java"
extension-element-prefixes="oleextracter">
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"
xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:aml="http://schemas.microsoft.com/aml/2001/core"
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
xmlns:math="http://www.w3.org/1998/Math/MathML"
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer"
xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events"
xmlns:ole="http://libreoffice.org/2011/xslt/ole" exclude-result-prefixes="w wx aml o dt v">
<xsl:include href="wordml2ooo_custom_draw.xsl"/>
- <xsl:include href="wordml2ooo_path.xsl"/>
- <xsl:param name="oleExtractor" as="java:com.sun.star.comp.xsltfilter.XSLTFilterOLEExtracter"
select="ole:new()"/>
- <xsl:param name="XMultiServiceFactory" as="java:com.sun.star.lang.XMultiServiceFactory"
select="ole:init($oleExtractor,
'uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager')"/>
-
<xsl:key name="imagedata" match="w:binData" use="@w:name"/>
<xsl:key name="shapetype" match="v:shapetype" use="concat('#', @id)"/>
@@ -581,7 +577,6 @@
</xsl:when>
</xsl:choose>
<xsl:if test="parent::w:pict/o:OLEObject">
- <xsl:variable name="style" select="concat(@style, ';')"/>
<xsl:variable name="width" select="substring-before(
substring-after($style,'width:') ,';')"/>
<xsl:variable name="height"
select="substring-before(substring-after($style,'height:'),';')"/>
<xsl:attribute name="draw:visible-area-left">0cm</xsl:attribute>
@@ -1642,43 +1637,16 @@
</xsl:element>
</xsl:template>
<xsl:template match="w:docOleData" mode="init">
- <xsl:choose>
- <xsl:when test="element-available('oleextracter:init')">
- <oleextracter:init
UNOURL="uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="ole:init($oleExtractor,
'uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager')"/>
- </xsl:otherwise>
- </xsl:choose>
<xsl:apply-templates select="w:binData[@w:name='oledata.mso']" mode="oledata.mso"/>
</xsl:template>
- <xsl:template match="w:docOleData" mode="exit">
- <oleextracter:exit/>
- </xsl:template>
<xsl:template match="w:binData" mode="oledata.mso">
- <!-- <xsl:choose>
- <xsl:when test="element-available('oleextracter:getByName')">
- <xsl:variable name="tmp" select="oleextracter:insertByName('oledata.mso',
translate(text(),'  ','' ) )"/>
- </xsl:when>
- <xsl:otherwise>-->
- <xsl:variable name="tmp" select="ole:insertByName($oleExtractor,'oledata.mso',
translate(text(),'  ','' ) )"/>
- <!-- </xsl:otherwise>
- </xsl:choose> -->
+ <xsl:variable name="tmp" select="ole:insertByName('oledata.mso',
translate(text(),'  ','' ) )"/>
</xsl:template>
<xsl:template match="o:OLEObject " mode="output">
<!-- depends on i43230,we can uncomment this code or find another way after i43230 got
fixed -->
<draw:object-ole>
<xsl:element name="office:binary-data">
- <!--
- <xsl:choose>
- <xsl:when test="element-available('oleextracter:getByName')">
- <xsl:value-of
select="translate(oleextracter:getByName(@ObjectID),' ','')"/>
- </xsl:when>
- <xsl:otherwise> -->
- <xsl:value-of
select="translate(ole:getByName($oleExtractor,@ObjectID),' ','')"/>
- <!--
- </xsl:otherwise>
- </xsl:choose> -->
+ <xsl:value-of select="translate(ole:getByName(@ObjectID),' ','')"/>
</xsl:element>
</draw:object-ole>
</xsl:template>
@@ -2207,7 +2175,4 @@
</xsl:otherwise>
</xsl:choose>
</xsl:template>
- <xalan:component prefix="oleextracter" elements="init exit" functions="getByName insertByName">
- <xalan:script lang="javaclass"
src="xalan://com.sun.star.comp.xsltfilter.XSLTFilterOLEExtracter"/>
- </xalan:component>
</xsl:stylesheet>
diff --git a/filter/source/xsltfilter/LibXSLTTransformer.cxx
b/filter/source/xsltfilter/LibXSLTTransformer.cxx
index 190c20e..18f18dc 100644
--- a/filter/source/xsltfilter/LibXSLTTransformer.cxx
+++ b/filter/source/xsltfilter/LibXSLTTransformer.cxx
@@ -39,9 +39,13 @@
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlIO.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/xmlstring.h>
#include <libxslt/transform.h>
#include <libxslt/xsltutils.h>
#include <libxslt/variables.h>
+#include <libxslt/extensions.h>
#include <cppuhelper/factory.hxx>
#include <cppuhelper/servicefactory.hxx>
@@ -62,6 +66,7 @@
#include <com/sun/star/io/XStreamListener.hpp>
#include <LibXSLTTransformer.hxx>
+#include <OleHandler.hxx>
using namespace ::rtl;
using namespace ::cppu;
@@ -93,6 +98,9 @@ namespace XSLT
const sal_Int32 Reader::INPUT_BUFFER_SIZE = _INPUT_BUFFER_SIZE;
+ /**
+ * ParserInputBufferCallback forwards IO call-backs to libxml stream IO.
+ */
struct ParserInputBufferCallback
{
static int
@@ -108,6 +116,9 @@ namespace XSLT
return tmp->closeInput();
}
};
+ /**
+ * ParserOutputBufferCallback forwards IO call-backs to libxml stream IO.
+ */
struct ParserOutputBufferCallback
{
static int
@@ -123,6 +134,99 @@ namespace XSLT
return tmp->closeOutput();
}
};
+ /**
+ * ExtFuncOleCB forwards XPath extension function calls registers with libxslt to the
OleHandler instance that actually
+ * provides the implementation for those functions.
+ *
+ * The OLE extension module currently supplies to functions
+ * insertByName: registers an OLE object to be later inserted into the output tree.
+ * getByName: reads a previously registered OLE object and returns a base64 encoded string
representation.
+ */
+ struct ExtFuncOleCB
+ {
+ static void *
+ init(xsltTransformContextPtr, const xmlChar*)
+ {
+ return NULL;
+ }
+ static void
+ insertByName(xmlXPathParserContextPtr ctxt, int nargs)
+ {
+ xsltTransformContextPtr tctxt;
+ void *data;
+ if (nargs != 2) {
+ xsltGenericError(xsltGenericErrorContext,
+ "insertByName: requires exactly 2 arguments\n");
+ return;
+ }
+ tctxt = xsltXPathGetTransformContext(ctxt);
+ if (tctxt == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtFunctionTest: failed to get the transformation context\n");
+ return;
+ }
+ // XXX: someone with better knowledge of libxslt might come up with a better
+ // idea to pass the OleHandler than by attaching it to tctxt->_private. See also
+ // below.
+ data = tctxt->_private;
+ if (data == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtFunctionTest: failed to get module data\n");
+ return;
+ }
+ OleHandler * oh = static_cast<OleHandler*> (data);
+
+ xmlXPathObjectPtr value = valuePop(ctxt);
+ value = ensureStringValue(value, ctxt);
+ xmlXPathObjectPtr streamName = valuePop(ctxt);
+ streamName = ensureStringValue(streamName, ctxt);
+
+ oh->insertByName(::rtl::OUString::createFromAscii((sal_Char*) streamName->stringval),
::rtl::OString((sal_Char*) value->stringval));
+ valuePush(ctxt, xmlXPathNewCString(""));
+ }
+
+ static xmlXPathObjectPtr ensureStringValue(xmlXPathObjectPtr obj, const
xmlXPathParserContextPtr ctxt)
+ {
+ if (obj->type != XPATH_STRING) {
+ valuePush(ctxt, obj);
+ xmlXPathStringFunction(ctxt, 1);
+ obj = valuePop(ctxt);
+ }
+ return obj;
+ }
+
+ static void getByName(xmlXPathParserContextPtr ctxt, int nargs)
+ {
+ xsltTransformContextPtr tctxt;
+ void *data;
+ if (nargs != 1) {
+ xsltGenericError(xsltGenericErrorContext,
+ "getByName: requires exactly 1 argument\n");
+ return;
+ }
+
+ tctxt = xsltXPathGetTransformContext(ctxt);
+ if (tctxt == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtFunctionTest: failed to get the transformation context\n");
+ return;
+ }
+ // XXX: someone with better knowledge of libxslt might come up with a better
+ // idea to pass the OleHandler than by attaching it to tctxt->_private
+ data = tctxt->_private;
+ if (data == NULL) {
+ xsltGenericError(xsltGenericErrorContext,
+ "xsltExtFunctionTest: failed to get module data\n");
+ return;
+ }
+ OleHandler * oh = static_cast<OleHandler*> (data);
+ xmlXPathObjectPtr streamName = valuePop(ctxt);
+ streamName = ensureStringValue(streamName, ctxt);
+ const OString content = oh->getByName(::rtl::OUString::createFromAscii((sal_Char*)
streamName->stringval));
+ valuePush(ctxt, xmlXPathNewCString(content.getStr()));
+ xmlXPathFreeObject(streamName);
+ }
+ };
Reader::Reader(LibXSLTTransformer* transformer) :
m_transformer(transformer), m_terminated(false), m_readBuf(
@@ -218,9 +322,12 @@ namespace XSLT
(const xmlChar *) m_transformer->getStyleSheetURL().getStr());
xmlDocPtr result = NULL;
xsltTransformContextPtr tcontext = NULL;
+ registerExtensionModule();
+ OleHandler* oh = new OleHandler(m_transformer->getServiceFactory());
if (styleSheet)
{
tcontext = xsltNewTransformContext(styleSheet, doc);
+ tcontext->_private = static_cast<void *> (oh);
xsltQuoteUserParams(tcontext, ¶ms[0]);
result = xsltApplyStylesheetUser(styleSheet, doc, 0, 0, 0,
tcontext);
@@ -249,19 +356,33 @@ namespace XSLT
m_transformer->error(msg);
}
closeOutput();
+ delete(oh);
xsltFreeStylesheet(styleSheet);
xsltFreeTransformContext(tcontext);
xmlFreeDoc(doc);
xmlFreeDoc(result);
}
- ;
void
Reader::onTerminated()
{
m_terminated = true;
}
- ;
+ void
+ Reader::registerExtensionModule()
+ {
+ const xmlChar* oleModuleURI = (const xmlChar *) EXT_MODULE_OLE_URI;
+ xsltRegisterExtModule(oleModuleURI, &ExtFuncOleCB::init, NULL);
+ xsltRegisterExtModuleFunction(
+ (const xmlChar*) "insertByName",
+ oleModuleURI,
+ &ExtFuncOleCB::insertByName);
+ xsltRegisterExtModuleFunction(
+ (const xmlChar*) "getByName",
+ oleModuleURI,
+ &ExtFuncOleCB::getByName);
+
+ }
Reader::~Reader()
{
diff --git a/filter/source/xsltfilter/LibXSLTTransformer.hxx
b/filter/source/xsltfilter/LibXSLTTransformer.hxx
index 16396a3..d5f93b0 100644
--- a/filter/source/xsltfilter/LibXSLTTransformer.hxx
+++ b/filter/source/xsltfilter/LibXSLTTransformer.hxx
@@ -40,6 +40,7 @@
#include <libxml/tree.h>
#include <libxml/xmlIO.h>
#include <libxslt/transform.h>
+#include <libxml/xpathInternals.h>
#include <cppuhelper/factory.hxx>
#include <cppuhelper/servicefactory.hxx>
@@ -70,6 +71,8 @@ using namespace ::com::sun::star::lang;
using ::std::list;
using ::std::map;
+#define EXT_MODULE_OLE_URI "http://libreoffice.org/2011/xslt/ole"
+
namespace XSLT
{
@@ -156,6 +159,11 @@ namespace XSLT
::std::map<const char*, OString> SAL_CALL
getParameters();
+ virtual SAL_CALL
+ Reference<XMultiServiceFactory> getServiceFactory() {
+ return m_rServiceFactory;
+ }
+
};
/*
@@ -192,6 +200,8 @@ namespace XSLT
run();
virtual void SAL_CALL
onTerminated();
+ void SAL_CALL
+ registerExtensionModule();
};
}
diff --git a/filter/source/xsltfilter/OleHandler.cxx b/filter/source/xsltfilter/OleHandler.cxx
new file mode 100644
index 0000000..874b288
--- /dev/null
+++ b/filter/source/xsltfilter/OleHandler.cxx
@@ -0,0 +1,249 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * [ Peter Jentsch <pjotr@guineapics.de> ]
+ * Portions created by the Initial Developer are Copyright (C) 2011 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Peter Jentsch <pjotr@guineapics.de>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_filter.hxx"
+
+#include <cstdio>
+#include <cstring>
+#include <list>
+#include <map>
+#include <vector>
+#include <iostream>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlIO.h>
+#include <libxslt/transform.h>
+#include <libxslt/xsltutils.h>
+#include <libxslt/variables.h>
+#include <xmloff/xmluconv.hxx>
+#include <package/Inflater.hxx>
+#include <package/Deflater.hxx>
+
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/servicefactory.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+
+#include <OleHandler.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::embed;
+using namespace ::rtl;
+
+
+namespace XSLT
+{
+ Reference<XStream> SAL_CALL OleHandler::createTempFile() {
+ Reference<XStream>
+ tempFile(
+ m_msf->createInstance(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile"
))),
+ UNO_QUERY);
+ OSL_ASSERT(tempFile.is());
+ return tempFile;
+ }
+
+ void SAL_CALL OleHandler::ensureCreateRootStorage()
+ {
+ if (m_storage == NULL || m_rootStream == NULL)
+ {
+ m_rootStream = createTempFile();
+ Sequence<Any> args(1);
+ args[0] <<= m_rootStream->getInputStream();
+ OUString
serviceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.OLESimpleStorage"));
+
+ Reference<XNameContainer> cont(m_msf->createInstanceWithArguments(serviceName,
args), UNO_QUERY);
+ m_storage = cont;
+ }
+ }
+
+ void SAL_CALL OleHandler::initRootStorageFromBase64(const OString& content)
+ {
+ Sequence<sal_Int8> oleData;
+ SvXMLUnitConverter::decodeBase64(oleData, ::rtl::OStringToOUString(content,
RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS));
+ m_rootStream = createTempFile();
+ Reference<XOutputStream> xOutput = m_rootStream->getOutputStream();
+ xOutput->writeBytes(oleData);
+ xOutput->flush();
+ //Get the input stream and seek to begin
+ Reference<XSeekable> xSeek(m_rootStream->getInputStream(), UNO_QUERY);
+ xSeek->seek(0);
+
+ //create an com.sun.star.embed.OLESimpleStorage from the temp stream
+ Sequence<Any> args(1);
+ args[0] <<= xSeek;
+ Reference<XNameContainer> cont(m_msf->createInstanceWithArguments(OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLESimpleStorage" )), args),
UNO_QUERY);
+ m_storage = cont;
+ }
+
+ OString SAL_CALL
+ OleHandler::encodeSubStorage(const OUString& streamName)
+ {
+ if (!m_storage->hasByName(streamName))
+ {
+ return "Not Found:";// + streamName;
+ }
+ ;
+ Reference<XInputStream> subStream((*(Reference< XInterface > *)
m_storage->getByName(streamName).getValue()), UNO_QUERY);
+ if (!subStream.is())
+ {
+ return "Not Found:";// + streamName;
+ }
+ //The first four byte are the length of the uncompressed data
+ Sequence<sal_Int8> pLength(4);
+ Reference<XSeekable> xSeek(subStream, UNO_QUERY);
+ xSeek->seek(0);
+ //Get the uncompressed length
+ int readbytes = subStream->readBytes(pLength, 4);
+ if (4 != readbytes)
+ {
+ return "Can not read the length.";
+ }
+ int oleLength = (pLength[0] << 0) + (pLength[1] << 8)
+ + (pLength[2] << 16) + (pLength[3] << 24);
+ Sequence<sal_Int8> content(oleLength);
+ //Read all bytes. The compressed length should less then the uncompressed length
+ readbytes = subStream->readBytes(content, oleLength);
+ if (oleLength < readbytes)
+ {
+ return "oleLength";// +oleLength + readBytes;
+ }
+
+ // Decompress the bytes
+ ::Inflater* decompresser = new ::Inflater(sal_False);
+ decompresser->setInput(content);
+ Sequence<sal_Int8> result(oleLength);
+ decompresser->doInflateSegment(result, 0, oleLength);
+ decompresser->end();
+ delete decompresser;
+ //return the base64 string of the uncompressed data
+ OUStringBuffer buf(oleLength);
+ SvXMLUnitConverter::encodeBase64(buf, result);
+ return ::rtl::OUStringToOString(buf.toString(), RTL_TEXTENCODING_UTF8);
+ }
+
+ void SAL_CALL
+ OleHandler::insertByName(const OUString& streamName, const OString& content)
+ {
+ if (streamName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("oledata.mso")))
+ {
+ initRootStorageFromBase64(content);
+ }
+ else
+ {
+ ensureCreateRootStorage();
+ insertSubStorage(streamName, content);
+ }
+ }
+
+ const OString
+ SAL_CALL OleHandler::getByName(const OUString& streamName)
+ {
+ if (streamName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("oledata.mso")))
+ {
+ //get the length and seek to 0
+ Reference<XSeekable> xSeek (m_rootStream, UNO_QUERY);
+ int oleLength = (int) xSeek->getLength();
+ xSeek->seek(0);
+ //read all bytes
+ Reference<XInputStream> xInput = m_rootStream->getInputStream();
+ Sequence<sal_Int8> oledata(oleLength);
+ xInput->readBytes(oledata, oleLength);
+ //return the base64 encoded string
+ OUStringBuffer buf(oleLength);
+ SvXMLUnitConverter::encodeBase64(buf, oledata);
+ return ::rtl::OUStringToOString(buf.toString(), RTL_TEXTENCODING_UTF8);
+ }
+ else
+ {
+ return encodeSubStorage(streamName);
+ }
+ return "";
+ }
+
+ void SAL_CALL
+ OleHandler::insertSubStorage(const OUString& streamName, const OString& content)
+ {
+ //decode the base64 string
+ Sequence<sal_Int8> oledata;
+ SvXMLUnitConverter::decodeBase64(oledata, rtl::OUString::createFromAscii(content));
+ //create a temp stream to write data to
+ Reference<XStream> subStream = createTempFile();
+ Reference<XInputStream> xInput = subStream->getInputStream();
+ Reference<XOutputStream> xOutput = subStream->getOutputStream();
+ //write the length to the temp stream
+ Sequence<sal_Int8> header(4);
+ header[0] = (sal_Int8) (oledata.getLength() >> 0) & 0xFF;
+ header[1] = (sal_Int8) (oledata.getLength() >> 8) & 0xFF;
+ header[2] = (sal_Int8) (oledata.getLength() >> 16) & 0xFF;
+ header[3] = (sal_Int8) (oledata.getLength() >> 24) & 0xFF;
+ xOutput->writeBytes(header);
+
+ // Compress the bytes
+ Sequence<sal_Int8> output(oledata.getLength());
+ ::Deflater* compresser = new ::Deflater((sal_Int32) 3, sal_False);
+ compresser->setInputSegment(oledata, 0, oledata.getLength());
+ compresser->finish();
+ int compressedDataLength = compresser->doDeflateSegment(output, 0, oledata.getLength());
+ delete(compresser);
+ //realloc the data length
+ Sequence<sal_Int8> compressed(compressedDataLength);
+ for (int i = 0; i < compressedDataLength; i++) {
+ compressed[i] = output[i];
+ }
+
+ //write the compressed data to the temp stream
+ xOutput->writeBytes(compressed);
+ //seek to 0
+ Reference<XSeekable> xSeek(xInput, UNO_QUERY);
+ xSeek->seek(0);
+
+ //insert the temp stream as a sub stream and use an XTransactedObject to commit it
immediately
+ Reference<XTransactedObject> xTransact(m_storage, UNO_QUERY);
+ Any entry;
+ entry <<= xInput;
+ m_storage->insertByName(streamName, entry);
+ xTransact->commit();
+ }
+
+
+
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+
diff --git a/filter/source/xsltfilter/OleHandler.hxx b/filter/source/xsltfilter/OleHandler.hxx
new file mode 100644
index 0000000..1452b1a
--- /dev/null
+++ b/filter/source/xsltfilter/OleHandler.hxx
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * [ Peter Jentsch <pjotr@guineapics.de> ]
+ * Portions created by the Initial Developer are Copyright (C) 2011 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Peter Jentsch <pjotr@guineapics.de>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef OLEHANDLER_HXX_
+#define OLEHANDLER_HXX_
+#include <cstdio>
+#include <cstring>
+#include <list>
+#include <map>
+#include <vector>
+#include <iostream>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlIO.h>
+#include <libxslt/transform.h>
+#include <libxslt/xsltutils.h>
+#include <libxslt/variables.h>
+#include <xmloff/xmluconv.hxx>
+
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/servicefactory.hxx>
+#include <cppuhelper/implbase4.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <osl/module.h>
+#include <osl/file.hxx>
+#include <osl/process.h>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XStream.hpp>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::io;
+using namespace ::rtl;
+
+namespace XSLT
+{
+ /*
+ * OleHandler provides implementations for the XSLT extension functions used by the WordML
2003 XSLT filters.
+ *
+ * The extension functions takes base64 encoded string representations of embedded OLE objects
provided by the XML filter framework,
+ * stores them into a com.sun.star.embed.OLESimpleStorage and retrieves them later as
individual base64 OLE objects.
+ *
+ * The implementation is ported from the former Java based implementation XSLTOleExtrater (sic)
+ *
+ * I believe the whole thing should provide round-trip editing of embedded OLE objects.
+ * I'm not sure if it currently does anything meaningful, because the Java implementation
seems to be broken both in OOo and LibO.
+ *
+ */
+ class OleHandler
+ {
+ public:
+ OleHandler(const Reference<XMultiServiceFactory>& msf){
+ m_msf =msf;
+ }
+ void SAL_CALL
+ insertByName(const OUString& streamName, const OString& content);
+ const OString SAL_CALL
+ getByName(const OUString& streamName);
+
+ private:
+ Reference<XMultiServiceFactory> m_msf;
+ Reference<XNameContainer> m_storage;
+ Reference<XStream> m_rootStream;
+ void SAL_CALL
+ ensureCreateRootStorage();
+ OString SAL_CALL
+ encodeSubStorage(const OUString& streamName);
+ void SAL_CALL
+ insertSubStorage(const OUString& streamName, const OString& content);
+ void SAL_CALL
+ initRootStorageFromBase64(const OString& content);
+ Reference<XStream> SAL_CALL
+ createTempFile();
+ };
+}
+
+
+#endif /* OLEHANDLER_HXX_ */
diff --git a/filter/source/xsltfilter/makefile.mk b/filter/source/xsltfilter/makefile.mk
index 6405fa7..473c98f 100644
--- a/filter/source/xsltfilter/makefile.mk
+++ b/filter/source/xsltfilter/makefile.mk
@@ -43,7 +43,7 @@ LIBXSLTINCDIR=external$/libxslt
CFLAGS+= -I$(SOLARINCDIR)$/$(LIBXSLTINCDIR)
.ENDIF
-SLOFILES=$(SLO)$/XSLTFilter.obj $(SLO)$/LibXSLTTransformer.obj $(SLO)$/fla.obj
+SLOFILES=$(SLO)$/XSLTFilter.obj $(SLO)$/LibXSLTTransformer.obj $(SLO)$/fla.obj
$(SLO)/OleHandler.obj
LIBNAME=xsltfilter
SHL1TARGETDEPN=makefile.mk
SHL1OBJS=$(SLOFILES)
@@ -60,7 +60,8 @@ SHL1STDLIBS= \
$(XMLOFFLIB) \
$(SALLIB) \
$(LIBXML2LIB) \
- $(XSLTLIB)
+ $(XSLTLIB) \
+ $(PACKAGE2LIB)
.IF "$(SOLAR_JAVA)"!=""
--
1.7.1
Context
- [Libreoffice] [PATCH] replace Saxon/J XSLT extension functions with libxslt/c++ equivalent · Peter Jentsch
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.