1*b47cbcf5SAndrew Rist /**************************************************************
2*b47cbcf5SAndrew Rist  *
3*b47cbcf5SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*b47cbcf5SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*b47cbcf5SAndrew Rist  * distributed with this work for additional information
6*b47cbcf5SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*b47cbcf5SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*b47cbcf5SAndrew Rist  * "License"); you may not use this file except in compliance
9*b47cbcf5SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*b47cbcf5SAndrew Rist  *
11*b47cbcf5SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*b47cbcf5SAndrew Rist  *
13*b47cbcf5SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*b47cbcf5SAndrew Rist  * software distributed under the License is distributed on an
15*b47cbcf5SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b47cbcf5SAndrew Rist  * KIND, either express or implied.  See the License for the
17*b47cbcf5SAndrew Rist  * specific language governing permissions and limitations
18*b47cbcf5SAndrew Rist  * under the License.
19*b47cbcf5SAndrew Rist  *
20*b47cbcf5SAndrew Rist  *************************************************************/
21*b47cbcf5SAndrew Rist 
22cdf0e10cSrcweir package com.sun.star.comp.xsltfilter;
23cdf0e10cSrcweir 
24*b47cbcf5SAndrew Rist 
25cdf0e10cSrcweir 
26cdf0e10cSrcweir //Standard Java classes
27cdf0e10cSrcweir import java.io.FileWriter;
28cdf0e10cSrcweir import java.util.zip.Inflater;
29cdf0e10cSrcweir import java.util.zip.Deflater;
30cdf0e10cSrcweir 
31cdf0e10cSrcweir //StarOffice Interfaces and UNO
32cdf0e10cSrcweir import com.sun.star.bridge.XBridgeFactory;
33cdf0e10cSrcweir import com.sun.star.bridge.XBridge;
34cdf0e10cSrcweir import com.sun.star.connection.XConnector;
35cdf0e10cSrcweir import com.sun.star.connection.XConnection;
36cdf0e10cSrcweir import com.sun.star.container.XNameContainer;
37cdf0e10cSrcweir import com.sun.star.embed.XTransactedObject;
38cdf0e10cSrcweir import com.sun.star.io.XStream;
39cdf0e10cSrcweir import com.sun.star.io.XSeekable;
40cdf0e10cSrcweir import com.sun.star.io.XInputStream;
41cdf0e10cSrcweir import com.sun.star.io.XOutputStream;
42cdf0e10cSrcweir import com.sun.star.lang.XMultiServiceFactory;
43cdf0e10cSrcweir import com.sun.star.lang.XComponent;
44cdf0e10cSrcweir import com.sun.star.uno.XComponentContext;
45cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
46cdf0e10cSrcweir 
47cdf0e10cSrcweir /** This class is an xalan extension class. It provider 2 elements
48cdf0e10cSrcweir  *  and 2 functions to used in xslt script. With this elements and functions
49cdf0e10cSrcweir  *  we can convert between oledata between Wordml and OOo flat.
50cdf0e10cSrcweir  *  To use it, we need a running OOo. There are two ways to get the XMultiServiceFactory.
51cdf0e10cSrcweir  *  When called by OOo xslt filter, an XMultiServiceFactory will be add to the transformer
52cdf0e10cSrcweir  *  by setParameter(), then we can get it using getParameter(). Another way is using an
53cdf0e10cSrcweir  *  XConnection to connect to a running OOo. We connect to a running OOo, we need know the
54cdf0e10cSrcweir  *  uno url. It can be set in the xslt script. The default uno url is:
55cdf0e10cSrcweir  *  "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager"
56cdf0e10cSrcweir  *  see XSLTXalanOLEExtracter.java
57cdf0e10cSrcweir  */
58cdf0e10cSrcweir public class XSLTFilterOLEExtracter {
59cdf0e10cSrcweir 
60cdf0e10cSrcweir     protected XMultiServiceFactory m_xMSF;
61cdf0e10cSrcweir     protected XNameContainer m_Storage;
62cdf0e10cSrcweir     protected XStream m_RootStream;
63cdf0e10cSrcweir     protected XConnection m_Connection;
64cdf0e10cSrcweir     protected String sConnectionString;
65cdf0e10cSrcweir     private static final String UNO_URL = "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager";
66cdf0e10cSrcweir 
XSLTFilterOLEExtracter()67cdf0e10cSrcweir     public XSLTFilterOLEExtracter() {
68cdf0e10cSrcweir     }
69cdf0e10cSrcweir 
init(String unoUrl)70cdf0e10cSrcweir     public void init(String unoUrl) {
71cdf0e10cSrcweir         if (unoUrl == null || unoUrl.equals("")) {
72cdf0e10cSrcweir             unoUrl = UNO_URL;
73cdf0e10cSrcweir         }
74cdf0e10cSrcweir         debugln("Init with uno url=" + unoUrl);
75cdf0e10cSrcweir         if (null == m_xMSF) {
76cdf0e10cSrcweir             try {
77cdf0e10cSrcweir                 m_xMSF = connectAwareGetServiceFactory();
78cdf0e10cSrcweir             } catch (Exception ex) {
79cdf0e10cSrcweir                 System.err.println("Could not connect to the office '" + unoUrl + "'\n" + ex.getMessage());
80cdf0e10cSrcweir             }
81cdf0e10cSrcweir         }
82cdf0e10cSrcweir     }
83cdf0e10cSrcweir 
exit()84cdf0e10cSrcweir     public void exit() {
85cdf0e10cSrcweir         m_Storage = null;
86cdf0e10cSrcweir         m_xMSF = null;
87cdf0e10cSrcweir         if (null != m_Connection) {
88cdf0e10cSrcweir             try {
89cdf0e10cSrcweir                 m_Connection.close();
90cdf0e10cSrcweir             } catch (Exception ex) {
91cdf0e10cSrcweir                 System.err.println("Could not close connection to the office.\n" + ex.getMessage());
92cdf0e10cSrcweir             }
93cdf0e10cSrcweir         }
94cdf0e10cSrcweir     }
95cdf0e10cSrcweir     //If aName = "oledata.mso" then we load the root storage from the given base64 string
96cdf0e10cSrcweir     //Otherwise we compress the stream and add it to the root storage under the name of aName
insertByName(String aName, String aBase64)97cdf0e10cSrcweir     public void insertByName(String aName, String aBase64) {
98cdf0e10cSrcweir         debugln("insertByName(" + aName + " : " + aBase64 + ")");
99cdf0e10cSrcweir         if (aName.equals("oledata.mso")) {
100cdf0e10cSrcweir             loadRootStorageFromBase64(aBase64);
101cdf0e10cSrcweir         } else {
102cdf0e10cSrcweir             ensureCreateRootStorage();
103cdf0e10cSrcweir             insertSubStorage(aName, aBase64);
104cdf0e10cSrcweir         }
105cdf0e10cSrcweir     }
106cdf0e10cSrcweir     //If aName = "oledata.mso" then we return the base64 encoded string of the root storage
107cdf0e10cSrcweir     //Otherwise we return the base64 encoded string of the sub stream under the name of aName
getByName(String aName)108cdf0e10cSrcweir     public String getByName(String aName) {
109cdf0e10cSrcweir         if (aName.equals("oledata.mso")) {
110cdf0e10cSrcweir             try {
111cdf0e10cSrcweir                 //get the length and seek to 0
112cdf0e10cSrcweir                 XSeekable xSeek = (XSeekable) UnoRuntime.queryInterface(XSeekable.class, m_RootStream);
113cdf0e10cSrcweir                 int oleLength = (int) xSeek.getLength();
114cdf0e10cSrcweir                 xSeek.seek(0);
115cdf0e10cSrcweir                 xSeek = null;
116cdf0e10cSrcweir                 //read all bytes
117cdf0e10cSrcweir                 XInputStream xInput = m_RootStream.getInputStream();
118cdf0e10cSrcweir                 byte oledata[][] = new byte[1][oleLength];
119cdf0e10cSrcweir                 xInput.readBytes(oledata, oleLength);
120cdf0e10cSrcweir                 //return the base64 encoded string
121cdf0e10cSrcweir                 return Base64.encodeBytes(oledata[0]);
122cdf0e10cSrcweir             } catch (Exception ex) {
123cdf0e10cSrcweir                 ex.printStackTrace();
124cdf0e10cSrcweir             }
125cdf0e10cSrcweir         } else {
126cdf0e10cSrcweir             return getEncodedSubStorage(aName);
127cdf0e10cSrcweir         }
128cdf0e10cSrcweir         return "";
129cdf0e10cSrcweir     }
130cdf0e10cSrcweir     //get the sub stream which name = aName, decompress it and return the base64 encoded string
getEncodedSubStorage(String aName)131cdf0e10cSrcweir     public String getEncodedSubStorage(String aName) {
132cdf0e10cSrcweir         debugln("getByName(" + aName + ")");
133cdf0e10cSrcweir         try {
134cdf0e10cSrcweir             if (!m_Storage.hasByName(aName)) {
135cdf0e10cSrcweir                 return "Not Found:" + aName;
136cdf0e10cSrcweir             }
137cdf0e10cSrcweir             Object oSubStream = m_Storage.getByName(aName);
138cdf0e10cSrcweir             if (oSubStream == null) {
139cdf0e10cSrcweir                 return "Not Found:" + aName;
140cdf0e10cSrcweir             }
141cdf0e10cSrcweir             XInputStream xSubStream = (XInputStream) UnoRuntime.queryInterface(XInputStream.class,
142cdf0e10cSrcweir                     oSubStream);
143cdf0e10cSrcweir             if (xSubStream == null) {
144cdf0e10cSrcweir                 return "Not Found:" + aName;
145cdf0e10cSrcweir             }
146cdf0e10cSrcweir             //The first four byte are the length of the uncompressed data
147cdf0e10cSrcweir             byte pLength[][] = new byte[1][4];
148cdf0e10cSrcweir             XSeekable xSeek = (XSeekable) UnoRuntime.queryInterface(XSeekable.class, xSubStream);
149cdf0e10cSrcweir             xSeek.seek(0);
150cdf0e10cSrcweir             xSeek = null;
151cdf0e10cSrcweir             //Get the uncompressed length
152cdf0e10cSrcweir             int readbytes = xSubStream.readBytes(pLength, 4);
153cdf0e10cSrcweir             if (4 != readbytes) {
154cdf0e10cSrcweir                 System.out.println("readbytes:" + readbytes);
155cdf0e10cSrcweir                 return "Can not read the length.";
156cdf0e10cSrcweir             }
157cdf0e10cSrcweir             int oleLength = (pLength[0][0] << 0) + (pLength[0][1] << 8) + (pLength[0][2] << 16) + (pLength[0][3] << 24);
158cdf0e10cSrcweir             byte pContents[][] = new byte[1][oleLength];
159cdf0e10cSrcweir             //Read all bytes. The compressed length should less then the uncompressed length
160cdf0e10cSrcweir             readbytes = xSubStream.readBytes(pContents, oleLength);
161cdf0e10cSrcweir             if (oleLength < readbytes) {
162cdf0e10cSrcweir                 return "oleLength :" + oleLength + " readbytes: " + readbytes;
163cdf0e10cSrcweir             }
164cdf0e10cSrcweir 
165cdf0e10cSrcweir             // Decompress the bytes
166cdf0e10cSrcweir             Inflater decompresser = new Inflater();
167cdf0e10cSrcweir             decompresser.setInput(pContents[0], 0, readbytes);
168cdf0e10cSrcweir             byte[] result = new byte[oleLength];
169cdf0e10cSrcweir             int resultLength = decompresser.inflate(result);
170cdf0e10cSrcweir             decompresser.end();
171cdf0e10cSrcweir 
172cdf0e10cSrcweir             //return the base64 string of the uncompressed data
173cdf0e10cSrcweir             return Base64.encodeBytes(result);
174cdf0e10cSrcweir         } catch (Exception ex) {
175cdf0e10cSrcweir             ex.printStackTrace();
176cdf0e10cSrcweir         }
177cdf0e10cSrcweir         return "";
178cdf0e10cSrcweir     }
179cdf0e10cSrcweir 
CreateTempFileStream(XMultiServiceFactory xMSF)180cdf0e10cSrcweir     public XStream CreateTempFileStream(XMultiServiceFactory xMSF) {
181cdf0e10cSrcweir         // try to get temporary file representation
182cdf0e10cSrcweir         XStream xTempFileStream = null;
183cdf0e10cSrcweir         try {
184cdf0e10cSrcweir             Object oTempFile = xMSF.createInstance("com.sun.star.io.TempFile");
185cdf0e10cSrcweir             xTempFileStream = (XStream) UnoRuntime.queryInterface(XStream.class, oTempFile);
186cdf0e10cSrcweir         } catch (Exception e) {
187cdf0e10cSrcweir         }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir         if (xTempFileStream == null) {
190cdf0e10cSrcweir             System.out.println("Can't create temporary file!");
191cdf0e10cSrcweir         }
192cdf0e10cSrcweir 
193cdf0e10cSrcweir         return xTempFileStream;
194cdf0e10cSrcweir     }
195cdf0e10cSrcweir     //decode the base64 string and create an com.sun.star.embed.OLESimpleStorage from it
loadRootStorageFromBase64(String aBase64)196cdf0e10cSrcweir     public void loadRootStorageFromBase64(String aBase64) {
197cdf0e10cSrcweir         try {
198cdf0e10cSrcweir             //Decode and write the data to an temp stream
199cdf0e10cSrcweir             byte[] oledata = Base64.decode(aBase64);
200cdf0e10cSrcweir             m_RootStream = CreateTempFileStream(m_xMSF);
201cdf0e10cSrcweir             XOutputStream xOutput = m_RootStream.getOutputStream();
202cdf0e10cSrcweir             xOutput.writeBytes(oledata);
203cdf0e10cSrcweir             xOutput.flush();
204cdf0e10cSrcweir             //Get the input stream and seek to begin
205cdf0e10cSrcweir             XInputStream xInput = m_RootStream.getInputStream();
206cdf0e10cSrcweir             XSeekable xSeek = (XSeekable) UnoRuntime.queryInterface(XSeekable.class, xInput);
207cdf0e10cSrcweir             xSeek.seek(0);
208cdf0e10cSrcweir             oledata = null;
209cdf0e10cSrcweir             xSeek = null;
210cdf0e10cSrcweir 
211cdf0e10cSrcweir             //create an com.sun.star.embed.OLESimpleStorage from the temp stream
212cdf0e10cSrcweir             Object pArgs[] = new Object[1];
213cdf0e10cSrcweir             pArgs[0] = (Object) xInput;
214cdf0e10cSrcweir             Object oTempStorage = m_xMSF.createInstanceWithArguments("com.sun.star.embed.OLESimpleStorage", pArgs);
215cdf0e10cSrcweir             pArgs = null;
216cdf0e10cSrcweir 
217cdf0e10cSrcweir             m_Storage = (XNameContainer) UnoRuntime.queryInterface(XNameContainer.class, oTempStorage);
218cdf0e10cSrcweir         } catch (Exception e) {
219cdf0e10cSrcweir             e.printStackTrace();
220cdf0e10cSrcweir         }
221cdf0e10cSrcweir     }
222cdf0e10cSrcweir     //Create a empty OLESimpleStorage if there is not one
ensureCreateRootStorage()223cdf0e10cSrcweir     public void ensureCreateRootStorage() {
224cdf0e10cSrcweir         if (null == m_RootStream || null == m_Storage) {
225cdf0e10cSrcweir             try {
226cdf0e10cSrcweir                 m_RootStream = CreateTempFileStream(m_xMSF);
227cdf0e10cSrcweir 
228cdf0e10cSrcweir                 Object pArgs[] = new Object[1];
229cdf0e10cSrcweir                 pArgs[0] = (Object) m_RootStream;
230cdf0e10cSrcweir                 Object oTempStorage = m_xMSF.createInstanceWithArguments("com.sun.star.embed.OLESimpleStorage", pArgs);
231cdf0e10cSrcweir                 pArgs = null;
232cdf0e10cSrcweir 
233cdf0e10cSrcweir                 m_Storage = (XNameContainer) UnoRuntime.queryInterface(XNameContainer.class, oTempStorage);
234cdf0e10cSrcweir             } catch (Exception e) {
235cdf0e10cSrcweir                 e.printStackTrace();
236cdf0e10cSrcweir             }
237cdf0e10cSrcweir         }
238cdf0e10cSrcweir     }
239cdf0e10cSrcweir     //decode the base64 string and insert the length and the compressed data of it to
240cdf0e10cSrcweir     //the root storage as a sub stream under aName
insertSubStorage(String aName, String aBase64)241cdf0e10cSrcweir     public void insertSubStorage(String aName, String aBase64) {
242cdf0e10cSrcweir         try {
243cdf0e10cSrcweir             //decode the base64 string
244cdf0e10cSrcweir             byte[] oledata = Base64.decode(aBase64);
245cdf0e10cSrcweir             //create a temp stream to write data to
246cdf0e10cSrcweir             XStream subStream = CreateTempFileStream(m_xMSF);
247cdf0e10cSrcweir             XInputStream xInput = subStream.getInputStream();
248cdf0e10cSrcweir             XOutputStream xOutput = subStream.getOutputStream();
249cdf0e10cSrcweir             //write the length to the temp stream
250cdf0e10cSrcweir             byte oleHead[] = new byte[4];
251cdf0e10cSrcweir             oleHead[0] = (byte) ((oledata.length >>> 0) & 0xFF);
252cdf0e10cSrcweir             oleHead[1] = (byte) ((oledata.length >>> 8) & 0xFF);
253cdf0e10cSrcweir             oleHead[2] = (byte) ((oledata.length >>> 16) & 0xFF);
254cdf0e10cSrcweir             oleHead[3] = (byte) ((oledata.length >>> 24) & 0xFF);
255cdf0e10cSrcweir             xOutput.writeBytes(oleHead);
256cdf0e10cSrcweir 
257cdf0e10cSrcweir             // Compress the bytes
258cdf0e10cSrcweir             byte[] output = new byte[oledata.length];
259cdf0e10cSrcweir             Deflater compresser = new Deflater();
260cdf0e10cSrcweir             compresser.setInput(oledata);
261cdf0e10cSrcweir             compresser.finish();
262cdf0e10cSrcweir             int compressedDataLength = compresser.deflate(output);
263cdf0e10cSrcweir             //realloc the data length
264cdf0e10cSrcweir             byte[] compressedBytes = new byte[compressedDataLength];
265cdf0e10cSrcweir             for (int i = 0; i < compressedDataLength; i++) {
266cdf0e10cSrcweir                 compressedBytes[i] = output[i];
267cdf0e10cSrcweir             }
268cdf0e10cSrcweir 
269cdf0e10cSrcweir             //write the compressed data to the temp stream
270cdf0e10cSrcweir             xOutput.writeBytes(compressedBytes);
271cdf0e10cSrcweir             //seek to 0
272cdf0e10cSrcweir             XSeekable xSeek = (XSeekable) UnoRuntime.queryInterface(XSeekable.class, xInput);
273cdf0e10cSrcweir             xSeek.seek(0);
274cdf0e10cSrcweir             xSeek = null;
275cdf0e10cSrcweir             oledata = null;
276cdf0e10cSrcweir 
277cdf0e10cSrcweir             //insert the temp stream as a sub stream and use an XTransactedObject to commit it immediately
278cdf0e10cSrcweir             XTransactedObject xTransact = (XTransactedObject) UnoRuntime.queryInterface(XTransactedObject.class, m_Storage);
279cdf0e10cSrcweir             m_Storage.insertByName(aName, xInput);
280cdf0e10cSrcweir             xTransact.commit();
281cdf0e10cSrcweir             xTransact = null;
282cdf0e10cSrcweir 
283cdf0e10cSrcweir         } catch (Exception e) {
284cdf0e10cSrcweir             e.printStackTrace();
285cdf0e10cSrcweir         }
286cdf0e10cSrcweir     }
287cdf0e10cSrcweir 
288cdf0e10cSrcweir     /** separtates the uno-url into 3 different parts.
289cdf0e10cSrcweir      */
parseUnoUrl(String url)290cdf0e10cSrcweir     protected static String[] parseUnoUrl(String url) {
291cdf0e10cSrcweir         String[] aRet = new String[3];
292cdf0e10cSrcweir 
293cdf0e10cSrcweir         if (!url.startsWith("uno:")) {
294cdf0e10cSrcweir             return null;
295cdf0e10cSrcweir         }
296cdf0e10cSrcweir 
297cdf0e10cSrcweir         int semicolon = url.indexOf(';');
298cdf0e10cSrcweir         if (semicolon == -1) {
299cdf0e10cSrcweir             return null;
300cdf0e10cSrcweir         }
301cdf0e10cSrcweir 
302cdf0e10cSrcweir         aRet[0] = url.substring(4, semicolon);
303cdf0e10cSrcweir         int nextSemicolon = url.indexOf(';', semicolon + 1);
304cdf0e10cSrcweir 
305cdf0e10cSrcweir         if (semicolon == -1) {
306cdf0e10cSrcweir             return null;
307cdf0e10cSrcweir         }
308cdf0e10cSrcweir         aRet[1] = url.substring(semicolon + 1, nextSemicolon);
309cdf0e10cSrcweir 
310cdf0e10cSrcweir         aRet[2] = url.substring(nextSemicolon + 1);
311cdf0e10cSrcweir         return aRet;
312cdf0e10cSrcweir     }
313cdf0e10cSrcweir     //connect to running OOo and keep an XConnection object so that we can disconnect from OOo as we wish
connectAwareGetServiceFactory()314cdf0e10cSrcweir     protected XMultiServiceFactory connectAwareGetServiceFactory() throws com.sun.star.uno.Exception,
315cdf0e10cSrcweir             com.sun.star.uno.RuntimeException,
316cdf0e10cSrcweir             Exception {
317cdf0e10cSrcweir 
318cdf0e10cSrcweir         // Get component context
319cdf0e10cSrcweir         XComponentContext xComponentContext =
320cdf0e10cSrcweir                 com.sun.star.comp.helper.Bootstrap.createInitialComponentContext(null);
321cdf0e10cSrcweir 
322cdf0e10cSrcweir         // instantiate connector service
323cdf0e10cSrcweir         Object x = xComponentContext.getServiceManager().createInstanceWithContext(
324cdf0e10cSrcweir                 "com.sun.star.connection.Connector", xComponentContext);
325cdf0e10cSrcweir 
326cdf0e10cSrcweir         XConnector xConnector = (XConnector) UnoRuntime.queryInterface(XConnector.class, x);
327cdf0e10cSrcweir 
328cdf0e10cSrcweir         String a[] = parseUnoUrl(sConnectionString);
329cdf0e10cSrcweir         if (null == a) {
330cdf0e10cSrcweir             throw new com.sun.star.uno.Exception("Couldn't parse uno-url " + sConnectionString);
331cdf0e10cSrcweir         }
332cdf0e10cSrcweir 
333cdf0e10cSrcweir         // connect using the connection string part of the uno-url only.
334cdf0e10cSrcweir         m_Connection = xConnector.connect(a[0]);
335cdf0e10cSrcweir 
336cdf0e10cSrcweir         x = xComponentContext.getServiceManager().createInstanceWithContext(
337cdf0e10cSrcweir                 "com.sun.star.bridge.BridgeFactory", xComponentContext);
338cdf0e10cSrcweir 
339cdf0e10cSrcweir         XBridgeFactory xBridgeFactory = (XBridgeFactory) UnoRuntime.queryInterface(
340cdf0e10cSrcweir                 XBridgeFactory.class, x);
341cdf0e10cSrcweir 
342cdf0e10cSrcweir         // create a nameless bridge with no instance provider
343cdf0e10cSrcweir         // using the middle part of the uno-url
344cdf0e10cSrcweir         XBridge bridge = xBridgeFactory.createBridge("", a[1], m_Connection, null);
345cdf0e10cSrcweir 
346cdf0e10cSrcweir         // query for the XComponent interface and add this as event listener
347cdf0e10cSrcweir         XComponent xComponent = (XComponent) UnoRuntime.queryInterface(
348cdf0e10cSrcweir                 XComponent.class, bridge);
349cdf0e10cSrcweir 
350cdf0e10cSrcweir         // get the remote instance
351cdf0e10cSrcweir         x = bridge.getInstance(a[2]);
352cdf0e10cSrcweir 
353cdf0e10cSrcweir         // Did the remote server export this object ?
354cdf0e10cSrcweir         if (null == x) {
355cdf0e10cSrcweir             throw new com.sun.star.uno.Exception(
356cdf0e10cSrcweir                     "Server didn't provide an instance for" + a[2], null);
357cdf0e10cSrcweir         }
358cdf0e10cSrcweir 
359cdf0e10cSrcweir         XMultiServiceFactory xFac = (XMultiServiceFactory) UnoRuntime.queryInterface(XMultiServiceFactory.class, x);
360cdf0e10cSrcweir         return xFac;
361cdf0e10cSrcweir     }
362cdf0e10cSrcweir     protected static boolean DEBUG = false;
363cdf0e10cSrcweir     protected static boolean DEBUGCHK = false;
364cdf0e10cSrcweir     protected static String debugfile;
365cdf0e10cSrcweir 
debugln(String s)366cdf0e10cSrcweir     protected static void debugln(String s) {
367cdf0e10cSrcweir         debug(s + "\n");
368cdf0e10cSrcweir     }
369cdf0e10cSrcweir 
debug(String s)370cdf0e10cSrcweir     protected static void debug(String s) {
371cdf0e10cSrcweir         if (!DEBUGCHK) {
372cdf0e10cSrcweir             if (System.getProperty("xsltfilter.debug") == null) {
373cdf0e10cSrcweir                 DEBUGCHK = true;
374cdf0e10cSrcweir                 return;
375cdf0e10cSrcweir             } else {
376cdf0e10cSrcweir                 debugfile = System.getProperty("xsltfilter.debug");
377cdf0e10cSrcweir                 DEBUG = true;
378cdf0e10cSrcweir             }
379cdf0e10cSrcweir         }
380cdf0e10cSrcweir         if (!DEBUG) {
381cdf0e10cSrcweir             return;
382cdf0e10cSrcweir         }
383cdf0e10cSrcweir         try {
384cdf0e10cSrcweir             FileWriter dbgwriter = new FileWriter(debugfile, true);
385cdf0e10cSrcweir             dbgwriter.write(s);
386cdf0e10cSrcweir             dbgwriter.close();
387cdf0e10cSrcweir         } catch (Exception e) {
388cdf0e10cSrcweir             e.printStackTrace();
389cdf0e10cSrcweir         }
390cdf0e10cSrcweir     }
391cdf0e10cSrcweir }
392