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 }