001: /*
002: * The contents of this file are subject to the terms
003: * of the Common Development and Distribution License
004: * (the "License"). You may not use this file except
005: * in compliance with the License.
006: *
007: * You can obtain a copy of the license at
008: * https://jwsdp.dev.java.net/CDDLv1.0.html
009: * See the License for the specific language governing
010: * permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL
013: * HEADER in each file and include the License file at
014: * https://jwsdp.dev.java.net/CDDLv1.0.html If applicable,
015: * add the following below this CDDL HEADER, with the
016: * fields enclosed by brackets "[]" replaced with your
017: * own identifying information: Portions Copyright [yyyy]
018: * [name of copyright owner]
019: */
020:
021: package src.com.sun.xml.xwss;
022:
023: import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
024: import com.sun.org.apache.xml.internal.security.utils.Base64;
025: import java.io.ByteArrayInputStream;
026: import java.io.ByteArrayOutputStream;
027: import java.io.InputStream;
028: import java.io.OutputStream;
029: import java.io.UnsupportedEncodingException;
030: import java.util.Random;
031: import java.util.Iterator;
032: import java.util.List;
033: import java.util.ArrayList;
034: import java.net.URLDecoder;
035: import javax.xml.XMLConstants;
036: import javax.xml.soap.AttachmentPart;
037: import javax.xml.soap.SOAPElement;
038: import javax.xml.soap.SOAPException;
039: import javax.xml.soap.SOAPMessage;
040: import javax.xml.soap.SOAPBody;
041: import javax.xml.soap.SOAPPart;
042:
043: import com.sun.xml.wss.impl.MessageConstants;
044: import org.w3c.dom.Document;
045: import org.w3c.dom.Element;
046: import org.w3c.dom.Node;
047: import org.w3c.dom.NodeList;
048: import org.w3c.dom.Text;
049:
050: /**
051: *
052: * @author K.Venugopal@sun.com
053: */
054: public class XOPProcessor {
055: private static String XOP_NS = "http://www.w3.org/2004/08/xop/include";
056: private static String XOP_INCLUDE = "Include";
057:
058: private static final List xopNodes = new ArrayList();
059:
060: private static void getXOPIncludeNode(Node node) {
061: NodeList nl = node.getChildNodes();
062: for (int i = 0; i < nl.getLength(); i++) {
063: Node n = nl.item(i);
064: //why its null?
065: if (n == null || (n.getLocalName() == null)
066: || (n.getNamespaceURI() == null))
067: continue;
068: if (n.getLocalName().equals(XOP_INCLUDE)
069: && n.getNamespaceURI().equals(XOP_NS)) {
070: xopNodes.add(n);
071: }
072: getXOPIncludeNode(n);
073: }
074: }
075:
076: public static void unmarshal(SOAPMessage soapMsg)
077: throws SOAPException {
078: try {
079: //System.out.println("++++++++++++++++++++Before unMarshal of XOP +++++++++++++++++++++++++++");
080: // soapMsg.writeTo(System.out);
081: } catch (Exception ex) {
082: ex.printStackTrace();
083: }
084:
085: getXOPIncludeNode(soapMsg.getSOAPPart().getEnvelope());
086:
087: for (Node n : xopNodes) {
088: replaceXOPContent((SOAPElement) n, soapMsg);
089: }
090: //NodeList bodyList = soapMsg.getSOAPPart().getElementsByTagNameNS(XOP_NS,XOP_INCLUDE);
091: // for (int i =0;i< bodyList.getLength();i++){
092: // replaceXOPContent((SOAPElement)bodyList.item(i),soapMsg);
093: // }
094:
095: /* if(secHeader != null){
096:
097: NodeList xopElement = secHeader.getElementsByTagNameNS(XOP_NS,XOP_INCLUDE);
098: for (int i =0;i< xopElement.getLength(); i++){
099: SOAPElement xe = (SOAPElement)xopElement.item(i);
100: replaceXOPContent(xe,soapMsg);
101: }
102: }
103: NodeList bodyList = soapMsg.getSOAPBody().getElementsByTagNameNS(MessageConstants.XENC_NS,MessageConstants.ENCRYPTED_DATA_LNAME);
104: for (int i =0;i< bodyList.getLength();i++){
105: SOAPElement xe = (SOAPElement)bodyList.item(i);
106: NodeList xeList = xe.getElementsByTagNameNS(XOP_NS,XOP_INCLUDE);
107: for (int j =0;j< xeList.getLength();j++){
108: replaceXOPContent((SOAPElement)xeList.item(j),soapMsg);
109: }
110: }
111: */
112: // soapMsg.getAttachment()
113: try {
114: //System.out.println("++++++++++++++++++++After unMarshal of XOP +++++++++++++++++++++++++++");
115: // soapMsg.writeTo(System.out);
116: } catch (Exception ex) {
117: ex.printStackTrace();
118: }
119: }
120:
121: private static void replaceXOPContent(SOAPElement xe,
122: SOAPMessage soapMsg) throws SOAPException {
123: String ref = xe.getAttribute("href");
124: if (ref == null)
125: return;//error
126:
127: AttachmentPart ap = getXOPAttachment(soapMsg, ref);
128: if (ap == null) {
129: //TODO: throw exception, unresolved xop reference
130: return;
131: }
132: // AttachmentPart ap =soapMsg.getAttachment(xe);
133: String data = getXOPContent(ap);
134: SOAPElement xeParent = xe.getParentElement();
135: Text text = xeParent.getOwnerDocument().createTextNode(data);
136: xeParent.replaceChild(text, xe);
137: //TODO :: Remove the Attachment.
138: }
139:
140: private static AttachmentPart getXOPAttachment(SOAPMessage sm,
141: String ref) {
142: ref = decodeCid(ref);
143: Iterator iter = sm.getAttachments();
144: while (iter.hasNext()) {
145: AttachmentPart ap = (AttachmentPart) iter.next();
146: if (ap.getContentId().equals(ref)) {
147: return ap;
148: }
149: }
150: return null;
151: }
152:
153: private static String decodeCid(String cid) {
154: if (cid.startsWith("cid:"))
155: cid = cid.substring(4, cid.length());
156: try {
157: return "<" + URLDecoder.decode(cid, "UTF-8") + ">";
158: } catch (UnsupportedEncodingException e) {
159: //TODO: throw exception
160: return null;
161: }
162: }
163:
164: private static String getXOPContent(AttachmentPart ap)
165: throws SOAPException {
166: byte[] data = ap.getRawContentBytes();
167: try {
168: String str = new String(data, "utf-8");
169:
170: } catch (UnsupportedEncodingException e) {
171: e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
172: }
173: return Base64.encode(data);
174: }
175:
176: public static void marshal(SOAPMessage soapMsg)
177: throws SOAPException {
178: NodeList bodyList = soapMsg.getSOAPPart()
179: .getElementsByTagNameNS(MessageConstants.XENC_NS,
180: MessageConstants.ENCRYPTED_DATA_LNAME);
181:
182: for (int i = 0; i < bodyList.getLength(); i++) {
183: SOAPElement xe = (SOAPElement) bodyList.item(i);
184: replaceBase64Data(xe, soapMsg);
185: }
186:
187: NodeList secTokenList = soapMsg
188: .getSOAPPart()
189: .getElementsByTagNameNS(
190: MessageConstants.WSSE_NS,
191: MessageConstants.WSSE_BINARY_SECURITY_TOKEN_LNAME);
192: for (int i = 0; i < secTokenList.getLength(); i++) {
193: SOAPElement xe = (SOAPElement) secTokenList.item(i);
194: replaceBase64Data(xe, soapMsg);
195: }
196: System.out.println("DONE replacing BinaryData");
197: try {
198: // soapMsg.writeTo(System.out);
199: } catch (Exception ex) {
200: ex.printStackTrace();
201: }
202: }
203:
204: private static void replaceBase64Data(SOAPElement sOAPElement,
205: SOAPMessage sOAPMessage) {
206: long id = new Random().nextLong();
207: Node childNode = sOAPElement.getFirstChild();
208: if (childNode.getNodeType() == Node.TEXT_NODE) {
209: AttachmentPart ap = sOAPMessage.createAttachmentPart();
210: String b64Data = childNode.getTextContent();
211: byte[] decodedData;
212: try {
213: decodedData = Base64.decode(b64Data);
214: ap.setDataHandler(new MTOMDataHandler(
215: new XOPDataSource(decodedData)));
216: sOAPMessage.addAttachmentPart(ap);
217: String cid = Long.toString(id);
218: ap.setContentId("<" + cid + ">");
219: ap.setMimeHeader("Content-transfer-encoding", "binary");
220: Document doc = sOAPElement.getOwnerDocument();
221: Element xe = doc.createElementNS(
222: "http://www.w3.org/2004/08/xop/include",
223: "xop:Include");
224: xe.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
225: "xmlns:xop",
226: "http://www.w3.org/2004/08/xop/include");
227: xe.setAttribute("href", "cid:" + cid);
228: sOAPElement.replaceChild(xe, childNode);
229: } catch (Base64DecodingException ex) {
230: ex.printStackTrace();
231: }
232: }
233: }
234:
235: private static class XOPDataSource implements
236: javax.activation.DataSource {
237: byte[] binaryData;
238:
239: XOPDataSource(byte[] data) {
240: binaryData = data;
241: }
242:
243: public String getContentType() {
244: return "application/octect-stream";
245: }
246:
247: public InputStream getInputStream() throws java.io.IOException {
248: return new ByteArrayInputStream(binaryData);
249: }
250:
251: public String getName() {
252: return "MTOM DataSource";
253: }
254:
255: public OutputStream getOutputStream()
256: throws java.io.IOException {
257: ByteArrayOutputStream baos = new ByteArrayOutputStream();
258: baos.write(binaryData, 0, binaryData.length);
259: return baos;
260: }
261: }
262:
263: private static class MTOMDataHandler extends
264: javax.activation.DataHandler {
265: MTOMDataHandler(javax.activation.DataSource ds) {
266: super (ds);
267: }
268:
269: public void writeTo(OutputStream os) throws java.io.IOException {
270: ((ByteArrayOutputStream) getDataSource().getOutputStream())
271: .writeTo(os);
272: }
273: }
274: }
|