/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.xml.ws.server; import gw.internal.schema.gw.xsd.w3c.xop_include.Include; import gw.internal.xml.ws.http.fragment.HttpFieldValue; import gw.internal.xml.ws.http.fragment.HttpHeadersAndBody; import gw.internal.xml.ws.http.fragment.HttpMultipartRelatedContent; import gw.internal.xml.ws.http.fragment.HttpToken; import gw.util.Pair; import gw.xml.XmlElement; import gw.xml.XmlSimpleValue; import gw.xml.ws.WebServiceException; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; public class XopUtil { public static InputStream getInputStream( HttpMultipartRelatedContent content ) throws URISyntaxException { HttpHeadersAndBody rootPart = content.getRootPart(); XmlElement xml = XmlElement.parse( rootPart.getBody() ); substituteXopIncludes( xml, content ); ByteArrayOutputStream baos = new ByteArrayOutputStream(); xml.writeTo( baos ); return new ByteArrayInputStream( baos.toByteArray() ); } // recursively searches the specified XML for xop:include elements, and replaces them with the appropriate included content private static void substituteXopIncludes( XmlElement xml, HttpMultipartRelatedContent content ) throws URISyntaxException { List<XmlElement> children = new ArrayList<XmlElement>( xml.getChildren( Include.$QNAME ) ); // make safe copy of list since it gets modified during iteration for ( XmlElement xopInclude : children ) { URI contentIdUrl = new URI( xopInclude.getAttributeValue( "href" ) ); if ( ! contentIdUrl.getScheme().equals( "cid" ) ) { throw new WebServiceException( "Unexpected URI scheme, expected 'cid', but was '" + contentIdUrl.getScheme() + "': " + contentIdUrl ); } String contentId = contentIdUrl.getSchemeSpecificPart(); HttpHeadersAndBody foundPart = null; for ( HttpHeadersAndBody part : content.getParts() ) { for ( Pair<HttpToken, HttpFieldValue> pair : part.getHttpHeaders() ) { if ( pair.getFirst().getText().toLowerCase().equals( "content-id" ) ) { if ( pair.getSecond().getText().equals( "<" + contentId + ">" ) ) { foundPart = part; break; } } } } if ( foundPart == null ) { throw new WebServiceException( "XOP Include not found for content id " + contentId ); } xml.setSimpleValue( XmlSimpleValue.makeBase64BinaryInstance( foundPart.getBody() ) ); } for ( XmlElement child : xml.getChildren() ) { substituteXopIncludes( child, content ); } } }