/* * 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.api.streaming; import com.sun.istack.internal.NotNull; import com.sun.istack.internal.Nullable; import com.sun.xml.internal.ws.encoding.HasEncoding; import com.sun.xml.internal.ws.encoding.SOAPBindingCodec; import com.sun.xml.internal.ws.streaming.XMLReaderException; import com.sun.xml.internal.ws.util.MrJarUtil; import com.sun.xml.internal.ws.util.xml.XMLStreamWriterFilter; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import javax.xml.transform.stream.StreamResult; import javax.xml.ws.WebServiceException; import java.io.OutputStream; import java.io.StringWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.logging.Level; import java.util.logging.Logger; /** * Factory for {@link XMLStreamWriter}. * *
* This wraps {@link XMLOutputFactory} and allows us to reuse {@link XMLStreamWriter} instances
* when appropriate.
*
* @author Kohsuke Kawaguchi
*/
@SuppressWarnings("StaticNonFinalUsedInInitialization")
public abstract class XMLStreamWriterFactory {
private static final Logger LOGGER = Logger.getLogger(XMLStreamWriterFactory.class.getName());
/**
* Singleton instance.
*/
private static volatile ContextClassloaderLocal
* If the recycled instance implements {@link RecycleAware},
* {@link RecycleAware#onRecycled()} will be invoked to let the instance
* know that it's being recycled.
*
*
* It is not a hard requirement to call this method on every {@link XMLStreamReader}
* instance. Not doing so just reduces the performance by throwing away
* possibly reusable instances. So the caller should always consider the effort
* it takes to recycle vs the possible performance gain by doing so.
*
*
* This method may be invked by multiple threads concurrently.
*
* @param r
* The {@link XMLStreamReader} instance that the caller finished using.
* This could be any {@link XMLStreamReader} implementation, not just
* the ones that were created from this factory. So the implementation
* of this class needs to be aware of that.
*/
public static void recycle(XMLStreamWriter r) {
get().doRecycle(r);
}
/**
* Interface that can be implemented by {@link XMLStreamWriter} to
* be notified when it's recycled.
*
*
* This provides a filtering {@link XMLStreamWriter} an opportunity to
* recycle its inner {@link XMLStreamWriter}.
*/
public interface RecycleAware {
void onRecycled();
}
/**
* Gets the singleton instance.
*/
public static @NotNull XMLStreamWriterFactory get() {
return writerFactory.get();
}
/**
* Overrides the singleton {@link XMLStreamWriterFactory} instance that
* the JAX-WS RI uses.
*
* @param f
* must not be null.
*/
@SuppressWarnings({"null", "ConstantConditions"})
public static void set(@NotNull XMLStreamWriterFactory f) {
if(f==null) throw new IllegalArgumentException();
writerFactory.set(f);
}
/**
* Short-cut for {@link #create(OutputStream, String)} with UTF-8.
*/
public static XMLStreamWriter create(OutputStream out) {
return get().doCreate(out);
}
public static XMLStreamWriter create(OutputStream out, String encoding) {
return get().doCreate(out, encoding);
}
/**
* @deprecated
* Use {@link #create(OutputStream)}
*/
public static XMLStreamWriter createXMLStreamWriter(OutputStream out) {
return create(out);
}
/**
* @deprecated
* Use {@link #create(OutputStream, String)}
*/
public static XMLStreamWriter createXMLStreamWriter(OutputStream out, String encoding) {
return create(out, encoding);
}
/**
* @deprecated
* Use {@link #create(OutputStream, String)}. The boolean flag was unused anyway.
*/
public static XMLStreamWriter createXMLStreamWriter(OutputStream out, String encoding, boolean declare) {
return create(out,encoding);
}
/**
* Default {@link XMLStreamWriterFactory} implementation
* that can work with any {@link XMLOutputFactory}.
*
*
* {@link XMLOutputFactory} is not required to be thread-safe, so the
* create method on this implementation is synchronized.
*/
public static final class Default extends XMLStreamWriterFactory {
private final XMLOutputFactory xof;
public Default(XMLOutputFactory xof) {
this.xof = xof;
}
@Override
public XMLStreamWriter doCreate(OutputStream out) {
return doCreate(out,"UTF-8");
}
@Override
public synchronized XMLStreamWriter doCreate(OutputStream out, String encoding) {
try {
XMLStreamWriter writer = xof.createXMLStreamWriter(out,encoding);
return new HasEncodingWriter(writer, encoding);
} catch (XMLStreamException e) {
throw new XMLReaderException("stax.cantCreate",e);
}
}
@Override
public void doRecycle(XMLStreamWriter r) {
// no recycling
}
}
/**
* {@link XMLStreamWriterFactory} implementation for Sun's StaX implementation.
*
*
* This implementation supports instance reuse.
*/
public static final class Zephyr extends XMLStreamWriterFactory {
private final XMLOutputFactory xof;
private final ThreadLocal