diff --git a/PowerDeComposer/.classpath b/PowerDeComposer/.classpath index dd846c3..70125a7 100644 --- a/PowerDeComposer/.classpath +++ b/PowerDeComposer/.classpath @@ -26,7 +26,6 @@ - diff --git a/PowerDeComposer/pom.xml b/PowerDeComposer/pom.xml index 010b17b..e87e66b 100644 --- a/PowerDeComposer/pom.xml +++ b/PowerDeComposer/pom.xml @@ -147,6 +147,7 @@ net.sf.saxon Saxon-HE 10.6 + diff --git a/PowerDeComposer/src/main/java/com/xbreeze/xml/compose/XmlComposer.java b/PowerDeComposer/src/main/java/com/xbreeze/xml/compose/XmlComposer.java index 6dc9db5..6897fbb 100644 --- a/PowerDeComposer/src/main/java/com/xbreeze/xml/compose/XmlComposer.java +++ b/PowerDeComposer/src/main/java/com/xbreeze/xml/compose/XmlComposer.java @@ -26,10 +26,15 @@ import java.io.IOException; import java.util.logging.Logger; +import javax.xml.namespace.QName; + +import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlOptions; import com.xbreeze.xml.DeComposerException; +import com.xbreeze.xml.utils.FileContentAndCharset; +import com.xbreeze.xml.utils.FileUtils; import com.xbreeze.xml.utils.XMLUtils; public class XmlComposer { @@ -65,96 +70,59 @@ private void composeXml(String xmlFilePath, String xmlTargetFilePath) throws Exc * @throws Exception */ private void composeXml(File xmlFile, String xmlTargetFilePath) throws Exception { - try { - Path basePath = FileUtils.getBasePath(xmlFile); + FileContentAndCharset xmlFileContentsAndCharset = FileUtils.getFileContent(xmlFile); - // Open the file and look for includes - // TODO: Make this XPath namespace aware so it actually looks for xi:include instead of include in all namespaces - VTDNav nav = XMLUtils.getVTDNav(xmlFileContentsAndCharset, false); - AutoPilot ap = new AutoPilot(nav); - // Declare the XInclude namespace. - //ap.declareXPathNameSpace("xi", "http://www.w3.org/2001/XInclude"); + // Get the XmlObject for the xmlFile. + XmlObject composedXmlObject = XMLUtils.parseXmlFile(xmlFile); + + // Loop over all ExtendedAttributes elements for de-formalize them. + for (XmlObject extAttrsXmlObject : composedXmlObject.selectPath("//ExtendedAttributes")) { + // Create a string buffer for the extended attribute text. + StringBuffer extendedAttributeText = new StringBuffer(); - String deformalizedXml = xmlFile; - try { - // Create a XMLModifier for changing the XML document. - XMLModifier vm = new XMLModifier(nav); + // Find the OriginatingExtension elements. + for (XmlObject origExtXmlObect : extAttrsXmlObject.selectPath("OriginatingExtension")) { + // Get the ObjectID and Name of the Extension. + String extObjectID = origExtXmlObect.selectAttribute(QName.valueOf("ObjectID")).toString(); + String extName = origExtXmlObect.selectAttribute(QName.valueOf("Name")).toString(); - // De-Formalize all extended attributes. - // Select all ExtendedAttributes elements. - ap.selectXPath("//ExtendedAttributes"); - boolean deformalizedExtendedAttributes = false; - // Loop thru the set of extended attributes. - while ((ap.evalXPath()) != -1) { - // Store the fragment of the ExtendedAttributes element (so we can remove it later. - long extAttrsNodeFragment = nav.getElementFragment(); + // Create a buffer for the extended attributes of the current extension. + StringBuffer extensionExtAttrTextBuffer = new StringBuffer(); + + for (XmlObject extAttrXmlObject : origExtXmlObect.selectPath("ExtendedAttribute")) { + // Get the ObjectID, Name and Value of the ExtendedAttribute. + String extAttrObjectID = extAttrXmlObject.selectAttribute(QName.valueOf("ObjectID")).toString(); + String extAttrName = extAttrXmlObject.selectAttribute(QName.valueOf("Name")).toString(); + String extAttrValue = extAttrXmlObject.xmlText(); - // Create a string buffer for the extended attribute text. - StringBuffer extendedAttributeText = new StringBuffer(); - extendedAttributeText.append(xmlFileContentsAndCharset.getLineSeparator()); - extendedAttributeText.append(""); + // Add the current extended attribute to the list for the current extension. + // For the length we use the unescaped version of the extended attribute text. + extensionExtAttrTextBuffer.append(String.format("{%s},%s,%d=%s", extAttrObjectID, extAttrName, XMLUtils.unescapeXMLChars(extAttrValue).length(), extAttrValue)); + extensionExtAttrTextBuffer.append(xmlFileContentsAndCharset.getLineSeparator()); - // Find the OriginatingExtension elements. - AutoPilot ap_extension = new AutoPilot(nav); - ap_extension.selectXPath("OriginatingExtension"); - // Loop thru the set of OriginatingExtension. - while ((ap_extension.evalXPath()) != -1) { - String extObjectID = nav.toString(nav.getAttrVal("ObjectID")); - String extName = nav.toString(nav.getAttrVal("Name")); - - // Find the ExtendedAttribute elements. - AutoPilot ap_extattribute = new AutoPilot(nav); - ap_extattribute.selectXPath("ExtendedAttribute"); - // Create a buffer for the extended attributes of the current extension. - StringBuffer extensionExtAttrTextBuffer = new StringBuffer(); - // Loop thru the set of ExtendedAttribute. - while ((ap_extattribute.evalXPath()) != -1) { - String extAttrObjectID = nav.toString(nav.getAttrVal("ObjectID")); - String extAttrName = nav.toString(nav.getAttrVal("Name")); - // Replace a LF without preceding LF to CRLF (since VTD-NAV removed it during parsing). - int extendedAttributeTextIndex = nav.getText(); - String extAttrValue = new String(nav.getXML().getBytes(nav.getTokenOffset(extendedAttributeTextIndex), nav.getTokenLength(extendedAttributeTextIndex))); - // Add the current extended attribute to the list for the current extension. - // For the length we use the unescaped version of the extended attribute text. - extensionExtAttrTextBuffer.append(String.format("{%s},%s,%d=%s", extAttrObjectID, extAttrName, XMLUtils.unescapeXMLChars(extAttrValue).length(), extAttrValue)); - extensionExtAttrTextBuffer.append(xmlFileContentsAndCharset.getLineSeparator()); - } - extensionExtAttrTextBuffer.append(xmlFileContentsAndCharset.getLineSeparator()); - String extensionExtAttrText = extensionExtAttrTextBuffer.toString(); - - // Add the extension extended attributes to the extended attributes buffer. - // For the length we use the unescaped version of the extended attribute text. - // The length is minus 2, to compensate for the trailing CRLF. - extendedAttributeText.append(String.format("{%s},%s,%d=%s", extObjectID, extName, XMLUtils.unescapeXMLChars(extensionExtAttrText).length() - 2, extensionExtAttrText)); - } - extendedAttributeText.append(""); - // Insert the ExtendedAttributesText element. - vm.insertAfterElement(extendedAttributeText.toString()); - // Now we added the replacement of the textual extended attributes, we can remove the ExtendedAttributesText element. - vm.remove(nav.expandWhiteSpaces(extAttrsNodeFragment, VTDNav.WS_LEADING)); - // Set the indicator whether we de-formalized anything to true. - deformalizedExtendedAttributes = true; } - - // Update the XML to process after deformalizing. - if (deformalizedExtendedAttributes) - deformalizedXml = XMLUtils.getResultingXml(vm); - } catch (ModifyException e) { - throw new Exception(String.format("Error modifying config file %s", xmlFile.toString()), e); - } catch (XPathParseException | XPathEvalException e) { - throw new Exception(String.format("XPath error scanning for includes in %s", xmlFile.toString()), e); - } - - // Get the XmlObject for the xmlFile. - XmlObject composedXmlObject = XMLUtils.parseXmlFile(deformalizedXml); - - try { - // Save the resulting composed file. - // XmlOption could be added as extra parameter for the save method: , new XmlOptions().setSaveOptimizeForSpeed(true) - composedXmlObject.save(new File(xmlTargetFilePath), new XmlOptions().setSavePrettyPrint()); - } catch (IOException ioe) { - throw new DeComposerException(String.format("Error writing to target file %s: %s", xmlTargetFilePath, ioe.getMessage())); + // Add a line separator. + extendedAttributeText.append(xmlFileContentsAndCharset.getLineSeparator()); + // Get the value for the extended attributes for the current extension. + String extensionExtAttrText = extensionExtAttrTextBuffer.toString(); + // Add the extension extended attributes to the extended attributes buffer. + // For the length we use the unescaped version of the extended attribute text. + // The length is minus 2, to compensate for the trailing CRLF. + extendedAttributeText.append(String.format("{%s},%s,%d=%s", extObjectID, extName, XMLUtils.unescapeXMLChars(extensionExtAttrText).length() - 2, extensionExtAttrText)); } + + // Create a new XmlCursor to insert the de-formalized extended attribute text. + XmlCursor xmlCursor = composedXmlObject.newCursor(); + xmlCursor.beginElement(QName.valueOf("a:ExtendedAttributesText")); + xmlCursor.setTextValue(extendedAttributeText.toString()); + } + + try { + // Save the resulting composed file. + // XmlOption could be added as extra parameter for the save method: , new XmlOptions().setSaveOptimizeForSpeed(true) + composedXmlObject.save(new File(xmlTargetFilePath), new XmlOptions().setSavePrettyPrint()); + } catch (IOException ioe) { + throw new DeComposerException(String.format("Error writing to target file %s: %s", xmlTargetFilePath, ioe.getMessage())); + } } - }