View Javadoc

1   /***
2    *  Copyright 2003-2010 Terracotta, Inc.
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  
17  package net.sf.ehcache.store.compound;
18  
19  import net.sf.ehcache.CacheException;
20  import net.sf.ehcache.Element;
21  
22  import java.io.ByteArrayInputStream;
23  import java.io.ByteArrayOutputStream;
24  import java.io.ObjectInputStream;
25  import java.io.ObjectOutputStream;
26  
27  /***
28   * A copy strategy that can use partial (if both copy on read and copy on write are set) or full Serialization to copy the object graph
29   *
30   * @author Alex Snaps
31   * @author Ludovic Orban
32   */
33  public class ReadWriteSerializationCopyStrategy implements ReadWriteCopyStrategy<Element> {
34  
35      /***
36       * @inheritDoc
37       */
38      public Element copyForWrite(Element value) {
39          if (value == null) {
40              return null;
41          } else {
42              ByteArrayOutputStream bout = new ByteArrayOutputStream();
43              ObjectOutputStream oos = null;
44  
45              if (value.getObjectValue() == null) {
46                  return duplicateElementWithNewValue(value, null);
47              }
48  
49              try {
50                  oos = new ObjectOutputStream(bout);
51                  oos.writeObject(value.getObjectValue());
52              } catch (Exception e) {
53                  throw new CacheException("When configured copyOnRead or copyOnWrite, a Store will only accept Serializable values", e);
54              } finally {
55                  try {
56                      if (oos != null) {
57                          oos.close();
58                      }
59                  } catch (Exception e) {
60                      //
61                  }
62              }
63  
64              return duplicateElementWithNewValue(value, bout.toByteArray());
65          }
66      }
67  
68      /***
69       * @inheritDoc
70       */
71      public Element copyForRead(Element storedValue) {
72          if (storedValue == null) {
73              return null;
74          } else {
75              if (storedValue.getObjectValue() == null) {
76                  return duplicateElementWithNewValue(storedValue, null);
77              }
78  
79              ByteArrayInputStream bin = new ByteArrayInputStream((byte[]) storedValue.getObjectValue());
80              ObjectInputStream ois = null;
81              try {
82                  ois = new ObjectInputStream(bin);
83                  return duplicateElementWithNewValue(storedValue, ois.readObject());
84              } catch (Exception e) {
85                  throw new CacheException("When configured copyOnRead or copyOnWrite, a Store will only accept Serializable values", e);
86              } finally {
87                  try {
88                      if (ois != null) {
89                          ois.close();
90                      }
91                  } catch (Exception e) {
92                      //
93                  }
94              }
95          }
96      }
97  
98      /***
99       * Make a duplicate of an element but using the specified value
100      *
101      * @param element  the element to duplicate
102      * @param newValue the new element's value
103      * @return the duplicated element
104      */
105     public Element duplicateElementWithNewValue(final Element element, final Object newValue) {
106         return new Element(element.getObjectKey(), newValue, element.getVersion(),
107                 element.getCreationTime(), element.getLastAccessTime(), element.getHitCount(), element.usesCacheDefaultLifespan(),
108                 element.getTimeToLive(), element.getTimeToIdle(), element.getLastUpdateTime(), element.isPinned());
109     }
110 
111 }