View Javadoc
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  
26  package com.sun.xml.internal.ws.client.sei;
27  
28  import com.sun.xml.internal.ws.api.message.Attachment;
29  import com.sun.xml.internal.ws.api.message.Headers;
30  import com.sun.xml.internal.ws.api.message.Message;
31  import com.sun.xml.internal.ws.message.ByteArrayAttachment;
32  import com.sun.xml.internal.ws.message.DataHandlerAttachment;
33  import com.sun.xml.internal.ws.message.JAXBAttachment;
34  import com.sun.xml.internal.ws.model.ParameterImpl;
35  import com.sun.xml.internal.ws.spi.db.XMLBridge;
36  
37  import java.io.UnsupportedEncodingException;
38  import java.net.URLEncoder;
39  import java.util.UUID;
40  import javax.activation.DataHandler;
41  import javax.xml.transform.Source;
42  import 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   */
55  abstract 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 }