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

javax.cache.implementation.RISerializer Maven / Gradle / Ivy

The newest version!
/**
 *  Copyright 2011 Terracotta, Inc.
 *  Copyright 2011 Oracle America Incorporated
 *
 *  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 javax.cache.implementation;

import javax.cache.CacheException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.util.Arrays;

/**
 * The reference implementation for JSR107.
 * 

* This serializer uses java serialization. * * @param the type of object to be stored * @author Yannis Cosmadopoulos * @since 1.0 */ public class RISerializer implements Serializer { private final SerializationHelper serializationHelper; /** * Constructor * @param classLoader the class loader */ public RISerializer(ClassLoader classLoader) { assert classLoader != null; this.serializationHelper = new SerializationHelper(classLoader); } /** * {@inheritDoc} */ @Override public Binary createBinary(T value) { if (value == null) { throw new NullPointerException(); } //TODO: do we want to validate? //serializationHelper.validate(value); return new RIBinary(value, serializationHelper); } /** * Binary that stores by reference * @param the type */ private static final class RIByReferenceBinary implements Binary { private final V value; public RIByReferenceBinary(V value) { this.value = value; } @Override public V get() { return value; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Binary binary = (Binary) o; return hashCode() == binary.hashCode() && get().equals(binary.get()); } @Override public int hashCode() { return value.hashCode(); } } /** * Binary implementation backed by a byte array. */ private static final class RIBinary implements Binary { private final byte[] bytes; private final int hashCode; private final SerializationHelper serializationHelper; private RIBinary(V value, SerializationHelper serializationHelper) { this.serializationHelper = serializationHelper; hashCode = value.hashCode(); try { bytes = serializationHelper.toBytes(value); } catch (IOException e) { throw new IllegalArgumentException("Serializer: " + e.getMessage(), e); } } /** * {@inheritDoc} */ @Override public V get() { try { /* * Only objects of type V can be set in constructor so the cast must be safe */ @SuppressWarnings("unchecked") final V value = (V) serializationHelper.fromBytes(bytes); return value; } catch (IOException e) { throw new CacheException("Serializer: " + e.getMessage(), e); } catch (ClassNotFoundException e) { throw new CacheException("Serializer: " + e.getMessage(), e); } } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; if (o instanceof RIBinary) { RIBinary riBinary = (RIBinary) o; return hashCode == riBinary.hashCode && (Arrays.equals(bytes, riBinary.bytes)); } else { Binary binary = (Binary) o; return hashCode == binary.hashCode() && get().equals(binary.get()); } } @Override public int hashCode() { return hashCode; } } /** * Simple helper to go to and from byte arrays using a classloader */ private static final class SerializationHelper { private final ClassLoader classLoader; private SerializationHelper(ClassLoader classLoader) { if (classLoader == null) { throw new NullPointerException("classLoader"); } this.classLoader = classLoader; } public byte[] toBytes(Object value) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(value); bos.flush(); return bos.toByteArray(); } finally { try { bos.close(); } catch (IOException e) { // eat this up } } } public Object fromBytes(byte[] bytes) throws IOException, ClassNotFoundException { ByteArrayInputStream bos = new ByteArrayInputStream(bytes); ObjectInputStream ois; try { ois = new MyObjectInputStream(bos, classLoader); return ois.readObject(); } finally { try { bos.close(); } catch (IOException e) { // eat this up } } } public void validate(Object toStore) { Class class1 = toStore.getClass(); try { Class class2 = classLoader.loadClass(class1.getName()); if (class1 != class2) { throw new IllegalArgumentException("from different class loader: " + toStore); } } catch (ClassNotFoundException e) { throw new IllegalArgumentException("not in class loader: " + toStore); } } /** * want to use our ClassLoader to resolve classes */ private static final class MyObjectInputStream extends ObjectInputStream { private final ClassLoader classloader; private MyObjectInputStream(InputStream in, ClassLoader classloader) throws IOException { super(in); this.classloader = classloader; } @Override protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException { String name = desc.getName(); try { return Class.forName(name, false, classloader); } catch (ClassNotFoundException ex) { return super.resolveClass(desc); } } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy