Skip to content

Commit

Permalink
Updated compose implemention to use XmlObject.
Browse files Browse the repository at this point in the history
  • Loading branch information
harmen-xb committed Apr 22, 2024
1 parent 21ab5ae commit 15570cc
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 85 deletions.
1 change: 0 additions & 1 deletion PowerDeComposer/.classpath
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
Expand Down
1 change: 1 addition & 0 deletions PowerDeComposer/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>10.6</version>
</dependency>

<!-- Test dependencies. -->
<dependency>
Expand Down
136 changes: 52 additions & 84 deletions PowerDeComposer/src/main/java/com/xbreeze/xml/compose/XmlComposer.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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("<a:ExtendedAttributesText>");
// 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("</a:ExtendedAttributesText>");
// 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()));
}
}

}

0 comments on commit 15570cc

Please sign in to comment.