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
17 package net.sf.ehcache.config;
18
19 import net.sf.ehcache.CacheManager;
20 import net.sf.ehcache.Ehcache;
21
22 /**
23 * Class to hold the SizeOf policy configuration.
24 *
25 * @author Ludovic Orban
26 */
27 public class SizeOfPolicyConfiguration implements Cloneable {
28 /**
29 * Default max traversal depth
30 */
31 public static final int DEFAULT_MAX_SIZEOF_DEPTH = 1000;
32 /**
33 * Default max traversal depth exceeded behavior
34 */
35 public static final MaxDepthExceededBehavior DEFAULT_MAX_DEPTH_EXCEEDED_BEHAVIOR = MaxDepthExceededBehavior.CONTINUE;
36
37 /**
38 * Enum of the possible behaviors of the SizeOf engine when the max depth is exceeded
39 */
40 public static enum MaxDepthExceededBehavior {
41 /**
42 * Abort the SizeOf engine's traversal and immediately return the partially calculated size
43 */
44 ABORT,
45
46 /**
47 * Warn about the exceeded max depth but continue traversal of the sized element
48 */
49 CONTINUE;
50
51 /**
52 * Returns true if this behavior is equal to ABORT
53 *
54 * @return true if this behavior is equal to ABORT
55 */
56 public boolean isAbort() {
57 return this == ABORT;
58 }
59
60 /**
61 * Returns true if this behavior is equal to CONTINUE
62 *
63 * @return true if this behavior is equal to CONTINUE
64 */
65 public boolean isContinue() {
66 return this == CONTINUE;
67 }
68 }
69
70 private volatile int maxDepth = DEFAULT_MAX_SIZEOF_DEPTH;
71 private volatile MaxDepthExceededBehavior maxDepthExceededBehavior = DEFAULT_MAX_DEPTH_EXCEEDED_BEHAVIOR;
72
73
74 /**
75 * Gets the maximum depth the SizeOf engine can normally traverse
76 *
77 * @return the maximum depth the SizeOf engine can normally traverse
78 */
79 public int getMaxDepth() {
80 return maxDepth;
81 }
82
83 /**
84 * Sets the maximum depth the SizeOf engine can normally traverse
85 *
86 * @param maxDepth the maximum depth the SizeOf engine can normally traverse
87 */
88 public void setMaxDepth(int maxDepth) {
89 this.maxDepth = maxDepth;
90 }
91
92 /**
93 * Builder method to set the maximum depth the SizeOf engine can normally traverse
94 *
95 * @param maxDepth the maximum depth the SizeOf engine can normally traverse
96 * @return this SizeOfPolicyConfiguration object
97 */
98 public SizeOfPolicyConfiguration maxDepth(int maxDepth) {
99 setMaxDepth(maxDepth);
100 return this;
101 }
102
103 /**
104 * Gets the behavior of the SizeOf engine when the max depth is reached
105 *
106 * @return the behavior of the SizeOf engine when the max depth is reached
107 */
108 public MaxDepthExceededBehavior getMaxDepthExceededBehavior() {
109 return maxDepthExceededBehavior;
110 }
111
112 /**
113 * Sets the behavior of the SizeOf engine when the max depth is reached
114 *
115 * @param maxDepthExceededBehavior the behavior of the SizeOf engine when the max depth is reached
116 */
117 public void setMaxDepthExceededBehavior(String maxDepthExceededBehavior) {
118 if (maxDepthExceededBehavior == null) {
119 throw new IllegalArgumentException("maxDepthExceededBehavior must be non-null");
120 }
121 this.maxDepthExceededBehavior(MaxDepthExceededBehavior.valueOf(MaxDepthExceededBehavior.class, maxDepthExceededBehavior.toUpperCase()));
122 }
123
124 /**
125 * Builder method to set the behavior of the SizeOf engine when the max depth is reached
126 *
127 * @param maxDepthExceededBehavior the behavior of the SizeOf engine when the max depth is reached
128 * @return this SizeOfPolicyConfiguration object
129 */
130 public SizeOfPolicyConfiguration maxDepthExceededBehavior(MaxDepthExceededBehavior maxDepthExceededBehavior) {
131 this.maxDepthExceededBehavior = maxDepthExceededBehavior;
132 return this;
133 }
134
135 /**
136 * Builder method to set the behavior of the SizeOf engine when the max depth is reached using a String object
137 *
138 * @param maxDepthExceededBehavior the behavior of the SizeOf engine when the max depth is reached
139 * @return this SizeOfPolicyConfiguration object
140 */
141 public SizeOfPolicyConfiguration maxDepthExceededBehavior(String maxDepthExceededBehavior) {
142 setMaxDepthExceededBehavior(maxDepthExceededBehavior);
143 return this;
144 }
145
146 /**
147 * Helper method which resolves the max depth of a cache, using the cache manager's one if none was configured
148 * on the cache itself.
149 *
150 * @param cache the cache from which to resolve the max depth
151 * @return the resolved max depth
152 */
153 public static int resolveMaxDepth(Ehcache cache) {
154 if (cache == null) {
155 return DEFAULT_MAX_SIZEOF_DEPTH;
156 }
157 CacheManager cacheManager = cache.getCacheManager();
158 return resolvePolicy(cacheManager == null ? null : cacheManager.getConfiguration(), cache.getCacheConfiguration()).getMaxDepth();
159 }
160
161 /**
162 * Helper method which resolves the MaxDepthExceededBehavior of a cache, using the cache manager's one if none was configured
163 * on the cache itself.
164 *
165 * @param cache the cache from which to resolve the MaxDepthExceededBehavior
166 * @return the resolved MaxDepthExceededBehavior
167 */
168 public static MaxDepthExceededBehavior resolveBehavior(Ehcache cache) {
169 if (cache == null) {
170 return DEFAULT_MAX_DEPTH_EXCEEDED_BEHAVIOR;
171 }
172 CacheManager cacheManager = cache.getCacheManager();
173 if (cacheManager == null) {
174 return resolvePolicy(null, cache.getCacheConfiguration()).getMaxDepthExceededBehavior();
175 } else {
176 return resolvePolicy(cacheManager.getConfiguration(), cache.getCacheConfiguration()).getMaxDepthExceededBehavior();
177 }
178 }
179
180 private static SizeOfPolicyConfiguration resolvePolicy(Configuration configuration, CacheConfiguration cacheConfiguration) {
181 SizeOfPolicyConfiguration sizeOfPolicyConfiguration = null;
182 if (cacheConfiguration != null) {
183 sizeOfPolicyConfiguration = cacheConfiguration.getSizeOfPolicyConfiguration();
184 }
185 if (sizeOfPolicyConfiguration == null) {
186 if (configuration != null) {
187 sizeOfPolicyConfiguration = configuration.getSizeOfPolicyConfiguration();
188 } else {
189 sizeOfPolicyConfiguration = new SizeOfPolicyConfiguration();
190 }
191 }
192
193 return sizeOfPolicyConfiguration;
194 }
195
196 @Override
197 public int hashCode() {
198 final int prime = 31;
199 int result = 1;
200 result = prime * result + maxDepth;
201 result = prime * result + ((maxDepthExceededBehavior == null) ? 0 : maxDepthExceededBehavior.hashCode());
202 return result;
203 }
204
205 @Override
206 public boolean equals(Object obj) {
207 if (this == obj) {
208 return true;
209 } else if (obj == null || getClass() != obj.getClass()) {
210 return false;
211 }
212 SizeOfPolicyConfiguration other = (SizeOfPolicyConfiguration) obj;
213 return (maxDepth == other.maxDepth && maxDepthExceededBehavior == other.maxDepthExceededBehavior);
214 }
215 }
216