SerializedCache.java

  1. /*
  2.  *    Copyright 2009-2023 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.  *       https://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.       throw new CacheException("SharedCache failed to make a copy of a non-serializable object: " + object);
  49.     }
  50.     delegate.putObject(key, serialize((Serializable) object));
  51.   }

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

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

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

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

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

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

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

  94.   public static class CustomObjectInputStream extends ObjectInputStream {

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

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

  102.   }

  103. }