import groovy.xml.StreamingMarkupBuilder import java.io.IOException; import java.text.SimpleDateFormat import java.util.HashMap; import java.util.List; import org.jdom.Content; import org.jdom.Document; import org.jdom.Element import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import org.jdom.output.XMLOutputter import org.jdom.output.Format import org.jaxen.JaxenException; import org.jaxen.SimpleNamespaceContext; import org.jaxen.XPath; import org.jaxen.jdom.JDOMXPath import org.jdom.Namespace; java.util.logging.Logger logger=com.boomi.execution.ExecutionUtil.getBaseLogger(); XMLOutputter xmlOutputter = new XMLOutputter(Format.getCompactFormat()); List effectiveDatedNames = ["compensation_information", "employment_information", "personal_information", "address_information", "alternative_cost_distribution", "deduction_recurring", "PaymentInformationV3"]; List includeLatest = ["personal_information", "address_information"]; // Build XML Document SAXBuilder builder = new SAXBuilder(); // Here's how to grab values from the current data // Determine Current Date SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date currentDate = new Date(); //precompile the xpath. Note document looping should be done below this. XPath xPathStartDate = new JDOMXPath("//start_date/.."); XPath xPathEffectiveStartDate = new JDOMXPath("//effectiveStartDate/.."); XPath xPathPersonChildren = new JDOMXPath("/CompoundEmployee/person/*"); for( int i = 0; i < dataContext.getDataCount(); i++ ) { InputStream is = dataContext.getStream(i); Properties props = dataContext.getProperties(i); Document doc = builder.build(is); Element newDocRoot = new Element("CompoundEmployee"); Document newDoc = new Document(newDocRoot); Element person = new Element("person"); newDocRoot.addContent(person); for(Element child: xPathPersonChildren.selectNodes(doc)) { if (!effectiveDatedNames.contains(child.getName())) person.addContent(child.clone()); } List employeeNodes = xPathStartDate.selectNodes(doc); List effEmployeeNodes = xPathEffectiveStartDate.selectNodes(doc); for(Element effEmployeeNode : effEmployeeNodes){ employeeNodes.add(effEmployeeNode); } //build sorted set of all start dates SortedSet sortedStartDates = new TreeSet(); for (Element employeeNode : employeeNodes) { //don't check for effective dates in non-effective dated entities if (isEffectiveDatedEntity(employeeNode)){ if(employeeNode.name == "deduction_recurring" || employeeNode.name == "alternative_cost_distribution" || employeeNode.name == "PaymentInformationV3"){ sortedStartDates.add(employeeNode?.getChildText("effectiveStartDate", employeeNode.getNamespace())); } else sortedStartDates.add(employeeNode?.getChildText("start_date", employeeNode.getNamespace())); } } int setLength = sortedStartDates.size(); int check = 0; logger.warning("sortedStartDates" +sortedStartDates); for (String snapShotDate:sortedStartDates) { check = check + 1; Document clonedDoc = doc.clone(); employeeNodes = xPathStartDate.selectNodes(clonedDoc); effEmployeeNodes = xPathEffectiveStartDate.selectNodes(clonedDoc); for(Element effEmployeeNode : effEmployeeNodes){ employeeNodes.add(effEmployeeNode); } List elementsToDelete = new ArrayList() //Create a new document to hold the data snapshot Element snapShotElement = new Element("snapshot"); person.addContent(snapShotElement); Element dateElement = new Element("asOfDate"); dateElement.setText(snapShotDate); snapShotElement.addContent(dateElement); currentDate = dateFormat.parse(snapShotDate); for (Element employeeNode : employeeNodes) { if (!employeeNode.getName().equals("employment_information")) { if(!employeeNode.getName().equals("deduction_recurring") && !employeeNode.getName().equals("alternative_cost_distribution") && !employeeNode.getName().equals("PaymentInformationV3")){ //don't check for effective dates in non-effective dated entities Date startDate = dateFormat.parse(employeeNode?.getChildText("start_date", employeeNode.getNamespace())) Date endDate = dateFormat.parse(employeeNode?.getChildText("end_date", employeeNode.getNamespace())) //Date outside current date range must be removed if ((currentDate < startDate || currentDate > endDate)) { elementsToDelete.add(employeeNode) } } else if(employeeNode.getName().equals("deduction_recurring") || employeeNode.getName().equals("alternative_cost_distribution") || employeeNode.getName().equals("PaymentInformationV3")){ Date startDate = dateFormat.parse(employeeNode?.getChildText("effectiveStartDate", employeeNode.getNamespace())) Date endDate = dateFormat.parse(employeeNode?.getChildText("effectiveEndDate", employeeNode.getNamespace())) //Date outside current date range must be removed if ( (currentDate < startDate || currentDate > endDate)) { elementsToDelete.add(employeeNode) } } } } // Remove node outside the current date range for (Element element : elementsToDelete) { element.getParent().removeContent(element); } for(Element child: xPathPersonChildren.selectNodes(clonedDoc)) { if (effectiveDatedNames.contains(child.getName())) snapShotElement.addContent(child.clone()); if (includeLatest.contains(child.getName()) && check == setLength) { person.addContent(child.clone()); } } } // When you're finished manipulating the XML data, you'll need to output the Document's data to an InputStream to pass to the next step in your Process work flow. os = new ByteArrayInputStream(xmlOutputter.outputString(newDoc).getBytes("UTF-8")); dataContext.storeStream(os, props); } //println xmlOutputter.outputString(newDoc); def boolean isEffectiveDatedEntity(Element employeeNode) { if(employeeNode.name == "deduction_recurring" || employeeNode.name == "alternative_cost_distribution" || employeeNode.name == "PaymentInformationV3") { return !(employeeNode.getChildText("effectiveStartDate", employeeNode.getNamespace())==null || employeeNode.getChildText("effectiveEndDate",employeeNode.getNamespace())==null); } else if(employeeNode.name != "deduction_recurring" && employeeNode.name != "alternative_cost_distribution" && employeeNode.name != "PaymentInformationV3"){ return !(employeeNode.getChildText("start_date", employeeNode.getNamespace())==null || employeeNode.getChildText("end_date",employeeNode.getNamespace())==null || employeeNode.name =="employment_information"); } }