org.jboss.marshalling.Marshalling Maven / Gradle / Ivy
Go to download
This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including
all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and
JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up
with different versions on classes on the class path).
/*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.marshalling;
import static java.lang.System.getSecurityManager;
import static java.security.AccessController.doPrivileged;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.EOFException;
import java.io.OptionalDataException;
import java.io.StreamCorruptedException;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.ServiceLoader;
import sun.reflect.ReflectionFactory;
/**
* Static utility methods for simplifying use of marshallers.
* @apiviz.landmark
*/
public final class Marshalling {
private Marshalling() {
}
/**
* Get a marshaller factory, by name. Uses the thread's current context classloader, if available, to locate
* the factory.
*
* @param name the name of the protocol to acquire
* @return the marshaller factory, or {@code null} if no matching factory was found
*
* @see ServiceLoader
*
* @deprecated It is recommended that you use {@link #getProvidedMarshallerFactory(String)} instead; using the context
* class loader to find a marshalling implementation is risky at best as the user may have just about anything on their
* class path.
*/
@Deprecated
public static MarshallerFactory getMarshallerFactory(final String name) {
if (getSecurityManager() == null) {
return loadMarshallerFactory(ServiceLoader.load(ProviderDescriptor.class), name);
} else {
return loadMarshallerFactory(doPrivileged(new PrivilegedAction>() {
public ServiceLoader run() {
return ServiceLoader.load(ProviderDescriptor.class);
}
}), name);
}
}
/**
* Get a marshaller factory, by name. Uses the given classloader to locate
* the factory.
*
* @param name the name of the protocol to acquire
* @param classLoader the class loader to use
* @return the marshaller factory, or {@code null} if no matching factory was found
*
* @see ServiceLoader
*/
public static MarshallerFactory getMarshallerFactory(final String name, final ClassLoader classLoader) {
if (getSecurityManager() == null) {
return loadMarshallerFactory(ServiceLoader.load(ProviderDescriptor.class, classLoader), name);
} else {
return loadMarshallerFactory(doPrivileged(new PrivilegedAction>() {
public ServiceLoader run() {
return ServiceLoader.load(ProviderDescriptor.class, classLoader);
}
}), name);
}
}
/**
* Get a marshaller factory which is visible to this implementation, by name. Uses the class loader of this API.
*
* @param name the name of the protocol to acquire
* @return the marshaller factory, or {@code null} if no matching factory was found
*/
public static MarshallerFactory getProvidedMarshallerFactory(final String name) {
if (getSecurityManager() == null) {
return loadMarshallerFactory(ServiceLoader.load(ProviderDescriptor.class, Marshalling.class.getClassLoader()), name);
} else {
return loadMarshallerFactory(doPrivileged(new PrivilegedAction>() {
public ServiceLoader run() {
return ServiceLoader.load(ProviderDescriptor.class, Marshalling.class.getClassLoader());
}
}), name);
}
}
private static MarshallerFactory loadMarshallerFactory(ServiceLoader loader, String name) {
for (ProviderDescriptor descriptor : loader) {
if (name.equals(descriptor.getName())) {
return descriptor.getMarshallerFactory();
}
}
return null;
}
private static final StreamHeader NULL_STREAM_HEADER = new StreamHeader() {
public void readHeader(final ByteInput input) throws IOException {
}
public void writeHeader(final ByteOutput output) throws IOException {
}
public String toString() {
return "Null StreamHeader";
}
};
/**
* Get the default stream header producer, which reads and writes no header at all.
*
* @return the default stream header producer
*/
public static StreamHeader nullStreamHeader() {
return NULL_STREAM_HEADER;
}
/**
* Create a stream header that uses the given bytes.
*
* @param headerBytes the header bytes
* @return the stream header object
*/
public static StreamHeader streamHeader(final byte[] headerBytes) {
return new StaticStreamHeader(headerBytes);
}
private static final class StaticStreamHeader implements StreamHeader, Serializable {
private final byte[] headerBytes;
private static final long serialVersionUID = 8465784729867667872L;
public StaticStreamHeader(final byte[] bytes) {
headerBytes = bytes;
}
public void readHeader(final ByteInput input) throws IOException {
final byte[] buf = new byte[headerBytes.length];
readFully(input, buf);
if (! Arrays.equals(buf, headerBytes)) {
throw new StreamCorruptedException("Header is incorrect (expected " + Arrays.toString(headerBytes) + ", got " + Arrays.toString(buf) + ")");
}
}
public void writeHeader(final ByteOutput output) throws IOException {
output.write(headerBytes);
}
public String toString() {
return "static StreamHeader@" + Integer.toHexString(hashCode()) + " (" + headerBytes.length + " bytes)";
}
}
/**
* Read bytes from a {@code ByteInput}. Fully fills in the array.
*
* @param input the input
* @param dest the destination
* @throws EOFException if the end of file is reached before the array is filled
* @throws IOException if an I/O error occurs
*/
public static void readFully(ByteInput input, byte[] dest) throws IOException {
readFully(input, dest, 0, dest.length);
}
/**
* Read bytes from a {@code ByteInput}. Fully fills in {@code len} bytes in the array.
*
* @param input the input
* @param dest the destination
* @param offs the offset into the array
* @param len the number of bytes
* @throws EOFException if the end of file is reached before the array is filled
* @throws IOException if an I/O error occurs
*/
public static void readFully(ByteInput input, byte[] dest, int offs, int len) throws IOException {
while (len > 0) {
final int r = input.read(dest, offs, len);
if (r == -1) {
throw new EOFException();
}
len -= r;
offs += r;
}
}
/**
* Create a {@code ByteInput} wrapper for a {@code ByteBuffer}.
*
* @param buffer the byte buffer
* @return the byte input wrapper
*/
public static ByteInput createByteInput(final ByteBuffer buffer) {
return new ByteBufferInput(buffer);
}
/**
* Create a {@code ByteInput} wrapper for an {@code InputStream}.
*
* @param inputStream the input stream
* @return the byte input wrapper
*/
public static ByteInput createByteInput(final InputStream inputStream) {
return inputStream instanceof ByteInput ? (ByteInput) inputStream : new InputStreamByteInput(inputStream);
}
/**
* Create an {@code InputStream} wrapper for a {@code ByteInput}.
*
* @param byteInput the byte input
* @return the input stream wrapper
*/
public static InputStream createInputStream(final ByteInput byteInput) {
return byteInput instanceof InputStream ? (InputStream) byteInput : new ByteInputStream(byteInput);
}
/**
* Create a {@code ByteOutput} wrapper for a {@code ByteBuffer}.
*
* @param buffer the byte buffer
* @return the byte output wrapper
*/
public static ByteOutput createByteOutput(final ByteBuffer buffer) {
return new ByteBufferOutput(buffer);
}
/**
* Create a {@code ByteOutput} wrapper for an {@code OutputStream}.
*
* @param outputStream the output stream
* @return the byte output wrapper
*/
public static ByteOutput createByteOutput(final OutputStream outputStream) {
return outputStream instanceof ByteOutput ? (ByteOutput) outputStream : new OutputStreamByteOutput(outputStream);
}
/**
* Create a {@code OutputStream} wrapper for a {@code ByteOutput}.
*
* @param byteOutput the byte output
* @return the output stream wrapper
*/
public static OutputStream createOutputStream(final ByteOutput byteOutput) {
return byteOutput instanceof OutputStream ? (OutputStream)byteOutput : new ByteOutputStream(byteOutput);
}
private static final ClassExternalizerFactory NULL_CLASS_EXTERNALIZER_FACTORY = new ClassExternalizerFactory() {
public Externalizer getExternalizer(final Class> type) {
return null;
}
public String toString() {
return "Null class externalizer factory";
}
};
/**
* Return the null class externalizer factory. This instance does not externalize any classes.
*
* @return the null class externalizer factory
*/
public static ClassExternalizerFactory nullClassExternalizerFactory() {
return NULL_CLASS_EXTERNALIZER_FACTORY;
}
private static final ObjectResolver NULL_OBJECT_RESOLVER = new ObjectResolver() {
public Object readResolve(final Object replacement) {
return replacement;
}
public Object writeReplace(final Object original) {
return original;
}
public String toString() {
return "Null object resolver";
}
};
/**
* Return the null object resolver. This instance does not translate objects in any way.
*
* @return the null object resolver
*/
public static ObjectResolver nullObjectResolver() {
return NULL_OBJECT_RESOLVER;
}
private static final ObjectTable NULL_OBJECT_TABLE = new ObjectTable() {
public Writer getObjectWriter(final Object object) {
return null;
}
public Object readObject(final Unmarshaller unmarshaller) throws IOException, ClassNotFoundException {
return null;
}
public String toString() {
return "Null object table";
}
};
/**
* Return the null object instance table. This instance contains no predefined instances.
*
* @return the null instance table
*/
public static ObjectTable nullObjectTable() {
return NULL_OBJECT_TABLE;
}
private static final ClassTable NULL_CLASS_TABLE = new ClassTable() {
public Writer getClassWriter(final Class> clazz) {
return null;
}
public Class> readClass(final Unmarshaller unmarshaller) throws IOException, ClassNotFoundException {
return null;
}
public String toString() {
return "Null class table";
}
};
/**
* Return the null class table instance. This instance contains no predefined classes.
*
* @return the null class table
*/
public static ClassTable nullClassTable() {
return NULL_CLASS_TABLE;
}
private static final ReflectionFactory reflectionFactory = doPrivileged((PrivilegedAction) ReflectionFactory::getReflectionFactory);
/**
* Construct a new {@link java.io.OptionalDataException}. This method is necessary because there are no
* public constructors in the API.
*
* @param eof {@code true} if there is no more data in the buffered part of the stream
* @return a new OptionalDataException
*/
public static OptionalDataException createOptionalDataException(boolean eof) {
return reflectionFactory.newOptionalDataExceptionForSerialization(eof);
}
/**
* Construct a new {@link java.io.OptionalDataException}. This method is necessary because there are no
* public constructors in the API.
*
* @param length the number of bytes of primitive data available to be read in the current buffer
* @return a new OptionalDataException
*/
public static OptionalDataException createOptionalDataException(int length) {
final OptionalDataException optionalDataException = createOptionalDataException(false);
optionalDataException.length = length;
return optionalDataException;
}
}