All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.marshalling.AbstractUnmarshaller 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).

The newest version!
/*
 * 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 java.io.IOException;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * An abstract implementation of the {@code Unmarshaller} interface.  Most of the
 * write methods delegate directly to the current data output.
 */
public abstract class AbstractUnmarshaller extends AbstractObjectInput implements Unmarshaller {

    private static final Logger LOG = Logger.getLogger(AbstractUnmarshaller.class.getName());
    /** The configured class externalizer factory. */
    protected final ClassExternalizerFactory classExternalizerFactory;
    /** The configured stream header. */
    protected final StreamHeader streamHeader;
    /** The configured class resolver. */
    protected final ClassResolver classResolver;
    /** The configured object resolver. */
    protected final ObjectResolver objectResolver;
    /** The configured object pre resolver. */
    protected final ObjectResolver objectPreResolver;
    /** The configured class table. */
    protected final ClassTable classTable;
    /** The configured object table. */
    protected final ObjectTable objectTable;
    /** The configured exception listener. */
    protected final ExceptionListener exceptionListener;
    /** The configured serializability checker. */
    protected final SerializabilityChecker serializabilityChecker;
    /** The configured unmarshalling filter */
    protected final UnmarshallingObjectInputFilter unmarshallingFilter;
    /** The configured version. */
    protected final int configuredVersion;

    /**
     * Construct a new unmarshaller instance.
     *
     * @param marshallerFactory the marshaller factory
     * @param configuration
     */
    protected AbstractUnmarshaller(final AbstractMarshallerFactory marshallerFactory, final MarshallingConfiguration configuration) {
        super(configuration.getBufferSize());
        final ClassExternalizerFactory classExternalizerFactory = configuration.getClassExternalizerFactory();
        this.classExternalizerFactory = classExternalizerFactory == null ? marshallerFactory.getDefaultClassExternalizerFactory() : classExternalizerFactory;
        final StreamHeader streamHeader = configuration.getStreamHeader();
        this.streamHeader = streamHeader == null ? marshallerFactory.getDefaultStreamHeader() : streamHeader;
        final ClassResolver classResolver = configuration.getClassResolver();
        final ClassNameTransformer classNameTransformer = configuration.getClassNameTransformer();
        if (classNameTransformer != null) {
            this.classResolver = new TransformingClassResolver(classResolver == null ? marshallerFactory.getDefaultClassResolver() : classResolver, classNameTransformer, true);
        } else {
            this.classResolver = classResolver == null ? marshallerFactory.getDefaultClassResolver() : classResolver;
        }
        final ObjectResolver objectResolver = configuration.getObjectResolver();
        this.objectResolver = objectResolver == null ? marshallerFactory.getDefaultObjectResolver() : objectResolver;
        final ObjectResolver objectPreResolver = configuration.getObjectPreResolver();
        this.objectPreResolver = objectPreResolver == null ? marshallerFactory.getDefaultObjectResolver() : objectPreResolver;
        final ClassTable classTable = configuration.getClassTable();
        this.classTable = classTable == null ? marshallerFactory.getDefaultClassTable() : classTable;
        final ObjectTable objectTable = configuration.getObjectTable();
        this.objectTable = objectTable == null ? marshallerFactory.getDefaultObjectTable() : objectTable;
        final ExceptionListener exceptionListener = configuration.getExceptionListener();
        this.exceptionListener = exceptionListener == null ? ExceptionListener.NO_OP : exceptionListener;
        final SerializabilityChecker serializabilityChecker = configuration.getSerializabilityChecker();
        this.serializabilityChecker = serializabilityChecker == null ? SerializabilityChecker.DEFAULT : serializabilityChecker;
        final UnmarshallingObjectInputFilter unmarshallingFilter = configuration.getUnmarshallingFilter();
        this.unmarshallingFilter = unmarshallingFilter == null ? UnmarshallingObjectInputFilter.ACCEPTING : unmarshallingFilter;
        final int configuredVersion = configuration.getVersion();
        this.configuredVersion = configuredVersion == -1 ? marshallerFactory.getDefaultVersion() : configuredVersion;
    }

    /** {@inheritDoc} */
    public void start(final ByteInput byteInput) throws IOException {
        this.byteInput = byteInput;
        position = limit = 0;
        streamHeader.readHeader(this);
    }

    /** {@inheritDoc} */
    public void finish() throws IOException {
        limit = -1;
        position = 0;
        byteInput = null;
        clearClassCache();
    }

    protected final void filterCheck(final Class unmarshallClass, final long arrayLength, final long depth,
                                final long references, final long streamBytes) throws InvalidClassException {
        if (unmarshallingFilter != UnmarshallingObjectInputFilter.ACCEPTING) {
            UnmarshallingObjectInputFilter.FilterInfo filterInfo = new FilterInfoImpl(unmarshallClass, arrayLength, depth, references, streamBytes);
            UnmarshallingObjectInputFilter.Status status = null;
            RuntimeException ex = null;
            try {
                status = unmarshallingFilter.checkInput(filterInfo);
            } catch (RuntimeException re) {
                ex = re;
                InvalidClassException ice = new InvalidClassException(String.format("Filtering failed for %s", filterInfo));
                ice.initCause(re);
                throw ice;
            } finally {
                Logging.logFilterResponse(filterInfo, status, ex);
            }

            if (status == UnmarshallingObjectInputFilter.Status.REJECTED) {
                throw new InvalidClassException(String.format("Filtering rejected %s", filterInfo));
            }
        }
    }

    /**
     * Creates an ObjectInputFilter adapter to given UnmarshallingFilter, and sets the filter to given
     * ObjectInputStream.
     * 

* This essentially delegates the filtering functionality to underlying ObjectInputStream. * * @param ois ObjectInputStream instance to set the filter to. * @param unmarshallingFilter UnmarshallingObjectInputFilter instance to delegate filtering decisions to. */ protected static void setObjectInputStreamFilter(ObjectInputStream ois, UnmarshallingObjectInputFilter unmarshallingFilter) { LOG.finer(String.format("Setting UnmarshallingFilter %s to ObjectInputStream %s", unmarshallingFilter, ois)); ois.setObjectInputFilter(new ObjectInputFilterAdapter(unmarshallingFilter)); } private static class FilterInfoImpl implements UnmarshallingObjectInputFilter.FilterInfo { private final Class unmarshallClass; private final long arrayLength; private final long depth; private final long references; private final long streamBytes; private FilterInfoImpl(final Class unmarshallClass, final long arrayLength, final long depth, final long references, final long streamBytes) { this.unmarshallClass = unmarshallClass; this.arrayLength = arrayLength; this.depth = depth; this.references = references; this.streamBytes = streamBytes; } @Override public Class getUnmarshalledClass() { return unmarshallClass; } @Override public long getArrayLength() { return arrayLength; } @Override public long getDepth() { return depth; } @Override public long getReferences() { return references; } @Override public long getStreamBytes() { return streamBytes; } @Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append(super.toString()).append(": "); if (unmarshallClass != null) { builder.append("unmarshallClass=<").append(unmarshallClass.toString()).append("> "); } builder.append("arrayLength=<").append(arrayLength).append("> "); builder.append("depth=<").append(depth).append("> "); builder.append("references=<").append(references).append("> "); builder.append("streamBytes=<").append(streamBytes).append("> "); return builder.toString(); } } private static class Logging { static final Logger marshallingLogger = Logger.getLogger("org.jboss.marshalling"); private static void logFilterResponse(final UnmarshallingObjectInputFilter.FilterInfo filterInfo, final UnmarshallingObjectInputFilter.Status status, final RuntimeException ex) { // Replicate logging message format from native deserialization filtering mechanism, except that the // logger name is "org.jboss.marshalling" instead of "java.io.serialization". if (status == null || status == UnmarshallingObjectInputFilter.Status.REJECTED) { logFilterResponse(filterInfo, status, ex, Level.FINER); } else { logFilterResponse(filterInfo, status, ex, Level.FINEST); } } private static void logFilterResponse(final UnmarshallingObjectInputFilter.FilterInfo filterInfo, final UnmarshallingObjectInputFilter.Status status, final RuntimeException ex, final Level level) { if (marshallingLogger.isLoggable(level)) { String message = String.format("UnmarshallingFilter %s: %s, array length: %d, nRefs: %d, depth: %d, bytes: %d, ex: %s", status, filterInfo.getUnmarshalledClass(), filterInfo.getArrayLength(), filterInfo.getReferences(), filterInfo.getDepth(), filterInfo.getStreamBytes(), Objects.toString(ex, "n/a")); if (Level.FINEST.equals(level)) { marshallingLogger.log(level, message, ex); } else { marshallingLogger.log(level, message); } } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy