View Javadoc

1   package com.atlassian.vcache.marshallers;
2   
3   import com.atlassian.annotations.Internal;
4   import com.atlassian.vcache.Marshaller;
5   import com.atlassian.vcache.MarshallerException;
6   
7   import java.io.ByteArrayInputStream;
8   import java.io.ByteArrayOutputStream;
9   import java.io.IOException;
10  import java.io.InputStream;
11  import java.io.ObjectInputStream;
12  import java.io.ObjectOutputStream;
13  import java.io.ObjectStreamClass;
14  import java.io.Serializable;
15  import java.util.Optional;
16  
17  import static java.util.Objects.requireNonNull;
18  
19  /**
20   * Implementation for {@link Serializable} objects that uses the standard Java Serialization mechanism. Any
21   * IOExceptions are wrapped as {@link MarshallerException}s.
22   *
23   * @param <T> the type being marshalled
24   * @since 1.0
25   * @deprecated since 1.5.0. Use the Atlassian Marshalling API and implementations instead.
26   */
27  @Internal
28  @Deprecated
29  class JavaSerializationMarshaller<T extends Serializable> implements Marshaller<T> {
30      private final Class<T> clazz;
31      private final Optional<ClassLoader> loader;
32  
33      /**
34       * Creates an instance that uses the default implementation of
35       * {@link java.io.ObjectInputStream#resolveClass(ObjectStreamClass)} to resolve {@link Class} objects.
36       */
37      JavaSerializationMarshaller(Class<T> clazz) {
38          this.clazz = requireNonNull(clazz);
39          this.loader = Optional.empty();
40      }
41  
42      /**
43       * Creates an instance that uses the supplied {@link ClassLoader} to resolve
44       * {@link Class} objects.
45       */
46      JavaSerializationMarshaller(Class<T> clazz, ClassLoader loader) {
47          this.clazz = requireNonNull(clazz);
48          this.loader = Optional.of(loader);
49      }
50  
51      @Override
52      public byte[] marshall(T obj) throws MarshallerException {
53          final ByteArrayOutputStream baos = new ByteArrayOutputStream();
54  
55          try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
56              oos.writeObject(obj);
57          } catch (IOException ioe) {
58              throw new MarshallerException("Unable to marshall", ioe);
59          }
60  
61          return baos.toByteArray();
62      }
63  
64      @Override
65      public T unmarshall(byte[] raw) throws MarshallerException {
66          final ByteArrayInputStream bais = new ByteArrayInputStream(raw);
67  
68          try (ObjectInputStream ois = createObjectInputStream(bais)) {
69              return clazz.cast(ois.readObject());
70          } catch (ClassCastException | ClassNotFoundException | IOException ex) {
71              throw new MarshallerException("Unable to unmarshall", ex);
72          }
73      }
74  
75      private ObjectInputStream createObjectInputStream(InputStream istr) throws IOException {
76          return loader.isPresent()
77                  ? new ObjectInputStreamWithLoader(istr, loader.get())
78                  : new ObjectInputStream(istr);
79      }
80  
81      private static class ObjectInputStreamWithLoader extends ObjectInputStream {
82          private final ClassLoader loader;
83  
84          public ObjectInputStreamWithLoader(InputStream in, ClassLoader loader) throws IOException {
85              super(in);
86              this.loader = requireNonNull(loader);
87          }
88  
89          @Override
90          protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
91              return Class.forName(desc.getName(), false, loader);
92          }
93      }
94  }