001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036:
037: package com.sun.xml.ws.server.sei;
038:
039: import com.sun.xml.bind.api.Bridge;
040: import com.sun.xml.ws.api.message.Headers;
041: import com.sun.xml.ws.api.message.Message;
042: import com.sun.xml.ws.message.ByteArrayAttachment;
043: import com.sun.xml.ws.message.DataHandlerAttachment;
044: import com.sun.xml.ws.message.JAXBAttachment;
045: import com.sun.xml.ws.model.ParameterImpl;
046: import java.io.UnsupportedEncodingException;
047: import java.net.URLEncoder;
048: import java.util.UUID;
049: import javax.activation.DataHandler;
050: import javax.xml.transform.Source;
051: import javax.xml.ws.WebServiceException;
052: import com.sun.xml.ws.api.message.Attachment;
053:
054: /**
055: * Puts a non-payload message parameter to {@link Message}.
056: *
057: * <p>
058: * Instance of this class is used to handle header parameters and attachment parameters.
059: * They add things to {@link Message}.
060: *
061: * @author Kohsuke Kawaguchi
062: * @author Jitendra Kotamraju
063: */
064: abstract class MessageFiller {
065:
066: /**
067: * The index of the method invocation parameters that this object looks for.
068: */
069: protected final int methodPos;
070:
071: protected MessageFiller(int methodPos) {
072: this .methodPos = methodPos;
073: }
074:
075: /**
076: * Moves an argument of a method invocation into a {@link Message}.
077: */
078: abstract void fillIn(Object[] methodArgs, Object returnValue,
079: Message msg);
080:
081: /**
082: * Adds a parameter as an MIME attachment to {@link Message}.
083: */
084: static abstract class AttachmentFiller extends MessageFiller {
085: protected final ParameterImpl param;
086: protected final ValueGetter getter;
087: protected final String mimeType;
088: private final String contentIdPart;
089:
090: protected AttachmentFiller(ParameterImpl param,
091: ValueGetter getter) {
092: super (param.getIndex());
093: this .param = param;
094: this .getter = getter;
095: mimeType = param.getBinding().getMimeType();
096: try {
097: contentIdPart = URLEncoder.encode(param.getPartName(),
098: "UTF-8") + '=';
099: } catch (UnsupportedEncodingException e) {
100: throw new WebServiceException(e);
101: }
102: }
103:
104: /**
105: * Creates an MessageFiller based on the parameter type
106: *
107: * @param param
108: * runtime Parameter that abstracts the annotated java parameter
109: * @param getter
110: * Gets a value from an object that represents a parameter passed
111: * as a method argument.
112: */
113: public static MessageFiller createAttachmentFiller(
114: ParameterImpl param, ValueGetter getter) {
115: Class type = (Class) param.getTypeReference().type;
116: if (DataHandler.class.isAssignableFrom(type)
117: || Source.class.isAssignableFrom(type)) {
118: return new DataHandlerFiller(param, getter);
119: } else if (byte[].class == type) {
120: return new ByteArrayFiller(param, getter);
121: } else if (isXMLMimeType(param.getBinding().getMimeType())) {
122: return new JAXBFiller(param, getter);
123: } else {
124: return new DataHandlerFiller(param, getter);
125: }
126: }
127:
128: String getContentId() {
129: return contentIdPart + UUID.randomUUID() + "@jaxws.sun.com";
130: }
131: }
132:
133: private static class ByteArrayFiller extends AttachmentFiller {
134: protected ByteArrayFiller(ParameterImpl param,
135: ValueGetter getter) {
136: super (param, getter);
137: }
138:
139: void fillIn(Object[] methodArgs, Object returnValue, Message msg) {
140: String contentId = getContentId();
141: Object obj = (methodPos == -1) ? returnValue : getter
142: .get(methodArgs[methodPos]);
143: if (obj != null) {
144: Attachment att = new ByteArrayAttachment(contentId,
145: (byte[]) obj, mimeType);
146: msg.getAttachments().add(att);
147: }
148: }
149: }
150:
151: private static class DataHandlerFiller extends AttachmentFiller {
152: protected DataHandlerFiller(ParameterImpl param,
153: ValueGetter getter) {
154: super (param, getter);
155: }
156:
157: void fillIn(Object[] methodArgs, Object returnValue, Message msg) {
158: String contentId = getContentId();
159: Object obj = (methodPos == -1) ? returnValue : getter
160: .get(methodArgs[methodPos]);
161: DataHandler dh = (obj instanceof DataHandler) ? (DataHandler) obj
162: : new DataHandler(obj, mimeType);
163: Attachment att = new DataHandlerAttachment(contentId, dh);
164: msg.getAttachments().add(att);
165: }
166: }
167:
168: private static class JAXBFiller extends AttachmentFiller {
169: protected JAXBFiller(ParameterImpl param, ValueGetter getter) {
170: super (param, getter);
171: }
172:
173: void fillIn(Object[] methodArgs, Object returnValue, Message msg) {
174: String contentId = getContentId();
175: Object obj = (methodPos == -1) ? returnValue : getter
176: .get(methodArgs[methodPos]);
177: Attachment att = new JAXBAttachment(contentId, obj, param
178: .getBridge(), mimeType);
179: msg.getAttachments().add(att);
180: }
181: }
182:
183: /**
184: * Adds a parameter as an header.
185: */
186: static final class Header extends MessageFiller {
187: private final Bridge bridge;
188: private final ValueGetter getter;
189:
190: protected Header(int methodPos, Bridge bridge,
191: ValueGetter getter) {
192: super (methodPos);
193: this .bridge = bridge;
194: this .getter = getter;
195: }
196:
197: void fillIn(Object[] methodArgs, Object returnValue, Message msg) {
198: Object value = (methodPos == -1) ? returnValue : getter
199: .get(methodArgs[methodPos]);
200: msg.getHeaders().add(Headers.create(bridge, value));
201: }
202: }
203:
204: private static boolean isXMLMimeType(String mimeType) {
205: return mimeType.equals("text/xml")
206: || mimeType.equals("application/xml");
207: }
208: }
|