001: /*
002: * Copyright 2004-2006 OpenSymphony
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy
006: * of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations
014: * under the License.
015: */
016: package org.quartz.utils;
017:
018: import java.io.Serializable;
019: import java.util.Iterator;
020: import java.util.Map;
021:
022: /**
023: * <p>
024: * An implementation of <code>Map</code> that wraps another <code>Map</code>
025: * and flags itself 'dirty' when it is modified, enforces that all keys are
026: * Strings.
027: * </p>
028: *
029: * <p>
030: * All allowsTransientData flag related methods are deprecated as of version 1.6.
031: * </p>
032: */
033: public class StringKeyDirtyFlagMap extends DirtyFlagMap {
034: static final long serialVersionUID = -9076749120524952280L;
035:
036: /**
037: * @deprecated JDBCJobStores no longer prune out transient data. If you
038: * include non-Serializable values in the Map, you will now get an
039: * exception when attempting to store it in a database.
040: */
041: private boolean allowsTransientData = false;
042:
043: public StringKeyDirtyFlagMap() {
044: super ();
045: }
046:
047: public StringKeyDirtyFlagMap(int initialCapacity) {
048: super (initialCapacity);
049: }
050:
051: public StringKeyDirtyFlagMap(int initialCapacity, float loadFactor) {
052: super (initialCapacity, loadFactor);
053: }
054:
055: /**
056: * Get a copy of the Map's String keys in an array of Strings.
057: */
058: public String[] getKeys() {
059: return (String[]) keySet().toArray(new String[size()]);
060: }
061:
062: /**
063: * Tell the <code>StringKeyDirtyFlagMap</code> that it should
064: * allow non-<code>Serializable</code> values. Enforces that the Map
065: * doesn't already include transient data.
066: *
067: * @deprecated JDBCJobStores no longer prune out transient data. If you
068: * include non-Serializable values in the Map, you will now get an
069: * exception when attempting to store it in a database.
070: */
071: public void setAllowsTransientData(boolean allowsTransientData) {
072:
073: if (containsTransientData() && !allowsTransientData) {
074: throw new IllegalStateException(
075: "Cannot set property 'allowsTransientData' to 'false' "
076: + "when data map contains non-serializable objects.");
077: }
078:
079: this .allowsTransientData = allowsTransientData;
080: }
081:
082: /**
083: * Whether the <code>StringKeyDirtyFlagMap</code> allows
084: * non-<code>Serializable</code> values.
085: *
086: * @deprecated JDBCJobStores no longer prune out transient data. If you
087: * include non-Serializable values in the Map, you will now get an
088: * exception when attempting to store it in a database.
089: */
090: public boolean getAllowsTransientData() {
091: return allowsTransientData;
092: }
093:
094: /**
095: * Determine whether any values in this Map do not implement
096: * <code>Serializable</code>. Always returns false if this Map
097: * is flagged to not allow transient data.
098: *
099: * @deprecated JDBCJobStores no longer prune out transient data. If you
100: * include non-Serializable values in the Map, you will now get an
101: * exception when attempting to store it in a database.
102: */
103: public boolean containsTransientData() {
104: if (!getAllowsTransientData()) { // short circuit...
105: return false;
106: }
107:
108: String[] keys = getKeys();
109: for (int i = 0; i < keys.length; i++) {
110: Object o = super .get(keys[i]);
111: if (!(o instanceof Serializable)) {
112: return true;
113: }
114: }
115:
116: return false;
117: }
118:
119: /**
120: * Removes any data values in the map that are non-Serializable. Does
121: * nothing if this Map does not allow transient data.
122: *
123: * @deprecated JDBCJobStores no longer prune out transient data. If you
124: * include non-Serializable values in the Map, you will now get an
125: * exception when attempting to store it in a database.
126: */
127: public void removeTransientData() {
128: if (!getAllowsTransientData()) { // short circuit...
129: return;
130: }
131:
132: String[] keys = getKeys();
133: for (int i = 0; i < keys.length; i++) {
134: Object o = super .get(keys[i]);
135: if (!(o instanceof Serializable)) {
136: remove(keys[i]);
137: }
138: }
139: }
140:
141: /**
142: * <p>
143: * Adds the name-value pairs in the given <code>Map</code> to the
144: * <code>StringKeyDirtyFlagMap</code>.
145: * </p>
146: *
147: * <p>
148: * All keys must be <code>String</code>s.
149: * </p>
150: */
151: public void putAll(Map map) {
152: for (Iterator entryIter = map.entrySet().iterator(); entryIter
153: .hasNext();) {
154: Map.Entry entry = (Map.Entry) entryIter.next();
155:
156: // will throw IllegalArgumentException if key is not a String
157: put(entry.getKey(), entry.getValue());
158: }
159: }
160:
161: /**
162: * <p>
163: * Adds the given <code>int</code> value to the <code>StringKeyDirtyFlagMap</code>.
164: * </p>
165: */
166: public void put(String key, int value) {
167: super .put(key, new Integer(value));
168: }
169:
170: /**
171: * <p>
172: * Adds the given <code>long</code> value to the <code>StringKeyDirtyFlagMap</code>.
173: * </p>
174: */
175: public void put(String key, long value) {
176: super .put(key, new Long(value));
177: }
178:
179: /**
180: * <p>
181: * Adds the given <code>float</code> value to the <code>StringKeyDirtyFlagMap</code>.
182: * </p>
183: */
184: public void put(String key, float value) {
185: super .put(key, new Float(value));
186: }
187:
188: /**
189: * <p>
190: * Adds the given <code>double</code> value to the <code>StringKeyDirtyFlagMap</code>.
191: * </p>
192: */
193: public void put(String key, double value) {
194: super .put(key, new Double(value));
195: }
196:
197: /**
198: * <p>
199: * Adds the given <code>boolean</code> value to the <code>StringKeyDirtyFlagMap</code>.
200: * </p>
201: */
202: public void put(String key, boolean value) {
203: super .put(key, new Boolean(value));
204: }
205:
206: /**
207: * <p>
208: * Adds the given <code>char</code> value to the <code>StringKeyDirtyFlagMap</code>.
209: * </p>
210: */
211: public void put(String key, char value) {
212: super .put(key, new Character(value));
213: }
214:
215: /**
216: * <p>
217: * Adds the given <code>String</code> value to the <code>StringKeyDirtyFlagMap</code>.
218: * </p>
219: */
220: public void put(String key, String value) {
221: super .put(key, value);
222: }
223:
224: /**
225: * <p>
226: * Adds the given <code>Object</code> value to the <code>StringKeyDirtyFlagMap</code>.
227: * </p>
228: */
229: public Object put(Object key, Object value) {
230: if (!(key instanceof String)) {
231: throw new IllegalArgumentException(
232: "Keys in map must be Strings.");
233: }
234:
235: return super .put(key, value);
236: }
237:
238: /**
239: * <p>
240: * Retrieve the identified <code>int</code> value from the <code>StringKeyDirtyFlagMap</code>.
241: * </p>
242: *
243: * @throws ClassCastException
244: * if the identified object is not an Integer.
245: */
246: public int getInt(String key) {
247: Object obj = get(key);
248:
249: try {
250: return ((Integer) obj).intValue();
251: } catch (Exception e) {
252: throw new ClassCastException(
253: "Identified object is not an Integer.");
254: }
255: }
256:
257: /**
258: * <p>
259: * Retrieve the identified <code>long</code> value from the <code>StringKeyDirtyFlagMap</code>.
260: * </p>
261: *
262: * @throws ClassCastException
263: * if the identified object is not a Long.
264: */
265: public long getLong(String key) {
266: Object obj = get(key);
267:
268: try {
269: return ((Long) obj).longValue();
270: } catch (Exception e) {
271: throw new ClassCastException(
272: "Identified object is not a Long.");
273: }
274: }
275:
276: /**
277: * <p>
278: * Retrieve the identified <code>float</code> value from the <code>StringKeyDirtyFlagMap</code>.
279: * </p>
280: *
281: * @throws ClassCastException
282: * if the identified object is not a Float.
283: */
284: public float getFloat(String key) {
285: Object obj = get(key);
286:
287: try {
288: return ((Float) obj).floatValue();
289: } catch (Exception e) {
290: throw new ClassCastException(
291: "Identified object is not a Float.");
292: }
293: }
294:
295: /**
296: * <p>
297: * Retrieve the identified <code>double</code> value from the <code>StringKeyDirtyFlagMap</code>.
298: * </p>
299: *
300: * @throws ClassCastException
301: * if the identified object is not a Double.
302: */
303: public double getDouble(String key) {
304: Object obj = get(key);
305:
306: try {
307: return ((Double) obj).doubleValue();
308: } catch (Exception e) {
309: throw new ClassCastException(
310: "Identified object is not a Double.");
311: }
312: }
313:
314: /**
315: * <p>
316: * Retrieve the identified <code>boolean</code> value from the <code>StringKeyDirtyFlagMap</code>.
317: * </p>
318: *
319: * @throws ClassCastException
320: * if the identified object is not a Boolean.
321: */
322: public boolean getBoolean(String key) {
323: Object obj = get(key);
324:
325: try {
326: return ((Boolean) obj).booleanValue();
327: } catch (Exception e) {
328: throw new ClassCastException(
329: "Identified object is not a Boolean.");
330: }
331: }
332:
333: /**
334: * <p>
335: * Retrieve the identified <code>char</code> value from the <code>StringKeyDirtyFlagMap</code>.
336: * </p>
337: *
338: * @throws ClassCastException
339: * if the identified object is not a Character.
340: */
341: public char getChar(String key) {
342: Object obj = get(key);
343:
344: try {
345: return ((Character) obj).charValue();
346: } catch (Exception e) {
347: throw new ClassCastException(
348: "Identified object is not a Character.");
349: }
350: }
351:
352: /**
353: * <p>
354: * Retrieve the identified <code>String</code> value from the <code>StringKeyDirtyFlagMap</code>.
355: * </p>
356: *
357: * @throws ClassCastException
358: * if the identified object is not a String.
359: */
360: public String getString(String key) {
361: Object obj = get(key);
362:
363: try {
364: return (String) obj;
365: } catch (Exception e) {
366: throw new ClassCastException(
367: "Identified object is not a String.");
368: }
369: }
370: }
|