feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
137
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/ContentType.java
Normal file
137
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/ContentType.java
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @(#)ContentType.java 1.7 02/03/27
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import javax.xml.ws.WebServiceException;
|
||||
|
||||
/**
|
||||
* This class represents a MIME ContentType value. It provides
|
||||
* methods to parse a ContentType string into individual components
|
||||
* and to generate a MIME style ContentType string.
|
||||
*
|
||||
* @version 1.7, 02/03/27
|
||||
* @author John Mani
|
||||
*/
|
||||
public final class ContentType {
|
||||
|
||||
private String primaryType; // primary type
|
||||
private String subType; // subtype
|
||||
private ParameterList list; // parameter list
|
||||
|
||||
/**
|
||||
* Constructor that takes a Content-Type string. The String
|
||||
* is parsed into its constituents: primaryType, subType
|
||||
* and parameters. A ParseException is thrown if the parse fails.
|
||||
*
|
||||
* @param s the Content-Type string.
|
||||
* @exception WebServiceException if the parse fails.
|
||||
*/
|
||||
public ContentType(String s) throws WebServiceException {
|
||||
HeaderTokenizer h = new HeaderTokenizer(s, HeaderTokenizer.MIME);
|
||||
HeaderTokenizer.Token tk;
|
||||
|
||||
// First "type" ..
|
||||
tk = h.next();
|
||||
if (tk.getType() != HeaderTokenizer.Token.ATOM)
|
||||
throw new WebServiceException();
|
||||
primaryType = tk.getValue();
|
||||
|
||||
// The '/' separator ..
|
||||
tk = h.next();
|
||||
if ((char)tk.getType() != '/')
|
||||
throw new WebServiceException();
|
||||
|
||||
// Then "subType" ..
|
||||
tk = h.next();
|
||||
if (tk.getType() != HeaderTokenizer.Token.ATOM)
|
||||
throw new WebServiceException();
|
||||
subType = tk.getValue();
|
||||
|
||||
// Finally parameters ..
|
||||
String rem = h.getRemainder();
|
||||
if (rem != null)
|
||||
list = new ParameterList(rem);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the primary type.
|
||||
* @return the primary type
|
||||
*/
|
||||
public String getPrimaryType() {
|
||||
return primaryType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the subType.
|
||||
* @return the subType
|
||||
*/
|
||||
public String getSubType() {
|
||||
return subType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the MIME type string, without the parameters.
|
||||
* The returned value is basically the concatenation of
|
||||
* the primaryType, the '/' character and the secondaryType.
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public String getBaseType() {
|
||||
return primaryType + '/' + subType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the specified parameter value. Returns <code>null</code>
|
||||
* if this parameter is absent.
|
||||
*
|
||||
* @param name parameter name
|
||||
* @return parameter value
|
||||
*/
|
||||
public String getParameter(String name) {
|
||||
if (list == null)
|
||||
return null;
|
||||
|
||||
return list.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a ParameterList object that holds all the available
|
||||
* parameters. Returns null if no parameters are available.
|
||||
*
|
||||
* @return ParameterList
|
||||
*/
|
||||
public ParameterList getParameterList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import com.sun.istack.internal.NotNull;
|
||||
|
||||
/**
|
||||
* @author Vivek Pandey
|
||||
*/
|
||||
public final class ContentTypeImpl implements com.sun.xml.internal.ws.api.pipe.ContentType {
|
||||
private final @NotNull String contentType;
|
||||
private final @NotNull String soapAction;
|
||||
private String accept;
|
||||
private final @Nullable String charset;
|
||||
private String boundary;
|
||||
private String boundaryParameter;
|
||||
private String rootId;
|
||||
private ContentType internalContentType;
|
||||
|
||||
public ContentTypeImpl(String contentType) {
|
||||
this(contentType, null, null);
|
||||
}
|
||||
|
||||
public ContentTypeImpl(String contentType, @Nullable String soapAction) {
|
||||
this(contentType, soapAction, null);
|
||||
}
|
||||
|
||||
public ContentTypeImpl(String contentType, @Nullable String soapAction, @Nullable String accept) {
|
||||
this(contentType, soapAction, accept, null);
|
||||
}
|
||||
|
||||
public ContentTypeImpl(String contentType, @Nullable String soapAction, @Nullable String accept, String charsetParam) {
|
||||
this.contentType = contentType;
|
||||
this.accept = accept;
|
||||
this.soapAction = getQuotedSOAPAction(soapAction);
|
||||
if (charsetParam == null) {
|
||||
String tmpCharset = null;
|
||||
try {
|
||||
internalContentType = new ContentType(contentType);
|
||||
tmpCharset = internalContentType.getParameter("charset");
|
||||
} catch(Exception e) {
|
||||
//Ignore the parsing exception.
|
||||
}
|
||||
charset = tmpCharset;
|
||||
} else {
|
||||
charset = charsetParam;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the character set encoding.
|
||||
*
|
||||
* @return returns the character set encoding.
|
||||
*/
|
||||
public @Nullable String getCharSet() {
|
||||
return charset;
|
||||
}
|
||||
|
||||
/** BP 1.1 R1109 requires SOAPAction too be a quoted value **/
|
||||
private String getQuotedSOAPAction(String soapAction){
|
||||
if(soapAction == null || soapAction.length() == 0){
|
||||
return "\"\"";
|
||||
}else if(soapAction.charAt(0) != '"' && soapAction.charAt(soapAction.length() -1) != '"'){
|
||||
//surround soapAction by double quotes for BP R1109
|
||||
return "\"" + soapAction + "\"";
|
||||
}else{
|
||||
return soapAction;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSOAPActionHeader() {
|
||||
return soapAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAcceptHeader() {
|
||||
return accept;
|
||||
}
|
||||
|
||||
public void setAcceptHeader(String accept) {
|
||||
this.accept = accept;
|
||||
}
|
||||
|
||||
public String getBoundary() {
|
||||
if (boundary == null) {
|
||||
if (internalContentType == null) internalContentType = new ContentType(contentType);
|
||||
boundary = internalContentType.getParameter("boundary");
|
||||
}
|
||||
return boundary;
|
||||
}
|
||||
|
||||
public void setBoundary(String boundary) {
|
||||
this.boundary = boundary;
|
||||
}
|
||||
|
||||
public String getBoundaryParameter() {
|
||||
return boundaryParameter;
|
||||
}
|
||||
|
||||
public void setBoundaryParameter(String boundaryParameter) {
|
||||
this.boundaryParameter = boundaryParameter;
|
||||
}
|
||||
|
||||
public String getRootId() {
|
||||
if (rootId == null) {
|
||||
if (internalContentType == null) internalContentType = new ContentType(contentType);
|
||||
rootId = internalContentType.getParameter("start");
|
||||
}
|
||||
return rootId;
|
||||
}
|
||||
|
||||
public void setRootId(String rootId) {
|
||||
this.rootId = rootId;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
public String contentType;
|
||||
public String soapAction;
|
||||
public String accept;
|
||||
public String charset;
|
||||
public ContentTypeImpl build() {
|
||||
return new ContentTypeImpl(contentType, soapAction, accept, charset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import javax.activation.DataSource;
|
||||
import javax.activation.DataHandler;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* {@link DataSource} impl using a DataHandler
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public class DataHandlerDataSource implements DataSource {
|
||||
private final DataHandler dataHandler;
|
||||
|
||||
public DataHandlerDataSource(DataHandler dh) {
|
||||
this.dataHandler = dh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>InputStream</code> representing this object.
|
||||
*
|
||||
* @return the <code>InputStream</code>
|
||||
*/
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return dataHandler.getInputStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>OutputStream</code> for this object.
|
||||
*
|
||||
* @return the <code>OutputStream</code>
|
||||
*/
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
return dataHandler.getOutputStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MIME type of the data represented by this object.
|
||||
*
|
||||
* @return the MIME type
|
||||
*/
|
||||
public String getContentType() {
|
||||
return dataHandler.getContentType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this object.
|
||||
*
|
||||
* @return the name of this object
|
||||
*/
|
||||
public String getName() {
|
||||
return dataHandler.getName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import javax.activation.DataSource;
|
||||
import java.io.*;
|
||||
|
||||
import com.sun.xml.internal.ws.developer.StreamingDataHandler;
|
||||
|
||||
/**
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public class DataSourceStreamingDataHandler extends StreamingDataHandler {
|
||||
|
||||
public DataSourceStreamingDataHandler(DataSource ds) {
|
||||
super(ds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream readOnce() throws IOException {
|
||||
return getInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveTo(File file) throws IOException {
|
||||
InputStream in = getInputStream();
|
||||
OutputStream os = new FileOutputStream(file);
|
||||
try {
|
||||
byte[] temp = new byte[8192];
|
||||
int len;
|
||||
while((len=in.read(temp)) != -1) {
|
||||
os.write(temp, 0, len);
|
||||
}
|
||||
in.close();
|
||||
} finally {
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
/**
|
||||
* A {@link javax.xml.stream.XMLStreamWriter} doesn't expose any method to
|
||||
* give encoding. An implementation of writer may implement
|
||||
* this interface to give the encoding with which the writer is created.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
* @since JAX-WS RI 2.2.6
|
||||
*/
|
||||
public interface HasEncoding {
|
||||
public String getEncoding();
|
||||
}
|
||||
@@ -0,0 +1,377 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import javax.xml.ws.WebServiceException;
|
||||
|
||||
/**
|
||||
* This class tokenizes RFC822 and MIME headers into the basic
|
||||
* symbols specified by RFC822 and MIME. <p>
|
||||
*
|
||||
* This class handles folded headers (ie headers with embedded
|
||||
* CRLF SPACE sequences). The folds are removed in the returned
|
||||
* tokens.
|
||||
*
|
||||
* @version 1.9, 02/03/27
|
||||
* @author John Mani
|
||||
*/
|
||||
|
||||
class HeaderTokenizer {
|
||||
|
||||
/**
|
||||
* The Token class represents tokens returned by the
|
||||
* HeaderTokenizer.
|
||||
*/
|
||||
static class Token {
|
||||
|
||||
private int type;
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* Token type indicating an ATOM.
|
||||
*/
|
||||
public static final int ATOM = -1;
|
||||
|
||||
/**
|
||||
* Token type indicating a quoted string. The value
|
||||
* field contains the string without the quotes.
|
||||
*/
|
||||
public static final int QUOTEDSTRING = -2;
|
||||
|
||||
/**
|
||||
* Token type indicating a comment. The value field
|
||||
* contains the comment string without the comment
|
||||
* start and end symbols.
|
||||
*/
|
||||
public static final int COMMENT = -3;
|
||||
|
||||
/**
|
||||
* Token type indicating end of input.
|
||||
*/
|
||||
public static final int EOF = -4;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param type Token type
|
||||
* @param value Token value
|
||||
*/
|
||||
public Token(int type, String value) {
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the token. If the token represents a
|
||||
* delimiter or a control character, the type is that character
|
||||
* itself, converted to an integer. Otherwise, it's value is
|
||||
* one of the following:
|
||||
* <ul>
|
||||
* <li><code>ATOM</code> A sequence of ASCII characters
|
||||
* delimited by either SPACE, CTL, "(", <"> or the
|
||||
* specified SPECIALS
|
||||
* <li><code>QUOTEDSTRING</code> A sequence of ASCII characters
|
||||
* within quotes
|
||||
* <li><code>COMMENT</code> A sequence of ASCII characters
|
||||
* within "(" and ")".
|
||||
* <li><code>EOF</code> End of header
|
||||
* </ul>
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the token just read. When the current
|
||||
* token is a quoted string, this field contains the body of the
|
||||
* string, without the quotes. When the current token is a comment,
|
||||
* this field contains the body of the comment.
|
||||
*
|
||||
* @return token value
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private String string; // the string to be tokenized
|
||||
private boolean skipComments; // should comments be skipped ?
|
||||
private String delimiters; // delimiter string
|
||||
private int currentPos; // current parse position
|
||||
private int maxPos; // string length
|
||||
private int nextPos; // track start of next Token for next()
|
||||
private int peekPos; // track start of next Token for peek()
|
||||
|
||||
/**
|
||||
* RFC822 specials
|
||||
*/
|
||||
private final static String RFC822 = "()<>@,;:\\\"\t .[]";
|
||||
|
||||
/**
|
||||
* MIME specials
|
||||
*/
|
||||
final static String MIME = "()<>@,;:\\\"\t []/?=";
|
||||
|
||||
// The EOF Token
|
||||
private final static Token EOFToken = new Token(Token.EOF, null);
|
||||
|
||||
/**
|
||||
* Constructor that takes a rfc822 style header.
|
||||
*
|
||||
* @param header The rfc822 header to be tokenized
|
||||
* @param delimiters Set of delimiter characters
|
||||
* to be used to delimit ATOMS. These
|
||||
* are usually <code>RFC822</code> or
|
||||
* <code>MIME</code>
|
||||
* @param skipComments If true, comments are skipped and
|
||||
* not returned as tokens
|
||||
*/
|
||||
HeaderTokenizer(String header, String delimiters,
|
||||
boolean skipComments) {
|
||||
string = (header == null) ? "" : header; // paranoia ?!
|
||||
this.skipComments = skipComments;
|
||||
this.delimiters = delimiters;
|
||||
currentPos = nextPos = peekPos = 0;
|
||||
maxPos = string.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Comments are ignored and not returned as tokens
|
||||
*
|
||||
* @param header The header that is tokenized
|
||||
* @param delimiters The delimiters to be used
|
||||
*/
|
||||
HeaderTokenizer(String header, String delimiters) {
|
||||
this(header, delimiters, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. The RFC822 defined delimiters - RFC822 - are
|
||||
* used to delimit ATOMS. Also comments are skipped and not
|
||||
* returned as tokens
|
||||
*/
|
||||
HeaderTokenizer(String header) {
|
||||
this(header, RFC822);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the next token from this String. <p>
|
||||
*
|
||||
* Clients sit in a loop calling next() to parse successive
|
||||
* tokens until an EOF Token is returned.
|
||||
*
|
||||
* @return the next Token
|
||||
* @exception WebServiceException if the parse fails
|
||||
*/
|
||||
Token next() throws WebServiceException {
|
||||
Token tk;
|
||||
|
||||
currentPos = nextPos; // setup currentPos
|
||||
tk = getNext();
|
||||
nextPos = peekPos = currentPos; // update currentPos and peekPos
|
||||
return tk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Peek at the next token, without actually removing the token
|
||||
* from the parse stream. Invoking this method multiple times
|
||||
* will return successive tokens, until <code>next()</code> is
|
||||
* called. <p>
|
||||
*
|
||||
* @return the next Token
|
||||
* @exception WebServiceException if the parse fails
|
||||
*/
|
||||
Token peek() throws WebServiceException {
|
||||
Token tk;
|
||||
|
||||
currentPos = peekPos; // setup currentPos
|
||||
tk = getNext();
|
||||
peekPos = currentPos; // update peekPos
|
||||
return tk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the rest of the Header.
|
||||
*
|
||||
* @return String rest of header. null is returned if we are
|
||||
* already at end of header
|
||||
*/
|
||||
String getRemainder() {
|
||||
return string.substring(nextPos);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the next token starting from 'currentPos'. After the
|
||||
* parse, 'currentPos' is updated to point to the start of the
|
||||
* next token.
|
||||
*/
|
||||
private Token getNext() throws WebServiceException {
|
||||
// If we're already at end of string, return EOF
|
||||
if (currentPos >= maxPos)
|
||||
return EOFToken;
|
||||
|
||||
// Skip white-space, position currentPos beyond the space
|
||||
if (skipWhiteSpace() == Token.EOF)
|
||||
return EOFToken;
|
||||
|
||||
char c;
|
||||
int start;
|
||||
boolean filter = false;
|
||||
|
||||
c = string.charAt(currentPos);
|
||||
|
||||
// Check or Skip comments and position currentPos
|
||||
// beyond the comment
|
||||
while (c == '(') {
|
||||
// Parsing comment ..
|
||||
int nesting;
|
||||
for (start = ++currentPos, nesting = 1;
|
||||
nesting > 0 && currentPos < maxPos;
|
||||
currentPos++) {
|
||||
c = string.charAt(currentPos);
|
||||
if (c == '\\') { // Escape sequence
|
||||
currentPos++; // skip the escaped character
|
||||
filter = true;
|
||||
} else if (c == '\r')
|
||||
filter = true;
|
||||
else if (c == '(')
|
||||
nesting++;
|
||||
else if (c == ')')
|
||||
nesting--;
|
||||
}
|
||||
if (nesting != 0)
|
||||
throw new WebServiceException("Unbalanced comments");
|
||||
|
||||
if (!skipComments) {
|
||||
// Return the comment, if we are asked to.
|
||||
// Note that the comment start & end markers are ignored.
|
||||
String s;
|
||||
if (filter) // need to go thru the token again.
|
||||
s = filterToken(string, start, currentPos-1);
|
||||
else
|
||||
s = string.substring(start,currentPos-1);
|
||||
|
||||
return new Token(Token.COMMENT, s);
|
||||
}
|
||||
|
||||
// Skip any whitespace after the comment.
|
||||
if (skipWhiteSpace() == Token.EOF)
|
||||
return EOFToken;
|
||||
c = string.charAt(currentPos);
|
||||
}
|
||||
|
||||
// Check for quoted-string and position currentPos
|
||||
// beyond the terminating quote
|
||||
if (c == '"') {
|
||||
for (start = ++currentPos; currentPos < maxPos; currentPos++) {
|
||||
c = string.charAt(currentPos);
|
||||
if (c == '\\') { // Escape sequence
|
||||
currentPos++;
|
||||
filter = true;
|
||||
} else if (c == '\r')
|
||||
filter = true;
|
||||
else if (c == '"') {
|
||||
currentPos++;
|
||||
String s;
|
||||
|
||||
if (filter)
|
||||
s = filterToken(string, start, currentPos-1);
|
||||
else
|
||||
s = string.substring(start,currentPos-1);
|
||||
|
||||
return new Token(Token.QUOTEDSTRING, s);
|
||||
}
|
||||
}
|
||||
throw new WebServiceException("Unbalanced quoted string");
|
||||
}
|
||||
|
||||
// Check for SPECIAL or CTL
|
||||
if (c < 040 || c >= 0177 || delimiters.indexOf(c) >= 0) {
|
||||
currentPos++; // re-position currentPos
|
||||
char ch[] = new char[1];
|
||||
ch[0] = c;
|
||||
return new Token((int)c, new String(ch));
|
||||
}
|
||||
|
||||
// Check for ATOM
|
||||
for (start = currentPos; currentPos < maxPos; currentPos++) {
|
||||
c = string.charAt(currentPos);
|
||||
// ATOM is delimited by either SPACE, CTL, "(", <">
|
||||
// or the specified SPECIALS
|
||||
if (c < 040 || c >= 0177 || c == '(' || c == ' ' ||
|
||||
c == '"' || delimiters.indexOf(c) >= 0)
|
||||
break;
|
||||
}
|
||||
return new Token(Token.ATOM, string.substring(start, currentPos));
|
||||
}
|
||||
|
||||
// Skip SPACE, HT, CR and NL
|
||||
private int skipWhiteSpace() {
|
||||
char c;
|
||||
for (; currentPos < maxPos; currentPos++)
|
||||
if (((c = string.charAt(currentPos)) != ' ') &&
|
||||
(c != '\t') && (c != '\r') && (c != '\n'))
|
||||
return currentPos;
|
||||
return Token.EOF;
|
||||
}
|
||||
|
||||
/* Process escape sequences and embedded LWSPs from a comment or
|
||||
* quoted string.
|
||||
*/
|
||||
private static String filterToken(String s, int start, int end) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
char c;
|
||||
boolean gotEscape = false;
|
||||
boolean gotCR = false;
|
||||
|
||||
for (int i = start; i < end; i++) {
|
||||
c = s.charAt(i);
|
||||
if (c == '\n' && gotCR) {
|
||||
// This LF is part of an unescaped
|
||||
// CRLF sequence (i.e, LWSP). Skip it.
|
||||
gotCR = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
gotCR = false;
|
||||
if (!gotEscape) {
|
||||
// Previous character was NOT '\'
|
||||
if (c == '\\') // skip this character
|
||||
gotEscape = true;
|
||||
else if (c == '\r') // skip this character
|
||||
gotCR = true;
|
||||
else // append this character
|
||||
sb.append(c);
|
||||
} else {
|
||||
// Previous character was '\'. So no need to
|
||||
// bother with any special processing, just
|
||||
// append this character
|
||||
sb.append(c);
|
||||
gotEscape = false;
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import javax.activation.DataContentHandler;
|
||||
import javax.activation.ActivationDataFlavor;
|
||||
import javax.activation.DataSource;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.Iterator;
|
||||
import java.io.IOException;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
|
||||
public class ImageDataContentHandler extends Component
|
||||
implements DataContentHandler {
|
||||
|
||||
private static final Logger log = Logger.getLogger(ImageDataContentHandler.class.getName());
|
||||
private final DataFlavor[] flavor;
|
||||
|
||||
public ImageDataContentHandler() {
|
||||
String[] mimeTypes = ImageIO.getReaderMIMETypes();
|
||||
flavor = new DataFlavor[mimeTypes.length];
|
||||
for(int i=0; i < mimeTypes.length; i++) {
|
||||
flavor[i] = new ActivationDataFlavor(Image.class, mimeTypes[i], "Image");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of DataFlavor objects indicating the flavors the
|
||||
* data can be provided in. The array should be ordered according to
|
||||
* preference for providing the data (from most richly descriptive to
|
||||
* least descriptive).
|
||||
*
|
||||
* @return The DataFlavors.
|
||||
*/
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return Arrays.copyOf(flavor, flavor.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object which represents the data to be transferred.
|
||||
* The class of the object returned is defined by the representation class
|
||||
* of the flavor.
|
||||
*
|
||||
* @param df The DataFlavor representing the requested type.
|
||||
* @param ds The DataSource representing the data to be converted.
|
||||
* @return The constructed Object.
|
||||
*/
|
||||
public Object getTransferData(DataFlavor df, DataSource ds)
|
||||
throws IOException {
|
||||
for (DataFlavor aFlavor : flavor) {
|
||||
if (aFlavor.equals(df)) {
|
||||
return getContent(ds);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an object representing the data in its most preferred form.
|
||||
* Generally this will be the form described by the first DataFlavor
|
||||
* returned by the <code>getTransferDataFlavors</code> method.
|
||||
*
|
||||
* @param ds The DataSource representing the data to be converted.
|
||||
* @return The constructed Object.
|
||||
*/
|
||||
public Object getContent(DataSource ds) throws IOException {
|
||||
return ImageIO.read(new BufferedInputStream(ds.getInputStream()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the object to a byte stream of the specified MIME type
|
||||
* and write it to the output stream.
|
||||
*
|
||||
* @param obj The object to be converted.
|
||||
* @param type The requested MIME type of the resulting byte stream.
|
||||
* @param os The output stream into which to write the converted
|
||||
* byte stream.
|
||||
*/
|
||||
|
||||
public void writeTo(Object obj, String type, OutputStream os)
|
||||
throws IOException {
|
||||
|
||||
try {
|
||||
BufferedImage bufImage;
|
||||
if (obj instanceof BufferedImage) {
|
||||
bufImage = (BufferedImage)obj;
|
||||
} else if (obj instanceof Image) {
|
||||
bufImage = render((Image)obj);
|
||||
} else {
|
||||
throw new IOException(
|
||||
"ImageDataContentHandler requires Image object, "
|
||||
+ "was given object of type "
|
||||
+ obj.getClass().toString());
|
||||
}
|
||||
ImageWriter writer = null;
|
||||
Iterator<ImageWriter> i = ImageIO.getImageWritersByMIMEType(type);
|
||||
if (i.hasNext()) {
|
||||
writer = i.next();
|
||||
}
|
||||
if (writer != null) {
|
||||
ImageOutputStream stream = ImageIO.createImageOutputStream(os);
|
||||
writer.setOutput(stream);
|
||||
writer.write(bufImage);
|
||||
writer.dispose();
|
||||
stream.close();
|
||||
} else {
|
||||
throw new IOException("Unsupported mime type:"+ type);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IOException("Unable to encode the image to a stream "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private BufferedImage render(Image img) throws InterruptedException {
|
||||
|
||||
MediaTracker tracker = new MediaTracker(this);
|
||||
tracker.addImage(img, 0);
|
||||
tracker.waitForAll();
|
||||
BufferedImage bufImage = new BufferedImage(img.getWidth(null),
|
||||
img.getHeight(null), BufferedImage.TYPE_INT_RGB);
|
||||
Graphics g = bufImage.createGraphics();
|
||||
g.drawImage(img, 0, 0, null);
|
||||
g.dispose();
|
||||
return bufImage;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import com.sun.xml.internal.org.jvnet.mimepull.MIMEPart;
|
||||
|
||||
import javax.activation.DataSource;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.File;
|
||||
|
||||
import com.sun.xml.internal.ws.developer.StreamingDataHandler;
|
||||
|
||||
/**
|
||||
* Implementation of {@link StreamingDataHandler} to access MIME
|
||||
* attachments efficiently. Applications can use the additional methods and decide
|
||||
* on how to access the attachment data in JAX-WS applications.
|
||||
*
|
||||
* <p>
|
||||
* for e.g.:
|
||||
*
|
||||
* DataHandler dh = proxy.getData();
|
||||
* StreamingDataHandler sdh = (StreamingDataHandler)dh;
|
||||
* // readOnce() doesn't store attachment on the disk in some cases
|
||||
* // for e.g when only one huge attachment after soap envelope part in MIME message
|
||||
* InputStream in = sdh.readOnce();
|
||||
* ...
|
||||
* in.close();
|
||||
* sdh.close();
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public class MIMEPartStreamingDataHandler extends StreamingDataHandler {
|
||||
private final StreamingDataSource ds;
|
||||
|
||||
public MIMEPartStreamingDataHandler(MIMEPart part) {
|
||||
super(new StreamingDataSource(part));
|
||||
ds = (StreamingDataSource)getDataSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream readOnce() throws IOException {
|
||||
return ds.readOnce();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveTo(File file) throws IOException {
|
||||
ds.moveTo(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
ds.close();
|
||||
}
|
||||
|
||||
private static final class StreamingDataSource implements DataSource {
|
||||
private final MIMEPart part;
|
||||
|
||||
StreamingDataSource(MIMEPart part) {
|
||||
this.part = part;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return part.read(); //readOnce() ??
|
||||
}
|
||||
|
||||
InputStream readOnce() throws IOException {
|
||||
try {
|
||||
return part.readOnce();
|
||||
} catch(Exception e) {
|
||||
throw new MyIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
void moveTo(File file) throws IOException {
|
||||
part.moveTo(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return part.getContentType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
part.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class MyIOException extends IOException {
|
||||
private final Exception linkedException;
|
||||
|
||||
MyIOException(Exception linkedException) {
|
||||
this.linkedException = linkedException;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Throwable getCause() {
|
||||
return linkedException;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
211
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/MimeCodec.java
Normal file
211
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/MimeCodec.java
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSFeatureList;
|
||||
import com.sun.xml.internal.ws.api.message.Attachment;
|
||||
import com.sun.xml.internal.ws.api.message.AttachmentEx;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
import com.sun.xml.internal.ws.api.pipe.ContentType;
|
||||
import com.sun.xml.internal.ws.developer.StreamingAttachmentFeature;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.Iterator;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* {@link Codec}s that uses the MIME multipart as the underlying format.
|
||||
*
|
||||
* <p>
|
||||
* When the runtime needs to dynamically choose a {@link Codec}, and
|
||||
* when there are more than one {@link Codec}s that use MIME multipart,
|
||||
* it is often impossible to determine the right {@link Codec} unless
|
||||
* you parse the multipart message to some extent.
|
||||
*
|
||||
* <p>
|
||||
* By having all such {@link Codec}s extending from this class,
|
||||
* the "sniffer" can decode a multipart message partially, and then
|
||||
* pass the partial parse result to the ultimately-responsible {@link Codec}.
|
||||
* This improves the performance.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
abstract class MimeCodec implements Codec {
|
||||
|
||||
public static final String MULTIPART_RELATED_MIME_TYPE = "multipart/related";
|
||||
|
||||
protected Codec mimeRootCodec;
|
||||
protected final SOAPVersion version;
|
||||
protected final WSFeatureList features;
|
||||
|
||||
protected MimeCodec(SOAPVersion version, WSFeatureList f) {
|
||||
this.version = version;
|
||||
this.features = f;
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return MULTIPART_RELATED_MIME_TYPE;
|
||||
}
|
||||
|
||||
protected Codec getMimeRootCodec(Packet packet) {
|
||||
return mimeRootCodec;
|
||||
}
|
||||
|
||||
// TODO: preencode String literals to byte[] so that they don't have to
|
||||
// go through char[]->byte[] conversion at runtime.
|
||||
public ContentType encode(Packet packet, OutputStream out) throws IOException {
|
||||
Message msg = packet.getMessage();
|
||||
if (msg == null) {
|
||||
return null;
|
||||
}
|
||||
ContentTypeImpl ctImpl = (ContentTypeImpl)getStaticContentType(packet);
|
||||
String boundary = ctImpl.getBoundary();
|
||||
boolean hasAttachments = (boundary != null);
|
||||
Codec rootCodec = getMimeRootCodec(packet);
|
||||
if (hasAttachments) {
|
||||
writeln("--"+boundary, out);
|
||||
ContentType ct = rootCodec.getStaticContentType(packet);
|
||||
String ctStr = (ct != null) ? ct.getContentType() : rootCodec.getMimeType();
|
||||
writeln("Content-Type: " + ctStr, out);
|
||||
writeln(out);
|
||||
}
|
||||
ContentType primaryCt = rootCodec.encode(packet, out);
|
||||
|
||||
if (hasAttachments) {
|
||||
writeln(out);
|
||||
// Encode all the attchments
|
||||
for (Attachment att : msg.getAttachments()) {
|
||||
writeln("--"+boundary, out);
|
||||
//SAAJ's AttachmentPart.getContentId() returns content id already enclosed with
|
||||
//angle brackets. For now put angle bracket only if its not there
|
||||
String cid = att.getContentId();
|
||||
if(cid != null && cid.length() >0 && cid.charAt(0) != '<')
|
||||
cid = '<' + cid + '>';
|
||||
writeln("Content-Id:" + cid, out);
|
||||
writeln("Content-Type: " + att.getContentType(), out);
|
||||
writeCustomMimeHeaders(att, out);
|
||||
writeln("Content-Transfer-Encoding: binary", out);
|
||||
writeln(out); // write \r\n
|
||||
att.writeTo(out);
|
||||
writeln(out); // write \r\n
|
||||
}
|
||||
writeAsAscii("--"+boundary, out);
|
||||
writeAsAscii("--", out);
|
||||
}
|
||||
// TODO not returing correct multipart/related type(no boundary)
|
||||
return hasAttachments ? ctImpl : primaryCt;
|
||||
}
|
||||
|
||||
private void writeCustomMimeHeaders(Attachment att, OutputStream out) throws IOException {
|
||||
if (att instanceof AttachmentEx) {
|
||||
Iterator<AttachmentEx.MimeHeader> allMimeHeaders = ((AttachmentEx) att).getMimeHeaders();
|
||||
while (allMimeHeaders.hasNext()) {
|
||||
AttachmentEx.MimeHeader mh = allMimeHeaders.next();
|
||||
String name = mh.getName();
|
||||
|
||||
if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Id".equalsIgnoreCase(name)) {
|
||||
writeln(name +": " + mh.getValue(), out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ContentType getStaticContentType(Packet packet) {
|
||||
ContentType ct = (ContentType) packet.getInternalContentType();
|
||||
if ( ct != null ) return ct;
|
||||
Message msg = packet.getMessage();
|
||||
boolean hasAttachments = !msg.getAttachments().isEmpty();
|
||||
Codec rootCodec = getMimeRootCodec(packet);
|
||||
|
||||
if (hasAttachments) {
|
||||
String boundary = "uuid:" + UUID.randomUUID().toString();
|
||||
String boundaryParameter = "boundary=\"" + boundary + "\"";
|
||||
// TODO use primaryEncoder to get type
|
||||
String messageContentType = MULTIPART_RELATED_MIME_TYPE +
|
||||
"; type=\"" + rootCodec.getMimeType() + "\"; " +
|
||||
boundaryParameter;
|
||||
ContentTypeImpl impl = new ContentTypeImpl(messageContentType, packet.soapAction, null);
|
||||
impl.setBoundary(boundary);
|
||||
impl.setBoundaryParameter(boundaryParameter);
|
||||
packet.setContentType(impl);
|
||||
return impl;
|
||||
} else {
|
||||
ct = rootCodec.getStaticContentType(packet);
|
||||
packet.setContentType(ct);
|
||||
return ct;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
protected MimeCodec(MimeCodec that) {
|
||||
this.version = that.version;
|
||||
this.features = that.features;
|
||||
}
|
||||
|
||||
public void decode(InputStream in, String contentType, Packet packet) throws IOException {
|
||||
MimeMultipartParser parser = new MimeMultipartParser(in, contentType, features.get(StreamingAttachmentFeature.class));
|
||||
decode(parser,packet);
|
||||
}
|
||||
|
||||
public void decode(ReadableByteChannel in, String contentType, Packet packet) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a {@link Packet} from a {@link MimeMultipartParser}.
|
||||
*/
|
||||
protected abstract void decode(MimeMultipartParser mpp, Packet packet) throws IOException;
|
||||
|
||||
public abstract MimeCodec copy();
|
||||
|
||||
|
||||
public static void writeln(String s,OutputStream out) throws IOException {
|
||||
writeAsAscii(s,out);
|
||||
writeln(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a string as ASCII string.
|
||||
*/
|
||||
public static void writeAsAscii(String s,OutputStream out) throws IOException {
|
||||
int len = s.length();
|
||||
for( int i=0; i<len; i++ )
|
||||
out.write((byte)s.charAt(i));
|
||||
}
|
||||
|
||||
public static void writeln(OutputStream out) throws IOException {
|
||||
out.write('\r');
|
||||
out.write('\n');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import com.sun.xml.internal.ws.api.message.Attachment;
|
||||
import com.sun.xml.internal.ws.api.message.AttachmentEx;
|
||||
import com.sun.xml.internal.ws.developer.StreamingAttachmentFeature;
|
||||
import com.sun.xml.internal.ws.developer.StreamingDataHandler;
|
||||
import com.sun.xml.internal.ws.util.ByteArrayBuffer;
|
||||
import com.sun.xml.internal.ws.util.ByteArrayDataSource;
|
||||
|
||||
import com.sun.xml.internal.org.jvnet.mimepull.Header;
|
||||
import com.sun.xml.internal.org.jvnet.mimepull.MIMEMessage;
|
||||
import com.sun.xml.internal.org.jvnet.mimepull.MIMEPart;
|
||||
|
||||
import javax.activation.DataHandler;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Parses Mime multipart message into primary part and attachment parts. It
|
||||
* parses the stream lazily as and when required.
|
||||
*
|
||||
* @author Vivek Pandey
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public final class MimeMultipartParser {
|
||||
|
||||
private final String start;
|
||||
private final MIMEMessage message;
|
||||
private Attachment root;
|
||||
private ContentTypeImpl contentType;
|
||||
|
||||
// Attachments without root part
|
||||
private final Map<String, Attachment> attachments = new HashMap<String, Attachment>();
|
||||
|
||||
private boolean gotAll;
|
||||
|
||||
public MimeMultipartParser(InputStream in, String cType, StreamingAttachmentFeature feature) {
|
||||
this.contentType = new ContentTypeImpl(cType);
|
||||
// ContentType ct = new ContentType(cType);
|
||||
// String boundary = ct.getParameter("boundary");
|
||||
String boundary = contentType.getBoundary();
|
||||
if (boundary == null || boundary.equals("")) {
|
||||
throw new WebServiceException("MIME boundary parameter not found" + contentType);
|
||||
}
|
||||
message = (feature != null)
|
||||
? new MIMEMessage(in, boundary, feature.getConfig())
|
||||
: new MIMEMessage(in, boundary);
|
||||
// Strip <...> from root part's Content-ID
|
||||
// String st = ct.getParameter("start");
|
||||
String st = contentType.getRootId();
|
||||
if (st != null && st.length() > 2 && st.charAt(0) == '<' && st.charAt(st.length()-1) == '>') {
|
||||
st = st.substring(1, st.length()-1);
|
||||
}
|
||||
start = st;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the stream and returns the root part. If start parameter is
|
||||
* present in Content-Type, it is used to determine the root part, otherwise
|
||||
* root part is the first part.
|
||||
*
|
||||
* @return StreamAttachment for root part
|
||||
* null if root part cannot be found
|
||||
*
|
||||
*/
|
||||
public @Nullable Attachment getRootPart() {
|
||||
if (root == null) {
|
||||
root = new PartAttachment((start != null) ? message.getPart(start) : message.getPart(0));
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the entire stream and returns all MIME parts except root MIME part.
|
||||
*
|
||||
* @return Map<String, StreamAttachment> for all attachment parts
|
||||
*/
|
||||
public @NotNull Map<String, Attachment> getAttachmentParts() {
|
||||
if (!gotAll) {
|
||||
MIMEPart rootPart = (start != null) ? message.getPart(start) : message.getPart(0);
|
||||
List<MIMEPart> parts = message.getAttachments();
|
||||
for(MIMEPart part : parts) {
|
||||
if (part != rootPart) {
|
||||
String cid = part.getContentId();
|
||||
if (!attachments.containsKey(cid)) {
|
||||
PartAttachment attach = new PartAttachment(part);
|
||||
attachments.put(attach.getContentId(), attach);
|
||||
}
|
||||
}
|
||||
}
|
||||
gotAll = true;
|
||||
}
|
||||
return attachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method can be called to get a matching MIME attachment part for the
|
||||
* given contentId. It parses the stream until it finds a matching part.
|
||||
*
|
||||
* @return StreamAttachment attachment for contentId
|
||||
* null if there is no attachment for contentId
|
||||
*/
|
||||
public @Nullable Attachment getAttachmentPart(String contentId) throws IOException {
|
||||
//first see if this attachment is already parsed, if so return it
|
||||
Attachment attach = attachments.get(contentId);
|
||||
if (attach == null) {
|
||||
MIMEPart part = message.getPart(contentId);
|
||||
attach = new PartAttachment(part);
|
||||
attachments.put(contentId, attach);
|
||||
}
|
||||
return attach;
|
||||
}
|
||||
|
||||
static class PartAttachment implements AttachmentEx {
|
||||
|
||||
final MIMEPart part;
|
||||
byte[] buf;
|
||||
private StreamingDataHandler streamingDataHandler;
|
||||
|
||||
PartAttachment(MIMEPart part) {
|
||||
this.part = part;
|
||||
}
|
||||
|
||||
public @NotNull @Override String getContentId() {
|
||||
return part.getContentId();
|
||||
}
|
||||
|
||||
public @NotNull @Override String getContentType() {
|
||||
return part.getContentType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] asByteArray() {
|
||||
if (buf == null) {
|
||||
ByteArrayBuffer baf = new ByteArrayBuffer();
|
||||
try {
|
||||
baf.write(part.readOnce());
|
||||
} catch(IOException ioe) {
|
||||
throw new WebServiceException(ioe);
|
||||
} finally {
|
||||
if (baf != null) {
|
||||
try {
|
||||
baf.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(MimeMultipartParser.class.getName()).log(Level.FINE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
buf = baf.toByteArray();
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataHandler asDataHandler() {
|
||||
if (streamingDataHandler == null) {
|
||||
streamingDataHandler = (buf != null)
|
||||
? new DataSourceStreamingDataHandler(new ByteArrayDataSource(buf,getContentType()))
|
||||
: new MIMEPartStreamingDataHandler(part);
|
||||
}
|
||||
return streamingDataHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Source asSource() {
|
||||
return (buf != null)
|
||||
? new StreamSource(new ByteArrayInputStream(buf))
|
||||
: new StreamSource(part.read());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream asInputStream() {
|
||||
return (buf != null)
|
||||
? new ByteArrayInputStream(buf) : part.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(OutputStream os) throws IOException {
|
||||
if (buf != null) {
|
||||
os.write(buf);
|
||||
} else {
|
||||
InputStream in = part.read();
|
||||
byte[] temp = new byte[8192];
|
||||
int len;
|
||||
while((len=in.read(temp)) != -1) {
|
||||
os.write(temp, 0, len);
|
||||
}
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(SOAPMessage saaj) throws SOAPException {
|
||||
saaj.createAttachmentPart().setDataHandler(asDataHandler());
|
||||
}
|
||||
|
||||
// AttachmentEx methods begin here
|
||||
@Override
|
||||
public Iterator<MimeHeader> getMimeHeaders() {
|
||||
final Iterator<? extends Header> ih = part.getAllHeaders()
|
||||
.iterator();
|
||||
return new Iterator<MimeHeader>() {
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return ih.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MimeHeader next() {
|
||||
final Header hdr = ih.next();
|
||||
return new AttachmentEx.MimeHeader() {
|
||||
@Override
|
||||
public String getValue() {
|
||||
return hdr.getValue();
|
||||
}
|
||||
@Override
|
||||
public String getName() {
|
||||
return hdr.getName();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public ContentTypeImpl getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
}
|
||||
662
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/MtomCodec.java
Normal file
662
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/MtomCodec.java
Normal file
@@ -0,0 +1,662 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.xml.internal.bind.DatatypeConverterImpl;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSFeatureList;
|
||||
import com.sun.xml.internal.ws.api.message.Attachment;
|
||||
import com.sun.xml.internal.ws.api.message.AttachmentSet;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.pipe.ContentType;
|
||||
import com.sun.xml.internal.ws.api.pipe.StreamSOAPCodec;
|
||||
import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
|
||||
import com.sun.xml.internal.ws.api.streaming.XMLStreamWriterFactory;
|
||||
import com.sun.xml.internal.ws.developer.SerializationFeature;
|
||||
import com.sun.xml.internal.ws.developer.StreamingDataHandler;
|
||||
import com.sun.xml.internal.ws.message.MimeAttachmentSet;
|
||||
import com.sun.xml.internal.ws.streaming.XMLStreamWriterUtil;
|
||||
import com.sun.xml.internal.ws.util.ByteArrayDataSource;
|
||||
import com.sun.xml.internal.ws.util.xml.NamespaceContextExAdaper;
|
||||
import com.sun.xml.internal.ws.util.xml.XMLStreamReaderFilter;
|
||||
import com.sun.xml.internal.ws.util.xml.XMLStreamWriterFilter;
|
||||
import com.sun.xml.internal.ws.streaming.MtomStreamWriter;
|
||||
import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
|
||||
import com.sun.xml.internal.ws.server.UnsupportedMediaException;
|
||||
import com.sun.xml.internal.org.jvnet.staxex.Base64Data;
|
||||
import com.sun.xml.internal.org.jvnet.staxex.NamespaceContextEx;
|
||||
import com.sun.xml.internal.org.jvnet.staxex.XMLStreamReaderEx;
|
||||
import com.sun.xml.internal.org.jvnet.staxex.XMLStreamWriterEx;
|
||||
|
||||
import javax.activation.DataHandler;
|
||||
import javax.xml.namespace.NamespaceContext;
|
||||
import javax.xml.stream.XMLStreamConstants;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import javax.xml.ws.soap.MTOMFeature;
|
||||
import javax.xml.bind.attachment.AttachmentMarshaller;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Mtom message Codec. It can be used even for non-soap message's mtom encoding.
|
||||
*
|
||||
* @author Vivek Pandey
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public class MtomCodec extends MimeCodec {
|
||||
|
||||
public static final String XOP_XML_MIME_TYPE = "application/xop+xml";
|
||||
public static final String XOP_LOCALNAME = "Include";
|
||||
public static final String XOP_NAMESPACEURI = "http://www.w3.org/2004/08/xop/include";
|
||||
|
||||
private final StreamSOAPCodec codec;
|
||||
private final MTOMFeature mtomFeature;
|
||||
private final SerializationFeature sf;
|
||||
private final static String DECODED_MESSAGE_CHARSET = "decodedMessageCharset";
|
||||
|
||||
MtomCodec(SOAPVersion version, StreamSOAPCodec codec, WSFeatureList features){
|
||||
super(version, features);
|
||||
this.codec = codec;
|
||||
sf = features.get(SerializationFeature.class);
|
||||
MTOMFeature mtom = features.get(MTOMFeature.class);
|
||||
if(mtom == null)
|
||||
this.mtomFeature = new MTOMFeature();
|
||||
else
|
||||
this.mtomFeature = mtom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the soap 1.1 and soap 1.2 specific XOP packaged ContentType
|
||||
*
|
||||
* @return A non-null content type for soap11 or soap 1.2 content type
|
||||
*/
|
||||
@Override
|
||||
public ContentType getStaticContentType(Packet packet) {
|
||||
return getStaticContentTypeStatic(packet, version);
|
||||
}
|
||||
|
||||
public static ContentType getStaticContentTypeStatic(Packet packet, SOAPVersion version) {
|
||||
ContentType ct = (ContentType) packet.getInternalContentType();
|
||||
if ( ct != null ) return ct;
|
||||
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
String boundary = "uuid:" + uuid;
|
||||
String rootId = "<rootpart*"+uuid+"@example.jaxws.sun.com>";
|
||||
String soapActionParameter = SOAPVersion.SOAP_11.equals(version) ? null : createActionParameter(packet);
|
||||
|
||||
String boundaryParameter = "boundary=\"" + boundary +"\"";
|
||||
String messageContentType = MULTIPART_RELATED_MIME_TYPE +
|
||||
";start=\""+rootId +"\"" +
|
||||
";type=\"" + XOP_XML_MIME_TYPE + "\";" +
|
||||
boundaryParameter +
|
||||
";start-info=\"" + version.contentType +
|
||||
(soapActionParameter == null? "" : soapActionParameter) +
|
||||
"\"";
|
||||
|
||||
ContentTypeImpl ctImpl = SOAPVersion.SOAP_11.equals(version) ?
|
||||
new ContentTypeImpl(messageContentType, (packet.soapAction == null)?"":packet.soapAction, null) :
|
||||
new ContentTypeImpl(messageContentType, null, null);
|
||||
ctImpl.setBoundary(boundary);
|
||||
ctImpl.setRootId(rootId);
|
||||
packet.setContentType(ctImpl);
|
||||
return ctImpl;
|
||||
}
|
||||
|
||||
private static String createActionParameter(Packet packet) {
|
||||
return packet.soapAction != null? ";action=\\\""+packet.soapAction+"\\\"" : "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentType encode(Packet packet, OutputStream out) throws IOException {
|
||||
ContentTypeImpl ctImpl = (ContentTypeImpl) this.getStaticContentType(packet);
|
||||
String boundary = ctImpl.getBoundary();
|
||||
String rootId = ctImpl.getRootId();
|
||||
|
||||
if(packet.getMessage() != null){
|
||||
try {
|
||||
String encoding = getPacketEncoding(packet);
|
||||
packet.invocationProperties.remove(DECODED_MESSAGE_CHARSET);
|
||||
|
||||
String actionParameter = getActionParameter(packet, version);
|
||||
String soapXopContentType = getSOAPXopContentType(encoding, version, actionParameter);
|
||||
|
||||
writeln("--"+boundary, out);
|
||||
writeMimeHeaders(soapXopContentType, rootId, out);
|
||||
|
||||
//mtom attachments that need to be written after the root part
|
||||
List<ByteArrayBuffer> mtomAttachments = new ArrayList<ByteArrayBuffer>();
|
||||
MtomStreamWriterImpl writer = new MtomStreamWriterImpl(
|
||||
XMLStreamWriterFactory.create(out, encoding), mtomAttachments, boundary, mtomFeature);
|
||||
|
||||
packet.getMessage().writeTo(writer);
|
||||
XMLStreamWriterFactory.recycle(writer);
|
||||
writeln(out);
|
||||
|
||||
for(ByteArrayBuffer bos : mtomAttachments){
|
||||
bos.write(out);
|
||||
}
|
||||
|
||||
// now write out the attachments in the message that weren't
|
||||
// previously written
|
||||
writeNonMtomAttachments(packet.getMessage().getAttachments(),
|
||||
out, boundary);
|
||||
|
||||
//write out the end boundary
|
||||
writeAsAscii("--"+boundary, out);
|
||||
writeAsAscii("--", out);
|
||||
|
||||
} catch (XMLStreamException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
}
|
||||
//now create the boundary for next encode() call
|
||||
// createConteTypeHeader();
|
||||
return ctImpl;
|
||||
}
|
||||
|
||||
public static String getSOAPXopContentType(String encoding, SOAPVersion version,
|
||||
String actionParameter) {
|
||||
return XOP_XML_MIME_TYPE +";charset="+encoding+";type=\""+version.contentType+ actionParameter + "\"";
|
||||
}
|
||||
|
||||
public static String getActionParameter(Packet packet, SOAPVersion version) {
|
||||
return (version == SOAPVersion.SOAP_11) ? "" : createActionParameter(packet);
|
||||
}
|
||||
|
||||
public static class ByteArrayBuffer{
|
||||
final String contentId;
|
||||
|
||||
private final DataHandler dh;
|
||||
private final String boundary;
|
||||
|
||||
ByteArrayBuffer(@NotNull DataHandler dh, String b) {
|
||||
this.dh = dh;
|
||||
String cid = null;
|
||||
if (dh instanceof StreamingDataHandler) {
|
||||
StreamingDataHandler sdh = (StreamingDataHandler) dh;
|
||||
if (sdh.getHrefCid() != null)
|
||||
cid = sdh.getHrefCid();
|
||||
}
|
||||
this.contentId = cid != null ? cid : encodeCid();
|
||||
boundary = b;
|
||||
}
|
||||
|
||||
public void write(OutputStream os) throws IOException {
|
||||
//build attachment frame
|
||||
writeln("--"+boundary, os);
|
||||
writeMimeHeaders(dh.getContentType(), contentId, os);
|
||||
dh.writeTo(os);
|
||||
writeln(os);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeMimeHeaders(String contentType, String contentId, OutputStream out) throws IOException {
|
||||
String cid = contentId;
|
||||
if(cid != null && cid.length() >0 && cid.charAt(0) != '<')
|
||||
cid = '<' + cid + '>';
|
||||
writeln("Content-Id: " + cid, out);
|
||||
writeln("Content-Type: " + contentType, out);
|
||||
writeln("Content-Transfer-Encoding: binary", out);
|
||||
writeln(out);
|
||||
}
|
||||
|
||||
// Compiler warning for not calling close, but cannot call close,
|
||||
// will consume attachment bytes.
|
||||
@SuppressWarnings("resource")
|
||||
private void writeNonMtomAttachments(AttachmentSet attachments,
|
||||
OutputStream out, String boundary) throws IOException {
|
||||
|
||||
for (Attachment att : attachments) {
|
||||
|
||||
DataHandler dh = att.asDataHandler();
|
||||
if (dh instanceof StreamingDataHandler) {
|
||||
StreamingDataHandler sdh = (StreamingDataHandler) dh;
|
||||
// If DataHandler has href Content-ID, it is MTOM, so skip.
|
||||
if (sdh.getHrefCid() != null)
|
||||
continue;
|
||||
}
|
||||
|
||||
// build attachment frame
|
||||
writeln("--" + boundary, out);
|
||||
writeMimeHeaders(att.getContentType(), att.getContentId(), out);
|
||||
att.writeTo(out);
|
||||
writeln(out); // write \r\n
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentType encode(Packet packet, WritableByteChannel buffer) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MtomCodec copy() {
|
||||
return new MtomCodec(version, (StreamSOAPCodec)codec.copy(), features);
|
||||
}
|
||||
|
||||
private static String encodeCid(){
|
||||
String cid="example.jaxws.sun.com";
|
||||
String name = UUID.randomUUID()+"@";
|
||||
return name + cid;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decode(MimeMultipartParser mpp, Packet packet) throws IOException {
|
||||
//TODO shouldn't we check for SOAP1.1/SOAP1.2 and throw
|
||||
//TODO UnsupportedMediaException like StreamSOAPCodec
|
||||
String charset = null;
|
||||
String ct = mpp.getRootPart().getContentType();
|
||||
if (ct != null) {
|
||||
charset = new ContentTypeImpl(ct).getCharSet();
|
||||
}
|
||||
if (charset != null && !Charset.isSupported(charset)) {
|
||||
throw new UnsupportedMediaException(charset);
|
||||
}
|
||||
|
||||
if (charset != null) {
|
||||
packet.invocationProperties.put(DECODED_MESSAGE_CHARSET, charset);
|
||||
} else {
|
||||
packet.invocationProperties.remove(DECODED_MESSAGE_CHARSET);
|
||||
}
|
||||
|
||||
// we'd like to reuse those reader objects but unfortunately decoder may be reused
|
||||
// before the decoded message is completely used.
|
||||
XMLStreamReader mtomReader = new MtomXMLStreamReaderEx( mpp,
|
||||
XMLStreamReaderFactory.create(null, mpp.getRootPart().asInputStream(), charset, true)
|
||||
);
|
||||
|
||||
packet.setMessage(codec.decode(mtomReader, new MimeAttachmentSet(mpp)));
|
||||
packet.setMtomFeature(mtomFeature);
|
||||
packet.setContentType(mpp.getContentType());
|
||||
}
|
||||
|
||||
private String getPacketEncoding(Packet packet) {
|
||||
// If SerializationFeature is set, just use that encoding
|
||||
if (sf != null && sf.getEncoding() != null) {
|
||||
return sf.getEncoding().equals("") ? SOAPBindingCodec.DEFAULT_ENCODING : sf.getEncoding();
|
||||
}
|
||||
return determinePacketEncoding(packet);
|
||||
}
|
||||
|
||||
public static String determinePacketEncoding(Packet packet) {
|
||||
if (packet != null && packet.endpoint != null) {
|
||||
// Use request message's encoding for Server-side response messages
|
||||
String charset = (String)packet.invocationProperties.get(DECODED_MESSAGE_CHARSET);
|
||||
return charset == null
|
||||
? SOAPBindingCodec.DEFAULT_ENCODING : charset;
|
||||
}
|
||||
|
||||
// Use default encoding for client-side request messages
|
||||
return SOAPBindingCodec.DEFAULT_ENCODING;
|
||||
}
|
||||
|
||||
public static class MtomStreamWriterImpl extends XMLStreamWriterFilter implements XMLStreamWriterEx,
|
||||
MtomStreamWriter, HasEncoding {
|
||||
private final List<ByteArrayBuffer> mtomAttachments;
|
||||
private final String boundary;
|
||||
private final MTOMFeature myMtomFeature;
|
||||
public MtomStreamWriterImpl(XMLStreamWriter w, List<ByteArrayBuffer> mtomAttachments, String b, MTOMFeature myMtomFeature) {
|
||||
super(w);
|
||||
this.mtomAttachments = mtomAttachments;
|
||||
this.boundary = b;
|
||||
this.myMtomFeature = myMtomFeature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBinary(byte[] data, int start, int len, String contentType) throws XMLStreamException {
|
||||
//check threshold and if less write as base64encoded value
|
||||
if(myMtomFeature.getThreshold() > len){
|
||||
writeCharacters(DatatypeConverterImpl._printBase64Binary(data, start, len));
|
||||
return;
|
||||
}
|
||||
ByteArrayBuffer bab = new ByteArrayBuffer(new DataHandler(new ByteArrayDataSource(data, start, len, contentType)), boundary);
|
||||
writeBinary(bab);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBinary(DataHandler dataHandler) throws XMLStreamException {
|
||||
// TODO how do we check threshold and if less inline the data
|
||||
writeBinary(new ByteArrayBuffer(dataHandler, boundary));
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream writeBinary(String contentType) throws XMLStreamException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePCDATA(CharSequence data) throws XMLStreamException {
|
||||
if(data == null)
|
||||
return;
|
||||
if(data instanceof Base64Data){
|
||||
Base64Data binaryData = (Base64Data)data;
|
||||
writeBinary(binaryData.getDataHandler());
|
||||
return;
|
||||
}
|
||||
writeCharacters(data.toString());
|
||||
}
|
||||
|
||||
private void writeBinary(ByteArrayBuffer bab) {
|
||||
try {
|
||||
mtomAttachments.add(bab);
|
||||
String prefix = writer.getPrefix(XOP_NAMESPACEURI);
|
||||
if (prefix == null || !prefix.equals("xop")) {
|
||||
writer.setPrefix("xop", XOP_NAMESPACEURI);
|
||||
writer.writeNamespace("xop", XOP_NAMESPACEURI);
|
||||
}
|
||||
writer.writeStartElement(XOP_NAMESPACEURI, XOP_LOCALNAME);
|
||||
writer.writeAttribute("href", "cid:"+bab.contentId);
|
||||
writer.writeEndElement();
|
||||
writer.flush();
|
||||
} catch (XMLStreamException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProperty(String name) throws IllegalArgumentException {
|
||||
// Hack for JDK6's SJSXP
|
||||
if (name.equals("sjsxp-outputstream") && writer instanceof Map) {
|
||||
Object obj = ((Map) writer).get("sjsxp-outputstream");
|
||||
if (obj != null) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return super.getProperty(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* JAXBMessage writes envelope directly to the OutputStream(for SJSXP, woodstox).
|
||||
* While writing, it calls the AttachmentMarshaller methods for adding attachments.
|
||||
* JAXB writes xop:Include in this case.
|
||||
*/
|
||||
@Override
|
||||
public AttachmentMarshaller getAttachmentMarshaller() {
|
||||
return new AttachmentMarshaller() {
|
||||
|
||||
@Override
|
||||
public String addMtomAttachment(DataHandler data, String elementNamespace, String elementLocalName) {
|
||||
// Should we do the threshold processing on DataHandler ? But that would be
|
||||
// expensive as DataHolder need to read the data again from its source
|
||||
ByteArrayBuffer bab = new ByteArrayBuffer(data, boundary);
|
||||
mtomAttachments.add(bab);
|
||||
return "cid:"+bab.contentId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String addMtomAttachment(byte[] data, int offset, int length, String mimeType, String elementNamespace, String elementLocalName) {
|
||||
// inline the data based on the threshold
|
||||
if (myMtomFeature.getThreshold() > length) {
|
||||
return null; // JAXB inlines the attachment data
|
||||
}
|
||||
ByteArrayBuffer bab = new ByteArrayBuffer(new DataHandler(new ByteArrayDataSource(data, offset, length, mimeType)), boundary);
|
||||
mtomAttachments.add(bab);
|
||||
return "cid:"+bab.contentId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String addSwaRefAttachment(DataHandler data) {
|
||||
ByteArrayBuffer bab = new ByteArrayBuffer(data, boundary);
|
||||
mtomAttachments.add(bab);
|
||||
return "cid:"+bab.contentId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isXOPPackage() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public List<ByteArrayBuffer> getMtomAttachments() {
|
||||
return this.mtomAttachments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEncoding() {
|
||||
return XMLStreamWriterUtil.getEncoding(writer);
|
||||
}
|
||||
|
||||
private static class MtomNamespaceContextEx implements NamespaceContextEx {
|
||||
private final NamespaceContext nsContext;
|
||||
|
||||
public MtomNamespaceContextEx(NamespaceContext nsContext) {
|
||||
this.nsContext = nsContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Binding> iterator() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespaceURI(String prefix) {
|
||||
return nsContext.getNamespaceURI(prefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrefix(String namespaceURI) {
|
||||
return nsContext.getPrefix(namespaceURI);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator getPrefixes(String namespaceURI) {
|
||||
return nsContext.getPrefixes(namespaceURI);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespaceContextEx getNamespaceContext() {
|
||||
NamespaceContext nsContext = writer.getNamespaceContext();
|
||||
return new MtomNamespaceContextEx(nsContext);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MtomXMLStreamReaderEx extends XMLStreamReaderFilter implements XMLStreamReaderEx {
|
||||
/**
|
||||
* The parser for the outer MIME 'shell'.
|
||||
*/
|
||||
private final MimeMultipartParser mimeMP;
|
||||
|
||||
private boolean xopReferencePresent = false;
|
||||
private Base64Data base64AttData;
|
||||
|
||||
//To be used with #getTextCharacters
|
||||
private char[] base64EncodedText;
|
||||
|
||||
private String xopHref;
|
||||
|
||||
public MtomXMLStreamReaderEx(MimeMultipartParser mimeMP, XMLStreamReader reader) {
|
||||
super(reader);
|
||||
this.mimeMP = mimeMP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getPCDATA() throws XMLStreamException {
|
||||
if(xopReferencePresent){
|
||||
return base64AttData;
|
||||
}
|
||||
return reader.getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespaceContextEx getNamespaceContext() {
|
||||
return new NamespaceContextExAdaper(reader.getNamespaceContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementTextTrim() throws XMLStreamException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTextLength() {
|
||||
if (xopReferencePresent) {
|
||||
return base64AttData.length();
|
||||
}
|
||||
return reader.getTextLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTextStart() {
|
||||
if (xopReferencePresent) {
|
||||
return 0;
|
||||
}
|
||||
return reader.getTextStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEventType() {
|
||||
if(xopReferencePresent)
|
||||
return XMLStreamConstants.CHARACTERS;
|
||||
return super.getEventType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int next() throws XMLStreamException {
|
||||
int event = reader.next();
|
||||
if (event == XMLStreamConstants.START_ELEMENT && reader.getLocalName().equals(XOP_LOCALNAME) && reader.getNamespaceURI().equals(XOP_NAMESPACEURI)) {
|
||||
//its xop reference, take the URI reference
|
||||
String href = reader.getAttributeValue(null, "href");
|
||||
try {
|
||||
xopHref = href;
|
||||
Attachment att = getAttachment(href);
|
||||
if(att != null){
|
||||
DataHandler dh = att.asDataHandler();
|
||||
if (dh instanceof StreamingDataHandler) {
|
||||
((StreamingDataHandler)dh).setHrefCid(att.getContentId());
|
||||
}
|
||||
base64AttData = new Base64Data();
|
||||
base64AttData.set(dh);
|
||||
}
|
||||
xopReferencePresent = true;
|
||||
} catch (IOException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
//move to the </xop:Include>
|
||||
XMLStreamReaderUtil.nextElementContent(reader);
|
||||
return XMLStreamConstants.CHARACTERS;
|
||||
}
|
||||
if(xopReferencePresent){
|
||||
xopReferencePresent = false;
|
||||
base64EncodedText = null;
|
||||
xopHref = null;
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
private String decodeCid(String cid) {
|
||||
try {
|
||||
cid = URLDecoder.decode(cid, "utf-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
//on recceiving side lets not fail now, try to look for it
|
||||
}
|
||||
return cid;
|
||||
}
|
||||
|
||||
private Attachment getAttachment(String cid) throws IOException {
|
||||
if (cid.startsWith("cid:"))
|
||||
cid = cid.substring(4, cid.length());
|
||||
if (cid.indexOf('%') != -1) {
|
||||
cid = decodeCid(cid);
|
||||
return mimeMP.getAttachmentPart(cid);
|
||||
}
|
||||
return mimeMP.getAttachmentPart(cid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getTextCharacters() {
|
||||
if (xopReferencePresent) {
|
||||
char[] chars = new char[base64AttData.length()];
|
||||
base64AttData.writeTo(chars, 0);
|
||||
return chars;
|
||||
}
|
||||
return reader.getTextCharacters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException {
|
||||
if(xopReferencePresent){
|
||||
if(target == null){
|
||||
throw new NullPointerException("target char array can't be null") ;
|
||||
}
|
||||
|
||||
if(targetStart < 0 || length < 0 || sourceStart < 0 || targetStart >= target.length ||
|
||||
(targetStart + length ) > target.length) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
int textLength = base64AttData.length();
|
||||
if(sourceStart > textLength)
|
||||
throw new IndexOutOfBoundsException();
|
||||
|
||||
if(base64EncodedText == null){
|
||||
base64EncodedText = new char[base64AttData.length()];
|
||||
base64AttData.writeTo(base64EncodedText, 0);
|
||||
}
|
||||
|
||||
int copiedLength = Math.min(textLength - sourceStart, length);
|
||||
System.arraycopy(base64EncodedText, sourceStart , target, targetStart, copiedLength);
|
||||
return copiedLength;
|
||||
}
|
||||
return reader.getTextCharacters(sourceStart, target, targetStart, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
if (xopReferencePresent) {
|
||||
return base64AttData.toString();
|
||||
}
|
||||
return reader.getText();
|
||||
}
|
||||
|
||||
protected boolean isXopReference() throws XMLStreamException {
|
||||
return xopReferencePresent;
|
||||
}
|
||||
|
||||
protected String getXopHref() {
|
||||
return xopHref;
|
||||
}
|
||||
|
||||
public MimeMultipartParser getMimeMultipartParser() {
|
||||
return mimeMP;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
131
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/ParameterList.java
Normal file
131
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/ParameterList.java
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This class holds MIME parameters (attribute-value pairs).
|
||||
*
|
||||
* @version 1.10, 03/02/12
|
||||
* @author John Mani
|
||||
*/
|
||||
|
||||
final class ParameterList {
|
||||
|
||||
private final Map<String, String> list;
|
||||
|
||||
/**
|
||||
* Constructor that takes a parameter-list string. The String
|
||||
* is parsed and the parameters are collected and stored internally.
|
||||
* A ParseException is thrown if the parse fails.
|
||||
* Note that an empty parameter-list string is valid and will be
|
||||
* parsed into an empty ParameterList.
|
||||
*
|
||||
* @param s the parameter-list string.
|
||||
* @exception WebServiceException if the parse fails.
|
||||
*/
|
||||
ParameterList(String s) {
|
||||
HeaderTokenizer h = new HeaderTokenizer(s, HeaderTokenizer.MIME);
|
||||
HeaderTokenizer.Token tk;
|
||||
int type;
|
||||
String name;
|
||||
|
||||
list = new HashMap<String, String>();
|
||||
while (true) {
|
||||
tk = h.next();
|
||||
type = tk.getType();
|
||||
|
||||
if (type == HeaderTokenizer.Token.EOF) // done
|
||||
return;
|
||||
|
||||
if ((char)type == ';') {
|
||||
// expect parameter name
|
||||
tk = h.next();
|
||||
// tolerate trailing semicolon, even though it violates the spec
|
||||
if (tk.getType() == HeaderTokenizer.Token.EOF)
|
||||
return;
|
||||
// parameter name must be a MIME Atom
|
||||
if (tk.getType() != HeaderTokenizer.Token.ATOM)
|
||||
throw new WebServiceException();
|
||||
name = tk.getValue().toLowerCase();
|
||||
|
||||
// expect '='
|
||||
tk = h.next();
|
||||
if ((char)tk.getType() != '=')
|
||||
throw new WebServiceException();
|
||||
|
||||
// expect parameter value
|
||||
tk = h.next();
|
||||
type = tk.getType();
|
||||
// parameter value must be a MIME Atom or Quoted String
|
||||
if (type != HeaderTokenizer.Token.ATOM &&
|
||||
type != HeaderTokenizer.Token.QUOTEDSTRING)
|
||||
throw new WebServiceException();
|
||||
|
||||
list.put(name, tk.getValue());
|
||||
} else
|
||||
throw new WebServiceException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of parameters in this list.
|
||||
*
|
||||
* @return number of parameters.
|
||||
*/
|
||||
int size() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified parameter. Note that
|
||||
* parameter names are case-insensitive.
|
||||
*
|
||||
* @param name parameter name.
|
||||
* @return Value of the parameter. Returns
|
||||
* <code>null</code> if the parameter is not
|
||||
* present.
|
||||
*/
|
||||
String get(String name) {
|
||||
return list.get(name.trim().toLowerCase());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return an enumeration of the names of all parameters in this
|
||||
* list.
|
||||
*
|
||||
* @return Enumeration of all parameter names in this list.
|
||||
*/
|
||||
Iterator<String> getNames() {
|
||||
return list.keySet().iterator();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.xml.internal.ws.api.message.AttachmentSet;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
|
||||
/**
|
||||
* {@link Codec} that works only on the root part of the MIME/multipart.
|
||||
* It doesn't work on the attachment parts, so it takes {@link AttachmentSet}
|
||||
* as an argument and creates a corresponding {@link Message}. This enables
|
||||
* attachments to be parsed lazily by wrapping the mimepull parser into an
|
||||
* {@link AttachmentSet}
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public interface RootOnlyCodec extends Codec {
|
||||
|
||||
/**
|
||||
* Reads root part bytes from {@link InputStream} and constructs a {@link Message}
|
||||
* along with the given attachments.
|
||||
*
|
||||
* @param in root part's data
|
||||
*
|
||||
* @param contentType root part's MIME content type (like "application/xml")
|
||||
*
|
||||
* @param packet the new created {@link Message} is set in this packet
|
||||
*
|
||||
* @param att attachments
|
||||
*
|
||||
* @throws IOException
|
||||
* if {@link InputStream} throws an exception.
|
||||
*/
|
||||
void decode(@NotNull InputStream in, @NotNull String contentType, @NotNull Packet packet, @NotNull AttachmentSet att)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @see #decode(InputStream, String, Packet, AttachmentSet)
|
||||
*/
|
||||
void decode(@NotNull ReadableByteChannel in, @NotNull String contentType, @NotNull Packet packet, @NotNull AttachmentSet att);
|
||||
}
|
||||
@@ -0,0 +1,484 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSFeatureList;
|
||||
import com.sun.xml.internal.ws.api.client.SelectOptimalEncodingFeature;
|
||||
import com.sun.xml.internal.ws.api.fastinfoset.FastInfosetFeature;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.message.ExceptionHasMessage;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codecs;
|
||||
import com.sun.xml.internal.ws.api.pipe.ContentType;
|
||||
import com.sun.xml.internal.ws.api.pipe.StreamSOAPCodec;
|
||||
import com.sun.xml.internal.ws.client.ContentNegotiation;
|
||||
import com.sun.xml.internal.ws.protocol.soap.MessageCreationException;
|
||||
import com.sun.xml.internal.ws.resources.StreamingMessages;
|
||||
import com.sun.xml.internal.ws.server.UnsupportedMediaException;
|
||||
import static com.sun.xml.internal.ws.binding.WebServiceFeatureList.getSoapVersion;
|
||||
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import javax.xml.ws.WebServiceFeature;
|
||||
import javax.xml.ws.soap.MTOMFeature;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
//import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* SOAP binding {@link Codec} that can handle MTOM, SwA, and SOAP messages
|
||||
* encoded using XML or Fast Infoset.
|
||||
*
|
||||
* <p>
|
||||
* This is used when we need to determine the encoding from what we received (for decoding)
|
||||
* and from configuration and {@link Message} contents (for encoding)
|
||||
*
|
||||
* <p>
|
||||
* TODO: Split this Codec into two, one that supports FI and one that does not.
|
||||
* Then further split the FI Codec into two, one for client and one for
|
||||
* server. This will simplify the logic and make it easier to understand/maintain.
|
||||
*
|
||||
* @author Vivek Pandey
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public class SOAPBindingCodec extends MimeCodec implements com.sun.xml.internal.ws.api.pipe.SOAPBindingCodec {
|
||||
|
||||
public static final String UTF8_ENCODING = "utf-8";
|
||||
public static final String DEFAULT_ENCODING = UTF8_ENCODING;
|
||||
|
||||
|
||||
/**
|
||||
* True if Fast Infoset functionality has been
|
||||
* configured to be disabled, or the Fast Infoset
|
||||
* runtime is not available.
|
||||
*/
|
||||
private boolean isFastInfosetDisabled;
|
||||
|
||||
/**
|
||||
* True if the Fast Infoset codec should be used for encoding.
|
||||
*/
|
||||
private boolean useFastInfosetForEncoding;
|
||||
|
||||
/**
|
||||
* True if the content negotiation property should
|
||||
* be ignored by the client. This will be used in
|
||||
* the case of Fast Infoset being configured to be
|
||||
* disabled or automatically selected.
|
||||
*/
|
||||
private boolean ignoreContentNegotiationProperty;
|
||||
|
||||
// The XML SOAP codec
|
||||
private final StreamSOAPCodec xmlSoapCodec;
|
||||
|
||||
// The Fast Infoset SOAP codec
|
||||
private final Codec fiSoapCodec;
|
||||
|
||||
// The XML MTOM codec
|
||||
private final MimeCodec xmlMtomCodec;
|
||||
|
||||
// The XML SWA codec
|
||||
private final MimeCodec xmlSwaCodec;
|
||||
|
||||
// The Fast Infoset SWA codec
|
||||
private final MimeCodec fiSwaCodec;
|
||||
|
||||
/**
|
||||
* The XML SOAP MIME type
|
||||
*/
|
||||
private final String xmlMimeType;
|
||||
|
||||
/**
|
||||
* The Fast Infoset SOAP MIME type
|
||||
*/
|
||||
private final String fiMimeType;
|
||||
|
||||
/**
|
||||
* The Accept header for XML encodings
|
||||
*/
|
||||
private final String xmlAccept;
|
||||
|
||||
/**
|
||||
* The Accept header for Fast Infoset and XML encodings
|
||||
*/
|
||||
private final String connegXmlAccept;
|
||||
|
||||
public StreamSOAPCodec getXMLCodec() {
|
||||
return xmlSoapCodec;
|
||||
}
|
||||
|
||||
private ContentTypeImpl setAcceptHeader(Packet p, ContentTypeImpl c) {
|
||||
String _accept;
|
||||
if (!ignoreContentNegotiationProperty && p.contentNegotiation != ContentNegotiation.none) {
|
||||
_accept = connegXmlAccept;
|
||||
} else {
|
||||
_accept = xmlAccept;
|
||||
}
|
||||
c.setAcceptHeader(_accept);
|
||||
return c;
|
||||
}
|
||||
|
||||
public SOAPBindingCodec(WSFeatureList features) {
|
||||
this(features, Codecs.createSOAPEnvelopeXmlCodec(features));
|
||||
}
|
||||
|
||||
public SOAPBindingCodec(WSFeatureList features, StreamSOAPCodec xmlSoapCodec) {
|
||||
super(getSoapVersion(features), features);
|
||||
|
||||
this.xmlSoapCodec = xmlSoapCodec;
|
||||
xmlMimeType = xmlSoapCodec.getMimeType();
|
||||
|
||||
xmlMtomCodec = new MtomCodec(version, xmlSoapCodec, features);
|
||||
|
||||
xmlSwaCodec = new SwACodec(version, features, xmlSoapCodec);
|
||||
|
||||
String clientAcceptedContentTypes = xmlSoapCodec.getMimeType() + ", " +
|
||||
xmlMtomCodec.getMimeType();
|
||||
|
||||
WebServiceFeature fi = features.get(FastInfosetFeature.class);
|
||||
isFastInfosetDisabled = (fi != null && !fi.isEnabled());
|
||||
if (!isFastInfosetDisabled) {
|
||||
fiSoapCodec = getFICodec(xmlSoapCodec, version);
|
||||
if (fiSoapCodec != null) {
|
||||
fiMimeType = fiSoapCodec.getMimeType();
|
||||
fiSwaCodec = new SwACodec(version, features, fiSoapCodec);
|
||||
connegXmlAccept = fiMimeType + ", " + clientAcceptedContentTypes;
|
||||
|
||||
/**
|
||||
* This feature will only be present on the client side.
|
||||
*
|
||||
* Fast Infoset is enabled on the client if the service
|
||||
* explicitly supports Fast Infoset.
|
||||
*/
|
||||
WebServiceFeature select = features.get(SelectOptimalEncodingFeature.class);
|
||||
if (select != null) { // if the client FI feature is set - ignore negotiation property
|
||||
ignoreContentNegotiationProperty = true;
|
||||
if (select.isEnabled()) {
|
||||
// If the client's FI encoding feature is enabled, and server's is not disabled
|
||||
if (fi != null) { // if server's FI feature also enabled
|
||||
useFastInfosetForEncoding = true;
|
||||
}
|
||||
|
||||
clientAcceptedContentTypes = connegXmlAccept;
|
||||
} else { // If client FI feature is disabled
|
||||
isFastInfosetDisabled = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Fast Infoset could not be loaded by the runtime
|
||||
isFastInfosetDisabled = true;
|
||||
fiSwaCodec = null;
|
||||
fiMimeType = "";
|
||||
connegXmlAccept = clientAcceptedContentTypes;
|
||||
ignoreContentNegotiationProperty = true;
|
||||
}
|
||||
} else {
|
||||
// Fast Infoset is explicitly not supported by the service
|
||||
fiSoapCodec = fiSwaCodec = null;
|
||||
fiMimeType = "";
|
||||
connegXmlAccept = clientAcceptedContentTypes;
|
||||
ignoreContentNegotiationProperty = true;
|
||||
}
|
||||
|
||||
xmlAccept = clientAcceptedContentTypes;
|
||||
|
||||
if(getSoapVersion(features) == null)
|
||||
throw new WebServiceException("Expecting a SOAP binding but found ");
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ContentType getStaticContentType(Packet packet) {
|
||||
ContentType toAdapt = getEncoder(packet).getStaticContentType(packet);
|
||||
return setAcceptHeader(packet, (ContentTypeImpl)toAdapt);
|
||||
}
|
||||
|
||||
public ContentType encode(Packet packet, OutputStream out) throws IOException {
|
||||
preEncode(packet);
|
||||
ContentType ct = getEncoder(packet).encode(packet, out);
|
||||
ct = setAcceptHeader(packet, (ContentTypeImpl)ct);
|
||||
postEncode();
|
||||
return ct;
|
||||
}
|
||||
|
||||
public ContentType encode(Packet packet, WritableByteChannel buffer) {
|
||||
preEncode(packet);
|
||||
ContentType ct = getEncoder(packet).encode(packet, buffer);
|
||||
ct = setAcceptHeader(packet, (ContentTypeImpl)ct);
|
||||
postEncode();
|
||||
return ct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called before encode().
|
||||
* Set the state so that such state is used by encode process.
|
||||
*/
|
||||
private void preEncode(Packet p) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called after encode()
|
||||
* Reset the encoding state.
|
||||
*/
|
||||
private void postEncode() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called before decode().
|
||||
* Set the state so that such state is used by decode().
|
||||
*/
|
||||
private void preDecode(Packet p) {
|
||||
if (p.contentNegotiation == null)
|
||||
useFastInfosetForEncoding = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called after decode().
|
||||
* Set the state so that such state is used by encode().
|
||||
*/
|
||||
private void postDecode(Packet p) {
|
||||
p.setFastInfosetDisabled(isFastInfosetDisabled);
|
||||
if(features.isEnabled(MTOMFeature.class)) p.checkMtomAcceptable();
|
||||
// p.setMtomAcceptable( isMtomAcceptable(p.acceptableMimeTypes) );
|
||||
MTOMFeature mtomFeature = features.get(MTOMFeature.class);
|
||||
if (mtomFeature != null) {
|
||||
p.setMtomFeature(mtomFeature);
|
||||
}
|
||||
if (!useFastInfosetForEncoding) {
|
||||
useFastInfosetForEncoding = p.getFastInfosetAcceptable(fiMimeType);
|
||||
// useFastInfosetForEncoding = isFastInfosetAcceptable(p.acceptableMimeTypes);
|
||||
}
|
||||
}
|
||||
|
||||
public void decode(InputStream in, String contentType, Packet packet) throws IOException {
|
||||
if (contentType == null) {
|
||||
contentType = xmlMimeType;
|
||||
}
|
||||
packet.setContentType(new ContentTypeImpl(contentType));
|
||||
preDecode(packet);
|
||||
try {
|
||||
if(isMultipartRelated(contentType))
|
||||
// parse the multipart portion and then decide whether it's MTOM or SwA
|
||||
super.decode(in, contentType, packet);
|
||||
else if(isFastInfoset(contentType)) {
|
||||
if (!ignoreContentNegotiationProperty && packet.contentNegotiation == ContentNegotiation.none)
|
||||
throw noFastInfosetForDecoding();
|
||||
|
||||
useFastInfosetForEncoding = true;
|
||||
fiSoapCodec.decode(in, contentType, packet);
|
||||
} else
|
||||
xmlSoapCodec.decode(in, contentType, packet);
|
||||
} catch(RuntimeException we) {
|
||||
if (we instanceof ExceptionHasMessage || we instanceof UnsupportedMediaException) {
|
||||
throw we;
|
||||
} else {
|
||||
throw new MessageCreationException(version, we);
|
||||
}
|
||||
}
|
||||
postDecode(packet);
|
||||
}
|
||||
|
||||
public void decode(ReadableByteChannel in, String contentType, Packet packet) {
|
||||
if (contentType == null) {
|
||||
throw new UnsupportedMediaException();
|
||||
}
|
||||
|
||||
preDecode(packet);
|
||||
try {
|
||||
if(isMultipartRelated(contentType))
|
||||
super.decode(in, contentType, packet);
|
||||
else if(isFastInfoset(contentType)) {
|
||||
if (packet.contentNegotiation == ContentNegotiation.none)
|
||||
throw noFastInfosetForDecoding();
|
||||
|
||||
useFastInfosetForEncoding = true;
|
||||
fiSoapCodec.decode(in, contentType, packet);
|
||||
} else
|
||||
xmlSoapCodec.decode(in, contentType, packet);
|
||||
} catch(RuntimeException we) {
|
||||
if (we instanceof ExceptionHasMessage || we instanceof UnsupportedMediaException) {
|
||||
throw we;
|
||||
} else {
|
||||
throw new MessageCreationException(version, we);
|
||||
}
|
||||
}
|
||||
postDecode(packet);
|
||||
}
|
||||
|
||||
public SOAPBindingCodec copy() {
|
||||
return new SOAPBindingCodec(features, (StreamSOAPCodec)xmlSoapCodec.copy());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decode(MimeMultipartParser mpp, Packet packet) throws IOException {
|
||||
// is this SwA or XOP?
|
||||
final String rootContentType = mpp.getRootPart().getContentType();
|
||||
boolean isMTOM = isApplicationXopXml(rootContentType);
|
||||
packet.setMtomRequest(isMTOM);
|
||||
if(isMTOM) {
|
||||
xmlMtomCodec.decode(mpp,packet);
|
||||
} else if (isFastInfoset(rootContentType)) {
|
||||
if (packet.contentNegotiation == ContentNegotiation.none)
|
||||
throw noFastInfosetForDecoding();
|
||||
|
||||
useFastInfosetForEncoding = true;
|
||||
fiSwaCodec.decode(mpp,packet);
|
||||
} else if (isXml(rootContentType))
|
||||
xmlSwaCodec.decode(mpp,packet);
|
||||
else {
|
||||
// TODO localize exception
|
||||
throw new IOException("");
|
||||
}
|
||||
// checkDuplicateKnownHeaders(packet);
|
||||
}
|
||||
|
||||
private boolean isMultipartRelated(String contentType) {
|
||||
return compareStrings(contentType, MimeCodec.MULTIPART_RELATED_MIME_TYPE);
|
||||
}
|
||||
|
||||
private boolean isApplicationXopXml(String contentType) {
|
||||
return compareStrings(contentType, MtomCodec.XOP_XML_MIME_TYPE);
|
||||
}
|
||||
|
||||
private boolean isXml(String contentType) {
|
||||
return compareStrings(contentType, xmlMimeType);
|
||||
}
|
||||
|
||||
private boolean isFastInfoset(String contentType) {
|
||||
if (isFastInfosetDisabled) return false;
|
||||
|
||||
return compareStrings(contentType, fiMimeType);
|
||||
}
|
||||
|
||||
private boolean compareStrings(String a, String b) {
|
||||
return a.length() >= b.length() &&
|
||||
b.equalsIgnoreCase(
|
||||
a.substring(0,
|
||||
b.length()));
|
||||
}
|
||||
|
||||
// private boolean isFastInfosetAcceptable(String accept) {
|
||||
// if (accept == null || isFastInfosetDisabled) return false;
|
||||
//
|
||||
// StringTokenizer st = new StringTokenizer(accept, ",");
|
||||
// while (st.hasMoreTokens()) {
|
||||
// final String token = st.nextToken().trim();
|
||||
// if (token.equalsIgnoreCase(fiMimeType)) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
/*
|
||||
* Just check if the Accept header contains application/xop+xml,
|
||||
* no need to worry about q values.
|
||||
*/
|
||||
// private boolean isMtomAcceptable(String accept) {
|
||||
// if (accept == null || isFastInfosetDisabled) return false;
|
||||
// StringTokenizer st = new StringTokenizer(accept, ",");
|
||||
// while (st.hasMoreTokens()) {
|
||||
// final String token = st.nextToken().trim();
|
||||
// if (token.toLowerCase().contains(MtomCodec.XOP_XML_MIME_TYPE)) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Determines the encoding codec.
|
||||
*/
|
||||
private Codec getEncoder(Packet p) {
|
||||
/**
|
||||
* The following logic is only for outbound packets
|
||||
* to be encoded by a client.
|
||||
* For a server the p.contentNegotiation == null.
|
||||
*/
|
||||
if (!ignoreContentNegotiationProperty) {
|
||||
if (p.contentNegotiation == ContentNegotiation.none) {
|
||||
// The client may have changed the negotiation property from
|
||||
// pessismistic to none between invocations
|
||||
useFastInfosetForEncoding = false;
|
||||
} else if (p.contentNegotiation == ContentNegotiation.optimistic) {
|
||||
// Always encode using Fast Infoset if in optimisitic mode
|
||||
useFastInfosetForEncoding = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Override the MTOM binding for now
|
||||
// Note: Using FI with MTOM does not make sense
|
||||
if (useFastInfosetForEncoding) {
|
||||
final Message m = p.getMessage();
|
||||
if(m==null || m.getAttachments().isEmpty() || features.isEnabled(MTOMFeature.class))
|
||||
return fiSoapCodec;
|
||||
else
|
||||
return fiSwaCodec;
|
||||
}
|
||||
|
||||
//If the packet does not have a binding, explicitly set the MTOMFeature
|
||||
//on the packet so that it has a way to determine whether to use MTOM
|
||||
if (p.getBinding() == null) {
|
||||
if (features != null) {
|
||||
p.setMtomFeature(features.get(MTOMFeature.class));
|
||||
}
|
||||
}
|
||||
|
||||
if (p.shouldUseMtom()) {
|
||||
return xmlMtomCodec;
|
||||
}
|
||||
|
||||
Message m = p.getMessage();
|
||||
if(m==null || m.getAttachments().isEmpty())
|
||||
return xmlSoapCodec;
|
||||
else
|
||||
return xmlSwaCodec;
|
||||
}
|
||||
|
||||
private RuntimeException noFastInfosetForDecoding() {
|
||||
return new RuntimeException(StreamingMessages.FASTINFOSET_DECODING_NOT_ACCEPTED());
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain an FI SOAP codec instance using reflection.
|
||||
*/
|
||||
private static Codec getFICodec(StreamSOAPCodec soapCodec, SOAPVersion version) {
|
||||
try {
|
||||
Class c = Class.forName("com.sun.xml.internal.ws.encoding.fastinfoset.FastInfosetStreamSOAPCodec");
|
||||
Method m = c.getMethod("create", StreamSOAPCodec.class, SOAPVersion.class);
|
||||
return (Codec)m.invoke(null, soapCodec, version);
|
||||
} catch (Exception e) {
|
||||
// TODO Log that FI cannot be loaded
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.WSFeatureList;
|
||||
import com.sun.xml.internal.ws.api.message.Header;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.pipe.ContentType;
|
||||
import com.sun.xml.internal.ws.message.stream.StreamHeader11;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* {@link StreamSOAPCodec} for SOAP 1.1.
|
||||
*
|
||||
* @author Paul.Sandoz@Sun.Com
|
||||
*/
|
||||
final class StreamSOAP11Codec extends StreamSOAPCodec {
|
||||
|
||||
public static final String SOAP11_MIME_TYPE = "text/xml";
|
||||
public static final String DEFAULT_SOAP11_CONTENT_TYPE =
|
||||
SOAP11_MIME_TYPE+"; charset="+SOAPBindingCodec.DEFAULT_ENCODING;
|
||||
|
||||
private static final List<String> EXPECTED_CONTENT_TYPES = Collections.singletonList(SOAP11_MIME_TYPE);
|
||||
|
||||
/*package*/ StreamSOAP11Codec() {
|
||||
super(SOAPVersion.SOAP_11);
|
||||
}
|
||||
|
||||
/*package*/ StreamSOAP11Codec(WSBinding binding) {
|
||||
super(binding);
|
||||
}
|
||||
|
||||
/*package*/ StreamSOAP11Codec(WSFeatureList features) {
|
||||
super(features);
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return SOAP11_MIME_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ContentType getContentType(Packet packet) {
|
||||
ContentTypeImpl.Builder b = getContenTypeBuilder(packet);
|
||||
b.soapAction = packet.soapAction;
|
||||
return b.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultContentType() {
|
||||
return DEFAULT_SOAP11_CONTENT_TYPE;
|
||||
}
|
||||
|
||||
protected List<String> getExpectedContentTypes() {
|
||||
return EXPECTED_CONTENT_TYPES;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.WSFeatureList;
|
||||
import com.sun.xml.internal.ws.api.message.Header;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.message.AttachmentSet;
|
||||
import com.sun.xml.internal.ws.api.pipe.ContentType;
|
||||
import com.sun.xml.internal.ws.message.stream.StreamHeader12;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* {@link StreamSOAPCodec} for SOAP 1.2.
|
||||
*
|
||||
* @author Paul.Sandoz@Sun.Com
|
||||
*/
|
||||
final class StreamSOAP12Codec extends StreamSOAPCodec {
|
||||
|
||||
public static final String SOAP12_MIME_TYPE = "application/soap+xml";
|
||||
public static final String DEFAULT_SOAP12_CONTENT_TYPE =
|
||||
SOAP12_MIME_TYPE+"; charset="+SOAPBindingCodec.DEFAULT_ENCODING;
|
||||
private static final List<String> EXPECTED_CONTENT_TYPES = Collections.singletonList(SOAP12_MIME_TYPE);
|
||||
|
||||
/*package*/ StreamSOAP12Codec() {
|
||||
super(SOAPVersion.SOAP_12);
|
||||
}
|
||||
|
||||
/*package*/ StreamSOAP12Codec(WSBinding binding) {
|
||||
super(binding);
|
||||
}
|
||||
|
||||
/*package*/ StreamSOAP12Codec(WSFeatureList features) {
|
||||
super(features);
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return SOAP12_MIME_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ContentType getContentType(Packet packet) {
|
||||
ContentTypeImpl.Builder b = getContenTypeBuilder(packet);
|
||||
// TODO: set accept header
|
||||
if (packet.soapAction == null) {
|
||||
return b.build();
|
||||
} else {
|
||||
b.contentType = b.contentType + ";action="+fixQuotesAroundSoapAction(packet.soapAction);
|
||||
return b.build();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(InputStream in, String contentType, Packet packet, AttachmentSet att ) throws IOException {
|
||||
com.sun.xml.internal.ws.encoding.ContentType ct = new com.sun.xml.internal.ws.encoding.ContentType(contentType);
|
||||
packet.soapAction = fixQuotesAroundSoapAction(ct.getParameter("action"));
|
||||
super.decode(in,contentType,packet,att);
|
||||
}
|
||||
|
||||
private String fixQuotesAroundSoapAction(String soapAction) {
|
||||
if(soapAction != null && (!soapAction.startsWith("\"") || !soapAction.endsWith("\"")) ) {
|
||||
String fixedSoapAction = soapAction;
|
||||
if(!soapAction.startsWith("\""))
|
||||
fixedSoapAction = "\"" + fixedSoapAction;
|
||||
if(!soapAction.endsWith("\""))
|
||||
fixedSoapAction = fixedSoapAction + "\"";
|
||||
return fixedSoapAction;
|
||||
}
|
||||
return soapAction;
|
||||
}
|
||||
|
||||
protected List<String> getExpectedContentTypes() {
|
||||
return EXPECTED_CONTENT_TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultContentType() {
|
||||
return DEFAULT_SOAP12_CONTENT_TYPE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import static com.sun.xml.internal.ws.binding.WebServiceFeatureList.getSoapVersion;
|
||||
|
||||
import com.oracle.webservices.internal.impl.encoding.StreamDecoderImpl;
|
||||
import com.oracle.webservices.internal.impl.internalspi.encoding.StreamDecoder;
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import com.sun.xml.internal.stream.buffer.MutableXMLStreamBuffer;
|
||||
import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
|
||||
import com.sun.xml.internal.stream.buffer.XMLStreamBufferMark;
|
||||
import com.sun.xml.internal.stream.buffer.stax.StreamReaderBufferCreator;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.WSFeatureList;
|
||||
import com.sun.xml.internal.ws.api.message.AttachmentSet;
|
||||
import com.sun.xml.internal.ws.api.message.Header;
|
||||
import com.sun.xml.internal.ws.api.message.HeaderList;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.pipe.ContentType;
|
||||
import com.sun.xml.internal.ws.api.streaming.XMLStreamWriterFactory;
|
||||
import com.sun.xml.internal.ws.developer.SerializationFeature;
|
||||
import com.sun.xml.internal.ws.message.AttachmentSetImpl;
|
||||
import com.sun.xml.internal.ws.message.stream.StreamMessage;
|
||||
import com.sun.xml.internal.ws.protocol.soap.VersionMismatchException;
|
||||
import com.sun.xml.internal.ws.server.UnsupportedMediaException;
|
||||
import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
|
||||
import com.sun.xml.internal.ws.util.ServiceFinder;
|
||||
|
||||
import javax.xml.stream.XMLStreamConstants;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A stream SOAP codec.
|
||||
*
|
||||
* @author Paul Sandoz
|
||||
*/
|
||||
@SuppressWarnings({"StringEquality"})
|
||||
public abstract class StreamSOAPCodec implements com.sun.xml.internal.ws.api.pipe.StreamSOAPCodec, RootOnlyCodec {
|
||||
|
||||
private static final String SOAP_ENVELOPE = "Envelope";
|
||||
private static final String SOAP_HEADER = "Header";
|
||||
private static final String SOAP_BODY = "Body";
|
||||
|
||||
private final SOAPVersion soapVersion;
|
||||
protected final SerializationFeature serializationFeature;
|
||||
|
||||
private final StreamDecoder streamDecoder;
|
||||
|
||||
// charset of last decoded message. Will be used for encoding server's
|
||||
// response messages with the request message's encoding
|
||||
// it will stored in the packet.invocationProperties
|
||||
private final static String DECODED_MESSAGE_CHARSET = "decodedMessageCharset";
|
||||
|
||||
/*package*/ StreamSOAPCodec(SOAPVersion soapVersion) {
|
||||
this(soapVersion, null);
|
||||
}
|
||||
|
||||
/*package*/ StreamSOAPCodec(WSBinding binding) {
|
||||
this(binding.getSOAPVersion(), binding.getFeature(SerializationFeature.class));
|
||||
}
|
||||
|
||||
StreamSOAPCodec(WSFeatureList features) {
|
||||
this(getSoapVersion(features), features.get(SerializationFeature.class));
|
||||
}
|
||||
|
||||
private StreamSOAPCodec(SOAPVersion soapVersion, @Nullable SerializationFeature sf) {
|
||||
this.soapVersion = soapVersion;
|
||||
this.serializationFeature = sf;
|
||||
this.streamDecoder = selectStreamDecoder();
|
||||
}
|
||||
|
||||
private StreamDecoder selectStreamDecoder() {
|
||||
for (StreamDecoder sd : ServiceFinder.find(StreamDecoder.class)) {
|
||||
return sd;
|
||||
}
|
||||
|
||||
return new StreamDecoderImpl();
|
||||
}
|
||||
|
||||
public ContentType getStaticContentType(Packet packet) {
|
||||
return getContentType(packet);
|
||||
}
|
||||
|
||||
public ContentType encode(Packet packet, OutputStream out) {
|
||||
if (packet.getMessage() != null) {
|
||||
String encoding = getPacketEncoding(packet);
|
||||
packet.invocationProperties.remove(DECODED_MESSAGE_CHARSET);
|
||||
XMLStreamWriter writer = XMLStreamWriterFactory.create(out, encoding);
|
||||
try {
|
||||
packet.getMessage().writeTo(writer);
|
||||
writer.flush();
|
||||
} catch (XMLStreamException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
XMLStreamWriterFactory.recycle(writer);
|
||||
}
|
||||
return getContentType(packet);
|
||||
}
|
||||
|
||||
protected abstract ContentType getContentType(Packet packet);
|
||||
|
||||
protected abstract String getDefaultContentType();
|
||||
|
||||
public ContentType encode(Packet packet, WritableByteChannel buffer) {
|
||||
//TODO: not yet implemented
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
protected abstract List<String> getExpectedContentTypes();
|
||||
|
||||
public void decode(InputStream in, String contentType, Packet packet) throws IOException {
|
||||
decode(in, contentType, packet, new AttachmentSetImpl());
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks against expected Content-Type headers that is handled by a codec
|
||||
*
|
||||
* @param ct the Content-Type of the request
|
||||
* @param expected expected Content-Types for a codec
|
||||
* @return true if the codec supports this Content-Type
|
||||
* false otherwise
|
||||
*/
|
||||
private static boolean isContentTypeSupported(String ct, List<String> expected) {
|
||||
for(String contentType : expected) {
|
||||
if (ct.contains(contentType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a message from {@link XMLStreamReader} that points to
|
||||
* the beginning of a SOAP infoset.
|
||||
*
|
||||
* @param reader
|
||||
* can point to the start document or the start element.
|
||||
*/
|
||||
public final @NotNull Message decode(@NotNull XMLStreamReader reader) {
|
||||
return decode(reader,new AttachmentSetImpl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a message from {@link XMLStreamReader} that points to
|
||||
* the beginning of a SOAP infoset.
|
||||
*
|
||||
* @param reader
|
||||
* can point to the start document or the start element.
|
||||
* @param attachmentSet
|
||||
* {@link StreamSOAPCodec} can take attachments parsed outside,
|
||||
* so that this codec can be used as a part of a biggre codec
|
||||
* (like MIME multipart codec.)
|
||||
*/
|
||||
public final Message decode(XMLStreamReader reader, @NotNull AttachmentSet attachmentSet) {
|
||||
return decode(soapVersion, reader, attachmentSet);
|
||||
}
|
||||
|
||||
public static final Message decode(SOAPVersion soapVersion, XMLStreamReader reader, @NotNull AttachmentSet attachmentSet) {
|
||||
// Move to soap:Envelope and verify
|
||||
if(reader.getEventType()!=XMLStreamConstants.START_ELEMENT)
|
||||
XMLStreamReaderUtil.nextElementContent(reader);
|
||||
XMLStreamReaderUtil.verifyReaderState(reader,XMLStreamConstants.START_ELEMENT);
|
||||
if (SOAP_ENVELOPE.equals(reader.getLocalName()) && !soapVersion.nsUri.equals(reader.getNamespaceURI())) {
|
||||
throw new VersionMismatchException(soapVersion, soapVersion.nsUri, reader.getNamespaceURI());
|
||||
}
|
||||
XMLStreamReaderUtil.verifyTag(reader, soapVersion.nsUri, SOAP_ENVELOPE);
|
||||
return new StreamMessage(soapVersion, reader, attachmentSet);
|
||||
}
|
||||
|
||||
public void decode(ReadableByteChannel in, String contentType, Packet packet ) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public final StreamSOAPCodec copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void decode(InputStream in, String contentType, Packet packet, AttachmentSet att ) throws IOException {
|
||||
List<String> expectedContentTypes = getExpectedContentTypes();
|
||||
if (contentType != null && !isContentTypeSupported(contentType,expectedContentTypes)) {
|
||||
throw new UnsupportedMediaException(contentType, expectedContentTypes);
|
||||
}
|
||||
com.oracle.webservices.internal.api.message.ContentType pct = packet.getInternalContentType();
|
||||
ContentTypeImpl cti = (pct != null && pct instanceof ContentTypeImpl) ?
|
||||
(ContentTypeImpl)pct : new ContentTypeImpl(contentType);
|
||||
String charset = cti.getCharSet();
|
||||
if (charset != null && !Charset.isSupported(charset)) {
|
||||
throw new UnsupportedMediaException(charset);
|
||||
}
|
||||
if (charset != null) {
|
||||
packet.invocationProperties.put(DECODED_MESSAGE_CHARSET, charset);
|
||||
} else {
|
||||
packet.invocationProperties.remove(DECODED_MESSAGE_CHARSET);
|
||||
}
|
||||
packet.setMessage(streamDecoder.decode(in, charset, att, soapVersion));
|
||||
}
|
||||
|
||||
public void decode(ReadableByteChannel in, String contentType, Packet response, AttachmentSet att ) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a new {@link StreamSOAPCodec} instance.
|
||||
*/
|
||||
public static StreamSOAPCodec create(SOAPVersion version) {
|
||||
if(version==null)
|
||||
// this decoder is for SOAP, not for XML/HTTP
|
||||
throw new IllegalArgumentException();
|
||||
switch(version) {
|
||||
case SOAP_11:
|
||||
return new StreamSOAP11Codec();
|
||||
case SOAP_12:
|
||||
return new StreamSOAP12Codec();
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a new {@link StreamSOAPCodec} instance using binding
|
||||
*/
|
||||
public static StreamSOAPCodec create(WSFeatureList features) {
|
||||
SOAPVersion version = getSoapVersion(features);
|
||||
if(version==null)
|
||||
// this decoder is for SOAP, not for XML/HTTP
|
||||
throw new IllegalArgumentException();
|
||||
switch(version) {
|
||||
case SOAP_11:
|
||||
return new StreamSOAP11Codec(features);
|
||||
case SOAP_12:
|
||||
return new StreamSOAP12Codec(features);
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link StreamSOAPCodec} instance using binding
|
||||
*
|
||||
* @deprecated use {@link #create(WSFeatureList)}
|
||||
*/
|
||||
public static StreamSOAPCodec create(WSBinding binding) {
|
||||
SOAPVersion version = binding.getSOAPVersion();
|
||||
if(version==null)
|
||||
// this decoder is for SOAP, not for XML/HTTP
|
||||
throw new IllegalArgumentException();
|
||||
switch(version) {
|
||||
case SOAP_11:
|
||||
return new StreamSOAP11Codec(binding);
|
||||
case SOAP_12:
|
||||
return new StreamSOAP12Codec(binding);
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
private String getPacketEncoding(Packet packet) {
|
||||
// If SerializationFeature is set, just use that encoding
|
||||
if (serializationFeature != null && serializationFeature.getEncoding() != null) {
|
||||
return serializationFeature.getEncoding().equals("")
|
||||
? SOAPBindingCodec.DEFAULT_ENCODING : serializationFeature.getEncoding();
|
||||
}
|
||||
|
||||
if (packet != null && packet.endpoint != null) {
|
||||
// Use request message's encoding for Server-side response messages
|
||||
String charset = (String)packet.invocationProperties.get(DECODED_MESSAGE_CHARSET);
|
||||
return charset == null
|
||||
? SOAPBindingCodec.DEFAULT_ENCODING : charset;
|
||||
}
|
||||
|
||||
// Use default encoding for client-side request messages
|
||||
return SOAPBindingCodec.DEFAULT_ENCODING;
|
||||
}
|
||||
|
||||
protected ContentTypeImpl.Builder getContenTypeBuilder(Packet packet) {
|
||||
ContentTypeImpl.Builder b = new ContentTypeImpl.Builder();
|
||||
String encoding = getPacketEncoding(packet);
|
||||
if (SOAPBindingCodec.DEFAULT_ENCODING.equalsIgnoreCase(encoding)) {
|
||||
b.contentType = getDefaultContentType();
|
||||
b.charset = SOAPBindingCodec.DEFAULT_ENCODING;
|
||||
return b;
|
||||
}
|
||||
b.contentType = getMimeType()+" ;charset="+encoding;
|
||||
b.charset = encoding;
|
||||
return b;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import javax.activation.ActivationDataFlavor;
|
||||
import javax.activation.DataSource;
|
||||
import javax.activation.DataContentHandler;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* JavaMail's data content handler for text/plain -->String
|
||||
*/
|
||||
public class StringDataContentHandler implements DataContentHandler {
|
||||
private static final ActivationDataFlavor myDF = new ActivationDataFlavor(
|
||||
java.lang.String.class, "text/plain", "Text String");
|
||||
|
||||
protected ActivationDataFlavor getDF() {
|
||||
return myDF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DataFlavors for this <code>DataContentHandler</code>.
|
||||
*
|
||||
* @return The DataFlavors
|
||||
*/
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return new DataFlavor[]{getDF()};
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Transfer Data of type DataFlavor from InputStream.
|
||||
*
|
||||
* @param df The DataFlavor
|
||||
* @param ds The DataSource corresponding to the data
|
||||
* @return String object
|
||||
*/
|
||||
public Object getTransferData(DataFlavor df, DataSource ds)
|
||||
throws IOException {
|
||||
// use myDF.equals to be sure to get ActivationDataFlavor.equals,
|
||||
// which properly ignores Content-Type parameters in comparison
|
||||
if (getDF().equals(df))
|
||||
return getContent(ds);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getContent(DataSource ds) throws IOException {
|
||||
String enc = null;
|
||||
InputStreamReader is;
|
||||
|
||||
try {
|
||||
enc = getCharset(ds.getContentType());
|
||||
is = new InputStreamReader(ds.getInputStream(), enc);
|
||||
} catch (IllegalArgumentException iex) {
|
||||
/*
|
||||
* An unknown charset of the form ISO-XXX-XXX will cause
|
||||
* the JDK to throw an IllegalArgumentException. The
|
||||
* JDK will attempt to create a classname using this string,
|
||||
* but valid classnames must not contain the character '-',
|
||||
* and this results in an IllegalArgumentException, rather than
|
||||
* the expected UnsupportedEncodingException. Yikes.
|
||||
*/
|
||||
throw new UnsupportedEncodingException(enc);
|
||||
}
|
||||
|
||||
try {
|
||||
int pos = 0;
|
||||
int count;
|
||||
char buf[] = new char[1024];
|
||||
|
||||
while ((count = is.read(buf, pos, buf.length - pos)) != -1) {
|
||||
pos += count;
|
||||
if (pos >= buf.length) {
|
||||
int size = buf.length;
|
||||
if (size < 256 * 1024)
|
||||
size += size;
|
||||
else
|
||||
size += 256 * 1024;
|
||||
char tbuf[] = new char[size];
|
||||
System.arraycopy(buf, 0, tbuf, 0, pos);
|
||||
buf = tbuf;
|
||||
}
|
||||
}
|
||||
return new String(buf, 0, pos);
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException ex) {
|
||||
// not much can be done
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the object to the output stream, using the specified MIME type.
|
||||
*/
|
||||
public void writeTo(Object obj, String type, OutputStream os)
|
||||
throws IOException {
|
||||
if (!(obj instanceof String))
|
||||
throw new IOException("\"" + getDF().getMimeType() +
|
||||
"\" DataContentHandler requires String object, " +
|
||||
"was given object of type " + obj.getClass().toString());
|
||||
|
||||
String enc = null;
|
||||
OutputStreamWriter osw;
|
||||
|
||||
try {
|
||||
enc = getCharset(type);
|
||||
osw = new OutputStreamWriter(os, enc);
|
||||
} catch (IllegalArgumentException iex) {
|
||||
/*
|
||||
* An unknown charset of the form ISO-XXX-XXX will cause
|
||||
* the JDK to throw an IllegalArgumentException. The
|
||||
* JDK will attempt to create a classname using this string,
|
||||
* but valid classnames must not contain the character '-',
|
||||
* and this results in an IllegalArgumentException, rather than
|
||||
* the expected UnsupportedEncodingException. Yikes.
|
||||
*/
|
||||
throw new UnsupportedEncodingException(enc);
|
||||
}
|
||||
|
||||
String s = (String) obj;
|
||||
osw.write(s, 0, s.length());
|
||||
osw.flush();
|
||||
}
|
||||
|
||||
private String getCharset(String type) {
|
||||
try {
|
||||
ContentType ct = new ContentType(type);
|
||||
String charset = ct.getParameter("charset");
|
||||
if (charset == null)
|
||||
// If the charset parameter is absent, use US-ASCII.
|
||||
charset = "us-ascii";
|
||||
|
||||
return Charset.forName(charset).name();
|
||||
//return MimeUtility.javaCharset(charset);
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
83
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/SwACodec.java
Normal file
83
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/SwACodec.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSFeatureList;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.message.Attachment;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
import com.sun.xml.internal.ws.api.pipe.ContentType;
|
||||
import com.sun.xml.internal.ws.message.MimeAttachmentSet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.ws.WebServiceFeature;
|
||||
|
||||
/**
|
||||
* {@link Codec} that uses MIME/multipart as the base format.
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public final class SwACodec extends MimeCodec {
|
||||
|
||||
public SwACodec(SOAPVersion version, WSFeatureList f, Codec rootCodec) {
|
||||
super(version, f);
|
||||
this.mimeRootCodec = rootCodec;
|
||||
}
|
||||
|
||||
private SwACodec(SwACodec that) {
|
||||
super(that);
|
||||
this.mimeRootCodec = that.mimeRootCodec.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decode(MimeMultipartParser mpp, Packet packet) throws IOException {
|
||||
// TODO: handle attachments correctly
|
||||
Attachment root = mpp.getRootPart();
|
||||
Codec rootCodec = getMimeRootCodec(packet);
|
||||
if (rootCodec instanceof RootOnlyCodec) {
|
||||
((RootOnlyCodec)rootCodec).decode(root.asInputStream(),root.getContentType(),packet, new MimeAttachmentSet(mpp));
|
||||
} else {
|
||||
rootCodec.decode(root.asInputStream(),root.getContentType(),packet);
|
||||
Map<String, Attachment> atts = mpp.getAttachmentParts();
|
||||
for(Map.Entry<String, Attachment> att : atts.entrySet()) {
|
||||
packet.getMessage().getAttachments().add(att.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ContentType encode(Packet packet, WritableByteChannel buffer) {
|
||||
//TODO: not yet implemented
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public SwACodec copy() {
|
||||
return new SwACodec(this);
|
||||
}
|
||||
}
|
||||
257
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/TagInfoset.java
Normal file
257
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/TagInfoset.java
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.xml.sax.helpers.AttributesImpl;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
|
||||
import com.sun.xml.internal.ws.message.stream.StreamMessage;
|
||||
import com.sun.xml.internal.ws.encoding.StreamSOAPCodec;
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import com.sun.istack.internal.NotNull;
|
||||
|
||||
/**
|
||||
* Complete infoset about a start tag.
|
||||
*
|
||||
* <p>
|
||||
* This is used between {@link StreamMessage} and {@link StreamSOAPCodec}
|
||||
* to capture the infoset of the s:Envelope, s:Header, and s:Body elements.
|
||||
*
|
||||
*
|
||||
* <h3>Design Note</h3>
|
||||
* <p>
|
||||
* Since StAX and SAX uses different null vs empty string convention, one has
|
||||
* to choose which format we store things. It can go either way, but I'm assuming
|
||||
* that we'll be using StAX more in JAX-WS, so things are kept in the StAX style
|
||||
* in this class.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public final class TagInfoset {
|
||||
/**
|
||||
* Namespace declarations on this tag. Read-only.
|
||||
*
|
||||
* This is an array of the even length of the form { prefix0, uri0, prefix1, uri1, ... }.
|
||||
*
|
||||
* URIs/prefixes can be null (StAX-style)
|
||||
*/
|
||||
public final @NotNull String[] ns;
|
||||
/**
|
||||
* Attributes on this tag. Read-only.
|
||||
*/
|
||||
public final @NotNull AttributesImpl atts;
|
||||
|
||||
/**
|
||||
* Prefix of the start tag in stax-style.
|
||||
*/
|
||||
public final @Nullable String prefix;
|
||||
|
||||
/**
|
||||
* Namespace URI of the start tag in stax-style.
|
||||
*/
|
||||
public final @Nullable String nsUri;
|
||||
|
||||
/**
|
||||
* Local name of the start tag.
|
||||
*/
|
||||
public final @NotNull String localName;
|
||||
|
||||
/**
|
||||
* Lazily computed QName (i.e., "foo:bar")
|
||||
*/
|
||||
private @Nullable String qname;
|
||||
|
||||
public TagInfoset(String nsUri, String localName, String prefix, AttributesImpl atts, String... ns) {
|
||||
this.nsUri = nsUri;
|
||||
this.prefix = prefix;
|
||||
this.localName = localName;
|
||||
this.atts = atts;
|
||||
this.ns = ns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills a {@link TagInfoset} object by the current element
|
||||
* that the reader points to.
|
||||
*/
|
||||
public TagInfoset(XMLStreamReader reader) {
|
||||
prefix = reader.getPrefix();
|
||||
nsUri = reader.getNamespaceURI();
|
||||
localName = reader.getLocalName();
|
||||
|
||||
int nsc = reader.getNamespaceCount();
|
||||
if(nsc>0) {
|
||||
ns = new String[nsc*2];
|
||||
for(int i=0; i<nsc; i++){
|
||||
ns[i*2 ] = fixNull(reader.getNamespacePrefix(i));
|
||||
ns[i*2+1] = fixNull(reader.getNamespaceURI(i));
|
||||
}
|
||||
} else {
|
||||
ns = EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
int ac = reader.getAttributeCount();
|
||||
if(ac>0) {
|
||||
atts = new AttributesImpl();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(int i=0; i< ac;i++){
|
||||
sb.setLength(0);
|
||||
String prefix = reader.getAttributePrefix(i);
|
||||
String localName = reader.getAttributeLocalName(i);
|
||||
|
||||
String qname;
|
||||
if(prefix != null && prefix.length()!=0){
|
||||
sb.append(prefix);
|
||||
sb.append(":");
|
||||
sb.append(localName);
|
||||
qname = sb.toString();
|
||||
} else {
|
||||
qname = localName;
|
||||
}
|
||||
|
||||
atts.addAttribute(
|
||||
fixNull(reader.getAttributeNamespace(i)),
|
||||
localName,
|
||||
qname,
|
||||
reader.getAttributeType(i),
|
||||
reader.getAttributeValue(i));
|
||||
}
|
||||
} else {
|
||||
atts = EMPTY_ATTRIBUTES;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the start element event.
|
||||
*/
|
||||
public void writeStart(ContentHandler contentHandler) throws SAXException {
|
||||
for( int i=0; i<ns.length; i+=2 )
|
||||
contentHandler.startPrefixMapping(fixNull(ns[i]),fixNull(ns[i+1]));
|
||||
contentHandler.startElement(fixNull(nsUri), localName ,getQName(), atts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the end element event.
|
||||
*/
|
||||
public void writeEnd(ContentHandler contentHandler) throws SAXException{
|
||||
contentHandler.endElement(fixNull(nsUri),localName,getQName());
|
||||
for( int i=ns.length-2; i>=0; i-=2 ) {
|
||||
contentHandler.endPrefixMapping(fixNull(ns[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the start element event.
|
||||
*/
|
||||
public void writeStart(XMLStreamWriter w) throws XMLStreamException {
|
||||
// write start tag.
|
||||
if(prefix==null) {
|
||||
if(nsUri==null)
|
||||
w.writeStartElement(localName);
|
||||
else {
|
||||
//fix Null prefix. otherwise throws XMLStreamException,
|
||||
// if the namespace URI has not been bound to a prefix
|
||||
w.writeStartElement("",localName,nsUri);
|
||||
}
|
||||
} else {
|
||||
w.writeStartElement(prefix,localName,nsUri);
|
||||
}
|
||||
|
||||
for( int i=0; i<ns.length; i+=2 ) {
|
||||
w.writeNamespace(ns[i],ns[i+1]);
|
||||
}
|
||||
|
||||
for( int i=0; i<atts.getLength(); i++ ) {
|
||||
String nsUri = atts.getURI(i);
|
||||
if(nsUri==null || nsUri.length() ==0) {
|
||||
w.writeAttribute(atts.getLocalName(i),atts.getValue(i));
|
||||
} else {
|
||||
String rawName = atts.getQName(i);
|
||||
String prefix = rawName.substring(0,rawName.indexOf(':'));
|
||||
w.writeAttribute(prefix,nsUri,atts.getLocalName(i),atts.getValue(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getQName() {
|
||||
if(qname!=null) return qname;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if(prefix!=null){
|
||||
sb.append(prefix);
|
||||
sb.append(':');
|
||||
sb.append(localName);
|
||||
qname = sb.toString();
|
||||
} else {
|
||||
qname = localName;
|
||||
}
|
||||
return qname;
|
||||
}
|
||||
private static String fixNull(String s) {
|
||||
if(s==null) return "";
|
||||
else return s;
|
||||
}
|
||||
|
||||
private static final String[] EMPTY_ARRAY = new String[0];
|
||||
private static final AttributesImpl EMPTY_ATTRIBUTES = new AttributesImpl();
|
||||
|
||||
public String getNamespaceURI(String prefix) {
|
||||
int size = ns.length/2;
|
||||
for(int i=0; i<size; i++){
|
||||
String p = ns[i*2 ];
|
||||
String n = ns[i*2+1];
|
||||
if (prefix.equals(p)) return n;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getPrefix(String namespaceURI) {
|
||||
int size = ns.length/2;
|
||||
for(int i=0; i<size; i++){
|
||||
String p = ns[i*2 ];
|
||||
String n = ns[i*2+1];
|
||||
if (namespaceURI.equals(n)) return p;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
//Who wants this?
|
||||
public List<String> allPrefixes(String namespaceURI) {
|
||||
int size = ns.length/2;
|
||||
List<String> l = new java.util.ArrayList<String>();
|
||||
for(int i=0; i<size; i++){
|
||||
String p = ns[i*2 ];
|
||||
String n = ns[i*2+1];
|
||||
if (namespaceURI.equals(n)) l.add(p);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSFeatureList;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
import com.sun.xml.internal.ws.api.pipe.ContentType;
|
||||
import com.sun.xml.internal.ws.client.ContentNegotiation;
|
||||
import com.sun.xml.internal.ws.encoding.xml.XMLCodec;
|
||||
import com.sun.xml.internal.ws.encoding.xml.XMLMessage;
|
||||
import com.sun.xml.internal.ws.encoding.xml.XMLMessage.MessageDataSource;
|
||||
import com.sun.xml.internal.ws.encoding.xml.XMLMessage.UnknownContent;
|
||||
import com.sun.xml.internal.ws.encoding.xml.XMLMessage.XMLMultiPart;
|
||||
import com.sun.xml.internal.ws.resources.StreamingMessages;
|
||||
import com.sun.xml.internal.ws.util.ByteArrayBuffer;
|
||||
|
||||
import javax.activation.DataSource;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* XML (infoset) over HTTP binding {@link Codec}.
|
||||
* <p>
|
||||
* TODO: Support FI for multipart/related
|
||||
* Support FI for MessageDataSource
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public final class XMLHTTPBindingCodec extends MimeCodec {
|
||||
/**
|
||||
* Base HTTP Accept request-header.
|
||||
*/
|
||||
private static final String BASE_ACCEPT_VALUE =
|
||||
"*";
|
||||
|
||||
/**
|
||||
* Fast Infoset MIME type.
|
||||
*/
|
||||
private static final String APPLICATION_FAST_INFOSET_MIME_TYPE =
|
||||
"application/fastinfoset";
|
||||
|
||||
/**
|
||||
* True if the Fast Infoset codec should be used
|
||||
*/
|
||||
private boolean useFastInfosetForEncoding;
|
||||
|
||||
/**
|
||||
* The XML codec
|
||||
*/
|
||||
private final Codec xmlCodec;
|
||||
|
||||
/**
|
||||
* The FI codec
|
||||
*/
|
||||
private final Codec fiCodec;
|
||||
|
||||
/**
|
||||
* The Accept header for XML encodings
|
||||
*/
|
||||
private static final String xmlAccept = null;
|
||||
|
||||
/**
|
||||
* The Accept header for Fast Infoset and XML encodings
|
||||
*/
|
||||
private static final String fiXmlAccept = APPLICATION_FAST_INFOSET_MIME_TYPE + ", " + BASE_ACCEPT_VALUE;
|
||||
|
||||
private ContentTypeImpl setAcceptHeader(Packet p, ContentType c) {
|
||||
ContentTypeImpl ctImpl = (ContentTypeImpl)c;
|
||||
if (p.contentNegotiation == ContentNegotiation.optimistic
|
||||
|| p.contentNegotiation == ContentNegotiation.pessimistic) {
|
||||
ctImpl.setAcceptHeader(fiXmlAccept);
|
||||
} else {
|
||||
ctImpl.setAcceptHeader(xmlAccept);
|
||||
}
|
||||
p.setContentType(ctImpl);
|
||||
return ctImpl;
|
||||
}
|
||||
|
||||
public XMLHTTPBindingCodec(WSFeatureList f) {
|
||||
super(SOAPVersion.SOAP_11, f);
|
||||
|
||||
xmlCodec = new XMLCodec(f);
|
||||
|
||||
fiCodec = getFICodec();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMimeType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentType getStaticContentType(Packet packet) {
|
||||
ContentType ct;
|
||||
if (packet.getInternalMessage() instanceof MessageDataSource) {
|
||||
final MessageDataSource mds = (MessageDataSource)packet.getInternalMessage();
|
||||
if (mds.hasUnconsumedDataSource()) {
|
||||
ct = getStaticContentType(mds);
|
||||
return (ct != null)
|
||||
? setAcceptHeader(packet, ct) //_adaptingContentType.set(packet, ct)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
ct = super.getStaticContentType(packet);
|
||||
return (ct != null)
|
||||
? setAcceptHeader(packet, ct) //_adaptingContentType.set(packet, ct)
|
||||
: null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentType encode(Packet packet, OutputStream out) throws IOException {
|
||||
if (packet.getInternalMessage() instanceof MessageDataSource) {
|
||||
final MessageDataSource mds = (MessageDataSource)packet.getInternalMessage();
|
||||
if (mds.hasUnconsumedDataSource())
|
||||
return setAcceptHeader(packet, encode(mds, out));
|
||||
}
|
||||
|
||||
return setAcceptHeader(packet, super.encode(packet, out));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentType encode(Packet packet, WritableByteChannel buffer) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(InputStream in, String contentType, Packet packet) throws IOException {
|
||||
/**
|
||||
* Reset the encoding state when on the server side for each
|
||||
* decode/encode step.
|
||||
*/
|
||||
if (packet.contentNegotiation == null)
|
||||
useFastInfosetForEncoding = false;
|
||||
|
||||
if (contentType == null) {
|
||||
xmlCodec.decode(in, contentType, packet);
|
||||
} else if (isMultipartRelated(contentType)) {
|
||||
packet.setMessage(new XMLMultiPart(contentType, in, features));
|
||||
} else if(isFastInfoset(contentType)) {
|
||||
if (fiCodec == null) {
|
||||
throw new RuntimeException(StreamingMessages.FASTINFOSET_NO_IMPLEMENTATION());
|
||||
}
|
||||
|
||||
useFastInfosetForEncoding = true;
|
||||
fiCodec.decode(in, contentType, packet);
|
||||
} else if (isXml(contentType)) {
|
||||
xmlCodec.decode(in, contentType, packet);
|
||||
} else {
|
||||
packet.setMessage(new UnknownContent(contentType, in));
|
||||
}
|
||||
|
||||
if (!useFastInfosetForEncoding) {
|
||||
useFastInfosetForEncoding = isFastInfosetAcceptable(packet.acceptableMimeTypes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decode(MimeMultipartParser mpp, Packet packet) throws IOException {
|
||||
// This method will never be invoked
|
||||
}
|
||||
|
||||
@Override
|
||||
public MimeCodec copy() {
|
||||
return new XMLHTTPBindingCodec(features);
|
||||
}
|
||||
|
||||
private boolean isMultipartRelated(String contentType) {
|
||||
return compareStrings(contentType, MimeCodec.MULTIPART_RELATED_MIME_TYPE);
|
||||
}
|
||||
|
||||
private boolean isXml(String contentType) {
|
||||
return compareStrings(contentType, XMLCodec.XML_APPLICATION_MIME_TYPE)
|
||||
|| compareStrings(contentType, XMLCodec.XML_TEXT_MIME_TYPE)
|
||||
|| (compareStrings(contentType, "application/")&&(contentType.toLowerCase().indexOf("+xml") != -1));
|
||||
}
|
||||
|
||||
private boolean isFastInfoset(String contentType) {
|
||||
return compareStrings(contentType, APPLICATION_FAST_INFOSET_MIME_TYPE);
|
||||
}
|
||||
|
||||
private boolean compareStrings(String a, String b) {
|
||||
return a.length() >= b.length() &&
|
||||
b.equalsIgnoreCase(
|
||||
a.substring(0,
|
||||
b.length()));
|
||||
}
|
||||
|
||||
private boolean isFastInfosetAcceptable(String accept) {
|
||||
if (accept == null) return false;
|
||||
|
||||
StringTokenizer st = new StringTokenizer(accept, ",");
|
||||
while (st.hasMoreTokens()) {
|
||||
final String token = st.nextToken().trim();
|
||||
if (token.equalsIgnoreCase(APPLICATION_FAST_INFOSET_MIME_TYPE)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private ContentType getStaticContentType(MessageDataSource mds) {
|
||||
final String contentType = mds.getDataSource().getContentType();
|
||||
final boolean isFastInfoset = XMLMessage.isFastInfoset(contentType);
|
||||
|
||||
if (!requiresTransformationOfDataSource(isFastInfoset,
|
||||
useFastInfosetForEncoding)) {
|
||||
return new ContentTypeImpl(contentType);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private ContentType encode(MessageDataSource mds, OutputStream out) {
|
||||
try {
|
||||
final boolean isFastInfoset = XMLMessage.isFastInfoset(
|
||||
mds.getDataSource().getContentType());
|
||||
DataSource ds = transformDataSource(mds.getDataSource(),
|
||||
isFastInfoset, useFastInfosetForEncoding, features);
|
||||
|
||||
InputStream is = ds.getInputStream();
|
||||
byte[] buf = new byte[1024];
|
||||
int count;
|
||||
while((count=is.read(buf)) != -1) {
|
||||
out.write(buf, 0, count);
|
||||
}
|
||||
return new ContentTypeImpl(ds.getContentType());
|
||||
} catch(IOException ioe) {
|
||||
throw new WebServiceException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Codec getMimeRootCodec(Packet p) {
|
||||
/**
|
||||
* The following logic is only for outbound packets
|
||||
* to be encoded by client.
|
||||
* On the server the p.contentNegotiation == null.
|
||||
*/
|
||||
if (p.contentNegotiation == ContentNegotiation.none) {
|
||||
// The client may have changed the negotiation property from
|
||||
// pessismistic to none between invocations
|
||||
useFastInfosetForEncoding = false;
|
||||
} else if (p.contentNegotiation == ContentNegotiation.optimistic) {
|
||||
// Always encode using Fast Infoset if in optimisitic mode
|
||||
useFastInfosetForEncoding = true;
|
||||
}
|
||||
|
||||
return (useFastInfosetForEncoding && fiCodec != null)? fiCodec : xmlCodec;
|
||||
}
|
||||
|
||||
public static boolean requiresTransformationOfDataSource(
|
||||
boolean isFastInfoset, boolean useFastInfoset) {
|
||||
return (isFastInfoset && !useFastInfoset) || (!isFastInfoset && useFastInfoset);
|
||||
}
|
||||
|
||||
public static DataSource transformDataSource(DataSource in,
|
||||
boolean isFastInfoset, boolean useFastInfoset, WSFeatureList f) {
|
||||
try {
|
||||
if (isFastInfoset && !useFastInfoset) {
|
||||
// Convert from Fast Infoset to XML
|
||||
Codec codec = new XMLHTTPBindingCodec(f);
|
||||
Packet p = new Packet();
|
||||
codec.decode(in.getInputStream(), in.getContentType(), p);
|
||||
|
||||
p.getMessage().getAttachments();
|
||||
codec.getStaticContentType(p);
|
||||
|
||||
ByteArrayBuffer bos = new ByteArrayBuffer();
|
||||
ContentType ct = codec.encode(p, bos);
|
||||
return XMLMessage.createDataSource(ct.getContentType(), bos.newInputStream());
|
||||
} else if (!isFastInfoset && useFastInfoset) {
|
||||
// Convert from XML to Fast Infoset
|
||||
Codec codec = new XMLHTTPBindingCodec(f);
|
||||
Packet p = new Packet();
|
||||
codec.decode(in.getInputStream(), in.getContentType(), p);
|
||||
|
||||
p.contentNegotiation = ContentNegotiation.optimistic;
|
||||
p.getMessage().getAttachments();
|
||||
codec.getStaticContentType(p);
|
||||
|
||||
ByteArrayBuffer bos = new ByteArrayBuffer();
|
||||
com.sun.xml.internal.ws.api.pipe.ContentType ct = codec.encode(p, bos);
|
||||
return XMLMessage.createDataSource(ct.getContentType(), bos.newInputStream());
|
||||
}
|
||||
} catch(Exception ex) {
|
||||
throw new WebServiceException(ex);
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain an FI SOAP codec instance using reflection.
|
||||
*/
|
||||
private static Codec getFICodec() {
|
||||
try {
|
||||
Class c = Class.forName("com.sun.xml.internal.ws.encoding.fastinfoset.FastInfosetCodec");
|
||||
Method m = c.getMethod("create");
|
||||
return (Codec)m.invoke(null);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding;
|
||||
|
||||
import com.sun.xml.internal.ws.util.xml.XmlUtil;
|
||||
|
||||
import javax.activation.ActivationDataFlavor;
|
||||
import javax.activation.DataContentHandler;
|
||||
import javax.activation.DataSource;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* JAF data handler for XML content
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public class XmlDataContentHandler implements DataContentHandler {
|
||||
|
||||
private final DataFlavor[] flavors;
|
||||
|
||||
public XmlDataContentHandler() throws ClassNotFoundException {
|
||||
flavors = new DataFlavor[3];
|
||||
flavors[0] = new ActivationDataFlavor(StreamSource.class, "text/xml", "XML");
|
||||
flavors[1] = new ActivationDataFlavor(StreamSource.class, "application/xml", "XML");
|
||||
flavors[2] = new ActivationDataFlavor(String.class, "text/xml", "XML String");
|
||||
}
|
||||
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
return Arrays.copyOf(flavors, flavors.length);
|
||||
}
|
||||
|
||||
public Object getTransferData(DataFlavor df, DataSource ds)
|
||||
throws IOException {
|
||||
|
||||
for (DataFlavor aFlavor : flavors) {
|
||||
if (aFlavor.equals(df)) {
|
||||
return getContent(ds);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an object from the input stream
|
||||
*/
|
||||
public Object getContent(DataSource ds) throws IOException {
|
||||
String ctStr = ds.getContentType();
|
||||
String charset = null;
|
||||
if (ctStr != null) {
|
||||
ContentType ct = new ContentType(ctStr);
|
||||
if (!isXml(ct)) {
|
||||
throw new IOException(
|
||||
"Cannot convert DataSource with content type \""
|
||||
+ ctStr + "\" to object in XmlDataContentHandler");
|
||||
}
|
||||
charset = ct.getParameter("charset");
|
||||
}
|
||||
return (charset != null)
|
||||
? new StreamSource(new InputStreamReader(ds.getInputStream()), charset)
|
||||
: new StreamSource(ds.getInputStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the object to a byte stream
|
||||
*/
|
||||
public void writeTo(Object obj, String mimeType, OutputStream os)
|
||||
throws IOException {
|
||||
|
||||
if (!(obj instanceof DataSource || obj instanceof Source || obj instanceof String)) {
|
||||
throw new IOException("Invalid Object type = "+obj.getClass()+
|
||||
". XmlDataContentHandler can only convert DataSource|Source|String to XML.");
|
||||
}
|
||||
|
||||
ContentType ct = new ContentType(mimeType);
|
||||
if (!isXml(ct)) {
|
||||
throw new IOException(
|
||||
"Invalid content type \"" + mimeType + "\" for XmlDataContentHandler");
|
||||
}
|
||||
|
||||
String charset = ct.getParameter("charset");
|
||||
if (obj instanceof String) {
|
||||
String s = (String) obj;
|
||||
if (charset == null) {
|
||||
charset = "utf-8";
|
||||
}
|
||||
OutputStreamWriter osw = new OutputStreamWriter(os, charset);
|
||||
osw.write(s, 0, s.length());
|
||||
osw.flush();
|
||||
return;
|
||||
}
|
||||
|
||||
Source source = (obj instanceof DataSource)
|
||||
? (Source)getContent((DataSource)obj) : (Source)obj;
|
||||
try {
|
||||
Transformer transformer = XmlUtil.newTransformer();
|
||||
if (charset != null) {
|
||||
transformer.setOutputProperty(OutputKeys.ENCODING, charset);
|
||||
}
|
||||
StreamResult result = new StreamResult(os);
|
||||
transformer.transform(source, result);
|
||||
} catch (Exception ex) {
|
||||
throw new IOException(
|
||||
"Unable to run the JAXP transformer in XmlDataContentHandler "
|
||||
+ ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isXml(ContentType ct) {
|
||||
return ct.getSubType().equals("xml") &&
|
||||
(ct.getPrimaryType().equals("text") || ct.getPrimaryType().equals("application"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.fastinfoset;
|
||||
|
||||
import com.sun.xml.internal.fastinfoset.stax.StAXDocumentSerializer;
|
||||
import com.sun.xml.internal.fastinfoset.stax.StAXDocumentParser;
|
||||
import com.sun.xml.internal.fastinfoset.vocab.ParserVocabulary;
|
||||
import com.sun.xml.internal.fastinfoset.vocab.SerializerVocabulary;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Messages;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
import com.sun.xml.internal.ws.api.pipe.ContentType;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.encoding.ContentTypeImpl;
|
||||
import java.io.BufferedInputStream;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetSource;
|
||||
|
||||
/**
|
||||
* A codec for encoding/decoding XML infosets to/from fast
|
||||
* infoset documents.
|
||||
*
|
||||
* @author Paul Sandoz
|
||||
*/
|
||||
public class FastInfosetCodec implements Codec {
|
||||
private static final int DEFAULT_INDEXED_STRING_SIZE_LIMIT = 32;
|
||||
private static final int DEFAULT_INDEXED_STRING_MEMORY_LIMIT = 4 * 1024 * 1024; //4M limit
|
||||
|
||||
private StAXDocumentParser _parser;
|
||||
|
||||
private StAXDocumentSerializer _serializer;
|
||||
|
||||
private final boolean _retainState;
|
||||
|
||||
private final ContentType _contentType;
|
||||
|
||||
/* package */ FastInfosetCodec(boolean retainState) {
|
||||
_retainState = retainState;
|
||||
_contentType = (retainState) ? new ContentTypeImpl(FastInfosetMIMETypes.STATEFUL_INFOSET) :
|
||||
new ContentTypeImpl(FastInfosetMIMETypes.INFOSET);
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return _contentType.getContentType();
|
||||
}
|
||||
|
||||
public Codec copy() {
|
||||
return new FastInfosetCodec(_retainState);
|
||||
}
|
||||
|
||||
public ContentType getStaticContentType(Packet packet) {
|
||||
return _contentType;
|
||||
}
|
||||
|
||||
public ContentType encode(Packet packet, OutputStream out) {
|
||||
Message message = packet.getMessage();
|
||||
if (message != null && message.hasPayload()) {
|
||||
final XMLStreamWriter writer = getXMLStreamWriter(out);
|
||||
try {
|
||||
writer.writeStartDocument();
|
||||
packet.getMessage().writePayloadTo(writer);
|
||||
writer.writeEndDocument();
|
||||
writer.flush();
|
||||
} catch (XMLStreamException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return _contentType;
|
||||
}
|
||||
|
||||
public ContentType encode(Packet packet, WritableByteChannel buffer) {
|
||||
//TODO: not yet implemented
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void decode(InputStream in, String contentType, Packet packet) throws IOException {
|
||||
/* Implements similar logic as the XMLMessage.create(String, InputStream).
|
||||
* But it's faster, as we know the InputStream has FastInfoset content*/
|
||||
Message message;
|
||||
in = hasSomeData(in);
|
||||
if (in != null) {
|
||||
message = Messages.createUsingPayload(new FastInfosetSource(in),
|
||||
SOAPVersion.SOAP_11);
|
||||
} else {
|
||||
message = Messages.createEmpty(SOAPVersion.SOAP_11);
|
||||
}
|
||||
|
||||
packet.setMessage(message);
|
||||
}
|
||||
|
||||
public void decode(ReadableByteChannel in, String contentType, Packet response) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private XMLStreamWriter getXMLStreamWriter(OutputStream out) {
|
||||
if (_serializer != null) {
|
||||
_serializer.setOutputStream(out);
|
||||
return _serializer;
|
||||
} else {
|
||||
return _serializer = createNewStreamWriter(out, _retainState);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link FastInfosetCodec} instance.
|
||||
*
|
||||
* @return a new {@link FastInfosetCodec} instance.
|
||||
*/
|
||||
public static FastInfosetCodec create() {
|
||||
return create(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link FastInfosetCodec} instance.
|
||||
*
|
||||
* @param retainState if true the Codec should retain the state of
|
||||
* vocabulary tables for multiple encode/decode invocations.
|
||||
* @return a new {@link FastInfosetCodec} instance.
|
||||
*/
|
||||
public static FastInfosetCodec create(boolean retainState) {
|
||||
return new FastInfosetCodec(retainState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new (@link StAXDocumentSerializer} instance.
|
||||
*
|
||||
* @param in the OutputStream to serialize to.
|
||||
* @param retainState if true the serializer should retain the state of
|
||||
* vocabulary tables for multiple serializations.
|
||||
* @return a new {@link StAXDocumentSerializer} instance.
|
||||
*/
|
||||
/* package */ static StAXDocumentSerializer createNewStreamWriter(OutputStream out, boolean retainState) {
|
||||
return createNewStreamWriter(out, retainState, DEFAULT_INDEXED_STRING_SIZE_LIMIT, DEFAULT_INDEXED_STRING_MEMORY_LIMIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new (@link StAXDocumentSerializer} instance.
|
||||
*
|
||||
* @param in the OutputStream to serialize to.
|
||||
* @param retainState if true the serializer should retain the state of
|
||||
* vocabulary tables for multiple serializations.
|
||||
* @return a new {@link StAXDocumentSerializer} instance.
|
||||
*/
|
||||
/* package */ static StAXDocumentSerializer createNewStreamWriter(OutputStream out,
|
||||
boolean retainState, int indexedStringSizeLimit, int stringsMemoryLimit) {
|
||||
StAXDocumentSerializer serializer = new StAXDocumentSerializer(out);
|
||||
if (retainState) {
|
||||
/**
|
||||
* Create a serializer vocabulary external to the serializer.
|
||||
* This will ensure that the vocabulary will never be cleared
|
||||
* for each serialization and will be retained (and will grow)
|
||||
* for each serialization
|
||||
*/
|
||||
SerializerVocabulary vocabulary = new SerializerVocabulary();
|
||||
serializer.setVocabulary(vocabulary);
|
||||
serializer.setMinAttributeValueSize(0);
|
||||
serializer.setMaxAttributeValueSize(indexedStringSizeLimit);
|
||||
serializer.setMinCharacterContentChunkSize(0);
|
||||
serializer.setMaxCharacterContentChunkSize(indexedStringSizeLimit);
|
||||
serializer.setAttributeValueMapMemoryLimit(stringsMemoryLimit);
|
||||
serializer.setCharacterContentChunkMapMemoryLimit(stringsMemoryLimit);
|
||||
}
|
||||
return serializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new (@link StAXDocumentParser} instance.
|
||||
*
|
||||
* @param in the InputStream to parse from.
|
||||
* @param retainState if true the parser should retain the state of
|
||||
* vocabulary tables for multiple parses.
|
||||
* @return a new {@link StAXDocumentParser} instance.
|
||||
*/
|
||||
/* package */ static StAXDocumentParser createNewStreamReader(InputStream in, boolean retainState) {
|
||||
StAXDocumentParser parser = new StAXDocumentParser(in);
|
||||
parser.setStringInterning(true);
|
||||
if (retainState) {
|
||||
/**
|
||||
* Create a parser vocabulary external to the parser.
|
||||
* This will ensure that the vocabulary will never be cleared
|
||||
* for each parse and will be retained (and will grow)
|
||||
* for each parse.
|
||||
*/
|
||||
ParserVocabulary vocabulary = new ParserVocabulary();
|
||||
parser.setVocabulary(vocabulary);
|
||||
}
|
||||
return parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new (@link StAXDocumentParser} recyclable instance.
|
||||
*
|
||||
* @param in the InputStream to parse from.
|
||||
* @param retainState if true the parser should retain the state of
|
||||
* vocabulary tables for multiple parses.
|
||||
* @return a new recyclable {@link StAXDocumentParser} instance.
|
||||
*/
|
||||
/* package */ static StAXDocumentParser createNewStreamReaderRecyclable(InputStream in, boolean retainState) {
|
||||
StAXDocumentParser parser = new FastInfosetStreamReaderRecyclable(in);
|
||||
parser.setStringInterning(true);
|
||||
parser.setForceStreamClose(true);
|
||||
if (retainState) {
|
||||
/**
|
||||
* Create a parser vocabulary external to the parser.
|
||||
* This will ensure that the vocabulary will never be cleared
|
||||
* for each parse and will be retained (and will grow)
|
||||
* for each parse.
|
||||
*/
|
||||
ParserVocabulary vocabulary = new ParserVocabulary();
|
||||
parser.setVocabulary(vocabulary);
|
||||
}
|
||||
return parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method is copied from com.sun.xml.internal.ws.encoding.xml.XMLMessage
|
||||
* @TODO method should be public in some util package?
|
||||
*
|
||||
* Finds if the stream has some content or not
|
||||
*
|
||||
* @return null if there is no data
|
||||
* else stream to be used
|
||||
*/
|
||||
private static InputStream hasSomeData(InputStream in) throws IOException {
|
||||
if (in != null) {
|
||||
if (in.available() < 1) {
|
||||
if (!in.markSupported()) {
|
||||
in = new BufferedInputStream(in);
|
||||
}
|
||||
in.mark(1);
|
||||
if (in.read() != -1) {
|
||||
in.reset();
|
||||
} else {
|
||||
in = null; // No data
|
||||
}
|
||||
}
|
||||
}
|
||||
return in;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.fastinfoset;
|
||||
|
||||
/**
|
||||
* MIME types for Infosets encoded as fast infoset documents.
|
||||
*
|
||||
* @author Paul.Sandoz@Sun.Com
|
||||
*/
|
||||
public final class FastInfosetMIMETypes {
|
||||
/**
|
||||
* MIME type for a generic Infoset encoded as a fast infoset document.
|
||||
*/
|
||||
static public final String INFOSET = "application/fastinfoset";
|
||||
/**
|
||||
* MIME type for a SOAP 1.1 Infoset encoded as a fast infoset document.
|
||||
*/
|
||||
static public final String SOAP_11 = "application/fastinfoset";
|
||||
/**
|
||||
* MIME type for a SOAP 1.2 Infoset encoded as a fast infoset document.
|
||||
*/
|
||||
static public final String SOAP_12 = "application/soap+fastinfoset";
|
||||
|
||||
/**
|
||||
* MIME type for a generic Infoset encoded as a stateful fast infoset document.
|
||||
*/
|
||||
static public final String STATEFUL_INFOSET = "application/vnd.sun.stateful.fastinfoset";
|
||||
/**
|
||||
* MIME type for a SOAP 1.1 Infoset encoded as a stateful fast infoset document.
|
||||
*/
|
||||
static public final String STATEFUL_SOAP_11 = "application/vnd.sun.stateful.fastinfoset";
|
||||
/**
|
||||
* MIME type for a SOAP 1.2 Infoset encoded as a stateful fast infoset document.
|
||||
*/
|
||||
static public final String STATEFUL_SOAP_12 = "application/vnd.sun.stateful.soap+fastinfoset";
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.fastinfoset;
|
||||
|
||||
import com.sun.xml.internal.fastinfoset.stax.StAXDocumentParser;
|
||||
import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
/**
|
||||
* @author Alexey Stashok
|
||||
*/
|
||||
public final class FastInfosetStreamReaderFactory extends XMLStreamReaderFactory {
|
||||
private static final FastInfosetStreamReaderFactory factory = new FastInfosetStreamReaderFactory();
|
||||
|
||||
private ThreadLocal<StAXDocumentParser> pool = new ThreadLocal<StAXDocumentParser>();
|
||||
|
||||
public static FastInfosetStreamReaderFactory getInstance() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
public XMLStreamReader doCreate(String systemId, InputStream in, boolean rejectDTDs) {
|
||||
StAXDocumentParser parser = fetch();
|
||||
if (parser == null) {
|
||||
return FastInfosetCodec.createNewStreamReaderRecyclable(in, false);
|
||||
}
|
||||
|
||||
parser.setInputStream(in);
|
||||
return parser;
|
||||
}
|
||||
|
||||
public XMLStreamReader doCreate(String systemId, Reader reader, boolean rejectDTDs) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private StAXDocumentParser fetch() {
|
||||
StAXDocumentParser parser = pool.get();
|
||||
pool.set(null);
|
||||
return parser;
|
||||
}
|
||||
|
||||
public void doRecycle(XMLStreamReader r) {
|
||||
if (r instanceof StAXDocumentParser) {
|
||||
pool.set((StAXDocumentParser) r);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.fastinfoset;
|
||||
|
||||
import com.sun.xml.internal.fastinfoset.stax.StAXDocumentParser;
|
||||
import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author Alexey Stashok
|
||||
*/
|
||||
public final class FastInfosetStreamReaderRecyclable extends StAXDocumentParser implements XMLStreamReaderFactory.RecycleAware {
|
||||
private static final FastInfosetStreamReaderFactory READER_FACTORY = FastInfosetStreamReaderFactory.getInstance();
|
||||
|
||||
public FastInfosetStreamReaderRecyclable() {
|
||||
super();
|
||||
}
|
||||
|
||||
public FastInfosetStreamReaderRecyclable(InputStream in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
public void onRecycled() {
|
||||
READER_FACTORY.doRecycle(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.fastinfoset;
|
||||
|
||||
import com.sun.xml.internal.ws.api.pipe.ContentType;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.pipe.StreamSOAPCodec;
|
||||
import com.sun.xml.internal.ws.encoding.ContentTypeImpl;
|
||||
import com.sun.xml.internal.ws.message.stream.StreamHeader;
|
||||
import com.sun.xml.internal.ws.message.stream.StreamHeader11;
|
||||
import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
/**
|
||||
* A codec that converts SOAP 1.1 messages infosets to fast infoset
|
||||
* documents.
|
||||
*
|
||||
* @author Paul.Sandoz@Sun.Com
|
||||
*/
|
||||
final class FastInfosetStreamSOAP11Codec extends FastInfosetStreamSOAPCodec {
|
||||
/*package*/ FastInfosetStreamSOAP11Codec(StreamSOAPCodec soapCodec, boolean retainState) {
|
||||
super(soapCodec, SOAPVersion.SOAP_11, retainState,
|
||||
(retainState) ? FastInfosetMIMETypes.STATEFUL_SOAP_11 : FastInfosetMIMETypes.SOAP_11);
|
||||
}
|
||||
|
||||
private FastInfosetStreamSOAP11Codec(FastInfosetStreamSOAP11Codec that) {
|
||||
super(that);
|
||||
}
|
||||
|
||||
public Codec copy() {
|
||||
return new FastInfosetStreamSOAP11Codec(this);
|
||||
}
|
||||
|
||||
protected final StreamHeader createHeader(XMLStreamReader reader, XMLStreamBuffer mark) {
|
||||
return new StreamHeader11(reader, mark);
|
||||
}
|
||||
|
||||
protected ContentType getContentType(String soapAction) {
|
||||
if (soapAction == null || soapAction.length() == 0) {
|
||||
return _defaultContentType;
|
||||
} else {
|
||||
return new ContentTypeImpl(_defaultContentType.getContentType(), soapAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.fastinfoset;
|
||||
|
||||
import com.sun.xml.internal.ws.api.pipe.ContentType;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.pipe.StreamSOAPCodec;
|
||||
import com.sun.xml.internal.ws.encoding.ContentTypeImpl;
|
||||
import com.sun.xml.internal.ws.message.stream.StreamHeader;
|
||||
import com.sun.xml.internal.ws.message.stream.StreamHeader12;
|
||||
import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
|
||||
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
|
||||
/**
|
||||
* A codec that converts SOAP 1.2 messages infosets to fast infoset
|
||||
* documents.
|
||||
*
|
||||
* @author Paul.Sandoz@Sun.Com
|
||||
*/
|
||||
final class FastInfosetStreamSOAP12Codec extends FastInfosetStreamSOAPCodec {
|
||||
/*package*/ FastInfosetStreamSOAP12Codec(StreamSOAPCodec soapCodec, boolean retainState) {
|
||||
super(soapCodec, SOAPVersion.SOAP_12, retainState,
|
||||
(retainState) ? FastInfosetMIMETypes.STATEFUL_SOAP_12 : FastInfosetMIMETypes.SOAP_12);
|
||||
}
|
||||
|
||||
private FastInfosetStreamSOAP12Codec(FastInfosetStreamSOAPCodec that) {
|
||||
super(that);
|
||||
}
|
||||
|
||||
public Codec copy() {
|
||||
return new FastInfosetStreamSOAP12Codec(this);
|
||||
}
|
||||
|
||||
protected final StreamHeader createHeader(XMLStreamReader reader, XMLStreamBuffer mark) {
|
||||
return new StreamHeader12(reader, mark);
|
||||
}
|
||||
|
||||
protected ContentType getContentType(String soapAction) {
|
||||
if (soapAction == null) {
|
||||
return _defaultContentType;
|
||||
} else {
|
||||
return new ContentTypeImpl(
|
||||
_defaultContentType.getContentType() + ";action=\""+soapAction+"\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.fastinfoset;
|
||||
|
||||
import com.sun.xml.internal.fastinfoset.stax.StAXDocumentSerializer;
|
||||
import com.sun.xml.internal.fastinfoset.stax.StAXDocumentParser;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
import com.sun.xml.internal.ws.api.pipe.ContentType;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.pipe.StreamSOAPCodec;
|
||||
import com.sun.xml.internal.ws.message.stream.StreamHeader;
|
||||
import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
|
||||
import com.sun.xml.internal.ws.encoding.ContentTypeImpl;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
|
||||
/**
|
||||
* A stream SOAP codec for handling SOAP message infosets to fast
|
||||
* infoset documents.
|
||||
*
|
||||
* <p>
|
||||
* This implementation currently defers to {@link StreamSOAPCodec} for the decoding
|
||||
* using {@link XMLStreamReader}.
|
||||
*
|
||||
* @author Paul Sandoz
|
||||
*/
|
||||
public abstract class FastInfosetStreamSOAPCodec implements Codec {
|
||||
private static final FastInfosetStreamReaderFactory READER_FACTORY = FastInfosetStreamReaderFactory.getInstance();
|
||||
|
||||
private StAXDocumentParser _statefulParser;
|
||||
private StAXDocumentSerializer _serializer;
|
||||
|
||||
private final StreamSOAPCodec _soapCodec;
|
||||
|
||||
private final boolean _retainState;
|
||||
|
||||
protected final ContentType _defaultContentType;
|
||||
|
||||
/* package */ FastInfosetStreamSOAPCodec(StreamSOAPCodec soapCodec, SOAPVersion soapVersion, boolean retainState, String mimeType) {
|
||||
// _soapCodec = StreamSOAPCodec.create(soapVersion);
|
||||
_soapCodec = soapCodec;
|
||||
_retainState = retainState;
|
||||
_defaultContentType = new ContentTypeImpl(mimeType);
|
||||
}
|
||||
|
||||
/* package */ FastInfosetStreamSOAPCodec(FastInfosetStreamSOAPCodec that) {
|
||||
this._soapCodec = (StreamSOAPCodec) that._soapCodec.copy();
|
||||
this._retainState = that._retainState;
|
||||
this._defaultContentType = that._defaultContentType;
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return _defaultContentType.getContentType();
|
||||
}
|
||||
|
||||
public ContentType getStaticContentType(Packet packet) {
|
||||
return getContentType(packet.soapAction);
|
||||
}
|
||||
|
||||
public ContentType encode(Packet packet, OutputStream out) {
|
||||
if (packet.getMessage() != null) {
|
||||
final XMLStreamWriter writer = getXMLStreamWriter(out);
|
||||
try {
|
||||
packet.getMessage().writeTo(writer);
|
||||
writer.flush();
|
||||
} catch (XMLStreamException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
}
|
||||
return getContentType(packet.soapAction);
|
||||
}
|
||||
|
||||
public ContentType encode(Packet packet, WritableByteChannel buffer) {
|
||||
//TODO: not yet implemented
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void decode(InputStream in, String contentType, Packet response) throws IOException {
|
||||
response.setMessage(
|
||||
_soapCodec.decode(getXMLStreamReader(in)));
|
||||
}
|
||||
|
||||
public void decode(ReadableByteChannel in, String contentType, Packet response) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
protected abstract StreamHeader createHeader(XMLStreamReader reader, XMLStreamBuffer mark);
|
||||
|
||||
protected abstract ContentType getContentType(String soapAction);
|
||||
|
||||
private XMLStreamWriter getXMLStreamWriter(OutputStream out) {
|
||||
if (_serializer != null) {
|
||||
_serializer.setOutputStream(out);
|
||||
return _serializer;
|
||||
} else {
|
||||
return _serializer = FastInfosetCodec.createNewStreamWriter(out, _retainState);
|
||||
}
|
||||
}
|
||||
|
||||
private XMLStreamReader getXMLStreamReader(InputStream in) {
|
||||
// If the _retainState is true (FI stateful) then pick up Codec assiciated XMLStreamReader
|
||||
if (_retainState) {
|
||||
if (_statefulParser != null) {
|
||||
_statefulParser.setInputStream(in);
|
||||
return _statefulParser;
|
||||
} else {
|
||||
return _statefulParser = FastInfosetCodec.createNewStreamReader(in, _retainState);
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise thread assiciated XMLStreamReader
|
||||
return READER_FACTORY.doCreate(null, in, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link FastInfosetStreamSOAPCodec} instance.
|
||||
*
|
||||
* @param version the SOAP version of the codec.
|
||||
* @return a new {@link FastInfosetStreamSOAPCodec} instance.
|
||||
*/
|
||||
public static FastInfosetStreamSOAPCodec create(StreamSOAPCodec soapCodec, SOAPVersion version) {
|
||||
return create(soapCodec, version, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link FastInfosetStreamSOAPCodec} instance.
|
||||
*
|
||||
* @param version the SOAP version of the codec.
|
||||
* @param retainState if true the Codec should retain the state of
|
||||
* vocabulary tables for multiple encode/decode invocations.
|
||||
* @return a new {@link FastInfosetStreamSOAPCodec} instance.
|
||||
*/
|
||||
public static FastInfosetStreamSOAPCodec create(StreamSOAPCodec soapCodec,
|
||||
SOAPVersion version, boolean retainState) {
|
||||
if(version==null)
|
||||
// this decoder is for SOAP, not for XML/HTTP
|
||||
throw new IllegalArgumentException();
|
||||
switch(version) {
|
||||
case SOAP_11:
|
||||
return new FastInfosetStreamSOAP11Codec(soapCodec, retainState);
|
||||
case SOAP_12:
|
||||
return new FastInfosetStreamSOAP12Codec(soapCodec, retainState);
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.policy;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
/**
|
||||
* File holding all encoding constants
|
||||
*
|
||||
* @author Marek Potociar (marek.potociar at sun.com)
|
||||
*/
|
||||
public final class EncodingConstants {
|
||||
/** Prevents creation of new EncodingConstants instance */
|
||||
private EncodingConstants() {
|
||||
}
|
||||
|
||||
public static final String SUN_FI_SERVICE_NS = "http://java.sun.com/xml/ns/wsit/2006/09/policy/fastinfoset/service";
|
||||
public static final QName OPTIMIZED_FI_SERIALIZATION_ASSERTION = new QName(SUN_FI_SERVICE_NS, "OptimizedFastInfosetSerialization");
|
||||
|
||||
public static final String SUN_ENCODING_CLIENT_NS = "http://java.sun.com/xml/ns/wsit/2006/09/policy/encoding/client";
|
||||
public static final QName SELECT_OPTIMAL_ENCODING_ASSERTION = new QName(SUN_ENCODING_CLIENT_NS, "AutomaticallySelectOptimalEncoding");
|
||||
|
||||
public static final String OPTIMIZED_MIME_NS = "http://schemas.xmlsoap.org/ws/2004/09/policy/optimizedmimeserialization";
|
||||
public static final QName OPTIMIZED_MIME_SERIALIZATION_ASSERTION = new QName(OPTIMIZED_MIME_NS, "OptimizedMimeSerialization");
|
||||
|
||||
public static final String ENCODING_NS = "http://schemas.xmlsoap.org/ws/2004/09/policy/encoding";
|
||||
public static final QName UTF816FFFE_CHARACTER_ENCODING_ASSERTION = new QName(ENCODING_NS, "Utf816FFFECharacterEncoding");
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.policy;
|
||||
|
||||
import com.sun.xml.internal.ws.policy. PolicyAssertion;
|
||||
import com.sun.xml.internal.ws.policy.spi.PolicyAssertionValidator;
|
||||
import com.sun.xml.internal.ws.policy.spi.PolicyAssertionValidator.Fitness;
|
||||
import java.util.ArrayList;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import static com.sun.xml.internal.ws.encoding.policy.EncodingConstants.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jakub Podlesak (jakub.podlesak at sun.com)
|
||||
*/
|
||||
public class EncodingPolicyValidator implements PolicyAssertionValidator {
|
||||
|
||||
private static final ArrayList<QName> serverSideSupportedAssertions = new ArrayList<QName>(3);
|
||||
private static final ArrayList<QName> clientSideSupportedAssertions = new ArrayList<QName>(4);
|
||||
|
||||
static {
|
||||
serverSideSupportedAssertions.add(OPTIMIZED_MIME_SERIALIZATION_ASSERTION);
|
||||
serverSideSupportedAssertions.add(UTF816FFFE_CHARACTER_ENCODING_ASSERTION);
|
||||
serverSideSupportedAssertions.add(OPTIMIZED_FI_SERIALIZATION_ASSERTION);
|
||||
|
||||
clientSideSupportedAssertions.add(SELECT_OPTIMAL_ENCODING_ASSERTION);
|
||||
clientSideSupportedAssertions.addAll(serverSideSupportedAssertions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of EncodingPolicyValidator
|
||||
*/
|
||||
public EncodingPolicyValidator() {
|
||||
}
|
||||
|
||||
public Fitness validateClientSide(PolicyAssertion assertion) {
|
||||
return clientSideSupportedAssertions.contains(assertion.getName()) ? Fitness.SUPPORTED : Fitness.UNKNOWN;
|
||||
}
|
||||
|
||||
public Fitness validateServerSide(PolicyAssertion assertion) {
|
||||
QName assertionName = assertion.getName();
|
||||
if (serverSideSupportedAssertions.contains(assertionName)) {
|
||||
return Fitness.SUPPORTED;
|
||||
} else if (clientSideSupportedAssertions.contains(assertionName)) {
|
||||
return Fitness.UNSUPPORTED;
|
||||
} else {
|
||||
return Fitness.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public String[] declareSupportedDomains() {
|
||||
return new String[] {OPTIMIZED_MIME_NS, ENCODING_NS, SUN_ENCODING_CLIENT_NS, SUN_FI_SERVICE_NS};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.policy;
|
||||
|
||||
import com.sun.xml.internal.ws.policy.spi.PrefixMapper;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Fabian Ritzmann
|
||||
*/
|
||||
public class EncodingPrefixMapper implements PrefixMapper {
|
||||
|
||||
private static final Map<String, String> prefixMap = new HashMap<String, String>();
|
||||
|
||||
static {
|
||||
prefixMap.put(EncodingConstants.ENCODING_NS, "wspe");
|
||||
prefixMap.put(EncodingConstants.OPTIMIZED_MIME_NS, "wsoma");
|
||||
prefixMap.put(EncodingConstants.SUN_ENCODING_CLIENT_NS, "cenc");
|
||||
prefixMap.put(EncodingConstants.SUN_FI_SERVICE_NS, "fi");
|
||||
}
|
||||
|
||||
public Map<String, String> getPrefixMap() {
|
||||
return prefixMap;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.policy;
|
||||
|
||||
import com.sun.xml.internal.ws.api.fastinfoset.FastInfosetFeature;
|
||||
import com.sun.xml.internal.ws.policy.AssertionSet;
|
||||
import com.sun.xml.internal.ws.policy.Policy;
|
||||
import com.sun.xml.internal.ws.policy.PolicyAssertion;
|
||||
import com.sun.xml.internal.ws.policy.PolicyException;
|
||||
import com.sun.xml.internal.ws.policy.PolicyMap;
|
||||
import com.sun.xml.internal.ws.policy.PolicyMapKey;
|
||||
import com.sun.xml.internal.ws.policy.jaxws.spi.PolicyFeatureConfigurator;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import static com.sun.xml.internal.ws.encoding.policy.EncodingConstants.OPTIMIZED_FI_SERIALIZATION_ASSERTION;
|
||||
import javax.xml.ws.WebServiceFeature;
|
||||
|
||||
/**
|
||||
* A configurator provider for FastInfoset policy assertions.
|
||||
*
|
||||
* @author Paul.Sandoz@Sun.Com
|
||||
* @author Fabian Ritzmann
|
||||
*/
|
||||
public class FastInfosetFeatureConfigurator implements PolicyFeatureConfigurator {
|
||||
|
||||
public static final QName enabled = new QName("enabled");
|
||||
|
||||
/**
|
||||
* Process FastInfoset policy assertions.
|
||||
*
|
||||
* @param key Key to identify the endpoint scope.
|
||||
* @param policyMap the policy map.
|
||||
* @throws PolicyException If retrieving the policy triggered an exception.
|
||||
*/
|
||||
public Collection<WebServiceFeature> getFeatures(final PolicyMapKey key, final PolicyMap policyMap) throws PolicyException {
|
||||
final Collection<WebServiceFeature> features = new LinkedList<WebServiceFeature>();
|
||||
if ((key != null) && (policyMap != null)) {
|
||||
Policy policy = policyMap.getEndpointEffectivePolicy(key);
|
||||
if (null!=policy && policy.contains(OPTIMIZED_FI_SERIALIZATION_ASSERTION)) {
|
||||
Iterator <AssertionSet> assertions = policy.iterator();
|
||||
while(assertions.hasNext()){
|
||||
AssertionSet assertionSet = assertions.next();
|
||||
Iterator<PolicyAssertion> policyAssertion = assertionSet.iterator();
|
||||
while(policyAssertion.hasNext()){
|
||||
PolicyAssertion assertion = policyAssertion.next();
|
||||
if(OPTIMIZED_FI_SERIALIZATION_ASSERTION.equals(assertion.getName())){
|
||||
String value = assertion.getAttributeValue(enabled);
|
||||
boolean isFastInfosetEnabled = Boolean.valueOf(value.trim());
|
||||
features.add(new FastInfosetFeature(isFastInfosetEnabled));
|
||||
} // end-if non optional fast infoset assertion found
|
||||
} // next assertion
|
||||
} // next alternative
|
||||
} // end-if policy contains fast infoset assertion
|
||||
}
|
||||
return features;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.policy;
|
||||
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundPortType;
|
||||
import com.sun.xml.internal.ws.policy.AssertionSet;
|
||||
import com.sun.xml.internal.ws.policy.Policy;
|
||||
import com.sun.xml.internal.ws.policy.PolicyAssertion;
|
||||
import com.sun.xml.internal.ws.policy.PolicyException;
|
||||
import com.sun.xml.internal.ws.policy.PolicyMap;
|
||||
import com.sun.xml.internal.ws.policy.PolicyMapKey;
|
||||
import com.sun.xml.internal.ws.policy.jaxws.spi.PolicyFeatureConfigurator;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import javax.xml.ws.WebServiceFeature;
|
||||
import javax.xml.ws.soap.MTOMFeature;
|
||||
|
||||
import static com.sun.xml.internal.ws.encoding.policy.EncodingConstants.OPTIMIZED_MIME_SERIALIZATION_ASSERTION;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author japod
|
||||
* @author Fabian Ritzmann
|
||||
*/
|
||||
public class MtomFeatureConfigurator implements PolicyFeatureConfigurator {
|
||||
/**
|
||||
* Creates a new instance of MtomFeatureConfigurator
|
||||
*/
|
||||
public MtomFeatureConfigurator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* process Mtom policy assertions and if found and is not optional then mtom is enabled on the
|
||||
* {@link WSDLBoundPortType}
|
||||
*
|
||||
* @param key Key that identifies the endpoint scope
|
||||
* @param policyMap Must be non-null
|
||||
* @throws PolicyException If retrieving the policy triggered an exception
|
||||
*/
|
||||
public Collection<WebServiceFeature> getFeatures(PolicyMapKey key, PolicyMap policyMap) throws PolicyException {
|
||||
final Collection<WebServiceFeature> features = new LinkedList<WebServiceFeature>();
|
||||
if ((key != null) && (policyMap != null)) {
|
||||
Policy policy = policyMap.getEndpointEffectivePolicy(key);
|
||||
if (null!=policy && policy.contains(OPTIMIZED_MIME_SERIALIZATION_ASSERTION)) {
|
||||
Iterator <AssertionSet> assertions = policy.iterator();
|
||||
while(assertions.hasNext()){
|
||||
AssertionSet assertionSet = assertions.next();
|
||||
Iterator<PolicyAssertion> policyAssertion = assertionSet.iterator();
|
||||
while(policyAssertion.hasNext()){
|
||||
PolicyAssertion assertion = policyAssertion.next();
|
||||
if(OPTIMIZED_MIME_SERIALIZATION_ASSERTION.equals(assertion.getName())){
|
||||
features.add(new MTOMFeature(true));
|
||||
} // end-if non optional mtom assertion found
|
||||
} // next assertion
|
||||
} // next alternative
|
||||
} // end-if policy contains mtom assertion
|
||||
}
|
||||
return features;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.policy;
|
||||
|
||||
import static com.sun.xml.internal.ws.encoding.policy.EncodingConstants.OPTIMIZED_MIME_SERIALIZATION_ASSERTION;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.model.SEIModel;
|
||||
import com.sun.xml.internal.ws.policy.AssertionSet;
|
||||
import com.sun.xml.internal.ws.policy.Policy;
|
||||
import com.sun.xml.internal.ws.policy.PolicyAssertion;
|
||||
import com.sun.xml.internal.ws.policy.PolicyException;
|
||||
import com.sun.xml.internal.ws.policy.PolicyMap;
|
||||
import com.sun.xml.internal.ws.policy.PolicySubject;
|
||||
import com.sun.xml.internal.ws.policy.jaxws.spi.PolicyMapConfigurator;
|
||||
import com.sun.xml.internal.ws.policy.privateutil.PolicyLogger;
|
||||
import com.sun.xml.internal.ws.policy.sourcemodel.AssertionData;
|
||||
import com.sun.xml.internal.ws.policy.subject.WsdlBindingSubject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.logging.Level;
|
||||
import javax.xml.namespace.QName;
|
||||
import javax.xml.ws.soap.MTOMFeature;
|
||||
|
||||
/**
|
||||
* Generate an MTOM policy if MTOM was enabled.
|
||||
*
|
||||
* @author Jakub Podlesak (japod at sun.com)
|
||||
* @author Fabian Ritzmann
|
||||
*/
|
||||
public class MtomPolicyMapConfigurator implements PolicyMapConfigurator {
|
||||
|
||||
private static final PolicyLogger LOGGER = PolicyLogger.getLogger(MtomPolicyMapConfigurator.class);
|
||||
|
||||
static class MtomAssertion extends PolicyAssertion {
|
||||
|
||||
private static final AssertionData mtomData;
|
||||
static {
|
||||
mtomData= AssertionData.createAssertionData(OPTIMIZED_MIME_SERIALIZATION_ASSERTION);
|
||||
//JAX-WS MTOMFeature does n't currently capture if MTOM is required/optional.
|
||||
//JAX-WS accepts both normal messages and XOP encoded messages. Using wsp:Optional=true represents that behavior.
|
||||
//Moreover, this allows interoperability with non-MTOM aware clients.
|
||||
//See https://wsit.dev.java.net/issues/show_bug.cgi?id=1062
|
||||
mtomData.setOptionalAttribute(true);
|
||||
}
|
||||
|
||||
MtomAssertion() {
|
||||
super(mtomData, null, null);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an MTOM policy if MTOM is enabled.
|
||||
*
|
||||
* <ol>
|
||||
* <li>If MTOM is enabled
|
||||
* <ol>
|
||||
* <li>If MTOM policy does not already exist, generate
|
||||
* <li>Otherwise do nothing
|
||||
* </ol>
|
||||
* <li>Otherwise, do nothing (that implies that we do not remove any MTOM policies if MTOM is disabled)
|
||||
* </ol>
|
||||
*
|
||||
*/
|
||||
public Collection<PolicySubject> update(PolicyMap policyMap, SEIModel model, WSBinding wsBinding) throws PolicyException {
|
||||
LOGGER.entering(policyMap, model, wsBinding);
|
||||
|
||||
Collection<PolicySubject> subjects = new ArrayList<PolicySubject>();
|
||||
if (policyMap != null) {
|
||||
final MTOMFeature mtomFeature = wsBinding.getFeature(MTOMFeature.class);
|
||||
if (LOGGER.isLoggable(Level.FINEST)) {
|
||||
LOGGER.finest("mtomFeature = " + mtomFeature);
|
||||
}
|
||||
if ((mtomFeature != null) && mtomFeature.isEnabled()) {
|
||||
final QName bindingName = model.getBoundPortTypeName();
|
||||
final WsdlBindingSubject wsdlSubject = WsdlBindingSubject.createBindingSubject(bindingName);
|
||||
final Policy mtomPolicy = createMtomPolicy(bindingName);
|
||||
final PolicySubject mtomPolicySubject = new PolicySubject(wsdlSubject, mtomPolicy);
|
||||
subjects.add(mtomPolicySubject);
|
||||
if (LOGGER.isLoggable(Level.FINEST)) {
|
||||
LOGGER.fine("Added MTOM policy with ID \"" + mtomPolicy.getIdOrName() + "\" to binding element \"" + bindingName + "\"");
|
||||
}
|
||||
}
|
||||
} // endif policy map not null
|
||||
|
||||
LOGGER.exiting(subjects);
|
||||
return subjects;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a policy with an MTOM assertion.
|
||||
*
|
||||
* @param model The binding element name. Used to generate a (locally) unique ID for the policy.
|
||||
* @return The policy.
|
||||
*/
|
||||
private Policy createMtomPolicy(final QName bindingName) {
|
||||
ArrayList<AssertionSet> assertionSets = new ArrayList<AssertionSet>(1);
|
||||
ArrayList<PolicyAssertion> assertions = new ArrayList<PolicyAssertion>(1);
|
||||
assertions.add(new MtomAssertion());
|
||||
assertionSets.add(AssertionSet.createAssertionSet(assertions));
|
||||
return Policy.createPolicy(null, bindingName.getLocalPart() + "_MTOM_Policy", assertionSets);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.policy;
|
||||
|
||||
import com.sun.xml.internal.ws.api.client.SelectOptimalEncodingFeature;
|
||||
import com.sun.xml.internal.ws.policy.AssertionSet;
|
||||
import com.sun.xml.internal.ws.policy.Policy;
|
||||
import com.sun.xml.internal.ws.policy.PolicyAssertion;
|
||||
import com.sun.xml.internal.ws.policy.PolicyException;
|
||||
import com.sun.xml.internal.ws.policy.PolicyMap;
|
||||
import com.sun.xml.internal.ws.policy.PolicyMapKey;
|
||||
import com.sun.xml.internal.ws.policy.jaxws.spi.PolicyFeatureConfigurator;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import static com.sun.xml.internal.ws.encoding.policy.EncodingConstants.SELECT_OPTIMAL_ENCODING_ASSERTION;
|
||||
import javax.xml.ws.WebServiceFeature;
|
||||
|
||||
/**
|
||||
* A configurator provider for FastInfoset policy assertions.
|
||||
*
|
||||
* @author Paul.Sandoz@Sun.Com
|
||||
* @author Fabian Ritzmann
|
||||
*/
|
||||
public class SelectOptimalEncodingFeatureConfigurator implements PolicyFeatureConfigurator {
|
||||
public static final QName enabled = new QName("enabled");
|
||||
|
||||
/**
|
||||
* Process SelectOptimalEncoding policy assertions.
|
||||
*
|
||||
* @param key Key that identifies the endpoint scope.
|
||||
* @param policyMap The policy map.
|
||||
* @throws PolicyException If retrieving the policy triggered an exception.
|
||||
*/
|
||||
public Collection<WebServiceFeature> getFeatures(PolicyMapKey key, PolicyMap policyMap) throws PolicyException {
|
||||
final Collection<WebServiceFeature> features = new LinkedList<WebServiceFeature>();
|
||||
if ((key != null) && (policyMap != null)) {
|
||||
Policy policy = policyMap.getEndpointEffectivePolicy(key);
|
||||
if (null!=policy && policy.contains(SELECT_OPTIMAL_ENCODING_ASSERTION)) {
|
||||
Iterator <AssertionSet> assertions = policy.iterator();
|
||||
while(assertions.hasNext()){
|
||||
AssertionSet assertionSet = assertions.next();
|
||||
Iterator<PolicyAssertion> policyAssertion = assertionSet.iterator();
|
||||
while(policyAssertion.hasNext()){
|
||||
PolicyAssertion assertion = policyAssertion.next();
|
||||
if(SELECT_OPTIMAL_ENCODING_ASSERTION.equals(assertion.getName())){
|
||||
String value = assertion.getAttributeValue(enabled);
|
||||
boolean isSelectOptimalEncodingEnabled = value == null || Boolean.valueOf(value.trim());
|
||||
features.add(new SelectOptimalEncodingFeature(isSelectOptimalEncodingEnabled));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return features;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.soap;
|
||||
|
||||
import com.sun.istack.internal.localization.Localizable;
|
||||
import com.sun.xml.internal.ws.util.exception.JAXWSExceptionBase;
|
||||
|
||||
/**
|
||||
* DeserializationException represents an exception that occurred while
|
||||
* deserializing a Java value from XML.
|
||||
*
|
||||
* @see JAXWSExceptionBase
|
||||
*
|
||||
* @author WS Development Team
|
||||
*/
|
||||
public class DeserializationException extends JAXWSExceptionBase {
|
||||
|
||||
public DeserializationException(String key, Object... args) {
|
||||
super(key, args);
|
||||
}
|
||||
|
||||
public DeserializationException(Throwable throwable) {
|
||||
super(throwable);
|
||||
}
|
||||
|
||||
public DeserializationException(Localizable arg) {
|
||||
super("nestedDeserializationError", arg);
|
||||
}
|
||||
|
||||
public String getDefaultResourceBundleName() {
|
||||
return "com.sun.xml.internal.ws.resources.encoding";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.soap;
|
||||
|
||||
import com.sun.xml.internal.ws.encoding.soap.streaming.SOAP12NamespaceConstants;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author WS Development Team
|
||||
*/
|
||||
public class SOAP12Constants {
|
||||
|
||||
public static final String URI_ENVELOPE = SOAP12NamespaceConstants.ENVELOPE;
|
||||
public static final String URI_ENCODING = "http://schemas.xmlsoap.org/soap/encoding/";
|
||||
public static final String URI_HTTP = SOAP12NamespaceConstants.TRANSPORT_HTTP;
|
||||
public static final String URI_SOAP_RPC = SOAP12NamespaceConstants.SOAP_RPC;
|
||||
|
||||
|
||||
public static final QName QNAME_SOAP_RPC = new QName(URI_SOAP_RPC, "rpc");
|
||||
public static final QName QNAME_SOAP_RESULT = new QName(URI_SOAP_RPC, "result");
|
||||
|
||||
public static final QName QNAME_SOAP_ENVELOPE = new QName(URI_ENVELOPE, "Envelope");
|
||||
public static final QName QNAME_SOAP_BODY = new QName(URI_ENVELOPE, "Body");
|
||||
public static final QName QNAME_SOAP_HEADER = new QName(URI_ENVELOPE, "Header");
|
||||
public static final QName QNAME_ENVELOPE_ENCODINGSTYLE = new QName(URI_ENVELOPE, "encodingStyle");
|
||||
public static final QName QNAME_SOAP_FAULT = new QName(URI_ENVELOPE, "Fault");
|
||||
public static final QName QNAME_MUSTUNDERSTAND = new QName(URI_ENVELOPE, "mustUnderstand");
|
||||
public static final QName QNAME_ROLE = new QName(URI_ENVELOPE, "role");
|
||||
|
||||
public static final QName QNAME_NOT_UNDERSTOOD = new QName(URI_ENVELOPE, "NotUnderstood");
|
||||
|
||||
//fault
|
||||
public static final QName QNAME_FAULT_CODE = new QName(URI_ENVELOPE, "Code");
|
||||
public static final QName QNAME_FAULT_SUBCODE = new QName(URI_ENVELOPE, "Subcode");
|
||||
public static final QName QNAME_FAULT_VALUE = new QName(URI_ENVELOPE, "Value");
|
||||
public static final QName QNAME_FAULT_REASON = new QName(URI_ENVELOPE, "Reason");
|
||||
public static final QName QNAME_FAULT_NODE = new QName(URI_ENVELOPE, "Node");
|
||||
public static final QName QNAME_FAULT_ROLE = new QName(URI_ENVELOPE, "Role");
|
||||
public static final QName QNAME_FAULT_DETAIL = new QName(URI_ENVELOPE, "Detail");
|
||||
public static final QName QNAME_FAULT_REASON_TEXT = new QName(URI_ENVELOPE, "Text");
|
||||
public final static QName QNAME_UPGRADE = new QName(URI_ENVELOPE, "Upgrade");
|
||||
public final static QName QNAME_UPGRADE_SUPPORTED_ENVELOPE = new QName(URI_ENVELOPE, "SupportedEnvelope");
|
||||
|
||||
|
||||
//fault codes
|
||||
public final static QName FAULT_CODE_MUST_UNDERSTAND = new QName(URI_ENVELOPE, "MustUnderstand");
|
||||
public final static QName FAULT_CODE_MISUNDERSTOOD = new QName(URI_ENVELOPE, "Misunderstood");
|
||||
public final static QName FAULT_CODE_VERSION_MISMATCH = new QName(URI_ENVELOPE, "VersionMismatch");
|
||||
public final static QName FAULT_CODE_DATA_ENCODING_UNKNOWN = new QName(URI_ENVELOPE, "DataEncodingUnknown");
|
||||
public final static QName FAULT_CODE_PROCEDURE_NOT_PRESENT = new QName(URI_ENVELOPE, "ProcedureNotPresent");
|
||||
public final static QName FAULT_CODE_BAD_ARGUMENTS = new QName(URI_ENVELOPE, "BadArguments");
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.soap;
|
||||
|
||||
import com.sun.xml.internal.ws.encoding.soap.streaming.SOAPNamespaceConstants;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author WS Development Team
|
||||
*/
|
||||
public class SOAPConstants {
|
||||
|
||||
public static final String URI_ENVELOPE = SOAPNamespaceConstants.ENVELOPE;
|
||||
public static final String URI_HTTP = SOAPNamespaceConstants.TRANSPORT_HTTP;
|
||||
public static final String URI_ENCODING = "http://schemas.xmlsoap.org/soap/encoding/";
|
||||
public static final String NS_WSDL_SOAP = "http://schemas.xmlsoap.org/wsdl/soap/";
|
||||
public static final QName QNAME_ENVELOPE_ENCODINGSTYLE = new QName(URI_ENVELOPE, "encodingStyle");
|
||||
|
||||
public final static QName QNAME_SOAP_ENVELOPE = new QName(URI_ENVELOPE, "Envelope");
|
||||
public final static QName QNAME_SOAP_HEADER = new QName(URI_ENVELOPE, "Header");
|
||||
public static final QName QNAME_MUSTUNDERSTAND = new QName(URI_ENVELOPE, "mustUnderstand");
|
||||
public static final QName QNAME_ROLE = new QName(URI_ENVELOPE, "actor");
|
||||
public final static QName QNAME_SOAP_BODY = new QName(URI_ENVELOPE, "Body");
|
||||
public final static QName QNAME_SOAP_FAULT = new QName(URI_ENVELOPE, "Fault");
|
||||
public final static QName QNAME_SOAP_FAULT_CODE = new QName("", "faultcode");
|
||||
public final static QName QNAME_SOAP_FAULT_STRING = new QName("", "faultstring");
|
||||
public final static QName QNAME_SOAP_FAULT_ACTOR = new QName("", "faultactor");
|
||||
public final static QName QNAME_SOAP_FAULT_DETAIL = new QName("", "detail");
|
||||
public final static QName FAULT_CODE_MUST_UNDERSTAND = new QName(URI_ENVELOPE, "MustUnderstand");
|
||||
|
||||
public final static QName FAULT_CODE_VERSION_MISMATCH = new QName(URI_ENVELOPE, "VersionMismatch");
|
||||
public final static QName FAULT_CODE_DATA_ENCODING_UNKNOWN = new QName(URI_ENVELOPE, "DataEncodingUnknown");
|
||||
public final static QName FAULT_CODE_PROCEDURE_NOT_PRESENT = new QName(URI_ENVELOPE, "ProcedureNotPresent");
|
||||
public final static QName FAULT_CODE_BAD_ARGUMENTS = new QName(URI_ENVELOPE, "BadArguments");
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.soap;
|
||||
|
||||
import com.sun.istack.internal.localization.Localizable;
|
||||
import com.sun.xml.internal.ws.util.exception.JAXWSExceptionBase;
|
||||
|
||||
/**
|
||||
* SerializationException represents an exception that occurred while
|
||||
* serializing a Java value as XML.
|
||||
*
|
||||
* @see JAXWSExceptionBase
|
||||
*
|
||||
* @author WS Development Team
|
||||
*/
|
||||
public class SerializationException extends JAXWSExceptionBase {
|
||||
|
||||
public SerializationException(String key, Object... args) {
|
||||
super(key, args);
|
||||
}
|
||||
|
||||
public SerializationException(Localizable arg) {
|
||||
super("nestedSerializationError", arg);
|
||||
}
|
||||
|
||||
public SerializationException(Throwable throwable) {
|
||||
super(throwable);
|
||||
}
|
||||
|
||||
public String getDefaultResourceBundleName() {
|
||||
return "com.sun.xml.internal.ws.resources.encoding";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.soap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author WS Development Team
|
||||
*/
|
||||
public interface SerializerConstants {
|
||||
public static final boolean ENCODE_TYPE = true;
|
||||
public static final boolean DONT_ENCODE_TYPE = false;
|
||||
public static final boolean SERIALIZE_AS_REF = true;
|
||||
public static final boolean DONT_SERIALIZE_AS_REF = false;
|
||||
public static final boolean REFERENCEABLE = true;
|
||||
public static final boolean NOT_REFERENCEABLE = false;
|
||||
public static final boolean NULLABLE = true;
|
||||
public static final boolean NOT_NULLABLE = false;
|
||||
public static final boolean REFERENCED_INSTANCE = true;
|
||||
public static final boolean UNREFERENCED_INSTANCE = false;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.soap.streaming;
|
||||
|
||||
/**
|
||||
* @author WS Development Team
|
||||
*/
|
||||
public class SOAP12NamespaceConstants {
|
||||
public static final String XML_NS = "http://www.w3.org/XML/1998/namespace";
|
||||
public static final String ENVELOPE =
|
||||
"http://www.w3.org/2003/05/soap-envelope";
|
||||
public static final String ENCODING =
|
||||
"http://www.w3.org/2003/05/soap-encoding";
|
||||
public static final String SOAP_RPC = "http://www.w3.org/2002/06/soap-rpc";
|
||||
public static final String XSD = "http://www.w3.org/2001/XMLSchema";
|
||||
public static final String XSI =
|
||||
"http://www.w3.org/2001/XMLSchema-instance";
|
||||
public static final String TRANSPORT_HTTP =
|
||||
"http://www.w3.org/2003/05/soap/bindings/HTTP/";
|
||||
|
||||
public static final String ACTOR_NEXT = "http://www.w3.org/2003/05/soap-envelope/role/next";
|
||||
|
||||
public static final String ROLE_NEXT =
|
||||
"http://www.w3.org/2003/05/soap-envelope/role/next";
|
||||
public static final String ROLE_NONE = "http://www.w3.org/2003/05/soap-envelope/role/none";
|
||||
public static final String ROLE_ULTIMATE_RECEIVER = "http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver";
|
||||
|
||||
public static final String SOAP_UPGRADE =
|
||||
"http://www.w3.org/2002/06/soap-upgrade";
|
||||
|
||||
public static final String TAG_ENVELOPE = "Envelope";
|
||||
public static final String TAG_HEADER = "Header";
|
||||
public static final String TAG_BODY = "Body";
|
||||
public static final String TAG_RESULT = "result";
|
||||
public static final String TAG_NOT_UNDERSTOOD = "NotUnderstood";
|
||||
|
||||
public static final String ATTR_ACTOR = "role";
|
||||
public static final String ATTR_MUST_UNDERSTAND = "mustUnderstand";
|
||||
public static final String ATTR_MISUNDERSTOOD = "missUnderstood";
|
||||
public static final String ATTR_ENCODING_STYLE = "encodingStyle";
|
||||
public static final String ATTR_NOT_UNDERSTOOD_QNAME = "qname";
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.soap.streaming;
|
||||
|
||||
/**
|
||||
* @author WS Development Team
|
||||
*/
|
||||
public class SOAPNamespaceConstants {
|
||||
public static final String NSPREFIX_SOAP_ENVELOPE = "soapenv";
|
||||
public static final String ENVELOPE = "http://schemas.xmlsoap.org/soap/envelope/";
|
||||
public static final String ENCODING =
|
||||
"http://schemas.xmlsoap.org/soap/encoding/";
|
||||
public static final String XSD = "http://www.w3.org/2001/XMLSchema";
|
||||
public static final String XSI =
|
||||
"http://www.w3.org/2001/XMLSchema-instance";
|
||||
public static final String XMLNS = "http://www.w3.org/XML/1998/namespace";
|
||||
public static final String TRANSPORT_HTTP =
|
||||
"http://schemas.xmlsoap.org/soap/http";
|
||||
public static final String ACTOR_NEXT =
|
||||
"http://schemas.xmlsoap.org/soap/actor/next";
|
||||
|
||||
public static final String TAG_ENVELOPE = "Envelope";
|
||||
public static final String TAG_HEADER = "Header";
|
||||
public static final String TAG_BODY = "Body";
|
||||
public static final String TAG_FAULT = "Fault";
|
||||
|
||||
public static final String ATTR_ACTOR = "actor";
|
||||
public static final String ATTR_MUST_UNDERSTAND = "mustUnderstand";
|
||||
public static final String ATTR_ENCODING_STYLE = "encodingStyle";
|
||||
}
|
||||
113
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/xml/XMLCodec.java
Normal file
113
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/xml/XMLCodec.java
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.xml;
|
||||
|
||||
import com.sun.xml.internal.ws.api.message.Message;
|
||||
import com.sun.xml.internal.ws.api.message.Packet;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
import com.sun.xml.internal.ws.api.pipe.ContentType;
|
||||
import com.sun.xml.internal.ws.api.streaming.XMLStreamWriterFactory;
|
||||
import com.sun.xml.internal.ws.api.WSBinding;
|
||||
import com.sun.xml.internal.ws.api.WSFeatureList;
|
||||
import com.sun.xml.internal.ws.encoding.ContentTypeImpl;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
import javax.xml.ws.WebServiceFeature;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
public final class XMLCodec implements Codec {
|
||||
public static final String XML_APPLICATION_MIME_TYPE = "application/xml";
|
||||
|
||||
public static final String XML_TEXT_MIME_TYPE = "text/xml";
|
||||
|
||||
private static final ContentType contentType = new ContentTypeImpl(XML_TEXT_MIME_TYPE);
|
||||
|
||||
// private final WSBinding binding;
|
||||
private WSFeatureList features;
|
||||
|
||||
public XMLCodec(WSFeatureList f) {
|
||||
// this.binding = binding;
|
||||
features = f;
|
||||
}
|
||||
|
||||
public String getMimeType() {
|
||||
return XML_APPLICATION_MIME_TYPE;
|
||||
}
|
||||
|
||||
public ContentType getStaticContentType(Packet packet) {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public ContentType encode(Packet packet, OutputStream out) {
|
||||
String encoding = (String) packet.invocationProperties
|
||||
.get(XMLConstants.OUTPUT_XML_CHARACTER_ENCODING);
|
||||
|
||||
XMLStreamWriter writer = null;
|
||||
|
||||
if (encoding != null && encoding.length() > 0) {
|
||||
writer = XMLStreamWriterFactory.create(out, encoding);
|
||||
} else {
|
||||
writer = XMLStreamWriterFactory.create(out);
|
||||
}
|
||||
|
||||
try {
|
||||
if (packet.getMessage().hasPayload()){
|
||||
writer.writeStartDocument();
|
||||
packet.getMessage().writePayloadTo(writer);
|
||||
writer.flush();
|
||||
}
|
||||
} catch (XMLStreamException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public ContentType encode(Packet packet, WritableByteChannel buffer) {
|
||||
//TODO: not yet implemented
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Codec copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void decode(InputStream in, String contentType, Packet packet) throws IOException {
|
||||
Message message = XMLMessage.create(contentType, in, features);
|
||||
packet.setMessage(message);
|
||||
}
|
||||
|
||||
public void decode(ReadableByteChannel in, String contentType, Packet packet) {
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.xml;
|
||||
|
||||
public class XMLConstants {
|
||||
|
||||
public static final String OUTPUT_XML_CHARACTER_ENCODING = "com.sun.jaxws.rest.contenttype";
|
||||
}
|
||||
636
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/xml/XMLMessage.java
Normal file
636
jdkSrc/jdk8/com/sun/xml/internal/ws/encoding/xml/XMLMessage.java
Normal file
@@ -0,0 +1,636 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.xml;
|
||||
|
||||
import com.sun.istack.internal.NotNull;
|
||||
import com.sun.xml.internal.bind.api.Bridge;
|
||||
import com.sun.xml.internal.ws.api.SOAPVersion;
|
||||
import com.sun.xml.internal.ws.api.WSFeatureList;
|
||||
import com.sun.xml.internal.ws.api.message.*;
|
||||
import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort;
|
||||
import com.sun.xml.internal.ws.api.pipe.Codec;
|
||||
import com.sun.xml.internal.ws.api.streaming.XMLStreamWriterFactory;
|
||||
import com.sun.xml.internal.ws.developer.StreamingAttachmentFeature;
|
||||
import com.sun.xml.internal.ws.encoding.ContentType;
|
||||
import com.sun.xml.internal.ws.encoding.MimeMultipartParser;
|
||||
import com.sun.xml.internal.ws.encoding.XMLHTTPBindingCodec;
|
||||
import com.sun.xml.internal.ws.message.AbstractMessageImpl;
|
||||
import com.sun.xml.internal.ws.message.EmptyMessageImpl;
|
||||
import com.sun.xml.internal.ws.message.MimeAttachmentSet;
|
||||
import com.sun.xml.internal.ws.message.source.PayloadSourceMessage;
|
||||
import com.sun.xml.internal.ws.util.ByteArrayBuffer;
|
||||
import com.sun.xml.internal.ws.util.StreamUtils;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.activation.DataSource;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.soap.SOAPException;
|
||||
import javax.xml.soap.SOAPMessage;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.ws.WebServiceException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jitendra Kotamraju
|
||||
*/
|
||||
public final class XMLMessage {
|
||||
|
||||
private static final int PLAIN_XML_FLAG = 1; // 00001
|
||||
private static final int MIME_MULTIPART_FLAG = 2; // 00010
|
||||
private static final int FI_ENCODED_FLAG = 16; // 10000
|
||||
|
||||
/*
|
||||
* Construct a message given a content type and an input stream.
|
||||
*/
|
||||
public static Message create(final String ct, InputStream in, WSFeatureList f) {
|
||||
Message data;
|
||||
try {
|
||||
in = StreamUtils.hasSomeData(in);
|
||||
if (in == null) {
|
||||
return Messages.createEmpty(SOAPVersion.SOAP_11);
|
||||
}
|
||||
|
||||
if (ct != null) {
|
||||
final ContentType contentType = new ContentType(ct);
|
||||
final int contentTypeId = identifyContentType(contentType);
|
||||
if ((contentTypeId & MIME_MULTIPART_FLAG) != 0) {
|
||||
data = new XMLMultiPart(ct, in, f);
|
||||
} else if ((contentTypeId & PLAIN_XML_FLAG) != 0) {
|
||||
data = new XmlContent(ct, in, f);
|
||||
} else {
|
||||
data = new UnknownContent(ct, in);
|
||||
}
|
||||
} else {
|
||||
// According to HTTP spec 7.2.1, if the media type remain
|
||||
// unknown, treat as application/octet-stream
|
||||
data = new UnknownContent("application/octet-stream", in);
|
||||
}
|
||||
} catch(Exception ex) {
|
||||
throw new WebServiceException(ex);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
public static Message create(Source source) {
|
||||
return (source == null) ?
|
||||
Messages.createEmpty(SOAPVersion.SOAP_11) :
|
||||
Messages.createUsingPayload(source, SOAPVersion.SOAP_11);
|
||||
}
|
||||
|
||||
public static Message create(DataSource ds, WSFeatureList f) {
|
||||
try {
|
||||
return (ds == null) ?
|
||||
Messages.createEmpty(SOAPVersion.SOAP_11) :
|
||||
create(ds.getContentType(), ds.getInputStream(), f);
|
||||
} catch(IOException ioe) {
|
||||
throw new WebServiceException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
public static Message create(Exception e) {
|
||||
return new FaultMessage(SOAPVersion.SOAP_11);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the content type ID from the content type.
|
||||
*/
|
||||
private static int getContentId(String ct) {
|
||||
try {
|
||||
final ContentType contentType = new ContentType(ct);
|
||||
return identifyContentType(contentType);
|
||||
} catch(Exception ex) {
|
||||
throw new WebServiceException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the content uses fast infoset.
|
||||
*/
|
||||
public static boolean isFastInfoset(String ct) {
|
||||
return (getContentId(ct) & FI_ENCODED_FLAG) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify a contentType.
|
||||
*
|
||||
* @return
|
||||
* MIME_MULTIPART_FLAG | PLAIN_XML_FLAG
|
||||
* MIME_MULTIPART_FLAG | FI_ENCODED_FLAG;
|
||||
* PLAIN_XML_FLAG
|
||||
* FI_ENCODED_FLAG
|
||||
*
|
||||
*/
|
||||
public static int identifyContentType(ContentType contentType) {
|
||||
String primary = contentType.getPrimaryType();
|
||||
String sub = contentType.getSubType();
|
||||
|
||||
if (primary.equalsIgnoreCase("multipart") && sub.equalsIgnoreCase("related")) {
|
||||
String type = contentType.getParameter("type");
|
||||
if (type != null) {
|
||||
if (isXMLType(type)) {
|
||||
return MIME_MULTIPART_FLAG | PLAIN_XML_FLAG;
|
||||
} else if (isFastInfosetType(type)) {
|
||||
return MIME_MULTIPART_FLAG | FI_ENCODED_FLAG;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else if (isXMLType(primary, sub)) {
|
||||
return PLAIN_XML_FLAG;
|
||||
} else if (isFastInfosetType(primary, sub)) {
|
||||
return FI_ENCODED_FLAG;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected static boolean isXMLType(@NotNull String primary, @NotNull String sub) {
|
||||
return (primary.equalsIgnoreCase("text") && sub.equalsIgnoreCase("xml"))
|
||||
|| (primary.equalsIgnoreCase("application") && sub.equalsIgnoreCase("xml"))
|
||||
|| (primary.equalsIgnoreCase("application") && sub.toLowerCase().endsWith("+xml"));
|
||||
}
|
||||
|
||||
protected static boolean isXMLType(String type) {
|
||||
String lowerType = type.toLowerCase();
|
||||
return lowerType.startsWith("text/xml")
|
||||
|| lowerType.startsWith("application/xml")
|
||||
|| (lowerType.startsWith("application/") && (lowerType.indexOf("+xml") != -1));
|
||||
}
|
||||
|
||||
protected static boolean isFastInfosetType(String primary, String sub) {
|
||||
return primary.equalsIgnoreCase("application") && sub.equalsIgnoreCase("fastinfoset");
|
||||
}
|
||||
|
||||
protected static boolean isFastInfosetType(String type) {
|
||||
return type.toLowerCase().startsWith("application/fastinfoset");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Access a {@link Message} as a {@link DataSource}.
|
||||
* <p>
|
||||
* A {@link Message} implementation will implement this if the
|
||||
* messages is to be access as data source.
|
||||
* <p>
|
||||
* TODO: consider putting as part of the API.
|
||||
*/
|
||||
public static interface MessageDataSource {
|
||||
/**
|
||||
* Check if the data source has been consumed.
|
||||
* @return true of the data source has been consumed, otherwise false.
|
||||
*/
|
||||
boolean hasUnconsumedDataSource();
|
||||
|
||||
/**
|
||||
* Get the data source.
|
||||
* @return the data source.
|
||||
*/
|
||||
DataSource getDataSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* It's conent-type is some XML type
|
||||
*
|
||||
*/
|
||||
private static class XmlContent extends AbstractMessageImpl implements MessageDataSource {
|
||||
private final XmlDataSource dataSource;
|
||||
private boolean consumed;
|
||||
private Message delegate;
|
||||
private final HeaderList headerList;
|
||||
// private final WSBinding binding;
|
||||
private WSFeatureList features;
|
||||
|
||||
public XmlContent(String ct, InputStream in, WSFeatureList f) {
|
||||
super(SOAPVersion.SOAP_11);
|
||||
dataSource = new XmlDataSource(ct, in);
|
||||
this.headerList = new HeaderList(SOAPVersion.SOAP_11);
|
||||
// this.binding = binding;
|
||||
features = f;
|
||||
}
|
||||
|
||||
private Message getMessage() {
|
||||
if (delegate == null) {
|
||||
InputStream in = dataSource.getInputStream();
|
||||
assert in != null;
|
||||
delegate = Messages.createUsingPayload(new StreamSource(in), SOAPVersion.SOAP_11);
|
||||
consumed = true;
|
||||
}
|
||||
return delegate;
|
||||
}
|
||||
|
||||
public boolean hasUnconsumedDataSource() {
|
||||
return !dataSource.consumed()&&!consumed;
|
||||
}
|
||||
|
||||
public DataSource getDataSource() {
|
||||
return hasUnconsumedDataSource() ? dataSource :
|
||||
XMLMessage.getDataSource(getMessage(), features);
|
||||
}
|
||||
|
||||
public boolean hasHeaders() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public @NotNull MessageHeaders getHeaders() {
|
||||
return headerList;
|
||||
}
|
||||
|
||||
public String getPayloadLocalPart() {
|
||||
return getMessage().getPayloadLocalPart();
|
||||
}
|
||||
|
||||
public String getPayloadNamespaceURI() {
|
||||
return getMessage().getPayloadNamespaceURI();
|
||||
}
|
||||
|
||||
public boolean hasPayload() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isFault() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Source readEnvelopeAsSource() {
|
||||
return getMessage().readEnvelopeAsSource();
|
||||
}
|
||||
|
||||
public Source readPayloadAsSource() {
|
||||
return getMessage().readPayloadAsSource();
|
||||
}
|
||||
|
||||
public SOAPMessage readAsSOAPMessage() throws SOAPException {
|
||||
return getMessage().readAsSOAPMessage();
|
||||
}
|
||||
|
||||
public SOAPMessage readAsSOAPMessage(Packet packet, boolean inbound) throws SOAPException {
|
||||
return getMessage().readAsSOAPMessage(packet, inbound);
|
||||
}
|
||||
|
||||
public <T> T readPayloadAsJAXB(Unmarshaller unmarshaller) throws JAXBException {
|
||||
return (T)getMessage().readPayloadAsJAXB(unmarshaller);
|
||||
}
|
||||
/** @deprecated */
|
||||
public <T> T readPayloadAsJAXB(Bridge<T> bridge) throws JAXBException {
|
||||
return getMessage().readPayloadAsJAXB(bridge);
|
||||
}
|
||||
|
||||
public XMLStreamReader readPayload() throws XMLStreamException {
|
||||
return getMessage().readPayload();
|
||||
}
|
||||
|
||||
|
||||
public void writePayloadTo(XMLStreamWriter sw) throws XMLStreamException {
|
||||
getMessage().writePayloadTo(sw);
|
||||
}
|
||||
|
||||
public void writeTo(XMLStreamWriter sw) throws XMLStreamException {
|
||||
getMessage().writeTo(sw);
|
||||
}
|
||||
|
||||
public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler) throws SAXException {
|
||||
getMessage().writeTo(contentHandler, errorHandler);
|
||||
}
|
||||
|
||||
public Message copy() {
|
||||
return getMessage().copy();
|
||||
}
|
||||
|
||||
protected void writePayloadTo(ContentHandler contentHandler, ErrorHandler errorHandler, boolean fragment) throws SAXException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Data represented as a multi-part MIME message.
|
||||
* <p>
|
||||
* The root part may be an XML or an FI document. This class
|
||||
* parses MIME message lazily.
|
||||
*/
|
||||
public static final class XMLMultiPart extends AbstractMessageImpl implements MessageDataSource {
|
||||
private final DataSource dataSource;
|
||||
private final StreamingAttachmentFeature feature;
|
||||
private Message delegate;
|
||||
private HeaderList headerList;// = new HeaderList();
|
||||
// private final WSBinding binding;
|
||||
private final WSFeatureList features;
|
||||
|
||||
public XMLMultiPart(final String contentType, final InputStream is, WSFeatureList f) {
|
||||
super(SOAPVersion.SOAP_11);
|
||||
headerList = new HeaderList(SOAPVersion.SOAP_11);
|
||||
dataSource = createDataSource(contentType, is);
|
||||
this.feature = f.get(StreamingAttachmentFeature.class);
|
||||
this.features = f;
|
||||
}
|
||||
|
||||
private Message getMessage() {
|
||||
if (delegate == null) {
|
||||
MimeMultipartParser mpp;
|
||||
try {
|
||||
mpp = new MimeMultipartParser(dataSource.getInputStream(),
|
||||
dataSource.getContentType(), feature);
|
||||
} catch(IOException ioe) {
|
||||
throw new WebServiceException(ioe);
|
||||
}
|
||||
InputStream in = mpp.getRootPart().asInputStream();
|
||||
assert in != null;
|
||||
delegate = new PayloadSourceMessage(headerList, new StreamSource(in), new MimeAttachmentSet(mpp), SOAPVersion.SOAP_11);
|
||||
}
|
||||
return delegate;
|
||||
}
|
||||
|
||||
public boolean hasUnconsumedDataSource() {
|
||||
return delegate == null;
|
||||
}
|
||||
|
||||
public DataSource getDataSource() {
|
||||
return hasUnconsumedDataSource() ? dataSource :
|
||||
XMLMessage.getDataSource(getMessage(), features);
|
||||
}
|
||||
|
||||
public boolean hasHeaders() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public @NotNull MessageHeaders getHeaders() {
|
||||
return headerList;
|
||||
}
|
||||
|
||||
public String getPayloadLocalPart() {
|
||||
return getMessage().getPayloadLocalPart();
|
||||
}
|
||||
|
||||
public String getPayloadNamespaceURI() {
|
||||
return getMessage().getPayloadNamespaceURI();
|
||||
}
|
||||
|
||||
public boolean hasPayload() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isFault() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Source readEnvelopeAsSource() {
|
||||
return getMessage().readEnvelopeAsSource();
|
||||
}
|
||||
|
||||
public Source readPayloadAsSource() {
|
||||
return getMessage().readPayloadAsSource();
|
||||
}
|
||||
|
||||
public SOAPMessage readAsSOAPMessage() throws SOAPException {
|
||||
return getMessage().readAsSOAPMessage();
|
||||
}
|
||||
|
||||
public SOAPMessage readAsSOAPMessage(Packet packet, boolean inbound) throws SOAPException {
|
||||
return getMessage().readAsSOAPMessage(packet, inbound);
|
||||
}
|
||||
|
||||
public <T> T readPayloadAsJAXB(Unmarshaller unmarshaller) throws JAXBException {
|
||||
return (T)getMessage().readPayloadAsJAXB(unmarshaller);
|
||||
}
|
||||
|
||||
public <T> T readPayloadAsJAXB(Bridge<T> bridge) throws JAXBException {
|
||||
return getMessage().readPayloadAsJAXB(bridge);
|
||||
}
|
||||
|
||||
public XMLStreamReader readPayload() throws XMLStreamException {
|
||||
return getMessage().readPayload();
|
||||
}
|
||||
|
||||
public void writePayloadTo(XMLStreamWriter sw) throws XMLStreamException {
|
||||
getMessage().writePayloadTo(sw);
|
||||
}
|
||||
|
||||
public void writeTo(XMLStreamWriter sw) throws XMLStreamException {
|
||||
getMessage().writeTo(sw);
|
||||
}
|
||||
|
||||
public void writeTo(ContentHandler contentHandler, ErrorHandler errorHandler) throws SAXException {
|
||||
getMessage().writeTo(contentHandler, errorHandler);
|
||||
}
|
||||
|
||||
public Message copy() {
|
||||
return getMessage().copy();
|
||||
}
|
||||
|
||||
protected void writePayloadTo(ContentHandler contentHandler, ErrorHandler errorHandler, boolean fragment) throws SAXException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOneWay(@NotNull WSDLPort port) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public @NotNull AttachmentSet getAttachments() {
|
||||
return getMessage().getAttachments();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class FaultMessage extends EmptyMessageImpl {
|
||||
|
||||
public FaultMessage(SOAPVersion version) {
|
||||
super(version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFault() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Don't know about this content. It's conent-type is NOT the XML types
|
||||
* we recognize(text/xml, application/xml, multipart/related;text/xml etc).
|
||||
*
|
||||
* This could be used to represent image/jpeg etc
|
||||
*/
|
||||
public static class UnknownContent extends AbstractMessageImpl implements MessageDataSource {
|
||||
private final DataSource ds;
|
||||
private final HeaderList headerList;
|
||||
|
||||
public UnknownContent(final String ct, final InputStream in) {
|
||||
this(createDataSource(ct,in));
|
||||
}
|
||||
|
||||
public UnknownContent(DataSource ds) {
|
||||
super(SOAPVersion.SOAP_11);
|
||||
this.ds = ds;
|
||||
this.headerList = new HeaderList(SOAPVersion.SOAP_11);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy constructor.
|
||||
*/
|
||||
private UnknownContent(UnknownContent that) {
|
||||
super(that.soapVersion);
|
||||
this.ds = that.ds;
|
||||
this.headerList = HeaderList.copy(that.headerList);
|
||||
}
|
||||
|
||||
public boolean hasUnconsumedDataSource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public DataSource getDataSource() {
|
||||
assert ds != null;
|
||||
return ds;
|
||||
}
|
||||
|
||||
protected void writePayloadTo(ContentHandler contentHandler,
|
||||
ErrorHandler errorHandler, boolean fragment) throws SAXException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean hasHeaders() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFault() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public MessageHeaders getHeaders() {
|
||||
return headerList;
|
||||
}
|
||||
|
||||
public String getPayloadLocalPart() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public String getPayloadNamespaceURI() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean hasPayload() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Source readPayloadAsSource() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public XMLStreamReader readPayload() throws XMLStreamException {
|
||||
throw new WebServiceException("There isn't XML payload. Shouldn't come here.");
|
||||
}
|
||||
|
||||
public void writePayloadTo(XMLStreamWriter sw) throws XMLStreamException {
|
||||
// No XML. Nothing to do
|
||||
}
|
||||
|
||||
public Message copy() {
|
||||
return new UnknownContent(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static DataSource getDataSource(Message msg, WSFeatureList f) {
|
||||
if (msg == null)
|
||||
return null;
|
||||
if (msg instanceof MessageDataSource) {
|
||||
return ((MessageDataSource)msg).getDataSource();
|
||||
} else {
|
||||
AttachmentSet atts = msg.getAttachments();
|
||||
if (atts != null && !atts.isEmpty()) {
|
||||
final ByteArrayBuffer bos = new ByteArrayBuffer();
|
||||
try {
|
||||
Codec codec = new XMLHTTPBindingCodec(f);
|
||||
Packet packet = new Packet(msg);
|
||||
com.sun.xml.internal.ws.api.pipe.ContentType ct = codec.getStaticContentType(packet);
|
||||
codec.encode(packet, bos);
|
||||
return createDataSource(ct.getContentType(), bos.newInputStream());
|
||||
} catch(IOException ioe) {
|
||||
throw new WebServiceException(ioe);
|
||||
}
|
||||
|
||||
} else {
|
||||
final ByteArrayBuffer bos = new ByteArrayBuffer();
|
||||
XMLStreamWriter writer = XMLStreamWriterFactory.create(bos);
|
||||
try {
|
||||
msg.writePayloadTo(writer);
|
||||
writer.flush();
|
||||
} catch (XMLStreamException e) {
|
||||
throw new WebServiceException(e);
|
||||
}
|
||||
return XMLMessage.createDataSource("text/xml", bos.newInputStream());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static DataSource createDataSource(final String contentType, final InputStream is) {
|
||||
return new XmlDataSource(contentType, is);
|
||||
}
|
||||
|
||||
private static class XmlDataSource implements DataSource {
|
||||
private final String contentType;
|
||||
private final InputStream is;
|
||||
private boolean consumed;
|
||||
|
||||
XmlDataSource(String contentType, final InputStream is) {
|
||||
this.contentType = contentType;
|
||||
this.is = is;
|
||||
}
|
||||
|
||||
public boolean consumed() {
|
||||
return consumed;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
consumed = !consumed;
|
||||
return is;
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.ws.encoding.xml;
|
||||
|
||||
import com.oracle.webservices.internal.api.message.BasePropertySet;
|
||||
import com.oracle.webservices.internal.api.message.PropertySet;
|
||||
|
||||
public class XMLPropertyBag extends BasePropertySet {
|
||||
|
||||
private String contentType;
|
||||
protected PropertyMap getPropertyMap() {
|
||||
return model;
|
||||
}
|
||||
|
||||
@Property(XMLConstants.OUTPUT_XML_CHARACTER_ENCODING)
|
||||
public String getXMLContentType(){
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public void setXMLContentType(String content){
|
||||
contentType = content;
|
||||
}
|
||||
|
||||
private static final PropertyMap model;
|
||||
|
||||
static {
|
||||
model = parse(XMLPropertyBag.class);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user