/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.module.purap.util.cxml; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.log4j.Logger; import org.apache.xml.serialize.OutputFormat; import org.apache.xml.serialize.XMLSerializer; import org.kuali.kfs.sys.batch.service.BatchInputFileService; import org.kuali.kfs.sys.context.SpringContext; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; public class B2BParserHelper { private static Logger log = Logger.getLogger(B2BParserHelper.class); private DocumentBuilder builder; private static B2BParserHelper _this; private B2BParserHelper(){ DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); builderFactory.setValidating(false); // It's not needed to validate here builderFactory.setIgnoringElementContentWhitespace(true); try { // This is a funky one. Without setting this "load-external-dtd" feature, even though we're // explicitly setting non-validating, the parser will still reach out and retrieve that DTD. If // the xml.cxml.org site happens to be down, it'll hang or fail on that dependency. // // http://xerces.apache.org/xerces2-j/features.html#nonvalidating.load-external-dtd builderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); builder = builderFactory.newDocumentBuilder(); // Create the parser } catch(ParserConfigurationException e) { throw new RuntimeException(e); } } public static B2BParserHelper getInstance(){ if (_this == null){ _this = new B2BParserHelper(); } return _this; } public synchronized B2BShoppingCart parseShoppingCartXML(String xmlChunk){ Document xmlDoc = null; try { xmlDoc = builder.parse(new ByteArrayInputStream(xmlChunk.getBytes())); } catch(Exception e) { e.printStackTrace(); throw new RuntimeException(e); } byte[] xmlDocAsBytes = addXMLNameSpace(xmlDoc,"http://www.kuali.org/kfs/purap/b2bPunchOutOrder"); B2BPunchOutOrderFileType fileType = SpringContext.getBean(B2BPunchOutOrderFileType.class); B2BShoppingCart cart = (B2BShoppingCart) SpringContext.getBean(BatchInputFileService.class).parse(fileType,xmlDocAsBytes); return cart; } public synchronized PunchOutSetupResponse parsePunchOutSetupResponse(String xmlChunk){ Document xmlDoc = null; try { xmlDoc = builder.parse(new ByteArrayInputStream(xmlChunk.getBytes())); } catch(Exception e) { e.printStackTrace(); throw new RuntimeException(e); } byte[] xmlDocAsBytes = addXMLNameSpace(xmlDoc,"http://www.kuali.org/kfs/purap/b2bPunchOutResponse"); PunchOutSetupResponseFileType fileType = SpringContext.getBean(PunchOutSetupResponseFileType.class); PunchOutSetupResponse response = (PunchOutSetupResponse) SpringContext.getBean(BatchInputFileService.class).parse(fileType,xmlDocAsBytes); return response; } public synchronized PurchaseOrderResponse parsePurchaseOrderResponse(String xmlChunk){ Document xmlDoc = null; try { xmlDoc = builder.parse(new ByteArrayInputStream(xmlChunk.getBytes())); } catch(Exception e) { e.printStackTrace(); throw new RuntimeException(e); } byte[] xmlDocAsBytes = addXMLNameSpace(xmlDoc,"http://www.kuali.org/kfs/purap/b2bPOResponse"); B2BPOResponseFileType fileType = SpringContext.getBean(B2BPOResponseFileType.class); PurchaseOrderResponse response = (PurchaseOrderResponse) SpringContext.getBean(BatchInputFileService.class).parse(fileType,xmlDocAsBytes); return response; } private byte[] addXMLNameSpace(Document xmlDoc, String nameSpace){ Node node = xmlDoc.getDocumentElement(); Element element = (Element)node; element.setAttribute("xmlns", nameSpace); OutputFormat outputFormat = new OutputFormat(xmlDoc); outputFormat.setOmitDocumentType(true); ByteArrayOutputStream out = new ByteArrayOutputStream(); XMLSerializer serializer = new XMLSerializer( out,outputFormat ); try { serializer.asDOMSerializer(); serializer.serialize( xmlDoc.getDocumentElement()); } catch (IOException e) { throw new RuntimeException(e); } return out.toByteArray(); } }