package com.unirisx.poc; import org.docx4j.customXmlProperties.DatastoreItem; import org.docx4j.customXmlProperties.SchemaRefs; import org.docx4j.jaxb.Context; import org.docx4j.model.datastorage.CustomXmlDataStorage; import org.docx4j.model.datastorage.CustomXmlDataStorageImpl; import org.docx4j.openpackaging.exceptions.InvalidFormatException; import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import org.docx4j.openpackaging.parts.CustomXmlDataStoragePart; import org.docx4j.openpackaging.parts.CustomXmlDataStoragePropertiesPart; import org.docx4j.openpackaging.parts.Part; import org.docx4j.openpackaging.parts.PartName; import org.docx4j.openpackaging.parts.opendope.*; import org.docx4j.openpackaging.parts.relationships.RelationshipsPart; import org.docx4j.wml.*; import org.docx4j.wml.Text; import org.opendope.answers.Answer; import org.opendope.answers.Answers; import org.opendope.conditions.Conditions; import org.opendope.xpaths.Xpaths; import org.xml.sax.SAXException; import javax.xml.bind.JAXBElement; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; /** * Created by Manish Chakravarty on 10-04-2017. */ public class MyTestMigrator { protected XPathsPart xPathsPart; protected QuestionsPart questionsPart; protected StandardisedAnswersPart standardisedAnswersPart; protected CustomXmlDataStoragePart customXmlDataStoragePart; protected String storeItemID; // of the answers part protected Map keys = new HashMap(); private String customXMLItemID; protected void createParts(WordprocessingMLPackage pkgOut, File inputXmlFile) throws Exception { // Add OpenDoPE parts to target // .. conditions - not that we use this here ConditionsPart conditionsPart = new ConditionsPart(new PartName("/customXml/item1.xml")); // name doesn't matter pkgOut.getMainDocumentPart().addTargetPart(conditionsPart, RelationshipsPart.AddPartBehaviour.RENAME_IF_NAME_EXISTS); // Word will silently drop the CXPs if they aren't added to the MDP! addPropertiesPart(conditionsPart, "http://opendope.org/conditions"); conditionsPart.setJaxbElement(new Conditions()); // .. XPaths xPathsPart = new XPathsPart(new PartName("/customXml/item1.xml")); pkgOut.getMainDocumentPart().addTargetPart(xPathsPart, RelationshipsPart.AddPartBehaviour.RENAME_IF_NAME_EXISTS); addPropertiesPart(xPathsPart, "http://opendope.org/xpaths"); xPathsPart.setJaxbElement(new Xpaths()); // .. Questions // questionsPart = new QuestionsPart(new PartName("/customXml/item1.xml")); // pkgOut.getMainDocumentPart().addTargetPart(questionsPart, RelationshipsPart.AddPartBehaviour.RENAME_IF_NAME_EXISTS); // addPropertiesPart(questionsPart,"http://opendope.org/questions"); // questionsPart.setJaxbElement(new Questionnaire()); // Questionnaire.Questions questions = new Questionnaire.Questions(); // questionsPart.getJaxbElement().setQuestions(questions); // .. Standardised Answer format standardisedAnswersPart = new StandardisedAnswersPart(new PartName("/customXml/item1.xml")); pkgOut.getMainDocumentPart().addTargetPart(standardisedAnswersPart, RelationshipsPart.AddPartBehaviour.RENAME_IF_NAME_EXISTS); storeItemID = addPropertiesPart(standardisedAnswersPart, "http://opendope.org/answers"); standardisedAnswersPart.setJaxbElement(new Answers()); // Create customXMLDataStoragePart to inject custom XML customXmlDataStoragePart = injectCustomXmlDataStoragePart(pkgOut.getMainDocumentPart(),inputXmlFile); //addPropertiesPart(customXmlDataStoragePart,"http://unirisx.com"); customXMLItemID = addPropertiesPartForSimpleBind(customXmlDataStoragePart, "http://unirisx.com"); } private String addPropertiesPartForSimpleBind(CustomXmlDataStoragePart customXmlDataStoragePart, String namespace) throws InvalidFormatException { CustomXmlDataStoragePropertiesPart customDataStoragePart = new CustomXmlDataStoragePropertiesPart(); org.docx4j.customXmlProperties.ObjectFactory of = new org.docx4j.customXmlProperties.ObjectFactory(); DatastoreItem dsi = of.createDatastoreItem(); String newItemId = "{" + UUID.randomUUID().toString().toUpperCase() + "}"; dsi.setItemID(newItemId); SchemaRefs srefs = of.createSchemaRefs(); dsi.setSchemaRefs(srefs); SchemaRefs.SchemaRef sref = of.createSchemaRefsSchemaRef(); sref.setUri(namespace); srefs.getSchemaRef().add(sref); customDataStoragePart.setJaxbElement(dsi); customXmlDataStoragePart.addTargetPart(customDataStoragePart,RelationshipsPart.AddPartBehaviour.RENAME_IF_NAME_EXISTS); return newItemId; } protected String addPropertiesPart(JaxbCustomXmlDataStoragePart customXmlDataStoragePart, String ns) throws InvalidFormatException { CustomXmlDataStoragePropertiesPart part = new CustomXmlDataStoragePropertiesPart(); org.docx4j.customXmlProperties.ObjectFactory of = new org.docx4j.customXmlProperties.ObjectFactory(); DatastoreItem dsi = of.createDatastoreItem(); String newItemId = "{" + UUID.randomUUID().toString().toUpperCase() + "}"; dsi.setItemID(newItemId); SchemaRefs srefs = of.createSchemaRefs(); dsi.setSchemaRefs(srefs); SchemaRefs.SchemaRef sref = of.createSchemaRefsSchemaRef(); sref.setUri(ns); srefs.getSchemaRef().add(sref); part.setJaxbElement(dsi); customXmlDataStoragePart.addTargetPart(part, RelationshipsPart.AddPartBehaviour.RENAME_IF_NAME_EXISTS); return newItemId; } /** * @param r * @param replacementContent * @param key */ protected void createContentControls(RPr rPr, List replacementContent, String key) { // Has it been encountered already? if (!keys.containsKey(key) ) { // add the part entries addPartEntries(key); keys.put(key, key); } // create the content control SdtRun sdtRun = Context.getWmlObjectFactory().createSdtRun(); replacementContent.add(sdtRun); SdtPr sdtPr = Context.getWmlObjectFactory().createSdtPr(); sdtRun.setSdtPr(sdtPr); /* */ SdtPr.Alias alias = Context.getWmlObjectFactory().createSdtPrAlias(); alias.setVal(key); Tag tag = Context.getWmlObjectFactory().createTag(); tag.setVal("od:xpath=" + key); sdtPr.setTag(tag); sdtPr.setId(); CTDataBinding ctDataBinding = Context.getWmlObjectFactory().createCTDataBinding(); JAXBElement jaxbDB = Context.getWmlObjectFactory().createSdtPrDataBinding(ctDataBinding); sdtPr.setDataBinding(ctDataBinding); // ctDataBinding.setXpath("/oda:answers/oda:answer[@id='" + key +"']"); ctDataBinding.setXpath("/employees/employee/" + key); ctDataBinding.setPrefixMappings("xmlns:oda='http://opendope.org/answers'"); ctDataBinding.setStoreItemID(customXMLItemID); CTSdtContentRun sdtContent = Context.getWmlObjectFactory().createCTSdtContentRun(); sdtRun.setSdtContent(sdtContent); R rnew = new R(); rnew.setRPr( rPr ); // point at old rPr, if any Text text = Context.getWmlObjectFactory().createText(); text.setValue(key); rnew.getContent().add(text); sdtContent.getContent().add(rnew); } private void addPartEntries(String key) { // TODO remove answer generation // answer // Answer a = new Answer(); // a.setId(key); // a.setValue("${" + key + "}"); // standardisedAnswersPart.getJaxbElement().getAnswerOrRepeat().add(a); // XPath // TODO fix XPaths to point to newer injected XML // TODO use customXMLItemID from above Xpaths.Xpath xp = new org.opendope.xpaths.ObjectFactory().createXpathsXpath(); xp.setId(key); xp.setQuestionID(key); Xpaths.Xpath.DataBinding db = new org.opendope.xpaths.ObjectFactory().createXpathsXpathDataBinding(); db.setXpath("/employees/employee/" + key); db.setPrefixMappings("xmlns:oda='http://opendope.org/answers'"); db.setStoreItemID(customXMLItemID); xp.setDataBinding(db); xPathsPart.getJaxbElement().getXpath().add(xp); } public static CustomXmlDataStoragePart injectCustomXmlDataStoragePart(Part parent, File inputXmlFile) throws Exception { org.docx4j.openpackaging.parts.CustomXmlDataStoragePart customXmlDataStoragePart = new org.docx4j.openpackaging.parts.CustomXmlDataStoragePart(); // Defaults to /customXml/item1.xml CustomXmlDataStorage data = new CustomXmlDataStorageImpl(); data.setDocument(createCustomXmlDocument(inputXmlFile)); customXmlDataStoragePart.setData(data); parent.addTargetPart(customXmlDataStoragePart, RelationshipsPart.AddPartBehaviour.RENAME_IF_NAME_EXISTS); return customXmlDataStoragePart; } public static org.w3c.dom.Document createCustomXmlDocument(File xmlFile) throws ParserConfigurationException, IOException, SAXException { // // org.w3c.dom.Document domDoc = XmlUtils.neww3cDomDocument(); // // Element someContentElement = domDoc.createElement("someContent"); // domDoc.appendChild(someContentElement); DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setNamespaceAware(true); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); org.w3c.dom.Document document = documentBuilder.parse(xmlFile); return document; } }