1/* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.xml.internal.ws.client.sei; 27 28import com.sun.xml.internal.ws.api.message.Attachment; 29import com.sun.xml.internal.ws.api.message.Headers; 30import com.sun.xml.internal.ws.api.message.Message; 31import com.sun.xml.internal.ws.message.ByteArrayAttachment; 32import com.sun.xml.internal.ws.message.DataHandlerAttachment; 33import com.sun.xml.internal.ws.message.JAXBAttachment; 34import com.sun.xml.internal.ws.model.ParameterImpl; 35import com.sun.xml.internal.ws.spi.db.XMLBridge; 36 37import java.io.UnsupportedEncodingException; 38import java.net.URLEncoder; 39import java.util.UUID; 40import javax.activation.DataHandler; 41import javax.xml.transform.Source; 42import javax.xml.ws.WebServiceException; 43 44/** 45 * Puts a non-payload message parameter to {@link Message}. 46 * 47 * <p> 48 * Instance of this class is used to handle header parameters and attachment parameters. 49 * They add things to {@link Message}. 50 * 51 * @see BodyBuilder 52 * @author Kohsuke Kawaguchi 53 * @author Jitendra Kotamraju 54 */ 55abstract class MessageFiller { 56 57 /** 58 * The index of the method invocation parameters that this object looks for. 59 */ 60 protected final int methodPos; 61 62 protected MessageFiller( int methodPos) { 63 this.methodPos = methodPos; 64 } 65 66 /** 67 * Moves an argument of a method invocation into a {@link Message}. 68 */ 69 abstract void fillIn(Object[] methodArgs, Message msg); 70 71 /** 72 * Adds a parameter as an MIME attachment to {@link Message}. 73 */ 74 static abstract class AttachmentFiller extends MessageFiller { 75 protected final ParameterImpl param; 76 protected final ValueGetter getter; 77 protected final String mimeType; 78 private final String contentIdPart; 79 80 protected AttachmentFiller(ParameterImpl param, ValueGetter getter) { 81 super(param.getIndex()); 82 this.param = param; 83 this.getter = getter; 84 mimeType = param.getBinding().getMimeType(); 85 try { 86 contentIdPart = URLEncoder.encode(param.getPartName(), "UTF-8")+'='; 87 } catch (UnsupportedEncodingException e) { 88 throw new WebServiceException(e); 89 } 90 } 91 92 /** 93 * Creates an MessageFiller based on the parameter type 94 * 95 * @param param 96 * runtime Parameter that abstracts the annotated java parameter 97 * @param getter 98 * Gets a value from an object that represents a parameter passed 99 * as a method argument. 100 */ 101 public static MessageFiller createAttachmentFiller(ParameterImpl param, ValueGetter getter) { 102 Class type = (Class)param.getTypeInfo().type; 103 if (DataHandler.class.isAssignableFrom(type) || Source.class.isAssignableFrom(type)) { 104 return new DataHandlerFiller(param, getter); 105 } else if (byte[].class==type) { 106 return new ByteArrayFiller(param, getter); 107 } else if(isXMLMimeType(param.getBinding().getMimeType())) { 108 return new JAXBFiller(param, getter); 109 } else { 110 return new DataHandlerFiller(param, getter); 111 } 112 } 113 114 String getContentId() { 115 return contentIdPart+UUID.randomUUID()+"@jaxws.sun.com"; 116 } 117 } 118 119 private static class ByteArrayFiller extends AttachmentFiller { 120 protected ByteArrayFiller(ParameterImpl param, ValueGetter getter) { 121 super(param, getter); 122 } 123 void fillIn(Object[] methodArgs, Message msg) { 124 String contentId = getContentId(); 125 Object obj = getter.get(methodArgs[methodPos]); 126 Attachment att = new ByteArrayAttachment(contentId,(byte[])obj,mimeType); 127 msg.getAttachments().add(att); 128 } 129 } 130 131 private static class DataHandlerFiller extends AttachmentFiller { 132 protected DataHandlerFiller(ParameterImpl param, ValueGetter getter) { 133 super(param, getter); 134 } 135 void fillIn(Object[] methodArgs, Message msg) { 136 String contentId = getContentId(); 137 Object obj = getter.get(methodArgs[methodPos]); 138 DataHandler dh = (obj instanceof DataHandler) ? (DataHandler)obj : new DataHandler(obj,mimeType); 139 Attachment att = new DataHandlerAttachment(contentId, dh); 140 msg.getAttachments().add(att); 141 } 142 } 143 144 private static class JAXBFiller extends AttachmentFiller { 145 protected JAXBFiller(ParameterImpl param, ValueGetter getter) { 146 super(param, getter); 147 } 148 void fillIn(Object[] methodArgs, Message msg) { 149 String contentId = getContentId(); 150 Object obj = getter.get(methodArgs[methodPos]); 151 Attachment att = new JAXBAttachment(contentId, obj, param.getXMLBridge(), mimeType); 152 msg.getAttachments().add(att); 153 } 154 } 155 156 /** 157 * Adds a parameter as an header. 158 */ 159 static final class Header extends MessageFiller { 160 private final XMLBridge bridge; 161 private final ValueGetter getter; 162 163 protected Header(int methodPos, XMLBridge bridge, ValueGetter getter) { 164 super(methodPos); 165 this.bridge = bridge; 166 this.getter = getter; 167 } 168 169 void fillIn(Object[] methodArgs, Message msg) { 170 Object value = getter.get(methodArgs[methodPos]); 171 msg.getHeaders().add(Headers.create(bridge,value)); 172 } 173 } 174 175 private static boolean isXMLMimeType(String mimeType){ 176 return (mimeType.equals("text/xml") || mimeType.equals("application/xml")); 177 } 178 179} 180