SerializedCache.java

  1. /*
  2.  *    Copyright 2009-2021 the original author or authors.
  3.  *
  4.  *    Licensed under the Apache License, Version 2.0 (the "License");
  5.  *    you may not use this file except in compliance with the License.
  6.  *    You may obtain a copy of the License at
  7.  *
  8.  *       http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  *    Unless required by applicable law or agreed to in writing, software
  11.  *    distributed under the License is distributed on an "AS IS" BASIS,
  12.  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  *    See the License for the specific language governing permissions and
  14.  *    limitations under the License.
  15.  */
  16. package org.apache.ibatis.cache.decorators;

  17. import java.io.ByteArrayInputStream;
  18. import java.io.ByteArrayOutputStream;
  19. import java.io.IOException;
  20. import java.io.InputStream;
  21. import java.io.ObjectInputStream;
  22. import java.io.ObjectOutputStream;
  23. import java.io.ObjectStreamClass;
  24. import java.io.Serializable;

  25. import org.apache.ibatis.cache.Cache;
  26. import org.apache.ibatis.cache.CacheException;
  27. import org.apache.ibatis.io.Resources;
  28. import org.apache.ibatis.io.SerialFilterChecker;

  29. /**
  30.  * @author Clinton Begin
  31.  */
  32. public class SerializedCache implements Cache {

  33.   private final Cache delegate;

  34.   public SerializedCache(Cache delegate) {
  35.     this.delegate = delegate;
  36.   }

  37.   @Override
  38.   public String getId() {
  39.     return delegate.getId();
  40.   }

  41.   @Override
  42.   public int getSize() {
  43.     return delegate.getSize();
  44.   }

  45.   @Override
  46.   public void putObject(Object key, Object object) {
  47.     if (object == null || object instanceof Serializable) {
  48.       delegate.putObject(key, serialize((Serializable) object));
  49.     } else {
  50.       throw new CacheException("SharedCache failed to make a copy of a non-serializable object: " + object);
  51.     }
  52.   }

  53.   @Override
  54.   public Object getObject(Object key) {
  55.     Object object = delegate.getObject(key);
  56.     return object == null ? null : deserialize((byte[]) object);
  57.   }

  58.   @Override
  59.   public Object removeObject(Object key) {
  60.     return delegate.removeObject(key);
  61.   }

  62.   @Override
  63.   public void clear() {
  64.     delegate.clear();
  65.   }

  66.   @Override
  67.   public int hashCode() {
  68.     return delegate.hashCode();
  69.   }

  70.   @Override
  71.   public boolean equals(Object obj) {
  72.     return delegate.equals(obj);
  73.   }

  74.   private byte[] serialize(Serializable value) {
  75.     try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
  76.         ObjectOutputStream oos = new ObjectOutputStream(bos)) {
  77.       oos.writeObject(value);
  78.       oos.flush();
  79.       return bos.toByteArray();
  80.     } catch (Exception e) {
  81.       throw new CacheException("Error serializing object.  Cause: " + e, e);
  82.     }
  83.   }

  84.   private Serializable deserialize(byte[] value) {
  85.     SerialFilterChecker.check();
  86.     Serializable result;
  87.     try (ByteArrayInputStream bis = new ByteArrayInputStream(value);
  88.         ObjectInputStream ois = new CustomObjectInputStream(bis)) {
  89.       result = (Serializable) ois.readObject();
  90.     } catch (Exception e) {
  91.       throw new CacheException("Error deserializing object.  Cause: " + e, e);
  92.     }
  93.     return result;
  94.   }

  95.   public static class CustomObjectInputStream extends ObjectInputStream {

  96.     public CustomObjectInputStream(InputStream in) throws IOException {
  97.       super(in);
  98.     }

  99.     @Override
  100.     protected Class<?> resolveClass(ObjectStreamClass desc) throws ClassNotFoundException {
  101.       return Resources.classForName(desc.getName());
  102.     }

  103.   }

  104. }