/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ package util; import java.io.PrintWriter ; import java.util.Vector ; import java.util.Hashtable ; import java.util.Enumeration ; import java.util.HashSet ; // access the implementations via names import com.sun.star.uno.XInterface; import com.sun.star.io.XOutputStream; import com.sun.star.io.XInputStream; import com.sun.star.io.XActiveDataSource; import com.sun.star.ucb.XSimpleFileAccess; import com.sun.star.lang.XMultiServiceFactory; import com.sun.star.xml.sax.XDocumentHandler; import com.sun.star.uno.Any; import com.sun.star.uno.Type; import com.sun.star.uno.UnoRuntime; import com.sun.star.beans.PropertyValue; import com.sun.star.xml.sax.XLocator; import com.sun.star.xml.sax.XAttributeList; import com.sun.star.xml.sax.XParser ; import com.sun.star.xml.sax.InputSource ; import com.sun.star.lang.XComponent; import com.sun.star.document.XExporter; import com.sun.star.document.XImporter; import com.sun.star.document.XFilter; public class XMLTools { /** * The implementation of com.sun.star.xml.sax.XAttributeList * where attributes and their values can be added. */ public static class AttributeList implements XAttributeList { private static class Attribute { public String Name ; public String Type ; public String Value ; } private Hashtable attrByName = new Hashtable() ; private Vector attributes = new Vector() ; private PrintWriter log = null ; /** * Creates a class instance. */ public AttributeList() {} /** * Constructs a list which will report to log * specified about each XDocumentHandler method * call. */ public AttributeList(PrintWriter log) { this.log = log ; } public AttributeList(XAttributeList list) { if (list == null) return ; for (short i = 0; i < list.getLength(); i++) { add(list.getNameByIndex(i), list.getTypeByIndex(i), list.getValueByIndex(i)) ; } } /** * Adds an attribute with type and value specified. * @param name The attribute name. * @param type Value type (usually 'CDATA' used). * @param value Attribute value. */ public void add(String name, String type, String value) { Attribute attr = new Attribute() ; attr.Name = name ; attr.Type = type ; attr.Value = value ; attributes.add(attr) ; attrByName.put(attr.Name, attr) ; } /** * Adds an attribute with value specified. As a type of * value 'CDATA' string specified. * @param name The attribute name. * @param value Attribute value. */ public void add(String name, String value) { add(name, "CDATA", value) ; } /** * Clears all attributes added before. */ public void clear() { attrByName.clear() ; attributes.clear() ; } /*************************************** * XAttributeList methods ****************************************/ public short getLength() { if (log != null) log.println("getLength() called -> " + attributes.size()) ; return (short) attributes.size() ; } public String getNameByIndex(short idx) { String name = ((Attribute) attributes.get(idx)).Name ; if (log != null) log.println("getNameByIndex(" + idx + ") called -> '" + name + "'") ; return name ; } public String getTypeByIndex(short idx) { String type = ((Attribute) attributes.get(idx)).Type ; if (log != null) log.println("getTypeByIndex(" + idx + ") called -> '" + type + "'") ; return type; } public String getTypeByName(String name) { String type = ((Attribute) attrByName.get(name)).Type ; if (log != null) log.println("getTypeByName('" + name + "') called -> '" + type + "'") ; return type; } public String getValueByIndex(short idx) { String value = ((Attribute) attributes.get(idx)).Value ; if (log != null) log.println("getValueByIndex(" + idx + ") called -> '" + value + "'") ; return value; } public String getValueByName(String name) { String value = ((Attribute) attrByName.get(name)).Value ; if (log != null) log.println("getValueByName('" + name + "') called -> '" + value + "'") ; return value; } } /** * This class writes all XML data handled into a stream specified * in the constructor. */ public static class XMLWriter implements XDocumentHandler { private PrintWriter _log = null ; private String align = "" ; /** * Creates a SAX handler which writes all XML data * handled into a log stream specified. */ public XMLWriter(PrintWriter log) { _log = log ; } /** * Creates a SAX handler which does nothing. */ public XMLWriter() { } public void processingInstruction(String appl, String data) { if (_log == null) return ; _log.println(align + "") ; } public void startDocument() { if (_log == null) return ; _log.println("START DOCUMENT:") ; } public void endDocument() { if (_log == null) return ; _log.println("END DOCUMENT:") ; } public void setDocumentLocator(XLocator loc) { if (_log == null) return ; _log.println("DOCUMENT LOCATOR: ('" + loc.getPublicId() + "','" + loc.getSystemId() + "')") ; } public void startElement(String name, XAttributeList attr) { if (_log == null) return ; _log.print(align + "<" + name + " ") ; if (attr != null) { short attrLen = attr.getLength() ; for (short i = 0; i < attrLen; i++) { if (i != 0) _log.print(align + " ") ; _log.print(attr.getNameByIndex(i) + "[" + attr.getTypeByIndex(i) + "]=\"" + attr.getValueByIndex(i) + "\"") ; if (i+1 != attrLen) { _log.println() ; } } } _log.println(">") ; align += " " ; } public void endElement(String name) { if (_log == null) return ; align = align.substring(3) ; _log.println(align + "") ; } public void characters(String chars) { if (_log == null) return ; _log.println(align + chars) ; } public void ignorableWhitespace(String sp) { if (_log == null) return ; _log.println(sp) ; } } /** * Checks if the XML structure is well formed (i.e. all tags opened must be * closed and all tags opened inside a tag must be closed * inside the same tag). It also checks parameters passed. * If any collisions found appropriate error message is * output into a stream specified. No XML data output, i.e. * no output will be performed if no errors occur.

* After document is completed there is a way to cehck * if the XML data and structure was valid. */ public static class XMLWellFormChecker extends XMLWriter { protected boolean docStarted = false ; protected boolean docEnded = false ; protected Vector tagStack = new Vector() ; protected boolean wellFormed = true ; protected boolean noOtherErrors = true ; protected PrintWriter log = null ; protected boolean printXMLData = false ; public XMLWellFormChecker(PrintWriter log) { super() ; this.log = log ; } public XMLWellFormChecker(PrintWriter log_, boolean printXMLData) { super(printXMLData ? log_ : null) ; this.printXMLData = printXMLData ; this.log = log_ ; } /** * Reset all values. This is important e.g. for test of XFilter * interface, where 'filter()' method istbstarted twice. */ public void reset() { docStarted = false ; docEnded = false ; tagStack = new Vector() ; wellFormed = true ; noOtherErrors = true ; PrintWriter log = null ; printXMLData = false ; } public void startDocument() { super.startDocument(); if (docStarted) { printError("Document is started twice.") ; wellFormed = false ; } docStarted = true ; } public void endDocument() { super.endDocument(); if (!docStarted) { wellFormed = false ; printError("Document ended but not started.") ; } docEnded = true ; } public void startElement(String name, XAttributeList attr) { super.startElement(name, attr); if (attr == null) { printError("attribute list passed as parameter to startElement()"+ " method has null value for tag <" + name + ">") ; noOtherErrors = false ; } tagStack.add(0, name) ; } public void endElement(String name) { super.endElement(name); if (wellFormed) { if (tagStack.size() == 0) { wellFormed = false ; printError("No tags to close (bad closing tag )") ; } else { String startTag = (String) tagStack.elementAt(0) ; tagStack.remove(0) ; if (!startTag.equals(name)) { wellFormed = false ; printError("Bad closing tag: ; tag expected: "); } } } } /** * Checks if there were no errors during document handling. * I.e. startDocument() and endDocument() must be called, * XML must be well formed, parameters must be valid. */ public boolean isWellFormed() { if (!docEnded) { printError("Document was not ended.") ; wellFormed = false ; } return wellFormed && noOtherErrors ; } /** * Prints error message and all tags where error occurred inside. * Also prints "Tag trace" in case if the full XML data isn't * printed. */ public void printError(String msg) { log.println("!!! Error: " + msg) ; if (printXMLData) return ; log.println(" Tag trace :") ; for (int i = 0; i < tagStack.size(); i++) { String tag = (String) tagStack.elementAt(i) ; log.println(" <" + tag + ">") ; } } } /** * Beside structure of XML this class also can check existence * of tags, inner tags, and character data. After document * completion there is a way to check if required tags and * character data was found. If there any error occurs an * appropriate message is output. */ public static class XMLTagsChecker extends XMLWellFormChecker { protected Hashtable tags = new Hashtable() ; protected Hashtable chars = new Hashtable() ; protected boolean allOK = true ; public XMLTagsChecker(PrintWriter log) { super(log) ; } /** * Adds a tag name which must be contained in the XML data. */ public void addTag(String tag) { tags.put(tag, "") ; } /** * Adds a tag name which must be contained in the XML data and * must be inside the tag with name outerTag. */ public void addTagEnclosed(String tag, String outerTag) { tags.put(tag, outerTag) ; } /** * Adds a character data which must be contained in the XML data. */ public void addCharacters(String ch) { chars.put(ch, "") ; } /** * Adds a character data which must be contained in the XML data and * must be inside the tag with name outerTag. */ public void addCharactersEnclosed(String ch, String outerTag) { chars.put(ch, outerTag) ; } public void startElement(String name, XAttributeList attrs) { super.startElement(name, attrs) ; if (tags.containsKey(name)) { String outerTag = (String) tags.get(name); if (!outerTag.equals("")) { boolean isInTag = false ; for (int i = 0; i < tagStack.size(); i++) { if (outerTag.equals((String) tagStack.elementAt(i))) { isInTag = true ; break ; } } if (!isInTag) { printError("Required tag <" + name + "> found, but is not enclosed in tag <" + outerTag + ">") ; allOK = false ; } } tags.remove(name) ; } } public void characters(String ch) { super.characters(ch) ; if (chars.containsKey(ch)) { String outerTag = (String) chars.get(ch); if (!outerTag.equals("")) { boolean isInTag = false ; for (int i = 0; i < tagStack.size(); i++) { if (outerTag.equals((String) tagStack.elementAt(i))) { isInTag = true ; break ; } } if (!isInTag) { printError("Required characters '" + ch + "' found, but are not enclosed in tag <" + outerTag + ">") ; allOK = false ; } } chars.remove(ch) ; } } /** * Checks if the XML data was valid and well formed and if * all necessary tags and character data was found. */ public boolean checkTags() { allOK &= isWellFormed() ; Enumeration badTags = tags.keys() ; Enumeration badChars = chars.keys() ; if (badTags.hasMoreElements()) { allOK = false ; log.println("Required tags were not found in export :") ; while(badTags.hasMoreElements()) { log.println(" <" + ((String) badTags.nextElement()) + ">") ; } } if (badChars.hasMoreElements()) { allOK = false ; log.println("Required characters were not found in export :") ; while(badChars.hasMoreElements()) { log.println(" <" + ((String) badChars.nextElement()) + ">") ; } } reset(); return allOK ; } } /** * Represents an XML tag which must be found in XML data written. * This tag can contain only its name or tag name and attribute * name, or attribute value additionally. */ public static class Tag { private String name = null; private String[][] attrList = new String[0][3] ; /** * Creates tag which has only a name. Attributes don't make sense. * @param tagName The name of the tag. */ public Tag(String tagName) { name = tagName ; } /** * Creates a tag with the name specified, which must have an * attribute with name specified. The value of this attribute * doesn't make sense. * @param tagName The name of the tag. * @param attrName The name of attribute which must be contained * in the tag. */ public Tag(String tagName, String attrName) { name = tagName ; attrList = new String[1][3] ; attrList[0][0] = attrName ; } /** * Creates a tag with the name specified, which must have an * attribute with the value specified. The type of value * assumed to be 'CDATA'. * @param tagName The name of the tag. * @param attrName The name of attribute which must be contained * in the tag. * @param attrValue Attribute value. */ public Tag(String tagName, String attrName, String attrValue) { name = tagName ; attrList = new String[1][3] ; attrList[0][0] = attrName ; attrList[0][1] = "CDATA" ; attrList[0][2] = attrValue ; } /** * Creates a tag with the name specified, which must have * attributes specified. The value of thesee attributes * doesn't make sense. * @param tagName The name of the tag. * @param attrNames Array with names of attributes which must * be contained in the tag. */ public Tag(String tagName, String[] attrNames) { name = tagName ; attrList = new String[attrNames.length][3] ; for (int i = 0; i < attrNames.length; i++) { attrList[i][0] = attrNames[i] ; } } /** * Creates a tag with the name specified, which must have an * attributes with their values specified. The type of all values * assumed to be 'CDATA'. * @param tagName The name of the tag. * @param attrValues An array with attribute names and their values. * attrValues[N][0] element contains the name of Nth * attribute, and attrValues[N][1] element contains * value of Nth attribute, if value is null then the * attribute value can be any. */ public Tag(String tagName, String[][] attrValues) { name = tagName ; attrList = new String[attrValues.length][3] ; for (int i = 0; i < attrValues.length; i++) { attrList[i][0] = attrValues[i][0] ; attrList[i][1] = "CDATA" ; attrList[i][2] = attrValues[i][1] ; } } /** * Gets tag String description. */ public String toString() { String ret = "<" + name ; for (int i = 0; i < attrList.length; i++) { ret += " " + attrList[i][0] + "="; if (attrList[i][2] == null) { ret += "(not specified)"; } else { ret += "\"" + attrList[i][2] + "\""; } } ret += ">"; return ret ; } protected boolean checkAttr(int attrListIdx, XAttributeList list) { short j = 0 ; int listLen = list.getLength(); while(j < listLen) { if (attrList[attrListIdx][0].equals(list.getNameByIndex(j))) { if (attrList[attrListIdx][2] == null) return true ; return attrList[attrListIdx][2].equals(list.getValueByIndex(j)) ; } j++ ; } return false ; } /** * Checks if this tag matches tag passed in parameters. * I.e. if tag specifies only it's name it mathes if names * are equal (attributes don't make sense). If there are * some attributes names specified in this tag method checks * if all names present in attribute list list * (attributes' values don't make sense). If attributes specified * with values method checks if these attributes exist and * have appropriate values. */ public boolean isMatchTo(String tagName, XAttributeList list) { if (!name.equals(tagName)) return false; boolean result = true ; for (int i = 0; i < attrList.length; i++) { result &= checkAttr(i, list) ; } return result ; } } /** * Class realises extended XML data checking. It has possibilities * to check if a tag exists, if it has some attributes with * values, and if this tag is contained in another tag (which * also can specify any attributes). It can check if some * character data exists inside any tag specified. */ public static class XMLChecker extends XMLWellFormChecker { protected HashSet tagSet = new HashSet() ; protected Vector tags = new Vector() ; protected Vector chars = new Vector() ; protected Vector tagStack = new Vector() ; protected Vector attrStack = new Vector() ; public XMLChecker(PrintWriter log, boolean writeXML) { super(log, writeXML) ; } public void addTag(Tag tag) { tags.add(new Tag[] {tag, null}) ; tagSet.add(tag.name) ; } public void addTagEnclosed(Tag tag, Tag outerTag) { tags.add(new Tag[] {tag, outerTag}) ; tagSet.add(tag.name) ; } public void addCharacters(String ch) { chars.add(new Object[] {ch.trim(), null}) ; } public void addCharactersEnclosed(String ch, Tag outerTag) { chars.add(new Object[] {ch.trim(), outerTag}) ; } public void startElement(String name, XAttributeList attr) { try { super.startElement(name, attr); if (tagSet.contains(name)) { for (int i = 0; i < tags.size(); i++) { Tag[] tag = (Tag[]) tags.elementAt(i); if (tag[0].isMatchTo(name, attr)) { if (tag[1] == null) { tags.remove(i--); } else { boolean isInStack = false ; for (int j = 0; j < tagStack.size(); j++) { if (tag[1].isMatchTo((String) tagStack.elementAt(j), (XAttributeList) attrStack.elementAt(j))) { isInStack = true ; break ; } } if (isInStack) { tags.remove(i--) ; } } } } } tagStack.add(0, name) ; attrStack.add(0, new AttributeList(attr)); } catch (Exception e) { e.printStackTrace(log); } } public void characters(String ch) { super.characters(ch) ; for (int i = 0; i < chars.size(); i++) { Object[] chr = (Object[]) chars.elementAt(i); if (((String) chr[0]).equals(ch)) { if (chr[1] == null) { chars.remove(i--); } else { boolean isInStack = false ; for (int j = 0; j < tagStack.size(); j++) { if (((Tag) chr[1]).isMatchTo((String) tagStack.elementAt(j), (XAttributeList) attrStack.elementAt(j))) { isInStack = true ; break ; } } if (isInStack) { chars.remove(i--) ; } } } } } public void endElement(String name) { try { super.endElement(name); if (tagStack.size() > 0) { tagStack.remove(0) ; attrStack.remove(0) ; } } catch(Exception e) { e.printStackTrace(log) ; } } public boolean check() { if (tags.size()> 0) { log.println("!!! Error: Some tags were not found :") ; for (int i = 0; i < tags.size(); i++) { Tag[] tag = (Tag[]) tags.elementAt(i) ; log.println(" Tag " + tag[0] + " was not found"); if (tag[1] != null) log.println(" inside tag " + tag[1]) ; } } if (chars.size() > 0) { log.println("!!! Error: Some character data blocks were not found :") ; for (int i = 0; i < chars.size(); i++) { Object[] ch = (Object[]) chars.elementAt(i) ; log.println(" Character data \"" + ch[0] + "\" was not found ") ; if (ch[1] != null) log.println(" inside tag " + ch[1]) ; } } if (!isWellFormed()) log.println("!!! Some errors were found in XML structure") ; boolean result = tags.size() == 0 && chars.size() == 0 && isWellFormed(); reset(); return result; } } /** * Creates XDocumentHandler implementation in form * of com.sun.star.xml.sax.Writer service, which * writes XML data into a com.sun.star.io.Pipe * created. * @return Single element array which contains the handler * contained in Any structure. */ public static Object[] getDocumentHandler(XMultiServiceFactory xMSF) { Object[] ret = new Object[1]; try { XInterface Writer = (XInterface) xMSF.createInstance( "com.sun.star.xml.sax.Writer"); XInterface oPipe = (XInterface) xMSF.createInstance ( "com.sun.star.io.Pipe" ); XOutputStream xPipeOutput = (XOutputStream) UnoRuntime. queryInterface(XOutputStream.class, oPipe) ; XActiveDataSource xADS = (XActiveDataSource) UnoRuntime.queryInterface(XActiveDataSource.class,Writer); xADS.setOutputStream(xPipeOutput); XDocumentHandler handler = (XDocumentHandler) UnoRuntime.queryInterface(XDocumentHandler.class,Writer); Any arg = new Any(new Type(XDocumentHandler.class),handler); ret[0] = arg; } catch (com.sun.star.uno.Exception e) { e.printStackTrace(); } return ret; } public static PropertyValue[] createMediaDescriptor(String[] propNames, Object[] values) { PropertyValue[] props = new PropertyValue[propNames.length] ; for (int i = 0; i < props.length; i++) { props[i] = new PropertyValue() ; props[i].Name = propNames[i] ; if (values != null && i < values.length) { props[i].Value = values[i] ; } } return props ; } /** * Gets the hanlder, which writes all the XML data passed to the * file specified. * @param xMSF Soffice ServiceManager factory. * @param fileURL The file URL (in form file:///) to which * XML data is written. * @return SAX handler to which XML data has to be written. */ public static XDocumentHandler getFileXMLWriter(XMultiServiceFactory xMSF, String fileURL) throws com.sun.star.uno.Exception { XInterface oFacc = (XInterface)xMSF.createInstance( "com.sun.star.comp.ucb.SimpleFileAccess"); XSimpleFileAccess xFacc = (XSimpleFileAccess)UnoRuntime.queryInterface (XSimpleFileAccess.class, oFacc) ; XInterface oWriter = (XInterface)xMSF.createInstance( "com.sun.star.xml.sax.Writer"); XActiveDataSource xWriterDS = (XActiveDataSource) UnoRuntime.queryInterface(XActiveDataSource.class, oWriter); XDocumentHandler xDocHandWriter = (XDocumentHandler) UnoRuntime.queryInterface (XDocumentHandler.class, oWriter) ; if (xFacc.exists(fileURL)) xFacc.kill(fileURL); XOutputStream fOut = xFacc.openFileWrite(fileURL) ; xWriterDS.setOutputStream(fOut); return xDocHandWriter ; } /** * Parses XML file and passes its data to the SAX handler specified. * @param xMSF Soffice ServiceManager factory. * @param fileURL XML file name (in form file:///) to be parsed. * @param handler SAX handler to which XML data from file will * be transferred. */ public static void parseXMLFile(XMultiServiceFactory xMSF, String fileURL, XDocumentHandler handler) throws com.sun.star.uno.Exception { XInterface oFacc = (XInterface)xMSF.createInstance( "com.sun.star.comp.ucb.SimpleFileAccess"); XSimpleFileAccess xFacc = (XSimpleFileAccess)UnoRuntime.queryInterface (XSimpleFileAccess.class, oFacc) ; XInputStream oIn = xFacc.openFileRead(fileURL) ; XInterface oParser = (XInterface)xMSF.createInstance( "com.sun.star.xml.sax.Parser"); XParser xParser = (XParser) UnoRuntime.queryInterface(XParser.class, oParser); xParser.setDocumentHandler(handler) ; InputSource inSrc = new InputSource() ; inSrc.aInputStream = oIn ; xParser.parseStream(inSrc) ; oIn.closeInput(); } /** * Exports document (the whole or a part) into the file specified * in XML format. * @param xMSF Soffice ServiceManager factory. * @param xDoc Document to be exported. * @param docType Type of document (for example 'Calc', 'Writer', 'Draw') * The type must start with capital letter. * @param exportType The type of export specifies if the whole * document will be exported or one of its parts (Meta info, Styles, etc.). * The following types supported (it also depends of document type) : * "" (empty string) - for the whole document ; * "Content" - only content exported ; * "Meta" - meta document info exported ; * "Settings" - view settings of document exported ; * "Styles" - document styles exported ; * @param fileURL XML file name (in form file:///) to be exported to. */ public static void exportDocument(XMultiServiceFactory xMSF, XComponent xDoc, String docType, String exportType, String fileURL) throws com.sun.star.uno.Exception { XDocumentHandler xDocHandWriter = XMLTools.getFileXMLWriter(xMSF, fileURL) ; Any arg = new Any(new Type(XDocumentHandler.class), xDocHandWriter); XInterface oExp = (XInterface)xMSF.createInstanceWithArguments( "com.sun.star.comp." + docType + ".XML" + exportType + "Exporter", new Object[] {arg}); XExporter xExp = (XExporter) UnoRuntime.queryInterface (XExporter.class, oExp) ; xExp.setSourceDocument(xDoc) ; XFilter filter = (XFilter) UnoRuntime.queryInterface(XFilter.class, oExp) ; filter.filter(XMLTools.createMediaDescriptor( new String[] {"FilterName"}, new Object[] {"Custom filter"})) ; } /** * Imports document (the whole or a part) from the file specified * in XML format. * @param xMSF Soffice ServiceManager factory. * @param xDoc Target document to be imported. * @param docType Type of document (for example 'Calc', 'Writer', 'Draw') * The type must start with capital letter. * @param exportType The type of export specifies if the whole * document will be exported or one of its parts (Meta info, Styles, etc.). * The following types supported (it hardly depends of XML data in file) : * "" (empty string) - for the whole document ; * "Content" - only content exported ; * "Meta" - meta document info exported ; * "Settings" - view settings of document exported ; * "Styles" - document styles exported ; * @param fileURL XML file name (in form file:///) to be imported from. */ public static void importDocument(XMultiServiceFactory xMSF, XComponent xDoc, String docType, String importType, String fileURL) throws com.sun.star.uno.Exception { XInterface oImp = (XInterface)xMSF.createInstance( "com.sun.star.comp." + docType + ".XML" + importType + "Importer"); XImporter xImp = (XImporter) UnoRuntime.queryInterface (XImporter.class, oImp) ; XDocumentHandler xDocHandImp = (XDocumentHandler) UnoRuntime.queryInterface (XDocumentHandler.class, oImp) ; xImp.setTargetDocument(xDoc) ; parseXMLFile(xMSF, fileURL, xDocHandImp) ; } }