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.server.sei; 27 28import com.sun.xml.internal.ws.api.message.Headers; 29import com.sun.xml.internal.ws.api.message.Message; 30import com.sun.xml.internal.ws.message.ByteArrayAttachment; 31import com.sun.xml.internal.ws.message.DataHandlerAttachment; 32import com.sun.xml.internal.ws.message.JAXBAttachment; 33import com.sun.xml.internal.ws.model.ParameterImpl; 34import com.sun.xml.internal.ws.spi.db.XMLBridge; 35 36import java.io.UnsupportedEncodingException; 37import java.net.URLEncoder; 38import java.util.UUID; 39import javax.activation.DataHandler; 40import javax.xml.transform.Source; 41import javax.xml.ws.WebServiceException; 42import com.sun.xml.internal.ws.api.message.Attachment; 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 * @author Kohsuke Kawaguchi 52 * @author Jitendra Kotamraju 53 */ 54public abstract class MessageFiller { 55 56 /** 57 * The index of the method invocation parameters that this object looks for. 58 */ 59 protected final int methodPos; 60 61 protected MessageFiller( int methodPos) { 62 this.methodPos = methodPos; 63 } 64 65 /** 66 * Moves an argument of a method invocation into a {@link Message}. 67 */ 68 public abstract void fillIn(Object[] methodArgs, Object returnValue, Message msg); 69 70 /** 71 * Adds a parameter as an MIME attachment to {@link Message}. 72 */ 73 public static abstract class AttachmentFiller extends MessageFiller { 74 protected final ParameterImpl param; 75 protected final ValueGetter getter; 76 protected final String mimeType; 77 private final String contentIdPart; 78 79 protected AttachmentFiller(ParameterImpl param, ValueGetter getter) { 80 super(param.getIndex()); 81 this.param = param; 82 this.getter = getter; 83 mimeType = param.getBinding().getMimeType(); 84 try { 85 contentIdPart = URLEncoder.encode(param.getPartName(), "UTF-8")+'='; 86 } catch (UnsupportedEncodingException e) { 87 throw new WebServiceException(e); 88 } 89 } 90 91 /** 92 * Creates an MessageFiller based on the parameter type 93 * 94 * @param param 95 * runtime Parameter that abstracts the annotated java parameter 96 * @param getter 97 * Gets a value from an object that represents a parameter passed 98 * as a method argument. 99 */ 100 public static MessageFiller createAttachmentFiller(ParameterImpl param, ValueGetter getter) { 101 Class type = (Class)param.getTypeInfo().type; 102 if (DataHandler.class.isAssignableFrom(type) || Source.class.isAssignableFrom(type)) { 103 return new DataHandlerFiller(param, getter); 104 } else if (byte[].class==type) { 105 return new ByteArrayFiller(param, getter); 106 } else if(isXMLMimeType(param.getBinding().getMimeType())) { 107 return new JAXBFiller(param, getter); 108 } else { 109 return new DataHandlerFiller(param, getter); 110 } 111 } 112 113 String getContentId() { 114 return contentIdPart+UUID.randomUUID()+"@jaxws.sun.com"; 115 } 116 } 117 118 private static class ByteArrayFiller extends AttachmentFiller { 119 protected ByteArrayFiller(ParameterImpl param, ValueGetter getter) { 120 super(param, getter); 121 } 122 123 public void fillIn(Object[] methodArgs, Object returnValue, Message msg) { 124 String contentId = getContentId(); 125 Object obj = (methodPos == -1) ? returnValue : getter.get(methodArgs[methodPos]); 126 if (obj != null) { 127 Attachment att = new ByteArrayAttachment(contentId,(byte[])obj,mimeType); 128 msg.getAttachments().add(att); 129 } 130 } 131 } 132 133 private static class DataHandlerFiller extends AttachmentFiller { 134 protected DataHandlerFiller(ParameterImpl param, ValueGetter getter) { 135 super(param, getter); 136 } 137 138 public void fillIn(Object[] methodArgs, Object returnValue, Message msg) { 139 String contentId = getContentId(); 140 Object obj = (methodPos == -1) ? returnValue : getter.get(methodArgs[methodPos]); 141 DataHandler dh = (obj instanceof DataHandler) ? (DataHandler)obj : new DataHandler(obj,mimeType); 142 Attachment att = new DataHandlerAttachment(contentId, dh); 143 msg.getAttachments().add(att); 144 } 145 } 146 147 private static class JAXBFiller extends AttachmentFiller { 148 protected JAXBFiller(ParameterImpl param, ValueGetter getter) { 149 super(param, getter); 150 } 151 152 public void fillIn(Object[] methodArgs, Object returnValue, Message msg) { 153 String contentId = getContentId(); 154 Object obj = (methodPos == -1) ? returnValue : getter.get(methodArgs[methodPos]); 155 Attachment att = new JAXBAttachment(contentId, obj, param.getXMLBridge(), mimeType); 156 msg.getAttachments().add(att); 157 } 158 } 159 160 /** 161 * Adds a parameter as an header. 162 */ 163 public static final class Header extends MessageFiller { 164 private final XMLBridge bridge; 165 private final ValueGetter getter; 166 167 public Header(int methodPos, XMLBridge bridge, ValueGetter getter) { 168 super(methodPos); 169 this.bridge = bridge; 170 this.getter = getter; 171 } 172 173 public void fillIn(Object[] methodArgs, Object returnValue, Message msg) { 174 Object value = (methodPos == -1) ? returnValue : getter.get(methodArgs[methodPos]); 175 msg.getHeaders().add(Headers.create(bridge,value)); 176 } 177 } 178 179 private static boolean isXMLMimeType(String mimeType){ 180 return mimeType.equals("text/xml") || mimeType.equals("application/xml"); 181 } 182} 183