feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,130 @@
/*
* 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.util;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* Copied from mail.jar.
*/
public class ASCIIUtility {
// Private constructor so that this class is not instantiated
private ASCIIUtility() { }
/**
* Convert the bytes within the specified range of the given byte
* array into a signed integer in the given radix . The range extends
* from <code>start</code> till, but not including <code>end</code>. <p>
*
* Based on java.lang.Integer.parseInt()
*/
public static int parseInt(byte[] b, int start, int end, int radix)
throws NumberFormatException {
if (b == null)
throw new NumberFormatException("null");
int result = 0;
boolean negative = false;
int i = start;
int limit;
int multmin;
int digit;
if (end > start) {
if (b[i] == '-') {
negative = true;
limit = Integer.MIN_VALUE;
i++;
} else {
limit = -Integer.MAX_VALUE;
}
multmin = limit / radix;
if (i < end) {
digit = Character.digit((char)b[i++], radix);
if (digit < 0) {
throw new NumberFormatException(
"illegal number: " + toString(b, start, end)
);
} else {
result = -digit;
}
}
while (i < end) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit((char)b[i++], radix);
if (digit < 0) {
throw new NumberFormatException("illegal number");
}
if (result < multmin) {
throw new NumberFormatException("illegal number");
}
result *= radix;
if (result < limit + digit) {
throw new NumberFormatException("illegal number");
}
result -= digit;
}
} else {
throw new NumberFormatException("illegal number");
}
if (negative) {
if (i > start + 1) {
return result;
} else { /* Only got "-" */
throw new NumberFormatException("illegal number");
}
} else {
return -result;
}
}
/**
* Convert the bytes within the specified range of the given byte
* array into a String. The range extends from <code>start</code>
* till, but not including <code>end</code>. <p>
*/
public static String toString(byte[] b, int start, int end) {
int size = end - start;
char[] theChars = new char[size];
for (int i = 0, j = start; i < size; )
theChars[i++] = (char)(b[j++]&0xff);
return new String(theChars);
}
public static void copyStream(InputStream is, OutputStream out) throws IOException {
int size = 1024;
byte[] buf = new byte[size];
int len;
while ((len = is.read(buf, 0, size)) != -1)
out.write(buf, 0, len);
}
}

View File

@@ -0,0 +1,213 @@
/*
* 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.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Read/write buffer that stores a sequence of bytes.
*
* <p>
* It works in a way similar to {@link ByteArrayOutputStream} but
* this class works better in the following ways:
*
* <ol>
* <li>no synchronization
* <li>offers a {@link #newInputStream()} that creates a new {@link InputStream}
* that won't cause buffer reallocation.
* <li>less parameter correctness checking
* <li>offers a {@link #write(InputStream)} method that reads the entirety of the
* given {@link InputStream} without using a temporary buffer.
* </ol>
*
* @author Kohsuke Kawaguchi
*/
public class ByteArrayBuffer extends OutputStream {
/**
* The buffer where data is stored.
*/
protected byte[] buf;
/**
* The number of valid bytes in the buffer.
*/
private int count;
private static final int CHUNK_SIZE = 4096;
/**
* Creates a new byte array output stream. The buffer capacity is
* initially 32 bytes, though its size increases if necessary.
*/
public ByteArrayBuffer() {
this(32);
}
/**
* Creates a new byte array output stream, with a buffer capacity of
* the specified size, in bytes.
*
* @param size the initial size.
* @throws IllegalArgumentException if size is negative.
*/
public ByteArrayBuffer(int size) {
if (size <= 0)
throw new IllegalArgumentException();
buf = new byte[size];
}
public ByteArrayBuffer(byte[] data) {
this(data,data.length);
}
public ByteArrayBuffer(byte[] data, int length) {
this.buf = data;
this.count = length;
}
/**
* Reads all the data of the given {@link InputStream} and appends them
* into this buffer.
*
* @throws IOException
* if the read operation fails with an {@link IOException}.
*/
public final void write(InputStream in) throws IOException {
while(true) {
int cap = buf.length-count; // the remaining buffer space
int sz = in.read(buf,count,cap);
if(sz<0) return; // hit EOS
count += sz;
if(cap==sz)
ensureCapacity(buf.length*2); // buffer filled up.
}
}
public final void write(int b) {
int newcount = count + 1;
ensureCapacity(newcount);
buf[count] = (byte) b;
count = newcount;
}
public final void write(byte b[], int off, int len) {
int newcount = count + len;
ensureCapacity(newcount);
System.arraycopy(b, off, buf, count, len);
count = newcount;
}
private void ensureCapacity(int newcount) {
if (newcount > buf.length) {
byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)];
System.arraycopy(buf, 0, newbuf, 0, count);
buf = newbuf;
}
}
public final void writeTo(OutputStream out) throws IOException {
// Instead of writing out.write(buf, 0, count)
// Writing it in chunks that would help larger payloads
// Also if out is System.out on windows, it doesn't show on the console
// for larger data.
int remaining = count;
int off = 0;
while(remaining > 0) {
int chunk = (remaining > CHUNK_SIZE) ? CHUNK_SIZE : remaining;
out.write(buf, off, chunk);
remaining -= chunk;
off += chunk;
}
}
public final void reset() {
count = 0;
}
/**
* Gets the <b>copy</b> of exact-size byte[] that represents the written data.
*
* <p>
* Since this method needs to allocate a new byte[], this method will be costly.
*
* @deprecated
* this method causes a buffer reallocation. Use it only when
* you have to.
*/
public final byte[] toByteArray() {
byte newbuf[] = new byte[count];
System.arraycopy(buf, 0, newbuf, 0, count);
return newbuf;
}
public final int size() {
return count;
}
/**
* Gets the underlying buffer that this {@link ByteArrayBuffer} uses.
* It's never small than its {@link #size()}.
*
* Use with caution.
*/
public final byte[] getRawData() {
return buf;
}
public void close() throws IOException {
}
/**
* Creates a new {@link InputStream} that reads from this buffer.
*/
public final InputStream newInputStream() {
return new ByteArrayInputStream(buf,0,count);
}
/**
* Creates a new {@link InputStream} that reads a part of this bfufer.
*/
public final InputStream newInputStream(int start, int length) {
return new ByteArrayInputStream(buf,start,length);
}
/**
* Decodes the contents of this buffer by the default encoding
* and returns it as a string.
*
* <p>
* Meant to aid debugging, but no more.
*/
public String toString() {
return new String(buf, 0, count);
}
}

View File

@@ -0,0 +1,76 @@
/*
* 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.util;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import javax.activation.DataSource;
/**
* {@link DataSource} backed by a byte buffer.
*
* @author Kohsuke Kawaguchi
*/
public final class ByteArrayDataSource implements DataSource {
private final String contentType;
private final byte[] buf;
private final int start;
private final int len;
public ByteArrayDataSource(byte[] buf, String contentType) {
this(buf,0,buf.length,contentType);
}
public ByteArrayDataSource(byte[] buf, int length, String contentType) {
this(buf,0,length,contentType);
}
public ByteArrayDataSource(byte[] buf, int start, int length, String contentType) {
this.buf = buf;
this.start = start;
this.len = length;
this.contentType = contentType;
}
public String getContentType() {
if(contentType==null)
return "application/octet-stream";
return contentType;
}
public InputStream getInputStream() {
return new ByteArrayInputStream(buf,start,len);
}
public String getName() {
return null;
}
public OutputStream getOutputStream() {
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,69 @@
/*
* 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.util;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* {@link Future} implementation that obtains an already available value.
*
* @author Kohsuke Kawaguchi
* @author Jitendra Kotamraju
*/
public class CompletedFuture<T> implements Future<T> {
private final T v;
private final Throwable re;
public CompletedFuture(T v, Throwable re) {
this.v = v;
this.re = re;
}
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
public boolean isCancelled() {
return false;
}
public boolean isDone() {
return true;
}
public T get() throws ExecutionException {
if (re != null) {
throw new ExecutionException(re);
}
return v;
}
public T get(long timeout, TimeUnit unit) throws ExecutionException {
return get();
}
}

View File

@@ -0,0 +1,39 @@
/*
* 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.util;
/**
* This holds generic constants information for the whole JAX-WS SI.
*
* @author WS Development Team
*/
public class Constants {
/**
* WS SI Logging Domain
*/
public static final String LoggingDomain = "com.sun.xml.internal.ws";
}

View File

@@ -0,0 +1,239 @@
/*
* Copyright (c) 1997, 2017, 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.util;
import com.sun.istack.internal.NotNull;
import com.sun.istack.internal.Nullable;
import com.sun.xml.internal.ws.util.xml.XmlUtil;
import org.w3c.dom.*;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @author JAXWS Development Team
*/
public class DOMUtil {
private static DocumentBuilder db;
/**
* Creates a new DOM document.
*/
public static Document createDom() {
synchronized (DOMUtil.class) {
if (db == null) {
try {
DocumentBuilderFactory dbf = XmlUtil.newDocumentBuilderFactory();
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new FactoryConfigurationError(e);
}
}
return db.newDocument();
}
}
/**
* Traverses a DOM node and writes out on a streaming writer.
*
* @param node
* @param writer
*/
public static void serializeNode(Element node, XMLStreamWriter writer) throws XMLStreamException {
writeTagWithAttributes(node, writer);
if (node.hasChildNodes()) {
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
switch (child.getNodeType()) {
case Node.PROCESSING_INSTRUCTION_NODE:
writer.writeProcessingInstruction(child.getNodeValue());
break;
case Node.DOCUMENT_TYPE_NODE:
break;
case Node.CDATA_SECTION_NODE:
writer.writeCData(child.getNodeValue());
break;
case Node.COMMENT_NODE:
writer.writeComment(child.getNodeValue());
break;
case Node.TEXT_NODE:
writer.writeCharacters(child.getNodeValue());
break;
case Node.ELEMENT_NODE:
serializeNode((Element) child, writer);
break;
default: break;
}
}
}
writer.writeEndElement();
}
public static void writeTagWithAttributes(Element node, XMLStreamWriter writer) throws XMLStreamException {
String nodePrefix = fixNull(node.getPrefix());
String nodeNS = fixNull(node.getNamespaceURI());
//fix to work with DOM level 1 nodes.
String nodeLocalName = node.getLocalName()== null?node.getNodeName():node.getLocalName();
// See if nodePrefix:nodeNS is declared in writer's NamespaceContext before writing start element
// Writing start element puts nodeNS in NamespaceContext even though namespace declaration not written
boolean prefixDecl = isPrefixDeclared(writer, nodeNS, nodePrefix);
writer.writeStartElement(nodePrefix, nodeLocalName, nodeNS);
if (node.hasAttributes()) {
NamedNodeMap attrs = node.getAttributes();
int numOfAttributes = attrs.getLength();
// write namespace declarations first.
// if we interleave this with attribue writing,
// Zephyr will try to fix it and we end up getting inconsistent namespace bindings.
for (int i = 0; i < numOfAttributes; i++) {
Node attr = attrs.item(i);
String nsUri = fixNull(attr.getNamespaceURI());
if (nsUri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
// handle default ns declarations
String local = attr.getLocalName().equals(XMLConstants.XMLNS_ATTRIBUTE) ? "" : attr.getLocalName();
if (local.equals(nodePrefix) && attr.getNodeValue().equals(nodeNS)) {
prefixDecl = true;
}
if (local.equals("")) {
writer.writeDefaultNamespace(attr.getNodeValue());
} else {
// this is a namespace declaration, not an attribute
writer.setPrefix(attr.getLocalName(), attr.getNodeValue());
writer.writeNamespace(attr.getLocalName(), attr.getNodeValue());
}
}
}
}
// node's namespace is not declared as attribute, but declared on ancestor
if (!prefixDecl) {
writer.writeNamespace(nodePrefix, nodeNS);
}
// Write all other attributes which are not namespace decl.
if (node.hasAttributes()) {
NamedNodeMap attrs = node.getAttributes();
int numOfAttributes = attrs.getLength();
for (int i = 0; i < numOfAttributes; i++) {
Node attr = attrs.item(i);
String attrPrefix = fixNull(attr.getPrefix());
String attrNS = fixNull(attr.getNamespaceURI());
if (!attrNS.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
String localName = attr.getLocalName();
if (localName == null) {
// TODO: this is really a bug in the caller for not creating proper DOM tree.
// will remove this workaround after plugfest
localName = attr.getNodeName();
}
boolean attrPrefixDecl = isPrefixDeclared(writer, attrNS, attrPrefix);
if (!attrPrefix.equals("") && !attrPrefixDecl) {
// attr has namespace but namespace decl is there in ancestor node
// So write the namespace decl before writing the attr
writer.setPrefix(attr.getLocalName(), attr.getNodeValue());
writer.writeNamespace(attrPrefix, attrNS);
}
writer.writeAttribute(attrPrefix, attrNS, localName, attr.getNodeValue());
}
}
}
}
private static boolean isPrefixDeclared(XMLStreamWriter writer, String nsUri, String prefix) {
boolean prefixDecl = false;
NamespaceContext nscontext = writer.getNamespaceContext();
Iterator prefixItr = nscontext.getPrefixes(nsUri);
while (prefixItr.hasNext()) {
if (prefix.equals(prefixItr.next())) {
prefixDecl = true;
break;
}
}
return prefixDecl;
}
/**
* Gets the first child of the given name, or null.
*/
public static Element getFirstChild(Element e, String nsUri, String local) {
for (Node n = e.getFirstChild(); n != null; n = n.getNextSibling()) {
if (n.getNodeType() == Node.ELEMENT_NODE) {
Element c = (Element) n;
if (c.getLocalName().equals(local) && c.getNamespaceURI().equals(nsUri)) {
return c;
}
}
}
return null;
}
private static
@NotNull
String fixNull(@Nullable String s) {
if (s == null) {
return "";
} else {
return s;
}
}
/**
* Gets the first element child.
*/
public static
@Nullable
Element getFirstElementChild(Node parent) {
for (Node n = parent.getFirstChild(); n != null; n = n.getNextSibling()) {
if (n.getNodeType() == Node.ELEMENT_NODE) {
return (Element) n;
}
}
return null;
}
public static @NotNull
List<Element> getChildElements(Node parent){
List<Element> elements = new ArrayList<Element>();
for (Node n = parent.getFirstChild(); n != null; n = n.getNextSibling()) {
if (n.getNodeType() == Node.ELEMENT_NODE) {
elements.add((Element)n);
}
}
return elements;
}
}

View File

@@ -0,0 +1,75 @@
/*
* 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.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
*
* @author Santiago.PericasGeertsen@sun.com
* @author Paul.Sandoz@sun.com
*/
public class FastInfosetReflection {
/**
* FI StAXDocumentParser constructor using reflection.
*/
public static final Constructor fiStAXDocumentParser_new;
/**
* FI <code>StAXDocumentParser.setInputStream()</code> method via reflection.
*/
public static final Method fiStAXDocumentParser_setInputStream;
/**
* FI <code>StAXDocumentParser.setStringInterning()</code> method via reflection.
*/
public static final Method fiStAXDocumentParser_setStringInterning;
static {
Constructor tmp_new = null;
Method tmp_setInputStream = null;
Method tmp_setStringInterning = null;
// Use reflection to avoid static dependency with FI jar
try {
Class clazz = Class.forName("com.sun.xml.internal.fastinfoset.stax.StAXDocumentParser");
tmp_new = clazz.getConstructor();
tmp_setInputStream =
clazz.getMethod("setInputStream", java.io.InputStream.class);
tmp_setStringInterning =
clazz.getMethod("setStringInterning", boolean.class);
}
catch (Exception e) {
// falls through
}
fiStAXDocumentParser_new = tmp_new;
fiStAXDocumentParser_setInputStream = tmp_setInputStream;
fiStAXDocumentParser_setStringInterning = tmp_setStringInterning;
}
}

View File

@@ -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.util;
import com.sun.xml.internal.ws.streaming.XMLReaderException;
import com.sun.xml.internal.ws.streaming.XMLStreamReaderException;
import javax.xml.stream.XMLStreamReader;
import java.io.InputStream;
public class FastInfosetUtil {
/**
* Returns the FI parser allocated for this thread.
*/
public static XMLStreamReader createFIStreamReader(InputStream in) {
// Check if compatible implementation of FI was found
if (FastInfosetReflection.fiStAXDocumentParser_new == null) {
throw new XMLReaderException("fastinfoset.noImplementation");
}
try {
// Do not use StAX pluggable layer for FI
Object sdp = FastInfosetReflection.fiStAXDocumentParser_new.newInstance();
FastInfosetReflection.fiStAXDocumentParser_setStringInterning.invoke(sdp, Boolean.TRUE);
FastInfosetReflection.fiStAXDocumentParser_setInputStream.invoke(sdp, in);
return (XMLStreamReader) sdp;
} catch (Exception e) {
throw new XMLStreamReaderException(e);
}
}
}

View File

@@ -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.util;
import java.util.List;
import java.util.Set;
import javax.xml.ws.handler.Handler;
/**
* Used to hold a list of handlers and a set of roles from an
* annotated endpoint. At runtime, these are created by the
* HandlerAnnotationProcessor at the request of client and
* server code to create the handler chains.
*
* @see com.sun.xml.internal.ws.util.HandlerAnnotationProcessor
*
* @author JAX-WS Development Team
*/
public class HandlerAnnotationInfo {
private List<Handler> handlers;
private Set<String> roles;
/**
* Return the handlers specified by the handler chain descriptor.
*
* @return A list of jax-ws handler objects.
*/
public List<Handler> getHandlers() {
return handlers;
}
/**
* This method should only be called by HandlerAnnotationProcessor.
*
* @param handlers The handlers specified by the handler chain descriptor.
*/
public void setHandlers(List<Handler> handlers) {
this.handlers = handlers;
}
/**
* Return the roles contained in the handler chain descriptor.
*
* @return A set of roles.
*/
public Set<String> getRoles() {
return roles;
}
/**
* This method should only be called by HandlerAnnotationProcessor.
*
* @param roles The roles contained in the handler chain descriptor.
*/
public void setRoles(Set<String> roles) {
this.roles = roles;
}
}

View File

@@ -0,0 +1,224 @@
/*
* 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.util;
import com.sun.xml.internal.ws.api.WSBinding;
import com.sun.xml.internal.ws.api.databinding.MetadataReader;
import com.sun.xml.internal.ws.api.server.AsyncProvider;
import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
import com.sun.xml.internal.ws.handler.HandlerChainsModel;
import com.sun.xml.internal.ws.model.ReflectAnnotationReader;
import com.sun.xml.internal.ws.server.EndpointFactory;
import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
import com.sun.istack.internal.NotNull;
import javax.jws.HandlerChain;
import javax.jws.WebService;
import javax.jws.soap.SOAPMessageHandlers;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.ws.Provider;
import javax.xml.ws.Service;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.logging.Logger;
/**
* <p>Used by client and server side to create handler information
* from annotated class. The public methods all return a
* HandlerChainInfo that contains the handlers and role information
* needed at runtime.
*
* <p>All of the handler chain descriptors follow the same schema,
* whether they are wsdl customizations, handler files specified
* by an annotation, or are included in the sun-jaxws.xml file.
* So this class is used for all handler xml information. The
* two public entry points are
* {@link HandlerAnnotationProcessor#buildHandlerInfo}, called
* when you have an annotated class that points to a file.
*
* <p>The methods in the class are static so that it may called
* from the runtime statically.
*
* @see com.sun.xml.internal.ws.util.HandlerAnnotationInfo
*
* @author JAX-WS Development Team
*/
public class HandlerAnnotationProcessor {
private static final Logger logger = Logger.getLogger(
com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".util");
/**
* <p>This method is called by
* {@link EndpointFactory} when
* they have an annotated class.
*
* <p>If there is no handler chain annotation on the class,
* this method will return null. Otherwise it will load the
* class and call the parseHandlerFile method to read the
* information.
*
* @return A HandlerAnnotationInfo object that stores the
* handlers and roles. Will return null if the class passed
* in has no handler chain annotation.
*/
public static HandlerAnnotationInfo buildHandlerInfo(@NotNull
Class<?> clazz, QName serviceName, QName portName, WSBinding binding) {
MetadataReader metadataReader = EndpointFactory.getExternalMetadatReader(clazz, binding);
if (metadataReader == null) {
metadataReader = new ReflectAnnotationReader();
}
// clazz = checkClass(clazz);
HandlerChain handlerChain = metadataReader.getAnnotation(HandlerChain.class, clazz);
if (handlerChain == null) {
clazz = getSEI(clazz, metadataReader);
if (clazz != null)
handlerChain = metadataReader.getAnnotation(HandlerChain.class, clazz);
if (handlerChain == null)
return null;
}
if (clazz.getAnnotation(SOAPMessageHandlers.class) != null) {
throw new UtilException(
"util.handler.cannot.combine.soapmessagehandlers");
}
InputStream iStream = getFileAsStream(clazz, handlerChain);
XMLStreamReader reader =
XMLStreamReaderFactory.create(null,iStream, true);
XMLStreamReaderUtil.nextElementContent(reader);
HandlerAnnotationInfo handlerAnnInfo = HandlerChainsModel.parseHandlerFile(reader, clazz.getClassLoader(),
serviceName, portName, binding);
try {
reader.close();
iStream.close();
} catch (XMLStreamException e) {
e.printStackTrace();
throw new UtilException(e.getMessage());
} catch (IOException e) {
e.printStackTrace();
throw new UtilException(e.getMessage());
}
return handlerAnnInfo;
}
public static HandlerChainsModel buildHandlerChainsModel(final Class<?> clazz) {
if(clazz == null) {
return null;
}
HandlerChain handlerChain =
clazz.getAnnotation(HandlerChain.class);
if(handlerChain == null)
return null;
InputStream iStream = getFileAsStream(clazz, handlerChain);
XMLStreamReader reader =
XMLStreamReaderFactory.create(null,iStream, true);
XMLStreamReaderUtil.nextElementContent(reader);
HandlerChainsModel handlerChainsModel = HandlerChainsModel.parseHandlerConfigFile(clazz, reader);
try {
reader.close();
iStream.close();
} catch (XMLStreamException e) {
e.printStackTrace();
throw new UtilException(e.getMessage());
} catch (IOException e) {
e.printStackTrace();
throw new UtilException(e.getMessage());
}
return handlerChainsModel;
}
static Class getClass(String className) {
try {
return Thread.currentThread().getContextClassLoader().loadClass(
className);
} catch (ClassNotFoundException e) {
throw new UtilException("util.handler.class.not.found",
className);
}
}
static Class getSEI(Class<?> clazz, MetadataReader metadataReader) {
if (metadataReader == null) {
metadataReader = new ReflectAnnotationReader();
}
if (Provider.class.isAssignableFrom(clazz) || AsyncProvider.class.isAssignableFrom(clazz)) {
//No SEI for Provider Implementation
return null;
}
if (Service.class.isAssignableFrom(clazz)) {
//No SEI for Service class
return null;
}
WebService webService = metadataReader.getAnnotation(WebService.class, clazz);
if (webService == null) {
throw new UtilException("util.handler.no.webservice.annotation", clazz.getCanonicalName());
}
String ei = webService.endpointInterface();
if (ei.length() > 0) {
clazz = getClass(webService.endpointInterface());
WebService ws = metadataReader.getAnnotation(WebService.class, clazz);
if (ws == null) {
throw new UtilException("util.handler.endpoint.interface.no.webservice",
webService.endpointInterface());
}
return clazz;
}
return null;
}
static InputStream getFileAsStream(Class clazz, HandlerChain chain) {
URL url = clazz.getResource(chain.file());
if (url == null) {
url = Thread.currentThread().getContextClassLoader().
getResource(chain.file());
}
if (url == null) {
String tmp = clazz.getPackage().getName();
tmp = tmp.replace('.', '/');
tmp += "/" + chain.file();
url =
Thread.currentThread().getContextClassLoader().getResource(tmp);
}
if (url == null) {
throw new UtilException("util.failed.to.find.handlerchain.file",
clazz.getName(), chain.file());
}
try {
return url.openStream();
} catch (IOException e) {
throw new UtilException("util.failed.to.parse.handlerchain.file",
clazz.getName(), chain.file());
}
}
}

View File

@@ -0,0 +1,233 @@
/*
* 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.util;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import javax.annotation.Resource;
import javax.xml.ws.WebServiceException;
/**
* Encapsulates which field/method the injection is done, and performs the
* injection.
*/
public abstract class InjectionPlan<T, R> {
/**
* Perform injection
*
* @param instance
* Instance
* @param resource
* Resource
*/
public abstract void inject(T instance, R resource);
/**
* Perform injection, but resource is only generated if injection is
* necessary.
*
* @param instance
* @param resource
*/
public void inject(T instance, Callable<R> resource) {
try {
inject(instance, resource.call());
} catch(Exception e) {
throw new WebServiceException(e);
}
}
/*
* Injects to a field.
*/
public static class FieldInjectionPlan<T, R> extends
InjectionPlan<T, R> {
private final Field field;
public FieldInjectionPlan(Field field) {
this.field = field;
}
public void inject(final T instance, final R resource) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
try {
if (!field.isAccessible()) {
field.setAccessible(true);
}
field.set(instance, resource);
return null;
} catch (IllegalAccessException e) {
throw new WebServiceException(e);
}
}
});
}
}
/*
* Injects to a method.
*/
public static class MethodInjectionPlan<T, R> extends
InjectionPlan<T, R> {
private final Method method;
public MethodInjectionPlan(Method method) {
this.method = method;
}
public void inject(T instance, R resource) {
invokeMethod(method, instance, resource);
}
}
/*
* Helper for invoking a method with elevated privilege.
*/
private static void invokeMethod(final Method method, final Object instance, final Object... args) {
if(method==null) return;
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
try {
if (!method.isAccessible()) {
method.setAccessible(true);
}
method.invoke(instance,args);
} catch (IllegalAccessException e) {
throw new WebServiceException(e);
} catch (InvocationTargetException e) {
throw new WebServiceException(e);
}
return null;
}
});
}
/*
* Combines multiple {@link InjectionPlan}s into one.
*/
private static class Compositor<T, R> extends InjectionPlan<T, R> {
private final Collection<InjectionPlan<T, R>> children;
public Compositor(Collection<InjectionPlan<T, R>> children) {
this.children = children;
}
public void inject(T instance, R res) {
for (InjectionPlan<T, R> plan : children)
plan.inject(instance, res);
}
public void inject(T instance, Callable<R> resource) {
if (!children.isEmpty()) {
super.inject(instance, resource);
}
}
}
/*
* Creates an {@link InjectionPlan} that injects the given resource type to the given class.
*
* @param isStatic
* Only look for static field/method
*
*/
public static <T,R>
InjectionPlan<T,R> buildInjectionPlan(Class<? extends T> clazz, Class<R> resourceType, boolean isStatic) {
List<InjectionPlan<T,R>> plan = new ArrayList<InjectionPlan<T,R>>();
Class<?> cl = clazz;
while(cl != Object.class) {
for(Field field: cl.getDeclaredFields()) {
Resource resource = field.getAnnotation(Resource.class);
if (resource != null) {
if(isInjectionPoint(resource, field.getType(),
"Incorrect type for field"+field.getName(),
resourceType)) {
if(isStatic && !Modifier.isStatic(field.getModifiers()))
throw new WebServiceException("Static resource "+resourceType+" cannot be injected to non-static "+field);
plan.add(new FieldInjectionPlan<T,R>(field));
}
}
}
cl = cl.getSuperclass();
}
cl = clazz;
while(cl != Object.class) {
for(Method method : cl.getDeclaredMethods()) {
Resource resource = method.getAnnotation(Resource.class);
if (resource != null) {
Class[] paramTypes = method.getParameterTypes();
if (paramTypes.length != 1)
throw new WebServiceException("Incorrect no of arguments for method "+method);
if(isInjectionPoint(resource,paramTypes[0],
"Incorrect argument types for method"+method.getName(),
resourceType)) {
if(isStatic && !Modifier.isStatic(method.getModifiers()))
throw new WebServiceException("Static resource "+resourceType+" cannot be injected to non-static "+method);
plan.add(new MethodInjectionPlan<T,R>(method));
}
}
}
cl = cl.getSuperclass();
}
return new Compositor<T,R>(plan);
}
/*
* Returns true if the combination of {@link Resource} and the field/method type
* are consistent for {@link WebServiceContext} injection.
*/
private static boolean isInjectionPoint(Resource resource, Class fieldType, String errorMessage, Class resourceType ) {
Class t = resource.type();
if (t.equals(Object.class)) {
return fieldType.equals(resourceType);
} else if (t.equals(resourceType)) {
if (fieldType.isAssignableFrom(resourceType)) {
return true;
} else {
// type compatibility error
throw new WebServiceException(errorMessage);
}
}
return false;
}
}

View File

@@ -0,0 +1,155 @@
/*
* 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.util;
import java.util.UUID;
import java.util.regex.Pattern;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.io.File;
import java.io.IOException;
import javax.xml.namespace.QName;
/**
* @author Vivek Pandey
*
* Wrapper utility class to be used from the generated code or run time.
*/
public final class JAXWSUtils {
public static String getUUID(){
return UUID.randomUUID().toString();
}
public static String getFileOrURLName(String fileOrURL) {
try{
try {
return escapeSpace(new URL(fileOrURL).toExternalForm());
} catch (MalformedURLException e) {
return new File(fileOrURL).getCanonicalFile().toURL().toExternalForm();
}
} catch (Exception e) {
// try it as an URL
return fileOrURL;
}
}
public static URL getFileOrURL(String fileOrURL) throws IOException {
try {
URL url = new URL(fileOrURL);
String scheme = String.valueOf(url.getProtocol()).toLowerCase();
if (scheme.equals("http") || scheme.equals("https"))
return new URL(url.toURI().toASCIIString());
return url;
} catch (URISyntaxException e) {
return new File(fileOrURL).toURL();
} catch (MalformedURLException e) {
return new File(fileOrURL).toURL();
}
}
public static URL getEncodedURL(String urlStr) throws MalformedURLException {
URL url = new URL(urlStr);
String scheme = String.valueOf(url.getProtocol()).toLowerCase();
if (scheme.equals("http") || scheme.equals("https")) {
try {
return new URL(url.toURI().toASCIIString());
} catch (URISyntaxException e) {
MalformedURLException malformedURLException = new MalformedURLException(e.getMessage());
malformedURLException.initCause(e);
throw malformedURLException;
}
}
return url;
}
private static String escapeSpace( String url ) {
// URLEncoder didn't work.
StringBuilder buf = new StringBuilder();
for (int i = 0; i < url.length(); i++) {
// TODO: not sure if this is the only character that needs to be escaped.
if (url.charAt(i) == ' ')
buf.append("%20");
else
buf.append(url.charAt(i));
}
return buf.toString();
}
public static String absolutize(String name) {
// absolutize all the system IDs in the input,
// so that we can map system IDs to DOM trees.
try {
URL baseURL = new File(".").getCanonicalFile().toURL();
return new URL(baseURL, name).toExternalForm();
} catch( IOException e) {
//ignore
}
return name;
}
/**
* Checks if the system ID is absolute.
*/
@SuppressWarnings("ResultOfObjectAllocationIgnored")
public static void checkAbsoluteness(String systemId) {
// we need to be able to handle system IDs like "urn:foo", which java.net.URL can't process,
// but OTOH we also need to be able to process system IDs like "file://a b c/def.xsd",
// which java.net.URI can't process. So for now, let's fail only if both of them fail.
// eventually we need a proper URI class that works for us.
try {
new URL(systemId);
} catch( MalformedURLException mue) {
try {
new URI(systemId);
} catch (URISyntaxException e) {
throw new IllegalArgumentException("system ID '"+systemId+"' isn't absolute",e);
}
}
}
/*
* To match, both QNames must have the same namespace and the local
* part of the target must match the local part of the 'pattern'
* QName, which may contain wildcard characters.
*/
public static boolean matchQNames(QName target, QName pattern) {
if ((target == null) || (pattern == null)) {
// if no service or port is in descriptor
return false;
}
if (pattern.getNamespaceURI().equals(target.getNamespaceURI())) {
String regex = pattern.getLocalPart().replaceAll("\\*", ".*");
return Pattern.matches(regex, target.getLocalPart());
}
return false;
}
}

View File

@@ -0,0 +1,79 @@
/*
* 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.util;
import com.sun.istack.internal.NotNull;
import com.sun.xml.internal.ws.api.server.SDDocument;
import com.sun.xml.internal.ws.wsdl.SDDocumentResolver;
import java.util.*;
/**
* WSDL, schema document metadata utility class.
*
* @author Jitendra Kotamraju
*/
public class MetadataUtil {
/**
* Gets closure of all the referenced documents from the primary document(typically
* the service WSDL). It traverses the WSDL and schema imports and builds a closure
* set of documents.
*
* @param systemId primary wsdl or the any root document
* @param resolver used to get SDDocumentImpl for a document
* @param onlyTopLevelSchemas if true, the imported schemas from a schema would be ignored
* @return all the documents
*/
public static Map<String, SDDocument> getMetadataClosure(@NotNull String systemId,
@NotNull SDDocumentResolver resolver, boolean onlyTopLevelSchemas) {
Map <String, SDDocument> closureDocs = new HashMap<String, SDDocument>();
Set<String> remaining = new HashSet<String>();
remaining.add(systemId);
while(!remaining.isEmpty()) {
Iterator<String> it = remaining.iterator();
String current = it.next();
remaining.remove(current);
SDDocument currentDoc = resolver.resolve(current);
SDDocument old = closureDocs.put(currentDoc.getURL().toExternalForm(), currentDoc);
assert old == null;
Set<String> imports = currentDoc.getImports();
if (!currentDoc.isSchema() || !onlyTopLevelSchemas) {
for(String importedDoc : imports) {
if (closureDocs.get(importedDoc) == null) {
remaining.add(importedDoc);
}
}
}
}
return closureDocs;
}
}

View File

@@ -0,0 +1,746 @@
/*
* 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.util;
import java.util.ArrayList;
import java.util.EmptyStackException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.sun.xml.internal.ws.encoding.soap.streaming.SOAPNamespaceConstants;
/**
* Encapsulate Namespace logic for use by SAX drivers.
*
* <blockquote>
* <em>This module, both source code and documentation, is in the
* Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
* </blockquote>
*
* <p>This class encapsulates the logic of Namespace processing:
* it tracks the declarations currently in force for each context
* and automatically processes qualified XML 1.0 names into their
* Namespace parts; it can also be used in reverse for generating
* XML 1.0 from Namespaces.</p>
*
* <p>Namespace support objects are reusable, but the reset method
* must be invoked between each session.</p>
*
* <p>Here is a simple session:</p>
*
* <pre>
* String parts[] = new String[3];
* NamespaceSupport support = new NamespaceSupport();
*
* support.pushContext();
* support.declarePrefix("", "http://www.w3.org/1999/xhtml");
* support.declarePrefix("dc", "http://www.purl.org/dc#");
*
* String parts[] = support.processName("p", parts, false);
* System.out.println("Namespace URI: " + parts[0]);
* System.out.println("Local name: " + parts[1]);
* System.out.println("Raw name: " + parts[2]);
* String parts[] = support.processName("dc:title", parts, false);
* System.out.println("Namespace URI: " + parts[0]);
* System.out.println("Local name: " + parts[1]);
* System.out.println("Raw name: " + parts[2]);
* support.popContext();
* </pre>
*
* <p>Note that this class is optimized for the use case where most
* elements do not contain Namespace declarations: if the same
* prefix/URI mapping is repeated for each context (for example), this
* class will be somewhat less efficient.</p>
*
* @author David Megginson
* @author WS Development Team
*/
public final class NamespaceSupport {
/* added two new methods, slideContextUp() and slideContextDown()
* needed to implement the revised streaming parser class (Parser2)
*/
////////////////////////////////////////////////////////////////////
// Constants.
////////////////////////////////////////////////////////////////////
/**
* The XML Namespace as a constant.
*
* <p>This is the Namespace URI that is automatically mapped
* to the "xml" prefix.</p>
*/
public final static String XMLNS = "http://www.w3.org/XML/1998/namespace";
/**
* An empty enumeration.
*/
private final static Iterable<String> EMPTY_ENUMERATION =
new ArrayList<String>();
////////////////////////////////////////////////////////////////////
// Constructor.
////////////////////////////////////////////////////////////////////
/**
* Create a new Namespace support object.
*/
public NamespaceSupport() {
reset();
}
// PBG May 6 2002 added a copy constructor to support recording
public NamespaceSupport(NamespaceSupport that) {
contexts = new Context[that.contexts.length];
currentContext = null;
contextPos = that.contextPos;
Context currentParent = null;
for (int i = 0; i < that.contexts.length; i++) {
Context thatContext = that.contexts[i];
if (thatContext == null) {
contexts[i] = null;
continue;
}
Context thisContext = new Context(thatContext, currentParent);
contexts[i] = thisContext;
if (that.currentContext == thatContext) {
currentContext = thisContext;
}
currentParent = thisContext;
}
}
////////////////////////////////////////////////////////////////////
// Context management.
////////////////////////////////////////////////////////////////////
/**
* Reset this Namespace support object for reuse.
*
* <p>It is necessary to invoke this method before reusing the
* Namespace support object for a new session.</p>
*/
public void reset() {
contexts = new Context[32];
contextPos = 0;
contexts[contextPos] = currentContext = new Context();
currentContext.declarePrefix("xml", XMLNS);
}
/**
* Start a new Namespace context.
*
* <p>Normally, you should push a new context at the beginning
* of each XML element: the new context will automatically inherit
* the declarations of its parent context, but it will also keep
* track of which declarations were made within this context.</p>
*
* <p>The Namespace support object always starts with a base context
* already in force: in this context, only the "xml" prefix is
* declared.</p>
*
* @see #popContext
*/
public void pushContext() {
int max = contexts.length;
contextPos++;
// Extend the array if necessary
if (contextPos >= max) {
Context newContexts[] = new Context[max * 2];
System.arraycopy(contexts, 0, newContexts, 0, max);
contexts = newContexts;
}
// Allocate the context if necessary.
currentContext = contexts[contextPos];
if (currentContext == null) {
contexts[contextPos] = currentContext = new Context();
}
// Set the parent, if any.
if (contextPos > 0) {
currentContext.setParent(contexts[contextPos - 1]);
}
}
/**
* Revert to the previous Namespace context.
*
* <p>Normally, you should pop the context at the end of each
* XML element. After popping the context, all Namespace prefix
* mappings that were previously in force are restored.</p>
*
* <p>You must not attempt to declare additional Namespace
* prefixes after popping a context, unless you push another
* context first.</p>
*
* @see #pushContext
*/
public void popContext() {
contextPos--;
if (contextPos < 0) {
throw new EmptyStackException();
}
currentContext = contexts[contextPos];
}
/*
* added for the revised streaming parser class (Parser2)
* Move the context artificially up one level (i.e. contracting it).
*/
public void slideContextUp() {
contextPos--;
currentContext = contexts[contextPos];
}
/*
* added for the revised streaming parser class (Parser2)
* Move the context artificially down one level (i.e. expanding it).
*/
public void slideContextDown() {
contextPos++;
if (contexts[contextPos] == null) {
// trying to slide to a context that was never created
contexts[contextPos] = contexts[contextPos - 1];
}
currentContext = contexts[contextPos];
}
////////////////////////////////////////////////////////////////////
// Operations within a context.
////////////////////////////////////////////////////////////////////
/**
* Declare a Namespace prefix.
*
* <p>This method declares a prefix in the current Namespace
* context; the prefix will remain in force until this context
* is popped, unless it is shadowed in a descendant context.</p>
*
* <p>To declare a default Namespace, use the empty string. The
* prefix must not be "xml" or "xmlns".</p>
*
* <p>Note that you must <em>not</em> declare a prefix after
* you've pushed and popped another Namespace.</p>
*
* <p>Note that there is an asymmetry in this library: while {@link
* #getPrefix getPrefix} will not return the default "" prefix,
* even if you have declared one; to check for a default prefix,
* you have to look it up explicitly using {@link #getURI getURI}.
* This asymmetry exists to make it easier to look up prefixes
* for attribute names, where the default prefix is not allowed.</p>
*
* @param prefix The prefix to declare, or null for the empty
* string.
* @param uri The Namespace URI to associate with the prefix.
* @return true if the prefix was legal, false otherwise
* @see #processName
* @see #getURI
* @see #getPrefix
*/
public boolean declarePrefix(String prefix, String uri) {
// bugfix#: 4989753
if ((prefix.equals("xml") && !uri.equals(SOAPNamespaceConstants.XMLNS))
|| prefix.equals("xmlns")) {
return false;
} else {
currentContext.declarePrefix(prefix, uri);
return true;
}
}
/**
* Process a raw XML 1.0 name.
*
* <p>This method processes a raw XML 1.0 name in the current
* context by removing the prefix and looking it up among the
* prefixes currently declared. The return value will be the
* array supplied by the caller, filled in as follows:</p>
*
* <dl>
* <dt>parts[0]</dt>
* <dd>The Namespace URI, or an empty string if none is
* in use.</dd>
* <dt>parts[1]</dt>
* <dd>The local name (without prefix).</dd>
* <dt>parts[2]</dt>
* <dd>The original raw name.</dd>
* </dl>
*
* <p>All of the strings in the array will be internalized. If
* the raw name has a prefix that has not been declared, then
* the return value will be null.</p>
*
* <p>Note that attribute names are processed differently than
* element names: an unprefixed element name will received the
* default Namespace (if any), while an unprefixed element name
* will not.</p>
*
* @param qName The raw XML 1.0 name to be processed.
* @param parts An array supplied by the caller, capable of
* holding at least three members.
* @param isAttribute A flag indicating whether this is an
* attribute name (true) or an element name (false).
* @return The supplied array holding three internalized strings
* representing the Namespace URI (or empty string), the
* local name, and the raw XML 1.0 name; or null if there
* is an undeclared prefix.
* @see #declarePrefix
* @see java.lang.String#intern */
public String[] processName(
String qName,
String parts[],
boolean isAttribute) {
String myParts[] = currentContext.processName(qName, isAttribute);
if (myParts == null) {
return null;
} else {
parts[0] = myParts[0];
parts[1] = myParts[1];
parts[2] = myParts[2];
return parts;
}
}
/**
* Look up a prefix and get the currently-mapped Namespace URI.
*
* <p>This method looks up the prefix in the current context.
* Use the empty string ("") for the default Namespace.</p>
*
* @param prefix The prefix to look up.
* @return The associated Namespace URI, or null if the prefix
* is undeclared in this context.
* @see #getPrefix
* @see #getPrefixes
*/
public String getURI(String prefix) {
return currentContext.getURI(prefix);
}
/**
* Return an enumeration of all prefixes currently declared.
*
* <p><strong>Note:</strong> if there is a default prefix, it will not be
* returned in this enumeration; check for the default prefix
* using the {@link #getURI getURI} with an argument of "".</p>
*
* @return An enumeration of all prefixes declared in the
* current context except for the empty (default)
* prefix.
* @see #getDeclaredPrefixes
* @see #getURI
*/
public Iterable<String> getPrefixes() {
return currentContext.getPrefixes();
}
/**
* Return one of the prefixes mapped to a Namespace URI.
*
* <p>If more than one prefix is currently mapped to the same
* URI, this method will make an arbitrary selection; if you
* want all of the prefixes, use the {@link #getPrefixes}
* method instead.</p>
*
* <p><strong>Note:</strong> this will never return the empty (default) prefix;
* to check for a default prefix, use the {@link #getURI getURI}
* method with an argument of "".</p>
*
* @param uri The Namespace URI.
* @return One of the prefixes currently mapped to the URI supplied,
* or null if none is mapped or if the URI is assigned to
* the default Namespace.
* @see #getPrefixes(java.lang.String)
* @see #getURI
*/
public String getPrefix(String uri) {
return currentContext.getPrefix(uri);
}
/**
* Return an enumeration of all prefixes currently declared for a URI.
*
* <p>This method returns prefixes mapped to a specific Namespace
* URI. The xml: prefix will be included. If you want only one
* prefix that's mapped to the Namespace URI, and you don't care
* which one you get, use the {@link #getPrefix getPrefix}
* method instead.</p>
*
* <p><strong>Note:</strong> the empty (default) prefix is <em>never</em> included
* in this enumeration; to check for the presence of a default
* Namespace, use the {@link #getURI getURI} method with an
* argument of "".</p>
*
* @param uri The Namespace URI.
* @return An enumeration of all prefixes declared in the
* current context.
* @see #getPrefix
* @see #getDeclaredPrefixes
* @see #getURI
*/
public Iterator getPrefixes(String uri) {
List prefixes = new ArrayList();
for (String prefix: getPrefixes()) {
if (uri.equals(getURI(prefix))) {
prefixes.add(prefix);
}
}
return prefixes.iterator();
}
/**
* Return an enumeration of all prefixes declared in this context.
*
* <p>The empty (default) prefix will be included in this
* enumeration; note that this behaviour differs from that of
* {@link #getPrefix} and {@link #getPrefixes}.</p>
*
* @return An enumeration of all prefixes declared in this
* context.
* @see #getPrefixes
* @see #getURI
*/
public Iterable<String> getDeclaredPrefixes() {
return currentContext.getDeclaredPrefixes();
}
////////////////////////////////////////////////////////////////////
// Internal state.
////////////////////////////////////////////////////////////////////
private Context contexts[];
private Context currentContext;
private int contextPos;
////////////////////////////////////////////////////////////////////
// Internal classes.
////////////////////////////////////////////////////////////////////
/**
* Internal class for a single Namespace context.
*
* <p>This module caches and reuses Namespace contexts, so the number
* allocated will be equal to the element depth of the document, not to the
* total number of elements (i.e. 5-10 rather than tens of thousands).</p>
*/
final static class Context {
/**
* Create the root-level Namespace context.
*/
Context() {
copyTables();
}
// PGB May 6 2002 added copy constructor
Context(Context that, Context newParent) {
if (that == null) {
copyTables();
return;
}
if (newParent != null && !that.tablesDirty) {
prefixTable =
that.prefixTable == that.parent.prefixTable
? newParent.prefixTable
: (HashMap) that.prefixTable.clone();
uriTable =
that.uriTable == that.parent.uriTable
? newParent.uriTable
: (HashMap) that.uriTable.clone();
elementNameTable =
that.elementNameTable == that.parent.elementNameTable
? newParent.elementNameTable
: (HashMap) that.elementNameTable.clone();
attributeNameTable =
that.attributeNameTable == that.parent.attributeNameTable
? newParent.attributeNameTable
: (HashMap) that.attributeNameTable.clone();
defaultNS =
that.defaultNS == that.parent.defaultNS
? newParent.defaultNS
: that.defaultNS;
} else {
prefixTable = (HashMap) that.prefixTable.clone();
uriTable = (HashMap) that.uriTable.clone();
elementNameTable = (HashMap) that.elementNameTable.clone();
attributeNameTable = (HashMap) that.attributeNameTable.clone();
defaultNS = that.defaultNS;
}
tablesDirty = that.tablesDirty;
parent = newParent;
declarations =
that.declarations == null
? null
: (ArrayList) that.declarations.clone();
}
/**
* (Re)set the parent of this Namespace context.
*
* @param parent The parent Namespace context object.
*/
void setParent(Context parent) {
this.parent = parent;
declarations = null;
prefixTable = parent.prefixTable;
uriTable = parent.uriTable;
elementNameTable = parent.elementNameTable;
attributeNameTable = parent.attributeNameTable;
defaultNS = parent.defaultNS;
tablesDirty = false;
}
/**
* Declare a Namespace prefix for this context.
*
* @param prefix The prefix to declare.
* @param uri The associated Namespace URI.
* @see org.xml.sax.helpers.NamespaceSupport#declarePrefix
*/
void declarePrefix(String prefix, String uri) {
// Lazy processing...
if (!tablesDirty) {
copyTables();
}
if (declarations == null) {
declarations = new ArrayList();
}
prefix = prefix.intern();
uri = uri.intern();
if ("".equals(prefix)) {
if ("".equals(uri)) {
defaultNS = null;
} else {
defaultNS = uri;
}
} else {
prefixTable.put(prefix, uri);
uriTable.put(uri, prefix); // may wipe out another prefix
}
declarations.add(prefix);
}
/**
* Process a raw XML 1.0 name in this context.
*
* @param qName The raw XML 1.0 name.
* @param isAttribute true if this is an attribute name.
* @return An array of three strings containing the
* URI part (or empty string), the local part,
* and the raw name, all internalized, or null
* if there is an undeclared prefix.
* @see org.xml.sax.helpers.NamespaceSupport#processName
*/
String[] processName(String qName, boolean isAttribute) {
String name[];
Map table;
// Select the appropriate table.
if (isAttribute) {
table = elementNameTable;
} else {
table = attributeNameTable;
}
// Start by looking in the cache, and
// return immediately if the name
// is already known in this content
name = (String[]) table.get(qName);
if (name != null) {
return name;
}
// We haven't seen this name in this
// context before.
name = new String[3];
int index = qName.indexOf(':');
// No prefix.
if (index == -1) {
if (isAttribute || defaultNS == null) {
name[0] = "";
} else {
name[0] = defaultNS;
}
name[1] = qName.intern();
name[2] = name[1];
}
// Prefix
else {
String prefix = qName.substring(0, index);
String local = qName.substring(index + 1);
String uri;
if ("".equals(prefix)) {
uri = defaultNS;
} else {
uri = (String) prefixTable.get(prefix);
}
if (uri == null) {
return null;
}
name[0] = uri;
name[1] = local.intern();
name[2] = qName.intern();
}
// Save in the cache for future use.
table.put(name[2], name);
tablesDirty = true;
return name;
}
/**
* Look up the URI associated with a prefix in this context.
*
* @param prefix The prefix to look up.
* @return The associated Namespace URI, or null if none is
* declared.
* @see org.xml.sax.helpers.NamespaceSupport#getURI
*/
String getURI(String prefix) {
if ("".equals(prefix)) {
return defaultNS;
} else if (prefixTable == null) {
return null;
} else {
return (String) prefixTable.get(prefix);
}
}
/**
* Look up one of the prefixes associated with a URI in this context.
*
* <p>Since many prefixes may be mapped to the same URI,
* the return value may be unreliable.</p>
*
* @param uri The URI to look up.
* @return The associated prefix, or null if none is declared.
* @see org.xml.sax.helpers.NamespaceSupport#getPrefix
*/
String getPrefix(String uri) {
if (uriTable == null) {
return null;
} else {
return (String) uriTable.get(uri);
}
}
/**
* Return an enumeration of prefixes declared in this context.
*
* @return An enumeration of prefixes (possibly empty).
* @see org.xml.sax.helpers.NamespaceSupport#getDeclaredPrefixes
*/
Iterable<String> getDeclaredPrefixes() {
if (declarations == null) {
return EMPTY_ENUMERATION;
} else {
return declarations;
}
}
/**
* Return an enumeration of all prefixes currently in force.
*
* <p>The default prefix, if in force, is <em>not</em>
* returned, and will have to be checked for separately.</p>
*
* @return An enumeration of prefixes (never empty).
* @see org.xml.sax.helpers.NamespaceSupport#getPrefixes
*/
Iterable<String> getPrefixes() {
if (prefixTable == null) {
return EMPTY_ENUMERATION;
} else {
return prefixTable.keySet();
}
}
////////////////////////////////////////////////////////////////
// Internal methods.
////////////////////////////////////////////////////////////////
/**
* Copy on write for the internal tables in this context.
*
* <p>This class is optimized for the normal case where most
* elements do not contain Namespace declarations.</p>
*/
private void copyTables() {
if (prefixTable != null) {
prefixTable = (HashMap) prefixTable.clone();
} else {
prefixTable = new HashMap();
}
if (uriTable != null) {
uriTable = (HashMap) uriTable.clone();
} else {
uriTable = new HashMap();
}
elementNameTable = new HashMap();
attributeNameTable = new HashMap();
tablesDirty = true;
}
////////////////////////////////////////////////////////////////
// Protected state.
////////////////////////////////////////////////////////////////
HashMap prefixTable;
HashMap uriTable;
// PBG May 6 2002 changed these two from Map to HashMap
HashMap elementNameTable;
HashMap attributeNameTable;
String defaultNS = null;
////////////////////////////////////////////////////////////////
// Internal state.
////////////////////////////////////////////////////////////////
// PBG May 6 2002 changed this from List to ArrayList
private ArrayList declarations = null;
private boolean tablesDirty = false;
private Context parent = null;
}
}

View File

@@ -0,0 +1,50 @@
/*
* 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.util;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* {@link InputStream} that cannot be closed.
*
* @author Kohsuke Kawaguchi
*/
public class NoCloseInputStream extends FilterInputStream {
public NoCloseInputStream(InputStream is) {
super(is);
}
@Override
public void close() throws IOException {
// Intentionally left empty. use closeInput() to close
}
public void doClose() throws IOException {
super.close();
}
}

View File

@@ -0,0 +1,50 @@
/*
* 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.util;
import java.io.FilterOutputStream;
import java.io.OutputStream;
import java.io.IOException;
/**
* {@link OutputStream} that cannot be closed.
*
* @author Kohsuke Kawaguchi
*/
public class NoCloseOutputStream extends FilterOutputStream {
public NoCloseOutputStream(OutputStream out) {
super(out);
}
@Override
public void close() throws IOException {
// Intentionally left empty. use closeOutput() to close
}
public void doClose() throws IOException {
super.close();
}
}

View File

@@ -0,0 +1,177 @@
/*
* 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.util;
import com.sun.xml.internal.ws.api.pipe.Tube;
import com.sun.xml.internal.ws.api.pipe.TubeCloner;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.lang.ref.WeakReference;
/**
* General-purpose object pool.
*
* <p>
* In many parts of the runtime, we need to pool instances of objects that
* are expensive to create (such as JAXB objects, StAX parsers, {@link Tube} instances.)
*
* <p>
* This class provides a default implementation of such a pool.
*
* TODO: improve the implementation
*
* @author Kohsuke Kawaguchi
*/
public abstract class Pool<T> {
// volatile since multiple threads may access queue reference
private volatile WeakReference<ConcurrentLinkedQueue<T>> queue;
/**
* Gets a new object from the pool.
*
* <p>
* If no object is available in the pool, this method creates a new one.
*
* @return
* always non-null.
*/
public final T take() {
T t = getQueue().poll();
if(t==null)
return create();
return t;
}
private ConcurrentLinkedQueue<T> getQueue() {
WeakReference<ConcurrentLinkedQueue<T>> q = queue;
if (q != null) {
ConcurrentLinkedQueue<T> d = q.get();
if (d != null)
return d;
}
// overwrite the queue
ConcurrentLinkedQueue<T> d = new ConcurrentLinkedQueue<T>();
queue = new WeakReference<ConcurrentLinkedQueue<T>>(d);
return d;
}
/**
* Returns an object back to the pool.
*/
public final void recycle(T t) {
getQueue().offer(t);
}
/**
* Creates a new instance of object.
*
* <p>
* This method is used when someone wants to
* {@link #take() take} an object from an empty pool.
*
* <p>
* Also note that multiple threads may call this method
* concurrently.
*/
protected abstract T create();
/**
* JAXB {@link javax.xml.bind.Marshaller} pool.
*/
public static final class Marshaller extends Pool<javax.xml.bind.Marshaller> {
private final JAXBContext context;
public Marshaller(JAXBContext context) {
this.context = context;
}
@Override
protected javax.xml.bind.Marshaller create() {
try {
return context.createMarshaller();
} catch (JAXBException e) {
// impossible
throw new AssertionError(e);
}
}
}
/**
* JAXB {@link javax.xml.bind.Marshaller} pool.
*/
public static final class Unmarshaller extends Pool<javax.xml.bind.Unmarshaller> {
private final JAXBContext context;
public Unmarshaller(JAXBContext context) {
this.context = context;
}
@Override
protected javax.xml.bind.Unmarshaller create() {
try {
return context.createUnmarshaller();
} catch (JAXBException e) {
// impossible
throw new AssertionError(e);
}
}
}
/**
* {@link Tube} pool.
*/
public static final class TubePool extends Pool<Tube> {
private final Tube master;
public TubePool(Tube master) {
this.master = master;
recycle(master); // we'll use master as a part of the pool, too.
}
@Override
protected Tube create() {
return TubeCloner.clone(master);
}
/**
*
* @return master tubeline from pool
* @deprecated Expected to be used in rare cases where access to master
* tubeline is required and safe, such as Stub.close()."
*/
@Deprecated()
public final Tube takeMaster() {
return master;
}
}
}

View File

@@ -0,0 +1,487 @@
/*
* 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.util;
import com.sun.istack.internal.NotNull;
import javax.xml.namespace.QName;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
/**
* Map keyed by {@link QName}.
*
* This specialized map allows a look up operation without constructing
* a new QName instance, for a performance reason. This {@link Map} assumes
* that both namespace URI and local name are {@link String#intern() intern}ed.
*
* @since JAXB 2.0
*/
public final class QNameMap<V> {
/**
* The default initial capacity - MUST be a power of two.
*/
private static final int DEFAULT_INITIAL_CAPACITY = 16;
/**
* The maximum capacity, used if a higher value is implicitly specified
* by either of the constructors with arguments.
* MUST be a power of two <= 1<<30.
*/
private static final int MAXIMUM_CAPACITY = 1 << 30;
/**
* The table, resized as necessary. Length MUST Always be a power of two.
*/
transient Entry<V>[] table = new Entry[DEFAULT_INITIAL_CAPACITY];
/**
* The number of key-value mappings contained in this identity hash map.
*/
transient int size;
/**
* The next size value at which to resize . Taking it as
* MAXIMUM_CAPACITY
* @serial
*/
private int threshold;
/**
* The load factor used when none specified in constructor.
**/
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
/**
* Gives an entrySet view of this map
*/
private Set<Entry<V>> entrySet = null;
public QNameMap() {
threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
table = new Entry[DEFAULT_INITIAL_CAPACITY];
}
/**
* Associates the specified value with the specified keys in this map.
* If the map previously contained a mapping for this key, the old
* value is replaced.
*
* @param namespaceUri First key with which the specified value is to be associated.
* @param localname Second key with which the specified value is to be associated.
* @param value value to be associated with the specified key.
*
*/
public void put(String namespaceUri,String localname, V value ) {
//keys cannot be null
assert localname !=null;
assert namespaceUri !=null;
int hash = hash(localname);
int i = indexFor(hash, table.length);
for (Entry<V> e = table[i]; e != null; e = e.next) {
if (e.hash == hash && localname.equals(e.localName) && namespaceUri.equals(e.nsUri)) {
e.value = value;
return;
}
}
addEntry(hash, namespaceUri,localname, value, i);
}
public void put(QName name, V value ) {
put(name.getNamespaceURI(),name.getLocalPart(),value);
}
/**
* Returns the value to which the specified keys are mapped in this QNameMap,
* or <tt>null</tt> if the map contains no mapping for this key.
*
* @param nsUri the namespaceUri key whose associated value is to be returned.
* @param localPart the localPart key whose associated value is to be returned.
* @return the value to which this map maps the specified set of keya, or
* <tt>null</tt> if the map contains no mapping for this set of keys.
* @see #put(String,String, Object)
*/
public V get( @NotNull String nsUri, String localPart ) {
Entry<V> e = getEntry(nsUri,localPart);
if(e==null) return null;
else return e.value;
}
public V get( QName name ) {
return get(name.getNamespaceURI(),name.getLocalPart());
}
/**
* Returns the number of keys-value mappings in this map.
*
* @return the number of keys-value mappings in this map.
*/
public int size() {
return size;
}
/**
* Copies all of the mappings from the specified map to this map
* These mappings will replace any mappings that
* this map had for any of the keys currently in the specified map.
*
* @param map mappings to be stored in this map.
*
*/
public QNameMap<V> putAll(QNameMap<? extends V> map) {
int numKeysToBeAdded = map.size();
if (numKeysToBeAdded == 0)
return this;
if (numKeysToBeAdded > threshold) {
int targetCapacity = numKeysToBeAdded;
if (targetCapacity > MAXIMUM_CAPACITY)
targetCapacity = MAXIMUM_CAPACITY;
int newCapacity = table.length;
while (newCapacity < targetCapacity)
newCapacity <<= 1;
if (newCapacity > table.length)
resize(newCapacity);
}
for( Entry<? extends V> e : map.entrySet() )
put(e.nsUri,e.localName,e.getValue());
return this;
}
public QNameMap<V> putAll(Map<QName,? extends V> map) {
for (Map.Entry<QName, ? extends V> e : map.entrySet()) {
QName qn = e.getKey();
put(qn.getNamespaceURI(),qn.getLocalPart(),e.getValue());
}
return this;
}
/**
* Returns a hash value for the specified object.The hash value is computed
* for the localName.
*/
private static int hash(String x) {
int h = x.hashCode();
h += ~(h << 9);
h ^= (h >>> 14);
h += (h << 4);
h ^= (h >>> 10);
return h;
}
/**
* Returns index for hash code h.
*/
private static int indexFor(int h, int length) {
return h & (length-1);
}
/**
* Add a new entry with the specified keys, value and hash code to
* the specified bucket. It is the responsibility of this
* method to resize the table if appropriate.
*
*/
private void addEntry(int hash, String nsUri, String localName, V value, int bucketIndex) {
Entry<V> e = table[bucketIndex];
table[bucketIndex] = new Entry<V>(hash, nsUri, localName, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}
/**
* Rehashes the contents of this map into a new array with a
* larger capacity. This method is called automatically when the
* number of keys in this map reaches its threshold.
*/
private void resize(int newCapacity) {
Entry[] oldTable = table;
int oldCapacity = oldTable.length;
if (oldCapacity == MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return;
}
Entry[] newTable = new Entry[newCapacity];
transfer(newTable);
table = newTable;
threshold = newCapacity;
}
/**
* Transfer all entries from current table to newTable.
*/
private void transfer(Entry<V>[] newTable) {
Entry<V>[] src = table;
int newCapacity = newTable.length;
for (int j = 0; j < src.length; j++) {
Entry<V> e = src[j];
if (e != null) {
src[j] = null;
do {
Entry<V> next = e.next;
int i = indexFor(e.hash, newCapacity);
e.next = newTable[i];
newTable[i] = e;
e = next;
} while (e != null);
}
}
}
/**
* Returns one random item in the map.
* If this map is empty, return null.
*
* <p>
* This method is useful to obtain the value from a map that only contains one element.
*/
public Entry<V> getOne() {
for( Entry<V> e : table ) {
if(e!=null)
return e;
}
return null;
}
public Collection<QName> keySet() {
Set<QName> r = new HashSet<QName>();
for (Entry<V> e : entrySet()) {
r.add(e.createQName());
}
return r;
}
public Iterable<V> values() {
return views;
}
private transient Iterable<V> views = new Iterable<V>() {
public Iterator<V> iterator() {
return new ValueIterator();
}
};
private abstract class HashIterator<E> implements Iterator<E> {
Entry<V> next; // next entry to return
int index; // current slot
HashIterator() {
Entry<V>[] t = table;
int i = t.length;
Entry<V> n = null;
if (size != 0) { // advance to first entry
while (i > 0 && (n = t[--i]) == null)
;
}
next = n;
index = i;
}
public boolean hasNext() {
return next != null;
}
Entry<V> nextEntry() {
Entry<V> e = next;
if (e == null)
throw new NoSuchElementException();
Entry<V> n = e.next;
Entry<V>[] t = table;
int i = index;
while (n == null && i > 0)
n = t[--i];
index = i;
next = n;
return e;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
private class ValueIterator extends HashIterator<V> {
public V next() {
return nextEntry().value;
}
}
public boolean containsKey(@NotNull String nsUri,String localName) {
return getEntry(nsUri,localName)!=null;
}
/**
* Returns true if this map is empty.
*/
public boolean isEmpty() {
return size == 0;
}
public static final class Entry<V> {
/** The namespace URI. */
public final String nsUri;
/** The localPart. */
public final String localName;
V value;
final int hash;
Entry<V> next;
/**
* Create new entry.
*/
Entry(int h, String nsUri, String localName, V v, Entry<V> n) {
value = v;
next = n;
this.nsUri = nsUri;
this.localName = localName;
hash = h;
}
/**
* Creates a new QName object from {@link #nsUri} and {@link #localName}.
*/
public QName createQName() {
return new QName(nsUri,localName);
}
public V getValue() {
return value;
}
public V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public boolean equals(Object o) {
if (!(o instanceof Entry))
return false;
Entry e = (Entry)o;
String k1 = nsUri;
String k2 = e.nsUri;
String k3 = localName;
String k4 = e.localName;
if (k1.equals(k2) && k3.equals(k4)) {
Object v1 = getValue();
Object v2 = e.getValue();
if (v1 == v2 || (v1 != null && v1.equals(v2)))
return true;
}
return false;
}
public int hashCode() {
return ( localName.hashCode()) ^
(value==null ? 0 : value.hashCode());
}
public String toString() {
return '"'+nsUri +"\",\"" +localName + "\"=" + getValue();
}
}
public Set<Entry<V>> entrySet() {
Set<Entry<V>> es = entrySet;
return es != null ? es : (entrySet = new EntrySet());
}
private Iterator<Entry<V>> newEntryIterator() {
return new EntryIterator();
}
private class EntryIterator extends HashIterator<Entry<V>> {
public Entry<V> next() {
return nextEntry();
}
}
private class EntrySet extends AbstractSet<Entry<V>> {
public Iterator<Entry<V>> iterator() {
return newEntryIterator();
}
public boolean contains(Object o) {
if (!(o instanceof Entry))
return false;
Entry<V> e = (Entry<V>) o;
Entry<V> candidate = getEntry(e.nsUri,e.localName);
return candidate != null && candidate.equals(e);
}
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
public int size() {
return size;
}
}
private Entry<V> getEntry(@NotNull String nsUri,String localName) {
int hash = hash(localName);
int i = indexFor(hash, table.length);
Entry<V> e = table[i];
while (e != null && !(localName.equals(e.localName) && nsUri.equals(e.nsUri)))
e = e.next;
return e;
}
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append('{');
for( Entry<V> e : entrySet() ) {
if(buf.length()>1)
buf.append(',');
buf.append('[');
buf.append(e);
buf.append(']');
}
buf.append('}');
return buf.toString();
}
}

View File

@@ -0,0 +1,253 @@
/*
* Copyright (c) 2009, 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.util;
import com.sun.istack.internal.NotNull;
import com.sun.istack.internal.Nullable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Reads a input stream completely and creates a new stream
* by keeping some data in memory and the rest on the file system.
*
* @author Jitendra Kotamraju
*/
public class ReadAllStream extends InputStream {
private final @NotNull MemoryStream memStream;
private final @NotNull FileStream fileStream;
private boolean readAll;
private boolean closed;
private static final Logger LOGGER = Logger.getLogger(ReadAllStream.class.getName());
public ReadAllStream() {
memStream = new MemoryStream();
fileStream = new FileStream();
}
/**
* Reads the data from input stream completely. It keeps
* inMemory size in the memory, and the rest on the file
* system.
*
* Caller's responsibility to close the InputStream. This
* method can be called only once.
*
* @param in from which to be read
* @param inMemory this much data is kept in the memory
* @throws IOException in case of exception
*/
public void readAll(InputStream in, long inMemory) throws IOException {
assert !readAll;
readAll = true;
boolean eof = memStream.readAll(in, inMemory);
if (!eof) {
fileStream.readAll(in);
}
}
@Override
public int read() throws IOException {
int ch = memStream.read();
if (ch == -1) {
ch = fileStream.read();
}
return ch;
}
@Override
public int read(byte b[], int off, int sz) throws IOException {
int len = memStream.read(b, off, sz);
if (len == -1) {
len = fileStream.read(b, off, sz);
}
return len;
}
@Override
public void close() throws IOException {
if (!closed) {
memStream.close();
fileStream.close();
closed = true;
}
}
// Keeps the rest of the data on the file system
private static class FileStream extends InputStream {
private @Nullable File tempFile;
private @Nullable FileInputStream fin;
void readAll(InputStream in) throws IOException {
tempFile = File.createTempFile("jaxws",".bin");
FileOutputStream fileOut = new FileOutputStream(tempFile);
try {
byte[] buf = new byte[8192];
int len;
while((len=in.read(buf)) != -1) {
fileOut.write(buf, 0, len);
}
} finally {
fileOut.close();
}
fin = new FileInputStream(tempFile);
}
@Override
public int read() throws IOException {
return (fin != null) ? fin.read() : -1;
}
@Override
public int read(byte b[], int off, int sz) throws IOException {
return (fin != null) ? fin.read(b, off, sz) : -1;
}
@Override
public void close() throws IOException {
if (fin != null) {
fin.close();
}
if (tempFile != null) {
boolean success = tempFile.delete();
if (!success) {
LOGGER.log(Level.INFO, "File {0} could not be deleted", tempFile);
}
}
}
}
// Keeps data in memory until certain size
private static class MemoryStream extends InputStream {
private Chunk head, tail;
private int curOff;
private void add(byte[] buf, int len) {
if (tail != null) {
tail = tail.createNext(buf, 0, len);
} else {
head = tail = new Chunk(buf, 0, len);
}
}
/**
* Reads until the size specified
*
* @param in stream from which to be read
* @param inMemory reads until this size
* @return true if eof
* false otherwise
* @throws IOException in case of exception
*/
boolean readAll(InputStream in, long inMemory) throws IOException {
long total = 0;
while(true) {
byte[] buf = new byte[8192];
int read = fill(in, buf);
total += read;
if (read != 0) {
add(buf, read);
}
if (read != buf.length) {
return true;
} // EOF
if (total > inMemory) {
return false; // Reached in-memory size
}
}
}
private int fill(InputStream in, byte[] buf) throws IOException {
int read;
int total = 0;
while(total < buf.length && (read=in.read(buf, total, buf.length-total)) != -1) {
total += read;
}
return total;
}
@Override
public int read() throws IOException {
if (!fetch()) {
return -1;
}
return (head.buf[curOff++] & 0xff);
}
@Override
public int read(byte b[], int off, int sz) throws IOException {
if (!fetch()) {
return -1;
}
sz = Math.min(sz, head.len-(curOff-head.off));
System.arraycopy(head.buf,curOff,b,off,sz);
curOff += sz;
return sz;
}
// if eof, return false else true
private boolean fetch() {
if (head == null) {
return false;
}
if (curOff == head.off+head.len) {
head = head.next;
if (head == null) {
return false;
}
curOff = head.off;
}
return true;
}
private static final class Chunk {
Chunk next;
final byte[] buf;
final int off;
final int len;
public Chunk(byte[] buf, int off, int len) {
this.buf = buf;
this.off = off;
this.len = len;
}
public Chunk createNext(byte[] buf, int off, int len) {
return next = new Chunk(buf, off, len);
}
}
}
}

View File

@@ -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.util;
import java.io.InputStream;
import java.io.IOException;
/**
* Obtains the version number of the JAX-WS runtime.
*
* @author Kohsuke Kawaguchi
* @author Jitendra Kotamraju
*/
public final class RuntimeVersion {
public static final Version VERSION;
static {
Version version = null;
InputStream in = RuntimeVersion.class.getResourceAsStream("version.properties");
try {
version = Version.create(in);
} finally {
if (in != null) {
try {
in.close();
} catch(IOException ioe) {
// Nothing to do
}
}
}
VERSION = version == null ? Version.create(null) : version;
}
/**
* Get JAX-WS version
*/
public String getVersion() {
return VERSION.toString();
}
}

View File

@@ -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.util;
/**
* Error thrown when something goes wrong while looking up service providers.
* In particular, this error will be thrown in the following situations:
*
* <ul>
* <li> A concrete provider class cannot be found,
* <li> A concrete provider class cannot be instantiated,
* <li> The format of a provider-configuration file is illegal, or
* <li> An IOException occurs while reading a provider-configuration file.
* </ul>
*
* @author Mark Reinhold
* @version 1.7, 03/12/19
* @since 1.3
*/
public class ServiceConfigurationError extends Error {
/**
* Constructs a new instance with the specified detail string.
*/
public ServiceConfigurationError(String msg) {
super(msg);
}
/**
* Constructs a new instance that wraps the specified throwable.
*/
public ServiceConfigurationError(Throwable x) {
super(x);
}
}

View File

@@ -0,0 +1,523 @@
/*
* 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.util;
import com.sun.istack.internal.NotNull;
import com.sun.istack.internal.Nullable;
import com.sun.xml.internal.ws.api.Component;
import com.sun.xml.internal.ws.api.ComponentEx;
import com.sun.xml.internal.ws.api.server.ContainerResolver;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.TreeSet;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
/**
* A simple service-provider lookup mechanism. A <i>service</i> is a
* well-known set of interfaces and (usually abstract) classes. A <i>service
* provider</i> is a specific implementation of a service. The classes in a
* provider typically implement the interfaces and subclass the classes defined
* in the service itself. Service providers may be installed in an
* implementation of the Java platform in the form of extensions, that is, jar
* files placed into any of the usual extension directories. Providers may
* also be made available by adding them to the applet or application class
* path or by some other platform-specific means.
* <p/>
* <p> In this lookup mechanism a service is represented by an interface or an
* abstract class. (A concrete class may be used, but this is not
* recommended.) A provider of a given service contains one or more concrete
* classes that extend this <i>service class</i> with data and code specific to
* the provider. This <i>provider class</i> will typically not be the entire
* provider itself but rather a proxy that contains enough information to
* decide whether the provider is able to satisfy a particular request together
* with code that can create the actual provider on demand. The details of
* provider classes tend to be highly service-specific; no single class or
* interface could possibly unify them, so no such class has been defined. The
* only requirement enforced here is that provider classes must have a
* zero-argument constructor so that they may be instantiated during lookup.
* <p/>
* <p> A service provider identifies itself by placing a provider-configuration
* file in the resource directory <tt>META-INF/services</tt>. The file's name
* should consist of the fully-qualified name of the abstract service class.
* The file should contain a list of fully-qualified concrete provider-class
* names, one per line. Space and tab characters surrounding each name, as
* well as blank lines, are ignored. The comment character is <tt>'#'</tt>
* (<tt>0x23</tt>); on each line all characters following the first comment
* character are ignored. The file must be encoded in UTF-8.
* <p/>
* <p> If a particular concrete provider class is named in more than one
* configuration file, or is named in the same configuration file more than
* once, then the duplicates will be ignored. The configuration file naming a
* particular provider need not be in the same jar file or other distribution
* unit as the provider itself. The provider must be accessible from the same
* class loader that was initially queried to locate the configuration file;
* note that this is not necessarily the class loader that found the file.
* <p/>
* <p> <b>Example:</b> Suppose we have a service class named
* <tt>java.io.spi.CharCodec</tt>. It has two abstract methods:
* <p/>
* <pre>
* public abstract CharEncoder getEncoder(String encodingName);
* public abstract CharDecoder getDecoder(String encodingName);
* </pre>
* <p/>
* Each method returns an appropriate object or <tt>null</tt> if it cannot
* translate the given encoding. Typical <tt>CharCodec</tt> providers will
* support more than one encoding.
* <p/>
* <p> If <tt>sun.io.StandardCodec</tt> is a provider of the <tt>CharCodec</tt>
* service then its jar file would contain the file
* <tt>META-INF/services/java.io.spi.CharCodec</tt>. This file would contain
* the single line:
* <p/>
* <pre>
* sun.io.StandardCodec # Standard codecs for the platform
* </pre>
* <p/>
* To locate an codec for a given encoding name, the internal I/O code would
* do something like this:
* <p/>
* <pre>
* CharEncoder getEncoder(String encodingName) {
* for( CharCodec cc : ServiceFinder.find(CharCodec.class) ) {
* CharEncoder ce = cc.getEncoder(encodingName);
* if (ce != null)
* return ce;
* }
* return null;
* }
* </pre>
* <p/>
* The provider-lookup mechanism always executes in the security context of the
* caller. Trusted system code should typically invoke the methods in this
* class from within a privileged security context.
*
* @author Mark Reinhold
* @version 1.11, 03/12/19
* @since 1.3
*/
public final class ServiceFinder<T> implements Iterable<T> {
private static final String prefix = "META-INF/services/";
private static WeakHashMap<ClassLoader, ConcurrentHashMap<String, ServiceName[]>> serviceNameCache
= new WeakHashMap<ClassLoader, ConcurrentHashMap<String, ServiceName[]>>();
private final Class<T> serviceClass;
private final @Nullable ClassLoader classLoader;
private final @Nullable ComponentEx component;
private static class ServiceName {
final String className;
final URL config;
public ServiceName(String className, URL config) {
this.className = className;
this.config = config;
}
}
public static <T> ServiceFinder<T> find(@NotNull Class<T> service, @Nullable ClassLoader loader, Component component) {
return new ServiceFinder<T>(service, loader, component);
}
public static <T> ServiceFinder<T> find(@NotNull Class<T> service, Component component) {
return find(service,Thread.currentThread().getContextClassLoader(),component);
}
/**
* Locates and incrementally instantiates the available providers of a
* given service using the given class loader.
* <p/>
* <p> This method transforms the name of the given service class into a
* provider-configuration filename as described above and then uses the
* <tt>getResources</tt> method of the given class loader to find all
* available files with that name. These files are then read and parsed to
* produce a list of provider-class names. The iterator that is returned
* uses the given class loader to lookup and then instantiate each element
* of the list.
* <p/>
* <p> Because it is possible for extensions to be installed into a running
* Java virtual machine, this method may return different results each time
* it is invoked. <p>
*
* @param service The service's abstract service class
* @param loader The class loader to be used to load provider-configuration files
* and instantiate provider classes, or <tt>null</tt> if the system
* class loader (or, failing that the bootstrap class loader) is to
* be used
* @throws ServiceConfigurationError If a provider-configuration file violates the specified format
* or names a provider class that cannot be found and instantiated
* @see #find(Class)
*/
public static <T> ServiceFinder<T> find(@NotNull Class<T> service, @Nullable ClassLoader loader) {
return find(service, loader, ContainerResolver.getInstance().getContainer());
}
/**
* Locates and incrementally instantiates the available providers of a
* given service using the context class loader. This convenience method
* is equivalent to
* <p/>
* <pre>
* ClassLoader cl = Thread.currentThread().getContextClassLoader();
* return Service.providers(service, cl);
* </pre>
*
* @param service The service's abstract service class
*
* @throws ServiceConfigurationError If a provider-configuration file violates the specified format
* or names a provider class that cannot be found and instantiated
* @see #find(Class, ClassLoader)
*/
public static <T> ServiceFinder<T> find(Class<T> service) {
return find(service,Thread.currentThread().getContextClassLoader());
}
private ServiceFinder(Class<T> service, ClassLoader loader, Component component) {
this.serviceClass = service;
this.classLoader = loader;
this.component = getComponentEx(component);
}
private static ServiceName[] serviceClassNames(Class serviceClass, ClassLoader classLoader) {
ArrayList<ServiceName> l = new ArrayList<ServiceName>();
for (Iterator<ServiceName> it = new ServiceNameIterator(serviceClass,classLoader);it.hasNext();) l.add(it.next());
return l.toArray(new ServiceName[l.size()]);
}
/**
* Returns discovered objects incrementally.
*
* @return An <tt>Iterator</tt> that yields provider objects for the given
* service, in some arbitrary order. The iterator will throw a
* <tt>ServiceConfigurationError</tt> if a provider-configuration
* file violates the specified format or if a provider class cannot
* be found and instantiated.
*/
@SuppressWarnings("unchecked")
public Iterator<T> iterator() {
Iterator<T> it = new LazyIterator<T>(serviceClass,classLoader);
return component != null ?
new CompositeIterator<T>(
component.getIterableSPI(serviceClass).iterator(),it) :
it;
}
/**
* Returns discovered objects all at once.
*
* @return
* can be empty but never null.
*
* @throws ServiceConfigurationError
*/
public T[] toArray() {
List<T> result = new ArrayList<T>();
for (T t : this) {
result.add(t);
}
return result.toArray((T[])Array.newInstance(serviceClass,result.size()));
}
private static void fail(Class service, String msg, Throwable cause)
throws ServiceConfigurationError {
ServiceConfigurationError sce
= new ServiceConfigurationError(service.getName() + ": " + msg);
sce.initCause(cause);
throw sce;
}
private static void fail(Class service, String msg)
throws ServiceConfigurationError {
throw new ServiceConfigurationError(service.getName() + ": " + msg);
}
private static void fail(Class service, URL u, int line, String msg)
throws ServiceConfigurationError {
fail(service, u + ":" + line + ": " + msg);
}
/**
* Parse a single line from the given configuration file, adding the name
* on the line to both the names list and the returned set iff the name is
* not already a member of the returned set.
*/
private static int parseLine(Class service, URL u, BufferedReader r, int lc,
List<String> names, Set<String> returned)
throws IOException, ServiceConfigurationError {
String ln = r.readLine();
if (ln == null) {
return -1;
}
int ci = ln.indexOf('#');
if (ci >= 0) ln = ln.substring(0, ci);
ln = ln.trim();
int n = ln.length();
if (n != 0) {
if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))
fail(service, u, lc, "Illegal configuration-file syntax");
int cp = ln.codePointAt(0);
if (!Character.isJavaIdentifierStart(cp))
fail(service, u, lc, "Illegal provider-class name: " + ln);
for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
cp = ln.codePointAt(i);
if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))
fail(service, u, lc, "Illegal provider-class name: " + ln);
}
if (!returned.contains(ln)) {
names.add(ln);
returned.add(ln);
}
}
return lc + 1;
}
/**
* Parse the content of the given URL as a provider-configuration file.
*
* @param service The service class for which providers are being sought;
* used to construct error detail strings
* @param u The URL naming the configuration file to be parsed
* @param returned A Set containing the names of provider classes that have already
* been returned. This set will be updated to contain the names
* that will be yielded from the returned <tt>Iterator</tt>.
* @return A (possibly empty) <tt>Iterator</tt> that will yield the
* provider-class names in the given configuration file that are
* not yet members of the returned set
* @throws ServiceConfigurationError If an I/O error occurs while reading from the given URL, or
* if a configuration-file format error is detected
*/
@SuppressWarnings({"StatementWithEmptyBody"})
private static Iterator<String> parse(Class service, URL u, Set<String> returned)
throws ServiceConfigurationError {
InputStream in = null;
BufferedReader r = null;
ArrayList<String> names = new ArrayList<String>();
try {
in = u.openStream();
r = new BufferedReader(new InputStreamReader(in, "utf-8"));
int lc = 1;
while ((lc = parseLine(service, u, r, lc, names, returned)) >= 0) ;
} catch (IOException x) {
fail(service, ": " + x);
} finally {
try {
if (r != null) r.close();
if (in != null) in.close();
} catch (IOException y) {
fail(service, ": " + y);
}
}
return names.iterator();
}
private static ComponentEx getComponentEx(Component component) {
if (component instanceof ComponentEx)
return (ComponentEx) component;
return component != null ? new ComponentExWrapper(component) : null;
}
private static class ComponentExWrapper implements ComponentEx {
private final Component component;
public ComponentExWrapper(Component component) {
this.component = component;
}
public <S> S getSPI(Class<S> spiType) {
return component.getSPI(spiType);
}
public <S> Iterable<S> getIterableSPI(Class<S> spiType) {
S item = getSPI(spiType);
if (item != null) {
Collection<S> c = Collections.singletonList(item);
return c;
}
return Collections.emptySet();
}
}
private static class CompositeIterator<T> implements Iterator<T> {
private final Iterator<Iterator<T>> it;
private Iterator<T> current = null;
public CompositeIterator(Iterator<T>... iterators) {
it = Arrays.asList(iterators).iterator();
}
public boolean hasNext() {
if (current != null && current.hasNext())
return true;
while (it.hasNext()) {
current = it.next();
if (current.hasNext())
return true;
}
return false;
}
public T next() {
if (!hasNext())
throw new NoSuchElementException();
return current.next();
}
public void remove() {
throw new UnsupportedOperationException();
}
}
/**
* Private inner class implementing fully-lazy provider lookup
*/
private static class ServiceNameIterator implements Iterator<ServiceName> {
Class service;
@Nullable ClassLoader loader;
Enumeration<URL> configs = null;
Iterator<String> pending = null;
Set<String> returned = new TreeSet<String>();
String nextName = null;
URL currentConfig = null;
private ServiceNameIterator(Class service, ClassLoader loader) {
this.service = service;
this.loader = loader;
}
public boolean hasNext() throws ServiceConfigurationError {
if (nextName != null) {
return true;
}
if (configs == null) {
try {
String fullName = prefix + service.getName();
if (loader == null)
configs = ClassLoader.getSystemResources(fullName);
else
configs = loader.getResources(fullName);
} catch (IOException x) {
fail(service, ": " + x);
}
}
while ((pending == null) || !pending.hasNext()) {
if (!configs.hasMoreElements()) {
return false;
}
currentConfig = configs.nextElement();
pending = parse(service, currentConfig, returned);
}
nextName = pending.next();
return true;
}
public ServiceName next() throws ServiceConfigurationError {
if (!hasNext()) {
throw new NoSuchElementException();
}
String cn = nextName;
nextName = null;
return new ServiceName(cn, currentConfig);
}
public void remove() {
throw new UnsupportedOperationException();
}
}
private static class LazyIterator<T> implements Iterator<T> {
Class<T> service;
@Nullable ClassLoader loader;
ServiceName[] names;
int index;
private LazyIterator(Class<T> service, ClassLoader loader) {
this.service = service;
this.loader = loader;
this.names = null;
index = 0;
}
@Override
public boolean hasNext() {
if (names == null) {
ConcurrentHashMap<String, ServiceName[]> nameMap = null;
synchronized(serviceNameCache){ nameMap = serviceNameCache.get(loader); }
names = (nameMap != null)? nameMap.get(service.getName()) : null;
if (names == null) {
names = serviceClassNames(service, loader);
if (nameMap == null) nameMap = new ConcurrentHashMap<String, ServiceName[]>();
nameMap.put(service.getName(), names);
synchronized(serviceNameCache){ serviceNameCache.put(loader,nameMap); }
}
}
return (index < names.length);
}
@Override
public T next() {
if (!hasNext()) throw new NoSuchElementException();
ServiceName sn = names[index++];
String cn = sn.className;
URL currentConfig = sn.config;
try {
return service.cast(Class.forName(cn, true, loader).newInstance());
} catch (ClassNotFoundException x) {
fail(service, "Provider " + cn + " is specified in "+currentConfig+" but not found");
} catch (Exception x) {
fail(service, "Provider " + cn + " is specified in "+currentConfig+"but could not be instantiated: " + x, x);
}
return null; /* This cannot happen */
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
}

View File

@@ -0,0 +1,64 @@
/*
* 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.util;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* @author Jitendra Kotamraju
*/
public class StreamUtils {
/*
* Finds if the stream has some content or not
*
* @return null if there is no data
* else stream to be used
*/
public static InputStream hasSomeData(InputStream in) {
if (in != null) {
try {
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
}
}
} catch(IOException ioe) {
in = null;
}
}
return in;
}
}

View File

@@ -0,0 +1,79 @@
/*
* 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.util;
/**
*
* @author WS Development Team
*/
public class StringUtils {
/**
* Utility method to take a string and convert it to normal Java variable
* name capitalization. This normally means converting the first
* character from upper case to lower case, but in the (unusual) special
* case when there is more than one character and both the first and
* second characters are upper case, we leave it alone.
* <p>
* Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays
* as "URL".
*
* @param name The string to be decapitalized.
* @return The decapitalized version of the string.
*/
public static String decapitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
if (name.length() > 1 &&
Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))) {
return name;
}
char chars[] = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}
/**
* Utility method to take a string and convert it to normal a string
* with the first character in upper case.
* <p>
* Thus "fooBah" becomes "FooBah" and "x" becomes "X".\
*
* @param name The string to be capitalized.
* @return The capitalized version of the string.
*/
public static String capitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
char chars[] = name.toCharArray();
chars[0] = Character.toUpperCase(chars[0]);
return new String(chars);
}
}

View File

@@ -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.util;
import com.sun.istack.internal.localization.Localizable;
import com.sun.xml.internal.ws.util.exception.JAXWSExceptionBase;
/**
* UtilException represents an exception that occurred while
* one of the util classes is operating.
*
* @see JAXWSExceptionBase
*
* @author JAX-WS Development Team
*/
public class UtilException extends JAXWSExceptionBase {
public UtilException(String key, Object... args) {
super(key, args);
}
public UtilException(Throwable throwable) {
super(throwable);
}
public UtilException(Localizable arg) {
super("nestedUtilError", arg);
}
public String getDefaultResourceBundleName() {
return "com.sun.xml.internal.ws.resources.util";
}
}

View File

@@ -0,0 +1,93 @@
/*
* 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.util;
import java.io.InputStream;
import java.io.IOException;
import java.util.Properties;
/**
* Represents the version information.
*
* @author Kohsuke Kawaguchi
*/
public final class Version {
/**
* Represents the build id, which is a string like "b13" or "hudson-250".
*/
public final String BUILD_ID;
/**
* Represents the complete version string, such as "JAX-WS RI 2.0-b19"
*/
public final String BUILD_VERSION;
/**
* Represents the major JAX-WS version, such as "2.0".
*/
public final String MAJOR_VERSION;
/**
* Represents the latest Subversion Reversion number.
*/
public final String SVN_REVISION;
/**
* The Runtime Version.
*/
public static final Version RUNTIME_VERSION = Version.create(Version.class.getResourceAsStream("version.properties"));
private Version(String buildId, String buildVersion, String majorVersion, String svnRev) {
this.BUILD_ID = fixNull(buildId);
this.BUILD_VERSION = fixNull(buildVersion);
this.MAJOR_VERSION = fixNull(majorVersion);
this.SVN_REVISION = fixNull(svnRev);
}
public static Version create(InputStream is) {
Properties props = new Properties();
try {
props.load(is);
} catch (IOException e) {
// ignore even if the property was not found. we'll treat everything as unknown
} catch (Exception e) {
//ignore even if property not found
}
return new Version(
props.getProperty("build-id"),
props.getProperty("build-version"),
props.getProperty("major-version"),
props.getProperty("svn-revision"));
}
private String fixNull(String v) {
if(v==null) return "unknown";
return v;
}
public String toString() {
return BUILD_VERSION + " svn-revision#" + SVN_REVISION;
}
}

View File

@@ -0,0 +1,168 @@
/*
* 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.util;
import java.util.StringTokenizer;
/**
* Provides some version utilities.
*
* @author JAX-WS Development Team
*/
public final class VersionUtil {
public static boolean isVersion20(String version) {
return JAXWS_VERSION_20.equals(version);
}
/**
* @param version
* @return true if version is a 2.0 version
*/
public static boolean isValidVersion(String version) {
return isVersion20(version);
}
public static String getValidVersionString() {
return JAXWS_VERSION_20;
}
/**
* BugFix# 4948171
* Method getCanonicalVersion.
*
* Converts a given version to the format "a.b.c.d"
* a - major version
* b - minor version
* c - minor minor version
* d - patch version
*
* @return int[] Canonical version number
*/
public static int[] getCanonicalVersion(String version) {
int[] canonicalVersion = new int[4];
// initialize the default version numbers
canonicalVersion[0] = 1;
canonicalVersion[1] = 1;
canonicalVersion[2] = 0;
canonicalVersion[3] = 0;
final String DASH_DELIM = "_";
final String DOT_DELIM = ".";
StringTokenizer tokenizer =
new StringTokenizer(version, DOT_DELIM);
String token = tokenizer.nextToken();
// first token is major version and must not have "_"
canonicalVersion[0] = Integer.parseInt(token);
// resolve the minor version
token = tokenizer.nextToken();
if (token.indexOf(DASH_DELIM) == -1) {
// a.b
canonicalVersion[1] = Integer.parseInt(token);
} else {
// a.b_c
StringTokenizer subTokenizer =
new StringTokenizer(token, DASH_DELIM);
canonicalVersion[1] = Integer.parseInt(subTokenizer.nextToken());
// leave minorMinor default
canonicalVersion[3] = Integer.parseInt(subTokenizer.nextToken());
}
// resolve the minorMinor and patch version, if any
if (tokenizer.hasMoreTokens()) {
token = tokenizer.nextToken();
if (token.indexOf(DASH_DELIM) == -1) {
// minorMinor
canonicalVersion[2] = Integer.parseInt(token);
// resolve patch, if any
if (tokenizer.hasMoreTokens())
canonicalVersion[3] = Integer.parseInt(tokenizer.nextToken());
} else {
// a.b.c_d
StringTokenizer subTokenizer =
new StringTokenizer(token, DASH_DELIM);
// minorMinor
canonicalVersion[2] = Integer.parseInt(subTokenizer.nextToken());
// patch
canonicalVersion[3] = Integer.parseInt(subTokenizer.nextToken());
}
}
return canonicalVersion;
}
/**
*
* @param version1
* @param version2
* @return -1, 0 or 1 based upon the comparison results
* -1 if version1 is less than version2
* 0 if version1 is equal to version2
* 1 if version1 is greater than version2
*/
public static int compare(String version1, String version2) {
int[] canonicalVersion1 = getCanonicalVersion(version1);
int[] canonicalVersion2 = getCanonicalVersion(version2);
if (canonicalVersion1[0] < canonicalVersion2[0]) {
return -1;
} else if (canonicalVersion1[0] > canonicalVersion2[0]) {
return 1;
} else {
if (canonicalVersion1[1] < canonicalVersion2[1]) {
return -1;
} else if (canonicalVersion1[1] > canonicalVersion2[1]) {
return 1;
} else {
if (canonicalVersion1[2] < canonicalVersion2[2]) {
return -1;
} else if (canonicalVersion1[2] > canonicalVersion2[2]) {
return 1;
} else {
if (canonicalVersion1[3] < canonicalVersion2[3]) {
return -1;
} else if (canonicalVersion1[3] > canonicalVersion2[3]) {
return 1;
} else
return 0;
}
}
}
}
public static final String JAXWS_VERSION_20 = "2.0";
// the latest version is default
public static final String JAXWS_VERSION_DEFAULT = JAXWS_VERSION_20;
}

View File

@@ -0,0 +1,176 @@
/*
* Copyright (c) 1997, 2017, 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.util.exception;
import com.sun.istack.internal.localization.Localizable;
import com.sun.istack.internal.localization.LocalizableMessage;
import com.sun.istack.internal.localization.LocalizableMessageFactory;
import com.sun.istack.internal.localization.Localizer;
import com.sun.istack.internal.localization.NullLocalizable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.xml.ws.WebServiceException;
/**
* Represents a {@link WebServiceException} with
* localizable message.
*
* @author WS Development Team
*/
public abstract class JAXWSExceptionBase
extends WebServiceException implements Localizable {
//Don't worry about previous serialVersionUID = 4818235090198755494L;, this class was not serializable before.
private static final long serialVersionUID = 1L;
private transient Localizable msg;
/**
* @deprecated
* Should use the localizable constructor instead.
*/
protected JAXWSExceptionBase(String key, Object... args) {
super(findNestedException(args));
this.msg = new LocalizableMessage(getDefaultResourceBundleName(), key, args);
}
protected JAXWSExceptionBase(String message) {
this(new NullLocalizable(message));
}
/**
* Creates a new exception that wraps the specified exception.
*/
protected JAXWSExceptionBase(Throwable throwable) {
this(new NullLocalizable(throwable.toString()),throwable);
}
protected JAXWSExceptionBase(Localizable msg) {
this.msg = msg;
}
protected JAXWSExceptionBase(Localizable msg, Throwable cause) {
super(cause);
this.msg = msg;
}
/**
* @serialData Default fields, followed by information in Localizable which comprises of.
* ResourceBundle name, then key and followed by arguments array.
* If there is no arguments array, then -1 is written. If there is a argument array (possible of zero
* length) then the array length is written as an integer, followed by each argument (Object).
* If the Object is serializable, the argument is written. Otherwise the output of Object.toString()
* is written.
*/
private void writeObject(ObjectOutputStream out) throws IOException {
// We have to call defaultWriteObject first.
out.defaultWriteObject();
out.writeObject(msg.getResourceBundleName());
out.writeObject(msg.getKey());
Object[] args = msg.getArguments();
if (args == null) {
out.writeInt(-1);
return;
}
out.writeInt(args.length);
// Write Object values for the parameters, if it is serializable otherwise write String form of it..
for (int i = 0; i < args.length; i++) {
if (args[i] == null || args[i] instanceof Serializable) {
out.writeObject(args[i]);
} else {
out.writeObject(args[i].toString());
}
}
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
// We have to call defaultReadObject first.
in.defaultReadObject();
Object[] args;
String resourceBundleName = (String) in.readObject();
String key = (String) in.readObject();
int len = in.readInt();
if (len < -1) {
throw new NegativeArraySizeException();
} else if (len == -1) {
args = null;
} else if (len < 255) {
args = new Object[len];
for (int i = 0; i < args.length; i++) {
args[i] = in.readObject();
}
} else {
List<Object> argList = new ArrayList<>(Math.min(len, 1024));
for (int i = 0; i < len; i++) {
argList.add(in.readObject());
}
args = argList.toArray(new Object[argList.size()]);
}
msg = new LocalizableMessageFactory(resourceBundleName).getMessage(key,args);
}
private static Throwable findNestedException(Object[] args) {
if (args == null)
return null;
for( Object o : args )
if(o instanceof Throwable)
return (Throwable)o;
return null;
}
public String getMessage() {
Localizer localizer = new Localizer();
return localizer.localize(this);
}
/**
* Gets the default resource bundle name for this kind of exception.
* Used for {@link #JAXWSExceptionBase(String, Object[])}.
*/
protected abstract String getDefaultResourceBundleName();
//
// Localizable delegation
//
public final String getKey() {
return msg.getKey();
}
public final Object[] getArguments() {
return msg.getArguments();
}
public final String getResourceBundleName() {
return msg.getResourceBundleName();
}
}

View File

@@ -0,0 +1,106 @@
/*
* 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.util.exception;
import com.sun.istack.internal.NotNull;
import com.sun.xml.internal.ws.resources.UtilMessages;
import org.xml.sax.Locator;
import org.xml.sax.helpers.LocatorImpl;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamReader;
import javax.xml.ws.WebServiceException;
import java.util.Arrays;
import java.util.List;
/**
* {@link WebServiceException} with source location informaiton.
*
* <p>
* This exception should be used wherever the location information is available,
* so that the location information is carried forward to users (to assist
* error diagnostics.)
*
* @author Kohsuke Kawaguchi
*/
public class LocatableWebServiceException extends WebServiceException {
/**
* Locations related to error.
*/
private final Locator[] location;
public LocatableWebServiceException(String message, Locator... location) {
this(message,null,location);
}
public LocatableWebServiceException(String message, Throwable cause, Locator... location) {
super(appendLocationInfo(message,location), cause);
this.location = location;
}
public LocatableWebServiceException(Throwable cause, Locator... location) {
this(cause.toString(),cause,location);
}
public LocatableWebServiceException(String message, XMLStreamReader locationSource) {
this(message,toLocation(locationSource));
}
public LocatableWebServiceException(String message, Throwable cause, XMLStreamReader locationSource) {
this(message,cause,toLocation(locationSource));
}
public LocatableWebServiceException(Throwable cause, XMLStreamReader locationSource) {
this(cause,toLocation(locationSource));
}
/**
* Locations related to this exception.
*
* @return
* Can be empty but never null.
*/
public @NotNull List<Locator> getLocation() {
return Arrays.asList(location);
}
private static String appendLocationInfo(String message, Locator[] location) {
StringBuilder buf = new StringBuilder(message);
for( Locator loc : location )
buf.append('\n').append(UtilMessages.UTIL_LOCATION( loc.getLineNumber(), loc.getSystemId() ));
return buf.toString();
}
private static Locator toLocation(XMLStreamReader xsr) {
LocatorImpl loc = new LocatorImpl();
Location in = xsr.getLocation();
loc.setSystemId(in.getSystemId());
loc.setPublicId(in.getPublicId());
loc.setLineNumber(in.getLineNumber());
loc.setColumnNumber(in.getColumnNumber());
return loc;
}
}

View File

@@ -0,0 +1,583 @@
/*
* 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.util.pipe;
import com.sun.istack.internal.NotNull;
import com.sun.istack.internal.Nullable;
import com.sun.xml.internal.stream.buffer.XMLStreamBufferResult;
import com.sun.xml.internal.ws.api.WSBinding;
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.Tube;
import com.sun.xml.internal.ws.api.pipe.TubeCloner;
import com.sun.xml.internal.ws.api.pipe.helper.AbstractFilterTubeImpl;
import com.sun.xml.internal.ws.api.server.DocumentAddressResolver;
import com.sun.xml.internal.ws.api.server.SDDocument;
import com.sun.xml.internal.ws.api.server.SDDocumentSource;
import com.sun.xml.internal.ws.developer.SchemaValidationFeature;
import com.sun.xml.internal.ws.developer.ValidationErrorHandler;
import com.sun.xml.internal.ws.server.SDDocumentImpl;
import com.sun.xml.internal.ws.util.ByteArrayBuffer;
import com.sun.xml.internal.ws.util.xml.XmlUtil;
import com.sun.xml.internal.ws.wsdl.SDDocumentResolver;
import com.sun.xml.internal.ws.wsdl.parser.WSDLConstants;
import org.w3c.dom.*;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.NamespaceSupport;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import javax.xml.ws.WebServiceException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.sun.xml.internal.ws.util.xml.XmlUtil.allowExternalAccess;
/**
* {@link Tube} that does the schema validation.
*
* @author Jitendra Kotamraju
*/
public abstract class AbstractSchemaValidationTube extends AbstractFilterTubeImpl {
private static final Logger LOGGER = Logger.getLogger(AbstractSchemaValidationTube.class.getName());
protected final WSBinding binding;
protected final SchemaValidationFeature feature;
protected final DocumentAddressResolver resolver = new ValidationDocumentAddressResolver();
protected final SchemaFactory sf;
public AbstractSchemaValidationTube(WSBinding binding, Tube next) {
super(next);
this.binding = binding;
feature = binding.getFeature(SchemaValidationFeature.class);
sf = allowExternalAccess(SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI), "file", false);
}
protected AbstractSchemaValidationTube(AbstractSchemaValidationTube that, TubeCloner cloner) {
super(that, cloner);
this.binding = that.binding;
this.feature = that.feature;
this.sf = that.sf;
}
protected abstract Validator getValidator();
protected abstract boolean isNoValidation();
private static class ValidationDocumentAddressResolver implements DocumentAddressResolver {
@Nullable
@Override
public String getRelativeAddressFor(@NotNull SDDocument current, @NotNull SDDocument referenced) {
LOGGER.log(Level.FINE, "Current = {0} resolved relative={1}", new Object[]{current.getURL(), referenced.getURL()});
return referenced.getURL().toExternalForm();
}
}
private Document createDOM(SDDocument doc) {
// Get infoset
ByteArrayBuffer bab = new ByteArrayBuffer();
try {
doc.writeTo(null, resolver, bab);
} catch (IOException ioe) {
throw new WebServiceException(ioe);
}
// Convert infoset to DOM
Transformer trans = XmlUtil.newTransformer();
Source source = new StreamSource(bab.newInputStream(), null); //doc.getURL().toExternalForm());
DOMResult result = new DOMResult();
try {
trans.transform(source, result);
} catch(TransformerException te) {
throw new WebServiceException(te);
}
return (Document)result.getNode();
}
protected class MetadataResolverImpl implements SDDocumentResolver, LSResourceResolver {
// systemID --> SDDocument
final Map<String, SDDocument> docs = new HashMap<String, SDDocument>();
// targetnamespace --> SDDocument
final Map<String, SDDocument> nsMapping = new HashMap<String, SDDocument>();
public MetadataResolverImpl() {
}
public MetadataResolverImpl(Iterable<SDDocument> it) {
for(SDDocument doc : it) {
if (doc.isSchema()) {
docs.put(doc.getURL().toExternalForm(), doc);
nsMapping.put(((SDDocument.Schema)doc).getTargetNamespace(), doc);
}
}
}
void addSchema(Source schema) {
assert schema.getSystemId() != null;
String systemId = schema.getSystemId();
try {
XMLStreamBufferResult xsbr = XmlUtil.identityTransform(schema, new XMLStreamBufferResult());
SDDocumentSource sds = SDDocumentSource.create(new URL(systemId), xsbr.getXMLStreamBuffer());
SDDocument sdoc = SDDocumentImpl.create(sds, new QName(""), new QName(""));
docs.put(systemId, sdoc);
nsMapping.put(((SDDocument.Schema)sdoc).getTargetNamespace(), sdoc);
} catch(Exception ex) {
LOGGER.log(Level.WARNING, "Exception in adding schemas to resolver", ex);
}
}
void addSchemas(Collection<? extends Source> schemas) {
for(Source src : schemas) {
addSchema(src);
}
}
@Override
public SDDocument resolve(String systemId) {
SDDocument sdi = docs.get(systemId);
if (sdi == null) {
SDDocumentSource sds;
try {
sds = SDDocumentSource.create(new URL(systemId));
} catch(MalformedURLException e) {
throw new WebServiceException(e);
}
sdi = SDDocumentImpl.create(sds, new QName(""), new QName(""));
docs.put(systemId, sdi);
}
return sdi;
}
@Override
public LSInput resolveResource(String type, String namespaceURI, String publicId, final String systemId, final String baseURI) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "type={0} namespaceURI={1} publicId={2} systemId={3} baseURI={4}", new Object[]{type, namespaceURI, publicId, systemId, baseURI});
}
try {
final SDDocument doc;
if (systemId == null) {
doc = nsMapping.get(namespaceURI);
} else {
URI rel = (baseURI != null)
? new URI(baseURI).resolve(systemId)
: new URI(systemId);
doc = docs.get(rel.toString());
}
if (doc != null) {
return new LSInput() {
@Override
public Reader getCharacterStream() {
return null;
}
@Override
public void setCharacterStream(Reader characterStream) {
throw new UnsupportedOperationException();
}
@Override
public InputStream getByteStream() {
ByteArrayBuffer bab = new ByteArrayBuffer();
try {
doc.writeTo(null, resolver, bab);
} catch (IOException ioe) {
throw new WebServiceException(ioe);
}
return bab.newInputStream();
}
@Override
public void setByteStream(InputStream byteStream) {
throw new UnsupportedOperationException();
}
@Override
public String getStringData() {
return null;
}
@Override
public void setStringData(String stringData) {
throw new UnsupportedOperationException();
}
@Override
public String getSystemId() {
return doc.getURL().toExternalForm();
}
@Override
public void setSystemId(String systemId) {
throw new UnsupportedOperationException();
}
@Override
public String getPublicId() {
return null;
}
@Override
public void setPublicId(String publicId) {
throw new UnsupportedOperationException();
}
@Override
public String getBaseURI() {
return doc.getURL().toExternalForm();
}
@Override
public void setBaseURI(String baseURI) {
throw new UnsupportedOperationException();
}
@Override
public String getEncoding() {
return null;
}
@Override
public void setEncoding(String encoding) {
throw new UnsupportedOperationException();
}
@Override
public boolean getCertifiedText() {
return false;
}
@Override
public void setCertifiedText(boolean certifiedText) {
throw new UnsupportedOperationException();
}
};
}
} catch(Exception e) {
LOGGER.log(Level.WARNING, "Exception in LSResourceResolver impl", e);
}
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Don''t know about systemId={0} baseURI={1}", new Object[]{systemId, baseURI});
}
return null;
}
}
private void updateMultiSchemaForTns(String tns, String systemId, Map<String, List<String>> schemas) {
List<String> docIdList = schemas.get(tns);
if (docIdList == null) {
docIdList = new ArrayList<String>();
schemas.put(tns, docIdList);
}
docIdList.add(systemId);
}
/*
* Using the following algorithm described in the xerces discussion thread:
*
* "If you're synthesizing schema documents to glue together the ones in
* the WSDL then you may not even need to use "honour-all-schemaLocations".
* Create a schema document for each namespace with <xs:include>s
* (for each schema document in the WSDL with that target namespace)
* and then combine those together with <xs:import>s for each of those
* namespaces in a "master" schema document.
*
* That should work with any schema processor, not just those which
* honour multiple imports for the same namespace."
*/
protected Source[] getSchemaSources(Iterable<SDDocument> docs, MetadataResolverImpl mdresolver) {
// All schema fragments in WSDLs are put inlinedSchemas
// systemID --> DOMSource
Map<String, DOMSource> inlinedSchemas = new HashMap<String, DOMSource>();
// Consolidates all the schemas(inlined and external) for a tns
// tns --> list of systemId
Map<String, List<String>> multiSchemaForTns = new HashMap<String, List<String>>();
for(SDDocument sdoc: docs) {
if (sdoc.isWSDL()) {
Document dom = createDOM(sdoc);
// Get xsd:schema node from WSDL's DOM
addSchemaFragmentSource(dom, sdoc.getURL().toExternalForm(), inlinedSchemas);
} else if (sdoc.isSchema()) {
updateMultiSchemaForTns(((SDDocument.Schema)sdoc).getTargetNamespace(), sdoc.getURL().toExternalForm(), multiSchemaForTns);
}
}
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "WSDL inlined schema fragment documents(these are used to create a pseudo schema) = {0}", inlinedSchemas.keySet());
}
for(DOMSource src: inlinedSchemas.values()) {
String tns = getTargetNamespace(src);
updateMultiSchemaForTns(tns, src.getSystemId(), multiSchemaForTns);
}
if (multiSchemaForTns.isEmpty()) {
return new Source[0]; // WSDL doesn't have any schema fragments
} else if (multiSchemaForTns.size() == 1 && multiSchemaForTns.values().iterator().next().size() == 1) {
// It must be a inlined schema, otherwise there would be at least two schemas
String systemId = multiSchemaForTns.values().iterator().next().get(0);
return new Source[] {inlinedSchemas.get(systemId)};
}
// need to resolve these inlined schema fragments
mdresolver.addSchemas(inlinedSchemas.values());
// If there are multiple schema fragments for the same tns, create a
// pseudo schema for that tns by using <xsd:include> of those.
// tns --> systemId of a pseudo schema document (consolidated for that tns)
Map<String, String> oneSchemaForTns = new HashMap<String, String>();
int i = 0;
for(Map.Entry<String, List<String>> e: multiSchemaForTns.entrySet()) {
String systemId;
List<String> sameTnsSchemas = e.getValue();
if (sameTnsSchemas.size() > 1) {
// SDDocumentSource should be changed to take String systemId
// String pseudoSystemId = "urn:x-jax-ws-include-"+i++;
systemId = "file:x-jax-ws-include-"+i++;
Source src = createSameTnsPseudoSchema(e.getKey(), sameTnsSchemas, systemId);
mdresolver.addSchema(src);
} else {
systemId = sameTnsSchemas.get(0);
}
oneSchemaForTns.put(e.getKey(), systemId);
}
// create a master pseudo schema with all the different tns
Source pseudoSchema = createMasterPseudoSchema(oneSchemaForTns);
return new Source[] { pseudoSchema };
}
private @Nullable void addSchemaFragmentSource(Document doc, String systemId, Map<String, DOMSource> map) {
Element e = doc.getDocumentElement();
assert e.getNamespaceURI().equals(WSDLConstants.NS_WSDL);
assert e.getLocalName().equals("definitions");
NodeList typesList = e.getElementsByTagNameNS(WSDLConstants.NS_WSDL, "types");
for(int i=0; i < typesList.getLength(); i++) {
NodeList schemaList = ((Element)typesList.item(i)).getElementsByTagNameNS(WSDLConstants.NS_XMLNS, "schema");
for(int j=0; j < schemaList.getLength(); j++) {
Element elem = (Element)schemaList.item(j);
NamespaceSupport nss = new NamespaceSupport();
// Doing this because transformer is not picking up inscope namespaces
// why doesn't transformer pickup the inscope namespaces ??
buildNamespaceSupport(nss, elem);
patchDOMFragment(nss, elem);
String docId = systemId+"#schema"+j;
map.put(docId, new DOMSource(elem, docId));
}
}
}
/*
* Recursively visit ancestors and build up {@link org.xml.sax.helpers.NamespaceSupport} object.
*/
private void buildNamespaceSupport(NamespaceSupport nss, Node node) {
if (node==null || node.getNodeType()!=Node.ELEMENT_NODE) {
return;
}
buildNamespaceSupport( nss, node.getParentNode() );
nss.pushContext();
NamedNodeMap atts = node.getAttributes();
for( int i=0; i<atts.getLength(); i++ ) {
Attr a = (Attr)atts.item(i);
if( "xmlns".equals(a.getPrefix()) ) {
nss.declarePrefix( a.getLocalName(), a.getValue() );
continue;
}
if( "xmlns".equals(a.getName()) ) {
nss.declarePrefix( "", a.getValue() );
//continue;
}
}
}
/**
* Adds inscope namespaces as attributes to <xsd:schema> fragment nodes.
*
* @param nss namespace context info
* @param elem that is patched with inscope namespaces
*/
private @Nullable void patchDOMFragment(NamespaceSupport nss, Element elem) {
NamedNodeMap atts = elem.getAttributes();
for( Enumeration en = nss.getPrefixes(); en.hasMoreElements(); ) {
String prefix = (String)en.nextElement();
for( int i=0; i<atts.getLength(); i++ ) {
Attr a = (Attr)atts.item(i);
if (!"xmlns".equals(a.getPrefix()) || !a.getLocalName().equals(prefix)) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Patching with xmlns:{0}={1}", new Object[]{prefix, nss.getURI(prefix)});
}
elem.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:"+prefix, nss.getURI(prefix));
}
}
}
}
/*
* Creates a pseudo schema for the WSDL schema fragments that have the same
* targetNamespace.
*
* <xsd:schema targetNamespace="X">
* <xsd:include schemaLocation="Y1"/>
* <xsd:include schemaLocation="Y2"/>
* </xsd:schema>
*
* @param tns targetNamespace of the the schema documents
* @param docs collection of systemId for the schema documents that have the
* same tns, the collection must have more than one document
* @param psuedoSystemId for the created pseudo schema
* @return Source of pseudo schema that can be used multiple times
*/
private @Nullable Source createSameTnsPseudoSchema(String tns, Collection<String> docs, String pseudoSystemId) {
assert docs.size() > 1;
final StringBuilder sb = new StringBuilder("<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'");
if (!tns.equals("")) {
sb.append(" targetNamespace='").append(tns).append("'");
}
sb.append(">\n");
for(String systemId : docs) {
sb.append("<xsd:include schemaLocation='").append(systemId).append("'/>\n");
}
sb.append("</xsd:schema>\n");
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Pseudo Schema for the same tns={0}is {1}", new Object[]{tns, sb});
}
// override getReader() so that the same source can be used multiple times
return new StreamSource(pseudoSystemId) {
@Override
public Reader getReader() {
return new StringReader(sb.toString());
}
};
}
/*
* Creates a master pseudo schema importing all WSDL schema fragments with
* different tns+pseudo schema for same tns.
* <xsd:schema targetNamespace="urn:x-jax-ws-master">
* <xsd:import schemaLocation="Y1" namespace="X1"/>
* <xsd:import schemaLocation="Y2" namespace="X2"/>
* </xsd:schema>
*
* @param pseudo a map(tns-->systemId) of schema documents
* @return Source of pseudo schema that can be used multiple times
*/
private Source createMasterPseudoSchema(Map<String, String> docs) {
final StringBuilder sb = new StringBuilder("<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema' targetNamespace='urn:x-jax-ws-master'>\n");
for(Map.Entry<String, String> e : docs.entrySet()) {
String systemId = e.getValue();
String ns = e.getKey();
sb.append("<xsd:import schemaLocation='").append(systemId).append("'");
if (!ns.equals("")) {
sb.append(" namespace='").append(ns).append("'");
}
sb.append("/>\n");
}
sb.append("</xsd:schema>");
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Master Pseudo Schema = {0}", sb);
}
// override getReader() so that the same source can be used multiple times
return new StreamSource("file:x-jax-ws-master-doc") {
@Override
public Reader getReader() {
return new StringReader(sb.toString());
}
};
}
protected void doProcess(Packet packet) throws SAXException {
getValidator().reset();
Class<? extends ValidationErrorHandler> handlerClass = feature.getErrorHandler();
ValidationErrorHandler handler;
try {
handler = handlerClass.newInstance();
} catch(Exception e) {
throw new WebServiceException(e);
}
handler.setPacket(packet);
getValidator().setErrorHandler(handler);
Message msg = packet.getMessage().copy();
Source source = msg.readPayloadAsSource();
try {
// Validator javadoc allows ONLY SAX, and DOM Sources
// But the impl seems to handle all kinds.
getValidator().validate(source);
} catch(IOException e) {
throw new WebServiceException(e);
}
}
private String getTargetNamespace(DOMSource src) {
Element elem = (Element)src.getNode();
return elem.getAttribute("targetNamespace");
}
// protected static void printSource(Source src) {
// try {
// ByteArrayBuffer bos = new ByteArrayBuffer();
// StreamResult sr = new StreamResult(bos );
// Transformer trans = TransformerFactory.newInstance().newTransformer();
// trans.transform(src, sr);
// LOGGER.info("**** src ******"+bos.toString());
// bos.close();
// } catch(Exception e) {
// e.printStackTrace();
// }
// }
}

View File

@@ -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.util.pipe;
import com.sun.xml.internal.ws.api.message.Packet;
import com.sun.xml.internal.ws.api.pipe.NextAction;
import com.sun.xml.internal.ws.api.pipe.Pipe;
import com.sun.xml.internal.ws.api.pipe.Tube;
import com.sun.xml.internal.ws.api.pipe.TubeCloner;
import com.sun.xml.internal.ws.api.pipe.helper.AbstractFilterTubeImpl;
import com.sun.xml.internal.ws.api.pipe.helper.AbstractTubeImpl;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.PrintStream;
import java.lang.reflect.Constructor;
/**
* {@link Pipe} that dumps messages that pass through.
*
* @author Kohsuke Kawaguchi
*/
public class DumpTube extends AbstractFilterTubeImpl {
private final String name;
private final PrintStream out;
private final XMLOutputFactory staxOut;
/**
* @param name
* Specify the name that identifies this {@link DumpTube}
* instance. This string will be printed when this pipe
* dumps messages, and allows people to distinguish which
* pipe instance is dumping a message when multiple
* {@link DumpTube}s print messages out.
* @param out
* The output to send dumps to.
* @param next
* The next {@link Tube} in the pipeline.
*/
public DumpTube(String name, PrintStream out, Tube next) {
super(next);
this.name = name;
this.out = out;
this.staxOut = XMLOutputFactory.newInstance();
//staxOut.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES,true);
}
/**
* Copy constructor.
*/
protected DumpTube(DumpTube that, TubeCloner cloner) {
super(that,cloner);
this.name = that.name;
this.out = that.out;
this.staxOut = that.staxOut;
}
@Override
public NextAction processRequest(Packet request) {
dump("request",request);
return super.processRequest(request);
}
@Override
public NextAction processResponse(Packet response) {
dump("response",response);
return super.processResponse(response);
}
protected void dump(String header, Packet packet) {
out.println("====["+name+":"+header+"]====");
if(packet.getMessage()==null)
out.println("(none)");
else
try {
XMLStreamWriter writer = staxOut.createXMLStreamWriter(new PrintStream(out) {
@Override
public void close() {
// noop
}
});
writer = createIndenter(writer);
packet.getMessage().copy().writeTo(writer);
writer.close();
} catch (XMLStreamException e) {
e.printStackTrace(out);
}
out.println("============");
}
/**
* Wraps {@link XMLStreamWriter} by an indentation engine if possible.
*
* <p>
* We can do this only when we have <tt>stax-utils.jar</tt> in the classpath.
*/
private XMLStreamWriter createIndenter(XMLStreamWriter writer) {
try {
Class clazz = getClass().getClassLoader().loadClass("javanet.staxutils.IndentingXMLStreamWriter");
Constructor c = clazz.getConstructor(XMLStreamWriter.class);
writer = (XMLStreamWriter)c.newInstance(writer);
} catch (Exception e) {
// if stax-utils.jar is not in the classpath, this will fail
// so, we'll just have to do without indentation
if(!warnStaxUtils) {
warnStaxUtils = true;
out.println("WARNING: put stax-utils.jar to the classpath to indent the dump output");
}
}
return writer;
}
public AbstractTubeImpl copy(TubeCloner cloner) {
return new DumpTube(this,cloner);
}
private static boolean warnStaxUtils;
}

View File

@@ -0,0 +1,88 @@
/*
* 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.util.pipe;
import com.sun.istack.internal.NotNull;
import com.sun.xml.internal.ws.api.pipe.ClientPipeAssemblerContext;
import com.sun.xml.internal.ws.api.pipe.Pipe;
import com.sun.xml.internal.ws.api.pipe.PipelineAssembler;
import com.sun.xml.internal.ws.api.pipe.ServerPipeAssemblerContext;
/**
* Default Pipeline assembler for JAX-WS client and server side runtimes. It
* assembles various pipes into a pipeline that a message needs to be passed
* through.
*
* @author Kohsuke Kawaguchi
* @author Jitendra Kotamraju
*/
public class StandalonePipeAssembler implements PipelineAssembler {
@NotNull
public Pipe createClient(ClientPipeAssemblerContext context) {
Pipe head = context.createTransportPipe();
head = context.createSecurityPipe(head);
if (dump) {
// for debugging inject a dump pipe. this is left in the production code,
// as it would be very handy for a trouble-shooting at the production site.
head = context.createDumpPipe("client", System.out, head);
}
head = context.createWsaPipe(head);
head = context.createClientMUPipe(head);
return context.createHandlerPipe(head);
}
/**
* On Server-side, HandlerChains cannot be changed after it is deployed.
* During assembling the Pipelines, we can decide if we really need a
* SOAPHandlerPipe and LogicalHandlerPipe for a particular Endpoint.
*/
public Pipe createServer(ServerPipeAssemblerContext context) {
Pipe head = context.getTerminalPipe();
head = context.createHandlerPipe(head);
head = context.createMonitoringPipe(head);
head = context.createServerMUPipe(head);
head = context.createWsaPipe(head);
head = context.createSecurityPipe(head);
return head;
}
/**
* Are we going to dump the message to System.out?
*/
private static final boolean dump;
static {
boolean b = false;
try {
b = Boolean.getBoolean(StandalonePipeAssembler.class.getName()+".dump");
} catch (Throwable t) {
// treat it as false
}
dump = b;
}
}

View File

@@ -0,0 +1,93 @@
/*
* 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.util.pipe;
import com.sun.istack.internal.NotNull;
import com.sun.xml.internal.ws.api.pipe.ClientTubeAssemblerContext;
import com.sun.xml.internal.ws.api.pipe.ServerTubeAssemblerContext;
import com.sun.xml.internal.ws.api.pipe.Tube;
import com.sun.xml.internal.ws.api.pipe.TubelineAssembler;
/**
* Default Pipeline assembler for JAX-WS client and server side runtimes. It
* assembles various pipes into a pipeline that a message needs to be passed
* through.
*
* @author Jitendra Kotamraju
*/
public class StandaloneTubeAssembler implements TubelineAssembler {
@NotNull
public Tube createClient(ClientTubeAssemblerContext context) {
Tube head = context.createTransportTube();
head = context.createSecurityTube(head);
if (dump) {
// for debugging inject a dump pipe. this is left in the production code,
// as it would be very handy for a trouble-shooting at the production site.
head = context.createDumpTube("client", System.out, head);
}
head = context.createWsaTube(head);
head = context.createClientMUTube(head);
head = context.createValidationTube(head);
return context.createHandlerTube(head);
}
/**
* On Server-side, HandlerChains cannot be changed after it is deployed.
* During assembling the Pipelines, we can decide if we really need a
* SOAPHandlerPipe and LogicalHandlerPipe for a particular Endpoint.
*/
public Tube createServer(ServerTubeAssemblerContext context) {
Tube head = context.getTerminalTube();
head = context.createValidationTube(head);
head = context.createHandlerTube(head);
head = context.createMonitoringTube(head);
head = context.createServerMUTube(head);
head = context.createWsaTube(head);
if (dump) {
// for debugging inject a dump pipe. this is left in the production code,
// as it would be very handy for a trouble-shooting at the production site.
head = context.createDumpTube("server", System.out, head);
}
head = context.createSecurityTube(head);
return head;
}
/**
* Are we going to dump the message to System.out?
*/
public static final boolean dump;
static {
boolean b = false;
try {
b = Boolean.getBoolean(StandaloneTubeAssembler.class.getName()+".dump");
} catch (Throwable t) {
// treat it as false
}
dump = b;
}
}

View File

@@ -0,0 +1,58 @@
/*
* 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.util.xml;
/**
* @author WS Development Team
*/
public final class CDATA {
public CDATA(String text) {
_text = text;
}
public String getText() {
return _text;
}
public boolean equals(Object obj) {
if (obj == null)
return false;
if (!(obj instanceof CDATA))
return false;
CDATA cdata = (CDATA) obj;
return this._text.equals(cdata._text);
}
public int hashCode() {
return _text.hashCode();
}
private String _text;
}

View File

@@ -0,0 +1,283 @@
/*
* 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.util.xml;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.util.Stack;
/**
* This is a simple utility class that adapts SAX events into StAX
* {@link XMLStreamWriter} events, bridging between
* the two parser technologies.
*
* This ContentHandler does not own the XMLStreamWriter. Therefore, it will
* not close or flush the writer at any point.
*
* @author Ryan.Shoemaker@Sun.COM
* @version 1.0
*/
public class ContentHandlerToXMLStreamWriter extends DefaultHandler {
// SAX events will be sent to this XMLStreamWriter
private final XMLStreamWriter staxWriter;
// storage for prefix bindings
private final Stack prefixBindings;
public ContentHandlerToXMLStreamWriter(XMLStreamWriter staxCore) {
this.staxWriter = staxCore;
prefixBindings = new Stack(); // default of 10 seems reasonable
}
/*
* (non-Javadoc)
*
* @see org.xml.sax.ContentHandler#endDocument()
*/
public void endDocument() throws SAXException {
try {
staxWriter.writeEndDocument();
staxWriter.flush();
} catch (XMLStreamException e) {
throw new SAXException(e);
}
}
/*
* (non-Javadoc)
*
* @see org.xml.sax.ContentHandler#startDocument()
*/
public void startDocument() throws SAXException {
try {
staxWriter.writeStartDocument();
} catch (XMLStreamException e) {
throw new SAXException(e);
}
}
/*
* (non-Javadoc)
*
* @see org.xml.sax.ContentHandler#characters(char[], int, int)
*/
public void characters(char[] ch, int start, int length)
throws SAXException {
try {
staxWriter.writeCharacters(ch, start, length);
} catch (XMLStreamException e) {
throw new SAXException(e);
}
}
/*
* (non-Javadoc)
*
* @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
*/
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
characters(ch,start,length);
}
/*
* (non-Javadoc)
*
* @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
*/
public void endPrefixMapping(String prefix) throws SAXException {
// TODO: no-op?
// I think we can ignore these SAX events because StAX
// automatically scopes the prefix bindings.
}
/*
* (non-Javadoc)
*
* @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
*/
public void skippedEntity(String name) throws SAXException {
try {
staxWriter.writeEntityRef(name);
} catch (XMLStreamException e) {
throw new SAXException(e);
}
}
/*
* (non-Javadoc)
*
* @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
*/
public void setDocumentLocator(Locator locator) {
// TODO: no-op?
// there doesn't seem to be any way to pass location info
// along to the XMLStreamWriter. On the XMLEventWriter side, you
// can set the location info on the event objects.
}
/*
* (non-Javadoc)
*
* @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String,
* java.lang.String)
*/
public void processingInstruction(String target, String data)
throws SAXException {
try {
staxWriter.writeProcessingInstruction(target, data);
} catch (XMLStreamException e) {
throw new SAXException(e);
}
}
/*
* (non-Javadoc)
*
* @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String,
* java.lang.String)
*/
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
// defend against parsers that pass null in for "xmlns" prefix
if (prefix == null) {
prefix = "";
}
if (prefix.equals("xml")) {
return;
}
prefixBindings.add(prefix);
prefixBindings.add(uri);
}
/*
* (non-Javadoc)
*
* @see org.xml.sax.ContentHandler#endElement(java.lang.String,
* java.lang.String, java.lang.String)
*/
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
try {
// TODO: is this all we have to do?
staxWriter.writeEndElement();
} catch (XMLStreamException e) {
throw new SAXException(e);
}
}
/*
* (non-Javadoc)
*
* @see org.xml.sax.ContentHandler#startElement(java.lang.String,
* java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
public void startElement(
String namespaceURI,
String localName,
String qName,
Attributes atts)
throws SAXException {
try {
staxWriter.writeStartElement(
getPrefix(qName),
localName,
namespaceURI);
String uri, prefix;
while (prefixBindings.size() != 0) {
uri = (String)prefixBindings.pop();
prefix = (String)prefixBindings.pop();
if (prefix.length() == 0) {
staxWriter.setDefaultNamespace(uri);
} else {
staxWriter.setPrefix(prefix, uri);
}
// this method handles "", null, and "xmlns" prefixes properly
staxWriter.writeNamespace(prefix, uri);
}
writeAttributes(atts);
} catch (XMLStreamException e) {
throw new SAXException(e);
}
}
/**
* Generate a StAX writeAttribute event for each attribute
*
* @param atts
* attributes from the SAX event
*/
private void writeAttributes(Attributes atts) throws XMLStreamException {
for (int i = 0; i < atts.getLength(); i++) {
final String prefix = getPrefix(atts.getQName(i));
if(!prefix.equals("xmlns")) { // defend againts broken transformers that report xmlns decls as attrs
staxWriter.writeAttribute(
prefix,
atts.getURI(i),
atts.getLocalName(i),
atts.getValue(i));
}
}
}
/**
* Pull the prefix off of the specified QName.
*
* @param qName
* the QName
* @return the prefix or the empty string if it doesn't exist.
*/
private String getPrefix(String qName) {
int idx = qName.indexOf(':');
if (idx == -1) {
return "";
} else {
return qName.substring(0, idx);
}
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2014, 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.util.xml;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.text.MessageFormat;
import java.util.ResourceBundle;
import java.util.WeakHashMap;
/**
* Simple utility ensuring that the value is cached only in case it is non-internal implementation
*/
abstract class ContextClassloaderLocal<V> {
private static final String FAILED_TO_CREATE_NEW_INSTANCE = "FAILED_TO_CREATE_NEW_INSTANCE";
private WeakHashMap<ClassLoader, V> CACHE = new WeakHashMap<ClassLoader, V>();
public V get() throws Error {
ClassLoader tccl = getContextClassLoader();
V instance = CACHE.get(tccl);
if (instance == null) {
instance = createNewInstance();
CACHE.put(tccl, instance);
}
return instance;
}
public void set(V instance) {
CACHE.put(getContextClassLoader(), instance);
}
protected abstract V initialValue() throws Exception;
private V createNewInstance() {
try {
return initialValue();
} catch (Exception e) {
throw new Error(format(FAILED_TO_CREATE_NEW_INSTANCE, getClass().getName()), e);
}
}
private static String format(String property, Object... args) {
String text = ResourceBundle.getBundle(ContextClassloaderLocal.class.getName()).getString(property);
return MessageFormat.format(text, args);
}
private static ClassLoader getContextClassLoader() {
return (ClassLoader)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
ClassLoader cl = null;
try {
cl = Thread.currentThread().getContextClassLoader();
} catch (SecurityException ex) {
}
return cl;
}
});
}
}

View File

@@ -0,0 +1,55 @@
/*
* 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.util.xml;
import javax.xml.stream.Location;
/**
* {@link Location} that returns no info.
*
* @author Santiago.PericasGeertsen@sun.com
*/
public final class DummyLocation implements Location {
private DummyLocation() {}
public static final Location INSTANCE = new DummyLocation();
public int getCharacterOffset() {
return -1;
}
public int getColumnNumber() {
return -1;
}
public int getLineNumber() {
return -1;
}
public String getPublicId() {
return null;
}
public String getSystemId() {
return null;
}
}

View File

@@ -0,0 +1,61 @@
/*
* 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.util.xml;
import java.util.Iterator;
import org.w3c.dom.NamedNodeMap;
/**
* @author WS Development Team
*/
public class NamedNodeMapIterator implements Iterator {
protected NamedNodeMap _map;
protected int _index;
public NamedNodeMapIterator(NamedNodeMap map) {
_map = map;
_index = 0;
}
public boolean hasNext() {
if (_map == null)
return false;
return _index < _map.getLength();
}
public Object next() {
Object obj = _map.item(_index);
if (obj != null)
++_index;
return obj;
}
public void remove() {
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 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.util.xml;
import java.util.Iterator;
import javax.xml.namespace.NamespaceContext;
import com.sun.xml.internal.org.jvnet.staxex.NamespaceContextEx;
public class NamespaceContextExAdaper implements NamespaceContextEx {
private final NamespaceContext nsContext;
public NamespaceContextExAdaper(NamespaceContext nsContext) {
this.nsContext = nsContext;
}
@Override //Who wants this?
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);
}
}

View File

@@ -0,0 +1,61 @@
/*
* 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.util.xml;
import java.util.Iterator;
import org.w3c.dom.NodeList;
/**
* @author WS Development Team
*/
public class NodeListIterator implements Iterator {
protected NodeList _list;
protected int _index;
public NodeListIterator(NodeList list) {
_list = list;
_index = 0;
}
public boolean hasNext() {
if (_list == null)
return false;
return _index < _list.getLength();
}
public Object next() {
Object obj = _list.item(_index);
if (obj != null)
++_index;
return obj;
}
public void remove() {
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,89 @@
/*
* 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.util.xml;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.sax.SAXResult;
/**
* A JAXP {@link javax.xml.transform.Result} implementation that produces
* a result on the specified {@link javax.xml.stream.XMLStreamWriter} or
* {@link javax.xml.stream.XMLEventWriter}.
*
* <p>
* Please note that you may need to call flush() on the underlying
* XMLStreamWriter or XMLEventWriter after the transform is complete.
* <p>
*
* The fact that JAXBResult derives from SAXResult is an implementation
* detail. Thus in general applications are strongly discouraged from
* accessing methods defined on SAXResult.
*
* <p>
* In particular it shall never attempt to call the following methods:
*
* <ul>
* <li>setHandler</li>
* <li>setLexicalHandler</li>
* <li>setSystemId</li>
* </ul>
*
* <p>
* Example:
*
* <pre>
// create a DOMSource
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(...);
Source domSource = new DOMSource(doc);
// create a StAXResult
XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(System.out);
Result staxResult = new StAXResult(writer);
// run the transform
TransformerFactory.newInstance().newTransformer().transform(domSource, staxResult);
* </pre>
*
* @author Ryan.Shoemaker@Sun.COM
* @version 1.0
*/
public class StAXResult extends SAXResult {
/**
* Create a new {@link javax.xml.transform.Result} that produces
* a result on the specified {@link javax.xml.stream.XMLStreamWriter}
*
* @param writer the XMLStreamWriter
* @throws IllegalArgumentException iff the writer is null
*/
public StAXResult(XMLStreamWriter writer) {
if( writer == null ) {
throw new IllegalArgumentException();
}
super.setHandler(new ContentHandlerToXMLStreamWriter( writer ));
}
}

View File

@@ -0,0 +1,303 @@
/*
* 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.util.xml;
import com.sun.istack.internal.NotNull;
import com.sun.istack.internal.SAXParseException2;
import com.sun.istack.internal.XMLStreamReaderToContentHandler;
import org.xml.sax.*;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.XMLFilterImpl;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.sax.SAXSource;
/**
* A JAXP {@link javax.xml.transform.Source} implementation that wraps
* the specified {@link javax.xml.stream.XMLStreamReader} or
* {@link javax.xml.stream.XMLEventReader} for use by applications that
* expect a {@link javax.xml.transform.Source}.
*
* <p>
* The fact that StAXSource derives from SAXSource is an implementation
* detail. Thus in general applications are strongly discouraged from
* accessing methods defined on SAXSource. In particular:
*
* <ul>
* <li> The setXMLReader and setInputSource methods shall never be called.</li>
* <li> The XMLReader object obtained by the getXMLReader method shall
* be used only for parsing the InputSource object returned by
* the getInputSource method.</li>
* <li> The InputSource object obtained by the getInputSource method shall
* be used only for being parsed by the XMLReader object returned by
* the getXMLReader method.</li>
* </ul>
*
* <p>
* Example:
*
* <pre>
// create a StAXSource
XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(new FileReader(args[0]));
Source staxSource = new StAXSource(reader);
// create a StreamResult
Result streamResult = new StreamResult(System.out);
// run the transform
TransformerFactory.newInstance().newTransformer().transform(staxSource, streamResult);
* </pre>
*
* @author Ryan.Shoemaker@Sun.COM
* @version 1.0
*/
public class StAXSource extends SAXSource {
// StAX to SAX converter that will read from StAX and produce SAX
// this object will be wrapped by the XMLReader exposed to the client
private final XMLStreamReaderToContentHandler reader;
private final XMLStreamReader staxReader;
// SAX allows ContentHandler to be changed during the parsing,
// but JAXB doesn't. So this repeater will sit between those
// two components.
private final XMLFilterImpl repeater = new XMLFilterImpl();
// this object will pretend as an XMLReader.
// no matter what parameter is specified to the parse method,
// it will just read from the StAX reader.
private final XMLReader pseudoParser = new XMLReader() {
@Override
public boolean getFeature(String name) throws SAXNotRecognizedException {
throw new SAXNotRecognizedException(name);
}
@Override
public void setFeature(String name, boolean value) throws SAXNotRecognizedException {
// Should support these two features according to XMLReader javadoc.
if (name.equals("http://xml.org/sax/features/namespaces") && value) {
// Ignore for now
} else if (name.equals("http://xml.org/sax/features/namespace-prefixes") && !value) {
// Ignore for now
} else {
throw new SAXNotRecognizedException(name);
}
}
@Override
public Object getProperty(String name) throws SAXNotRecognizedException {
if( "http://xml.org/sax/properties/lexical-handler".equals(name) ) {
return lexicalHandler;
}
throw new SAXNotRecognizedException(name);
}
@Override
public void setProperty(String name, Object value) throws SAXNotRecognizedException {
if( "http://xml.org/sax/properties/lexical-handler".equals(name) ) {
this.lexicalHandler = (LexicalHandler)value;
return;
}
throw new SAXNotRecognizedException(name);
}
private LexicalHandler lexicalHandler;
// we will store this value but never use it by ourselves.
private EntityResolver entityResolver;
@Override
public void setEntityResolver(EntityResolver resolver) {
this.entityResolver = resolver;
}
@Override
public EntityResolver getEntityResolver() {
return entityResolver;
}
private DTDHandler dtdHandler;
@Override
public void setDTDHandler(DTDHandler handler) {
this.dtdHandler = handler;
}
@Override
public DTDHandler getDTDHandler() {
return dtdHandler;
}
@Override
public void setContentHandler(ContentHandler handler) {
repeater.setContentHandler(handler);
}
@Override
public ContentHandler getContentHandler() {
return repeater.getContentHandler();
}
private ErrorHandler errorHandler;
@Override
public void setErrorHandler(ErrorHandler handler) {
this.errorHandler = handler;
}
@Override
public ErrorHandler getErrorHandler() {
return errorHandler;
}
@Override
public void parse(InputSource input) throws SAXException {
parse();
}
@Override
public void parse(String systemId) throws SAXException {
parse();
}
public void parse() throws SAXException {
// parses from a StAX reader and generates SAX events which
// go through the repeater and are forwarded to the appropriate
// component
try {
reader.bridge();
} catch( XMLStreamException e ) {
// wrap it in a SAXException
SAXParseException se =
new SAXParseException2(
e.getMessage(),
null,
null,
e.getLocation() == null ? -1 : e.getLocation().getLineNumber(),
e.getLocation() == null ? -1 : e.getLocation().getColumnNumber(),
e);
// if the consumer sets an error handler, it is our responsibility
// to notify it.
if(errorHandler!=null)
errorHandler.fatalError(se);
// this is a fatal error. Even if the error handler
// returns, we will abort anyway.
throw se;
} finally {
try {
staxReader.close();
} catch(XMLStreamException xe) {
//falls through. Not much can be done.
}
}
}
};
/**
* Creates a new {@link javax.xml.transform.Source} for the given
* {@link XMLStreamReader}.
*
* @param reader XMLStreamReader that will be exposed as a Source
* @param eagerQuit if true, when the conversion is completed, leave the cursor to the last
* event that was fired (such as end element)
* @see #StAXSource(XMLStreamReader, boolean, String[])
*/
public StAXSource(XMLStreamReader reader, boolean eagerQuit) {
this(reader, eagerQuit, new String[0]);
}
/**
* Creates a new {@link javax.xml.transform.Source} for the given
* {@link XMLStreamReader}.
*
* The XMLStreamReader must be pointing at either a
* {@link javax.xml.stream.XMLStreamConstants#START_DOCUMENT} or
* {@link javax.xml.stream.XMLStreamConstants#START_ELEMENT} event.
*
* @param reader XMLStreamReader that will be exposed as a Source
* @param eagerQuit if true, when the conversion is completed, leave the cursor to the last
* event that was fired (such as end element)
* @param inscope inscope Namespaces
* array of the even length of the form { prefix0, uri0, prefix1, uri1, ... }
* @throws IllegalArgumentException iff the reader is null
* @throws IllegalStateException iff the reader is not pointing at either a
* START_DOCUMENT or START_ELEMENT event
*/
public StAXSource(XMLStreamReader reader, boolean eagerQuit, @NotNull String[] inscope) {
if( reader == null )
throw new IllegalArgumentException();
this.staxReader = reader;
int eventType = reader.getEventType();
if (!(eventType == XMLStreamConstants.START_DOCUMENT)
&& !(eventType == XMLStreamConstants.START_ELEMENT)) {
throw new IllegalStateException();
}
this.reader = new XMLStreamReaderToContentHandler(reader,repeater,eagerQuit,false,inscope);
super.setXMLReader(pseudoParser);
// pass a dummy InputSource. We don't care
super.setInputSource(new InputSource());
}
// /**
// * Creates a new {@link javax.xml.transform.Source} for the given
// * {@link XMLEventReader}.
// *
// * The XMLEventReader must be pointing at either a
// * {@link javax.xml.stream.XMLStreamConstants#START_DOCUMENT} or
// * {@link javax.xml.stream.XMLStreamConstants#START_ELEMENT} event.
// *
// * @param reader XMLEventReader that will be exposed as a Source
// * @throws IllegalArgumentException iff the reader is null
// * @throws IllegalStateException iff the reader is not pointing at either a
// * START_DOCUEMENT or START_ELEMENT event
// */
// public StAXSource(XMLEventReader reader) {
// if( reader == null )
// throw new IllegalArgumentException();
//
// // TODO: detect IllegalStateException for START_ELEMENT|DOCUMENT
// // bugid 5046340 - peek not implemented
// // XMLEvent event = staxEventReader.peek();
//
// this.reader =
// new XMLEventReaderToContentHandler(
// reader,
// repeater);
//
// super.setXMLReader(pseudoParser);
// // pass a dummy InputSource. We don't care
// super.setInputSource(new InputSource());
// }
}

View File

@@ -0,0 +1,662 @@
/*
* Copyright (c) 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.util.xml;
import java.util.Iterator;
import java.util.List;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import com.sun.xml.internal.org.jvnet.staxex.NamespaceContextEx;
import com.sun.xml.internal.org.jvnet.staxex.XMLStreamReaderEx;
import com.sun.xml.internal.ws.encoding.TagInfoset;
/**
* XMLReaderComposite
*
* @author shih-chang.chen@oracle.com
*/
public class XMLReaderComposite implements XMLStreamReaderEx {
static public enum State { StartTag, Payload, EndTag }
protected State state = State.StartTag;
protected ElemInfo elemInfo;
protected TagInfoset tagInfo;
protected XMLStreamReader[] children;
protected int payloadIndex = -1;
protected XMLStreamReader payloadReader;
static public class ElemInfo implements NamespaceContext {
ElemInfo ancestor;
TagInfoset tagInfo;
public ElemInfo(TagInfoset tag, ElemInfo parent) { tagInfo = tag; ancestor = parent; }
public String getNamespaceURI(String prefix) {
String n = tagInfo.getNamespaceURI(prefix);
return (n != null) ? n : (ancestor != null) ? ancestor.getNamespaceURI(prefix) : null;
}
public String getPrefix(String uri) {
String p = tagInfo.getPrefix(uri);
return (p != null) ? p : (ancestor != null) ? ancestor.getPrefix(uri) : null;
}
//Who wants this?
public List<String> allPrefixes(String namespaceURI) {
List<String> l = tagInfo.allPrefixes(namespaceURI);
if (ancestor != null) {
List<String> p = ancestor.allPrefixes(namespaceURI);
p.addAll(l);
return p;
}
return l;
}
public Iterator<String> getPrefixes(String namespaceURI) {
return allPrefixes(namespaceURI).iterator();
}
}
public XMLReaderComposite(final ElemInfo elem, XMLStreamReader[] wrapees) {
elemInfo = elem;
tagInfo = elem.tagInfo;
children = wrapees;
if (children != null && children.length > 0) {
payloadIndex = 0;
payloadReader = children[payloadIndex];
}
}
@Override
public int next() throws XMLStreamException {
switch (state) {
case StartTag:
if (payloadReader != null) {
state = State.Payload;
return payloadReader.getEventType();
} else {
state = State.EndTag;
return XMLStreamReader.END_ELEMENT;
}
case EndTag: return XMLStreamReader.END_DOCUMENT;
case Payload:
default:
int next = XMLStreamReader.END_DOCUMENT;
if (payloadReader != null && payloadReader.hasNext()) {
next = payloadReader.next();
}
if (next != XMLStreamReader.END_DOCUMENT) return next;
else {
if (payloadIndex+1 < children.length ) {
payloadIndex++;
payloadReader = children[payloadIndex];
return payloadReader.getEventType();
} else {
state = State.EndTag;
return XMLStreamReader.END_ELEMENT;
}
}
}
}
@Override
public boolean hasNext() throws XMLStreamException {
switch (state) {
case EndTag: return false;
case StartTag:
case Payload:
default: return true;
}
}
@Override
public String getElementText() throws XMLStreamException {
switch (state) {
case StartTag:
if (payloadReader.isCharacters()) return payloadReader.getText();
return "";
case Payload:
default:
return payloadReader.getElementText();
}
}
@Override
public int nextTag() throws XMLStreamException {
int e = next();
if (e == XMLStreamReader.END_DOCUMENT) return e;
while (e != XMLStreamReader.END_DOCUMENT) {
if (e == XMLStreamReader.START_ELEMENT) return e;
if (e == XMLStreamReader.END_ELEMENT) return e;
e = next();
}
return e;
}
@Override
public Object getProperty(String name) throws IllegalArgumentException {
return (payloadReader != null) ? payloadReader.getProperty(name) : null;
}
@Override
public void require(int type, String namespaceURI, String localName) throws XMLStreamException {
if (payloadReader!=null) payloadReader.require(type, namespaceURI, localName);
}
@Override
public void close() throws XMLStreamException {
if (payloadReader!=null) payloadReader.close();
}
@Override
public String getNamespaceURI(String prefix) {
switch (state) {
case StartTag:
case EndTag:
return elemInfo.getNamespaceURI(prefix);
case Payload:
default:
return payloadReader.getNamespaceURI(prefix);
}
}
@Override
public boolean isStartElement() {
switch (state) {
case StartTag: return true;
case EndTag: return false;
case Payload:
default:
return payloadReader.isStartElement();
}
}
@Override
public boolean isEndElement() {
switch (state) {
case StartTag: return false;
case EndTag: return true;
case Payload:
default:
return payloadReader.isEndElement();
}
}
@Override
public boolean isCharacters() {
switch (state) {
case StartTag:
case EndTag: return false;
case Payload:
default:
return payloadReader.isCharacters();
}
}
@Override
public boolean isWhiteSpace() {
switch (state) {
case StartTag:
case EndTag: return false;
case Payload:
default:
return payloadReader.isWhiteSpace();
}
}
@Override
public String getAttributeValue(String uri, String localName) {
switch (state) {
case StartTag:
case EndTag: return tagInfo.atts.getValue(uri, localName);
case Payload:
default:
return payloadReader.getAttributeValue(uri, localName);
}
}
@Override
public int getAttributeCount() {
switch (state) {
case StartTag:
case EndTag: return tagInfo.atts.getLength();
case Payload:
default:
return payloadReader.getAttributeCount();
}
}
@Override
public QName getAttributeName(int i) {
switch (state) {
case StartTag:
case EndTag: return new QName(tagInfo.atts.getURI(i),tagInfo.atts.getLocalName(i),getPrfix(tagInfo.atts.getQName(i)));
case Payload:
default:
return payloadReader.getAttributeName(i);
}
}
@Override
public String getAttributeNamespace(int index) {
switch (state) {
case StartTag:
case EndTag: return tagInfo.atts.getURI(index);
case Payload:
default:
return payloadReader.getAttributeNamespace(index);
}
}
@Override
public String getAttributeLocalName(int index) {
switch (state) {
case StartTag:
case EndTag: return tagInfo.atts.getLocalName(index);
case Payload:
default:
return payloadReader.getAttributeLocalName(index);
}
}
@Override
public String getAttributePrefix(int index) {
switch (state) {
case StartTag:
case EndTag: return getPrfix(tagInfo.atts.getQName(index));
case Payload:
default:
return payloadReader.getAttributePrefix(index);
}
}
static private String getPrfix(String qName) {
if (qName == null) return null;
int i = qName.indexOf(":");
return (i > 0)? qName.substring(0, i) : "";
}
@Override
public String getAttributeType(int index) {
switch (state) {
case StartTag:
case EndTag: return tagInfo.atts.getType(index);
case Payload:
default:
return payloadReader.getAttributeType(index);
}
}
@Override
public String getAttributeValue(int index) {
switch (state) {
case StartTag:
case EndTag: return tagInfo.atts.getValue(index);
case Payload:
default:
return payloadReader.getAttributeValue(index);
}
}
@Override
public boolean isAttributeSpecified(int index) {
switch (state) {
case StartTag:
case EndTag: return (index < tagInfo.atts.getLength()) ? tagInfo.atts.getLocalName(index) != null : false;
case Payload:
default:
return payloadReader.isAttributeSpecified(index);
}
}
@Override
public int getNamespaceCount() {
switch (state) {
case StartTag:
case EndTag: return (tagInfo.ns.length/2);
case Payload:
default:
return payloadReader.getNamespaceCount();
}
}
@Override
public String getNamespacePrefix(int index) {
switch (state) {
case StartTag:
case EndTag: return tagInfo.ns[2*index];
case Payload:
default:
return payloadReader.getNamespacePrefix(index);
}
}
@Override
public String getNamespaceURI(int index) {
switch (state) {
case StartTag:
case EndTag: return tagInfo.ns[2*index+1];
case Payload:
default:
return payloadReader.getNamespaceURI(index);
}
}
@Override
public NamespaceContextEx getNamespaceContext() {
switch (state) {
case StartTag:
case EndTag: return new NamespaceContextExAdaper(elemInfo);
case Payload:
default:
return isPayloadReaderEx()?
payloadReaderEx().getNamespaceContext() :
new NamespaceContextExAdaper(payloadReader.getNamespaceContext());
}
}
private boolean isPayloadReaderEx() { return (payloadReader instanceof XMLStreamReaderEx); }
private XMLStreamReaderEx payloadReaderEx() { return (XMLStreamReaderEx)payloadReader; }
@Override
public int getEventType() {
switch (state) {
case StartTag: return XMLStreamReader.START_ELEMENT;
case EndTag: return XMLStreamReader.END_ELEMENT;
case Payload:
default:
return payloadReader.getEventType();
}
}
@Override
public String getText() {
switch (state) {
case StartTag:
case EndTag: return null;
case Payload:
default:
return payloadReader.getText();
}
}
@Override
public char[] getTextCharacters() {
switch (state) {
case StartTag:
case EndTag: return null;
case Payload:
default:
return payloadReader.getTextCharacters();
}
}
@Override
public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException {
switch (state) {
case StartTag:
case EndTag: return -1;
case Payload:
default:
return payloadReader.getTextCharacters(sourceStart, target, targetStart, length);
}
}
@Override
public int getTextStart() {
switch (state) {
case StartTag:
case EndTag: return 0;
case Payload:
default:
return payloadReader.getTextStart();
}
}
@Override
public int getTextLength() {
switch (state) {
case StartTag:
case EndTag: return 0;
case Payload:
default:
return payloadReader.getTextLength();
}
}
@Override
public String getEncoding() {
switch (state) {
case StartTag:
case EndTag: return null;
case Payload:
default:
return payloadReader.getEncoding();
}
}
@Override
public boolean hasText() {
switch (state) {
case StartTag:
case EndTag: return false;
case Payload:
default:
return payloadReader.hasText();
}
}
@Override
public Location getLocation() {
switch (state) {
case StartTag:
case EndTag: return new Location() {
@Override
public int getLineNumber() {
// TODO Auto-generated method stub
return 0;
}
@Override
public int getColumnNumber() {
// TODO Auto-generated method stub
return 0;
}
@Override
public int getCharacterOffset() {
// TODO Auto-generated method stub
return 0;
}
@Override
public String getPublicId() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getSystemId() {
// TODO Auto-generated method stub
return null;
}
};
case Payload:
default:
return payloadReader.getLocation();
}
}
@Override
public QName getName() {
switch (state) {
case StartTag:
case EndTag: return new QName(tagInfo.nsUri, tagInfo.localName, tagInfo.prefix);
case Payload:
default:
return payloadReader.getName();
}
}
@Override
public String getLocalName() {
switch (state) {
case StartTag:
case EndTag: return tagInfo.localName;
case Payload:
default:
return payloadReader.getLocalName();
}
}
@Override
public boolean hasName() {
switch (state) {
case StartTag:
case EndTag: return true;
case Payload:
default:
return payloadReader.hasName();
}
}
@Override
public String getNamespaceURI() {
switch (state) {
case StartTag:
case EndTag: return tagInfo.nsUri;
case Payload:
default:
return payloadReader.getNamespaceURI();
}
}
@Override
public String getPrefix() {
switch (state) {
case StartTag:
case EndTag: return tagInfo.prefix;
case Payload:
default:
return payloadReader.getPrefix();
}
}
@Override
public String getVersion() {
switch (state) {
case StartTag:
case EndTag: return null;
case Payload:
default:
return payloadReader.getVersion();
}
}
@Override
public boolean isStandalone() {
switch (state) {
case StartTag:
case EndTag: return true;
case Payload:
default:
return payloadReader.isStandalone();
}
}
@Override
public boolean standaloneSet() {
switch (state) {
case StartTag:
case EndTag: return true;
case Payload:
default:
return payloadReader.standaloneSet();
}
}
@Override
public String getCharacterEncodingScheme() {
switch (state) {
case StartTag:
case EndTag: return null;
case Payload:
default:
return payloadReader.getCharacterEncodingScheme();
}
}
@Override
public String getPITarget() {
switch (state) {
case StartTag:
case EndTag: return null;
case Payload:
default:
return payloadReader.getPITarget();
}
}
@Override
public String getPIData() {
switch (state) {
case StartTag:
case EndTag: return null;
case Payload:
default:
return payloadReader.getPIData();
}
}
@Override
public String getElementTextTrim() throws XMLStreamException {
switch (state) {
case StartTag:
case EndTag: return null;
case Payload:
default:
return isPayloadReaderEx()? payloadReaderEx().getElementTextTrim() : payloadReader.getElementText().trim();
}
}
@Override
public CharSequence getPCDATA() throws XMLStreamException {
switch (state) {
case StartTag:
case EndTag: return null;
case Payload:
default:
return isPayloadReaderEx()? payloadReaderEx().getPCDATA() : payloadReader.getElementText();
}
}
}

View File

@@ -0,0 +1,239 @@
/*
* 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.util.xml;
import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
/**
* {@link XMLStreamReader} that delegates to another {@link XMLStreamReader}.
*
* <p>
* This class isn't very useful by itself, but works as a base class
* for {@link XMLStreamReader} filtering.
*
* @author Kohsuke Kawaguchi
*/
public class XMLStreamReaderFilter implements XMLStreamReaderFactory.RecycleAware, XMLStreamReader {
/**
* The underlying {@link XMLStreamReader} that does the parsing of the root part.
*/
protected XMLStreamReader reader;
public XMLStreamReaderFilter(XMLStreamReader core) {
this.reader = core;
}
public void onRecycled() {
XMLStreamReaderFactory.recycle(reader);
reader = null;
}
public int getAttributeCount() {
return reader.getAttributeCount();
}
public int getEventType() {
return reader.getEventType();
}
public int getNamespaceCount() {
return reader.getNamespaceCount();
}
public int getTextLength() {
return reader.getTextLength();
}
public int getTextStart() {
return reader.getTextStart();
}
public int next() throws XMLStreamException {
return reader.next();
}
public int nextTag() throws XMLStreamException {
return reader.nextTag();
}
public void close() throws XMLStreamException {
reader.close();
}
public boolean hasName() {
return reader.hasName();
}
public boolean hasNext() throws XMLStreamException {
return reader.hasNext();
}
public boolean hasText() {
return reader.hasText();
}
public boolean isCharacters() {
return reader.isCharacters();
}
public boolean isEndElement() {
return reader.isEndElement();
}
public boolean isStandalone() {
return reader.isStandalone();
}
public boolean isStartElement() {
return reader.isStartElement();
}
public boolean isWhiteSpace() {
return reader.isWhiteSpace();
}
public boolean standaloneSet() {
return reader.standaloneSet();
}
public char[] getTextCharacters() {
return reader.getTextCharacters();
}
public boolean isAttributeSpecified(int index) {
return reader.isAttributeSpecified(index);
}
public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException {
return reader.getTextCharacters(sourceStart, target, targetStart, length);
}
public String getCharacterEncodingScheme() {
return reader.getCharacterEncodingScheme();
}
public String getElementText() throws XMLStreamException {
return reader.getElementText();
}
public String getEncoding() {
return reader.getEncoding();
}
public String getLocalName() {
return reader.getLocalName();
}
public String getNamespaceURI() {
return reader.getNamespaceURI();
}
public String getPIData() {
return reader.getPIData();
}
public String getPITarget() {
return reader.getPITarget();
}
public String getPrefix() {
return reader.getPrefix();
}
public String getText() {
return reader.getText();
}
public String getVersion() {
return reader.getVersion();
}
public String getAttributeLocalName(int index) {
return reader.getAttributeLocalName(index);
}
public String getAttributeNamespace(int index) {
return reader.getAttributeNamespace(index);
}
public String getAttributePrefix(int index) {
return reader.getAttributePrefix(index);
}
public String getAttributeType(int index) {
return reader.getAttributeType(index);
}
public String getAttributeValue(int index) {
return reader.getAttributeValue(index);
}
public String getNamespacePrefix(int index) {
return reader.getNamespacePrefix(index);
}
public String getNamespaceURI(int index) {
return reader.getNamespaceURI(index);
}
public NamespaceContext getNamespaceContext() {
return reader.getNamespaceContext();
}
public QName getName() {
return reader.getName();
}
public QName getAttributeName(int index) {
return reader.getAttributeName(index);
}
public Location getLocation() {
return reader.getLocation();
}
public Object getProperty(String name) throws IllegalArgumentException {
return reader.getProperty(name);
}
public void require(int type, String namespaceURI, String localName) throws XMLStreamException {
reader.require(type, namespaceURI, localName);
}
public String getNamespaceURI(String prefix) {
return reader.getNamespaceURI(prefix);
}
public String getAttributeValue(String namespaceURI, String localName) {
return reader.getAttributeValue(namespaceURI, localName);
}
}

View File

@@ -0,0 +1,265 @@
/*
* 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.util.xml;
import java.io.IOException;
import javax.xml.bind.attachment.AttachmentMarshaller;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.XMLConstants;
import com.sun.xml.internal.ws.streaming.MtomStreamWriter;
import com.sun.xml.internal.org.jvnet.staxex.Base64Data;
import com.sun.xml.internal.org.jvnet.staxex.XMLStreamReaderEx;
import com.sun.xml.internal.org.jvnet.staxex.XMLStreamWriterEx;
/**
* Reads a sub-tree from {@link XMLStreamReader} and writes to {@link XMLStreamWriter}
* as-is.
*
* <p>
* This class can be sub-classed to implement a simple transformation logic.
*
* @author Kohsuke Kawaguchi
* @author Ryan Shoemaker
*/
public class XMLStreamReaderToXMLStreamWriter {
private static final int BUF_SIZE = 4096;
protected XMLStreamReader in;
protected XMLStreamWriter out;
private char[] buf;
boolean optimizeBase64Data = false;
AttachmentMarshaller mtomAttachmentMarshaller;
/**
* Reads one subtree and writes it out.
*
* <p>
* The {@link XMLStreamWriter} never receives a start/end document event.
* Those need to be written separately by the caller.
*/
public void bridge(XMLStreamReader in, XMLStreamWriter out) throws XMLStreamException {
assert in!=null && out!=null;
this.in = in;
this.out = out;
optimizeBase64Data = (in instanceof XMLStreamReaderEx);
if (out instanceof XMLStreamWriterEx && out instanceof MtomStreamWriter) {
mtomAttachmentMarshaller = ((MtomStreamWriter) out).getAttachmentMarshaller();
}
// remembers the nest level of elements to know when we are done.
int depth=0;
buf = new char[BUF_SIZE];
// if the parser is at the start tag, proceed to the first element
int event = in.getEventType();
if(event == XMLStreamConstants.START_DOCUMENT) {
// nextTag doesn't correctly handle DTDs
while( !in.isStartElement() ) {
event = in.next();
if (event == XMLStreamConstants.COMMENT)
handleComment();
}
}
if( event!=XMLStreamConstants.START_ELEMENT)
throw new IllegalStateException("The current event is not START_ELEMENT\n but " + event);
do {
// These are all of the events listed in the javadoc for
// XMLEvent.
// The spec only really describes 11 of them.
switch (event) {
case XMLStreamConstants.START_ELEMENT :
depth++;
handleStartElement();
break;
case XMLStreamConstants.END_ELEMENT :
handleEndElement();
depth--;
if(depth==0)
return;
break;
case XMLStreamConstants.CHARACTERS :
handleCharacters();
break;
case XMLStreamConstants.ENTITY_REFERENCE :
handleEntityReference();
break;
case XMLStreamConstants.PROCESSING_INSTRUCTION :
handlePI();
break;
case XMLStreamConstants.COMMENT :
handleComment();
break;
case XMLStreamConstants.DTD :
handleDTD();
break;
case XMLStreamConstants.CDATA :
handleCDATA();
break;
case XMLStreamConstants.SPACE :
handleSpace();
break;
case XMLStreamConstants.END_DOCUMENT:
throw new XMLStreamException("Malformed XML at depth="+depth+", Reached EOF. Event="+event);
default :
throw new XMLStreamException("Cannot process event: " + event);
}
event=in.next();
} while (depth!=0);
}
protected void handlePI() throws XMLStreamException {
out.writeProcessingInstruction(
in.getPITarget(),
in.getPIData());
}
protected void handleCharacters() throws XMLStreamException {
CharSequence c = null;
if (optimizeBase64Data) {
c = ((XMLStreamReaderEx)in).getPCDATA();
}
if ((c != null) && (c instanceof Base64Data)) {
if (mtomAttachmentMarshaller != null) {
Base64Data b64d = (Base64Data) c;
((XMLStreamWriterEx)out).writeBinary(b64d.getDataHandler());
} else {
try {
((Base64Data)c).writeTo(out);
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
} else {
for (int start=0,read=buf.length; read == buf.length; start+=buf.length) {
read = in.getTextCharacters(start, buf, 0, buf.length);
out.writeCharacters(buf, 0, read);
}
}
}
protected void handleEndElement() throws XMLStreamException {
out.writeEndElement();
}
protected void handleStartElement() throws XMLStreamException {
String nsUri = in.getNamespaceURI();
if(nsUri==null)
out.writeStartElement(in.getLocalName());
else
out.writeStartElement(
fixNull(in.getPrefix()),
in.getLocalName(),
nsUri
);
// start namespace bindings
int nsCount = in.getNamespaceCount();
for (int i = 0; i < nsCount; i++) {
out.writeNamespace(
in.getNamespacePrefix(i),
fixNull(in.getNamespaceURI(i))); // zephyr doesn't like null, I don't know what is correct, so just fix null to "" for now
}
// write attributes
int attCount = in.getAttributeCount();
for (int i = 0; i < attCount; i++) {
handleAttribute(i);
}
}
/**
* Writes out the {@code i}-th attribute of the current element.
*
* <p>
* Used from {@link #handleStartElement()}.
*/
protected void handleAttribute(int i) throws XMLStreamException {
String nsUri = in.getAttributeNamespace(i);
String prefix = in.getAttributePrefix(i);
if (fixNull(nsUri).equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
//Its a namespace decl, ignore as it is already written.
return;
}
if(nsUri==null || prefix == null || prefix.equals("")) {
out.writeAttribute(
in.getAttributeLocalName(i),
in.getAttributeValue(i)
);
} else {
out.writeAttribute(
prefix,
nsUri,
in.getAttributeLocalName(i),
in.getAttributeValue(i)
);
}
}
protected void handleDTD() throws XMLStreamException {
out.writeDTD(in.getText());
}
protected void handleComment() throws XMLStreamException {
out.writeComment(in.getText());
}
protected void handleEntityReference() throws XMLStreamException {
out.writeEntityRef(in.getText());
}
protected void handleSpace() throws XMLStreamException {
handleCharacters();
}
protected void handleCDATA() throws XMLStreamException {
out.writeCData(in.getText());
}
private static String fixNull(String s) {
if(s==null) return "";
else return s;
}
}

View File

@@ -0,0 +1,183 @@
/*
* 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.util.xml;
import com.sun.xml.internal.ws.api.streaming.XMLStreamWriterFactory;
import com.sun.xml.internal.ws.api.streaming.XMLStreamWriterFactory.RecycleAware;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
/**
* {@link XMLStreamWriter} that delegates to another {@link XMLStreamWriter}.
*
* <p>
* This class isn't very useful by itself, but works as a base class
* for {@link XMLStreamWriter} filtering.
*
* @author Kohsuke Kawaguchi
*/
public class XMLStreamWriterFilter implements XMLStreamWriter, RecycleAware {
protected XMLStreamWriter writer;
public XMLStreamWriterFilter(XMLStreamWriter writer) {
this.writer = writer;
}
public void close() throws XMLStreamException {
writer.close();
}
public void flush() throws XMLStreamException {
writer.flush();
}
public void writeEndDocument() throws XMLStreamException {
writer.writeEndDocument();
}
public void writeEndElement() throws XMLStreamException {
writer.writeEndElement();
}
public void writeStartDocument() throws XMLStreamException {
writer.writeStartDocument();
}
public void writeCharacters(char[] text, int start, int len) throws XMLStreamException {
writer.writeCharacters(text, start, len);
}
public void setDefaultNamespace(String uri) throws XMLStreamException {
writer.setDefaultNamespace(uri);
}
public void writeCData(String data) throws XMLStreamException {
writer.writeCData(data);
}
public void writeCharacters(String text) throws XMLStreamException {
writer.writeCharacters(text);
}
public void writeComment(String data) throws XMLStreamException {
writer.writeComment(data);
}
public void writeDTD(String dtd) throws XMLStreamException {
writer.writeDTD(dtd);
}
public void writeDefaultNamespace(String namespaceURI) throws XMLStreamException {
writer.writeDefaultNamespace(namespaceURI);
}
public void writeEmptyElement(String localName) throws XMLStreamException {
writer.writeEmptyElement(localName);
}
public void writeEntityRef(String name) throws XMLStreamException {
writer.writeEntityRef(name);
}
public void writeProcessingInstruction(String target) throws XMLStreamException {
writer.writeProcessingInstruction(target);
}
public void writeStartDocument(String version) throws XMLStreamException {
writer.writeStartDocument(version);
}
public void writeStartElement(String localName) throws XMLStreamException {
writer.writeStartElement(localName);
}
public NamespaceContext getNamespaceContext() {
return writer.getNamespaceContext();
}
public void setNamespaceContext(NamespaceContext context) throws XMLStreamException {
writer.setNamespaceContext(context);
}
public Object getProperty(String name) throws IllegalArgumentException {
return writer.getProperty(name);
}
public String getPrefix(String uri) throws XMLStreamException {
return writer.getPrefix(uri);
}
public void setPrefix(String prefix, String uri) throws XMLStreamException {
writer.setPrefix(prefix, uri);
}
public void writeAttribute(String localName, String value) throws XMLStreamException {
writer.writeAttribute(localName, value);
}
public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
writer.writeEmptyElement(namespaceURI, localName);
}
public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException {
writer.writeNamespace(prefix, namespaceURI);
}
public void writeProcessingInstruction(String target, String data) throws XMLStreamException {
writer.writeProcessingInstruction(target, data);
}
public void writeStartDocument(String encoding, String version) throws XMLStreamException {
writer.writeStartDocument(encoding, version);
}
public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
writer.writeStartElement(namespaceURI, localName);
}
public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException {
writer.writeAttribute(namespaceURI, localName, value);
}
public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
writer.writeEmptyElement(prefix, localName, namespaceURI);
}
public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
writer.writeStartElement(prefix, localName, namespaceURI);
}
public void writeAttribute(String prefix, String namespaceURI, String localName, String value) throws XMLStreamException {
writer.writeAttribute(prefix, namespaceURI, localName, value);
}
public void onRecycled() {
XMLStreamWriterFactory.recycle(writer);
writer = null;
}
}

View File

@@ -0,0 +1,502 @@
/*
* Copyright (c) 1997, 2017, 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.util.xml;
import com.sun.istack.internal.Nullable;
import com.sun.org.apache.xml.internal.resolver.Catalog;
import com.sun.org.apache.xml.internal.resolver.CatalogManager;
import com.sun.org.apache.xml.internal.resolver.tools.CatalogResolver;
import com.sun.xml.internal.ws.server.ServerRtException;
import com.sun.xml.internal.ws.util.ByteArrayBuffer;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.EntityReference;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.*;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;
import javax.xml.ws.WebServiceException;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPathFactoryConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author WS Development Team
*/
public class XmlUtil {
// not in older JDK, so must be duplicated here, otherwise javax.xml.XMLConstants should be used
private static final String ACCESS_EXTERNAL_SCHEMA = "http://javax.xml.XMLConstants/property/accessExternalSchema";
private final static String LEXICAL_HANDLER_PROPERTY =
"http://xml.org/sax/properties/lexical-handler";
private static final String DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
private static final String EXTERNAL_GE = "http://xml.org/sax/features/external-general-entities";
private static final String EXTERNAL_PE = "http://xml.org/sax/features/external-parameter-entities";
private static final String LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
private static final Logger LOGGER = Logger.getLogger(XmlUtil.class.getName());
private static final String DISABLE_XML_SECURITY = "com.sun.xml.internal.ws.disableXmlSecurity";
private static boolean XML_SECURITY_DISABLED = AccessController.doPrivileged(
new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return Boolean.getBoolean(DISABLE_XML_SECURITY);
}
}
);
public static String getPrefix(String s) {
int i = s.indexOf(':');
if (i == -1)
return null;
return s.substring(0, i);
}
public static String getLocalPart(String s) {
int i = s.indexOf(':');
if (i == -1)
return s;
return s.substring(i + 1);
}
public static String getAttributeOrNull(Element e, String name) {
Attr a = e.getAttributeNode(name);
if (a == null)
return null;
return a.getValue();
}
public static String getAttributeNSOrNull(
Element e,
String name,
String nsURI) {
Attr a = e.getAttributeNodeNS(nsURI, name);
if (a == null)
return null;
return a.getValue();
}
public static String getAttributeNSOrNull(
Element e,
QName name) {
Attr a = e.getAttributeNodeNS(name.getNamespaceURI(), name.getLocalPart());
if (a == null)
return null;
return a.getValue();
}
/* public static boolean matchesTagNS(Element e, String tag, String nsURI) {
try {
return e.getLocalName().equals(tag)
&& e.getNamespaceURI().equals(nsURI);
} catch (NullPointerException npe) {
// localname not null since parsing would fail before here
throw new WSDLParseException(
"null.namespace.found",
e.getLocalName());
}
}
public static boolean matchesTagNS(
Element e,
javax.xml.namespace.QName name) {
try {
return e.getLocalName().equals(name.getLocalPart())
&& e.getNamespaceURI().equals(name.getNamespaceURI());
} catch (NullPointerException npe) {
// localname not null since parsing would fail before here
throw new WSDLParseException(
"null.namespace.found",
e.getLocalName());
}
}*/
public static Iterator getAllChildren(Element element) {
return new NodeListIterator(element.getChildNodes());
}
public static Iterator getAllAttributes(Element element) {
return new NamedNodeMapIterator(element.getAttributes());
}
public static List<String> parseTokenList(String tokenList) {
List<String> result = new ArrayList<String>();
StringTokenizer tokenizer = new StringTokenizer(tokenList, " ");
while (tokenizer.hasMoreTokens()) {
result.add(tokenizer.nextToken());
}
return result;
}
public static String getTextForNode(Node node) {
StringBuilder sb = new StringBuilder();
NodeList children = node.getChildNodes();
if (children.getLength() == 0)
return null;
for (int i = 0; i < children.getLength(); ++i) {
Node n = children.item(i);
if (n instanceof Text)
sb.append(n.getNodeValue());
else if (n instanceof EntityReference) {
String s = getTextForNode(n);
if (s == null)
return null;
else
sb.append(s);
} else
return null;
}
return sb.toString();
}
public static InputStream getUTF8Stream(String s) {
try {
ByteArrayBuffer bab = new ByteArrayBuffer();
Writer w = new OutputStreamWriter(bab, "utf-8");
w.write(s);
w.close();
return bab.newInputStream();
} catch (IOException e) {
throw new RuntimeException("should not happen");
}
}
static final ContextClassloaderLocal<TransformerFactory> transformerFactory = new ContextClassloaderLocal<TransformerFactory>() {
@Override
protected TransformerFactory initialValue() throws Exception {
return TransformerFactory.newInstance();
}
};
static final ContextClassloaderLocal<SAXParserFactory> saxParserFactory = new ContextClassloaderLocal<SAXParserFactory>() {
@Override
protected SAXParserFactory initialValue() throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
return factory;
}
};
/**
* Creates a new identity transformer.
*/
public static Transformer newTransformer() {
try {
return transformerFactory.get().newTransformer();
} catch (TransformerConfigurationException tex) {
throw new IllegalStateException("Unable to create a JAXP transformer");
}
}
/**
* Performs identity transformation.
*/
public static <T extends Result>
T identityTransform(Source src, T result) throws TransformerException, SAXException, ParserConfigurationException, IOException {
if (src instanceof StreamSource) {
// work around a bug in JAXP in JDK6u4 and earlier where the namespace processing
// is not turned on by default
StreamSource ssrc = (StreamSource) src;
TransformerHandler th = ((SAXTransformerFactory) transformerFactory.get()).newTransformerHandler();
th.setResult(result);
XMLReader reader = saxParserFactory.get().newSAXParser().getXMLReader();
reader.setContentHandler(th);
reader.setProperty(LEXICAL_HANDLER_PROPERTY, th);
reader.parse(toInputSource(ssrc));
} else {
newTransformer().transform(src, result);
}
return result;
}
private static InputSource toInputSource(StreamSource src) {
InputSource is = new InputSource();
is.setByteStream(src.getInputStream());
is.setCharacterStream(src.getReader());
is.setPublicId(src.getPublicId());
is.setSystemId(src.getSystemId());
return is;
}
/*
* Gets an EntityResolver using XML catalog
*/
public static EntityResolver createEntityResolver(@Nullable URL catalogUrl) {
// set up a manager
CatalogManager manager = new CatalogManager();
manager.setIgnoreMissingProperties(true);
// Using static catalog may result in to sharing of the catalog by multiple apps running in a container
manager.setUseStaticCatalog(false);
Catalog catalog = manager.getCatalog();
try {
if (catalogUrl != null) {
catalog.parseCatalog(catalogUrl);
}
} catch (IOException e) {
throw new ServerRtException("server.rt.err",e);
}
return workaroundCatalogResolver(catalog);
}
/**
* Gets a default EntityResolver for catalog at META-INF/jaxws-catalog.xml
*/
public static EntityResolver createDefaultCatalogResolver() {
// set up a manager
CatalogManager manager = new CatalogManager();
manager.setIgnoreMissingProperties(true);
// Using static catalog may result in to sharing of the catalog by multiple apps running in a container
manager.setUseStaticCatalog(false);
// parse the catalog
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Enumeration<URL> catalogEnum;
Catalog catalog = manager.getCatalog();
try {
if (cl == null) {
catalogEnum = ClassLoader.getSystemResources("META-INF/jax-ws-catalog.xml");
} else {
catalogEnum = cl.getResources("META-INF/jax-ws-catalog.xml");
}
while(catalogEnum.hasMoreElements()) {
URL url = catalogEnum.nextElement();
catalog.parseCatalog(url);
}
} catch (IOException e) {
throw new WebServiceException(e);
}
return workaroundCatalogResolver(catalog);
}
/**
* Default CatalogResolver implementation is broken as it depends on CatalogManager.getCatalog() which will always create a new one when
* useStaticCatalog is false.
* This returns a CatalogResolver that uses the catalog passed as parameter.
* @param catalog
* @return CatalogResolver
*/
private static CatalogResolver workaroundCatalogResolver(final Catalog catalog) {
// set up a manager
CatalogManager manager = new CatalogManager() {
@Override
public Catalog getCatalog() {
return catalog;
}
};
manager.setIgnoreMissingProperties(true);
// Using static catalog may result in to sharing of the catalog by multiple apps running in a container
manager.setUseStaticCatalog(false);
return new CatalogResolver(manager);
}
/**
* {@link ErrorHandler} that always treat the error as fatal.
*/
public static final ErrorHandler DRACONIAN_ERROR_HANDLER = new ErrorHandler() {
@Override
public void warning(SAXParseException exception) {
}
@Override
public void error(SAXParseException exception) throws SAXException {
throw exception;
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
throw exception;
}
};
public static DocumentBuilderFactory newDocumentBuilderFactory() {
return newDocumentBuilderFactory(false);
}
public static DocumentBuilderFactory newDocumentBuilderFactory(boolean disableSecurity) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
String featureToSet = XMLConstants.FEATURE_SECURE_PROCESSING;
try {
boolean securityOn = !isXMLSecurityDisabled(disableSecurity);
factory.setFeature(featureToSet, securityOn);
factory.setNamespaceAware(true);
if (securityOn) {
factory.setExpandEntityReferences(false);
featureToSet = DISALLOW_DOCTYPE_DECL;
factory.setFeature(featureToSet, true);
featureToSet = EXTERNAL_GE;
factory.setFeature(featureToSet, false);
featureToSet = EXTERNAL_PE;
factory.setFeature(featureToSet, false);
featureToSet = LOAD_EXTERNAL_DTD;
factory.setFeature(featureToSet, false);
}
} catch (ParserConfigurationException e) {
LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support "+featureToSet+" feature!", new Object[] {factory.getClass().getName()} );
}
return factory;
}
public static TransformerFactory newTransformerFactory(boolean secureXmlProcessingEnabled) {
TransformerFactory factory = TransformerFactory.newInstance();
try {
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, isXMLSecurityDisabled(secureXmlProcessingEnabled));
} catch (TransformerConfigurationException e) {
LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[]{factory.getClass().getName()});
}
return factory;
}
public static TransformerFactory newTransformerFactory() {
return newTransformerFactory(true);
}
public static SAXParserFactory newSAXParserFactory(boolean disableSecurity) {
SAXParserFactory factory = SAXParserFactory.newInstance();
String featureToSet = XMLConstants.FEATURE_SECURE_PROCESSING;
try {
boolean securityOn = !isXMLSecurityDisabled(disableSecurity);
factory.setFeature(featureToSet, securityOn);
factory.setNamespaceAware(true);
if (securityOn) {
featureToSet = DISALLOW_DOCTYPE_DECL;
factory.setFeature(featureToSet, true);
featureToSet = EXTERNAL_GE;
factory.setFeature(featureToSet, false);
featureToSet = EXTERNAL_PE;
factory.setFeature(featureToSet, false);
featureToSet = LOAD_EXTERNAL_DTD;
factory.setFeature(featureToSet, false);
}
} catch (ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) {
LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support "+featureToSet+" feature!", new Object[]{factory.getClass().getName()});
}
return factory;
}
public static XPathFactory newXPathFactory(boolean secureXmlProcessingEnabled) {
XPathFactory factory = XPathFactory.newInstance();
try {
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, isXMLSecurityDisabled(secureXmlProcessingEnabled));
} catch (XPathFactoryConfigurationException e) {
LOGGER.log(Level.WARNING, "Factory [{0}] doesn't support secure xml processing!", new Object[] { factory.getClass().getName() } );
}
return factory;
}
public static XMLInputFactory newXMLInputFactory(boolean secureXmlProcessingEnabled) {
XMLInputFactory factory = XMLInputFactory.newInstance();
if (isXMLSecurityDisabled(secureXmlProcessingEnabled)) {
// TODO-Miran: are those apppropriate defaults?
factory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
}
return factory;
}
private static boolean isXMLSecurityDisabled(boolean runtimeDisabled) {
return XML_SECURITY_DISABLED || runtimeDisabled;
}
public static SchemaFactory allowExternalAccess(SchemaFactory sf, String value, boolean disableSecureProcessing) {
// if xml security (feature secure processing) disabled, nothing to do, no restrictions applied
if (isXMLSecurityDisabled(disableSecureProcessing)) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Xml Security disabled, no JAXP xsd external access configuration necessary.");
}
return sf;
}
if (System.getProperty("javax.xml.accessExternalSchema") != null) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Detected explicitly JAXP configuration, no JAXP xsd external access configuration necessary.");
}
return sf;
}
try {
sf.setProperty(ACCESS_EXTERNAL_SCHEMA, value);
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Property \"{0}\" is supported and has been successfully set by used JAXP implementation.", new Object[]{ACCESS_EXTERNAL_SCHEMA});
}
} catch (SAXException ignored) {
// nothing to do; support depends on version JDK or SAX implementation
if (LOGGER.isLoggable(Level.CONFIG)) {
LOGGER.log(Level.CONFIG, "Property \"{0}\" is not supported by used JAXP implementation.", new Object[]{ACCESS_EXTERNAL_SCHEMA});
}
}
return sf;
}
}