1 /**
2  *  Copyright 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 package net.sf.ehcache.store;
17
18 import net.sf.ehcache.Element;
19 import net.sf.ehcache.config.CacheConfiguration;
20 import net.sf.ehcache.store.compound.ReadWriteCopyStrategy;
21
22 import java.util.Arrays;
23
24 /**
25  * @author Ludovic Orban
26  */

27 public class DefaultElementValueComparator implements ElementValueComparator {
28
29     private final CacheConfiguration cacheConfiguration;
30
31     /**
32      * Constructor
33      *
34      * @param cacheConfiguration the cache configuration
35      */

36     public DefaultElementValueComparator(CacheConfiguration cacheConfiguration) {
37         this.cacheConfiguration = cacheConfiguration;
38     }
39
40     /**
41      * {@inheritDoc}
42      */

43     public boolean equals(Element e1, Element e2) {
44         if (e1 == null && e2 == null) {
45             return true;
46         } else if (e1 != null && e1.equals(e2)) {
47             if (e1.getObjectValue() == null) {
48                 return e2.getObjectValue() == null;
49             } else {
50                 return compareValues(copyForReadIfNeeded(e1).getObjectValue(), copyForReadIfNeeded(e2).getObjectValue());
51             }
52         } else {
53             return false;
54         }
55     }
56
57     private static boolean compareValues(Object objectValue1, Object objectValue2) {
58         if (objectValue1 != null && objectValue2 != null && objectValue1.getClass().isArray() && objectValue2.getClass().isArray()) {
59             return Arrays.deepEquals(new Object[] {objectValue1}, new Object[] {objectValue2});
60         } else {
61             if (objectValue1 == null) {
62                 return objectValue2 == null;
63             } else {
64                 return objectValue1.equals(objectValue2);
65             }
66         }
67     }
68
69     private Element copyForReadIfNeeded(Element element) {
70         ReadWriteCopyStrategy<Element> readWriteCopyStrategy = cacheConfiguration.getCopyStrategy();
71         if (readWriteCopyStrategy == null || skipCopyForRead()) {
72             return element;
73         }
74         return readWriteCopyStrategy.copyForRead(element);
75     }
76
77     private boolean skipCopyForRead() {
78         // only do a copy for read before comparing if both copy on read and copy on write are enabled
79         return !(cacheConfiguration.isCopyOnRead() && cacheConfiguration.isCopyOnWrite());
80     }
81
82 }
83