1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package com.tomgibara.pronto.config.source;
19
20 import java.util.HashMap;
21 import java.util.Map;
22
23 import com.tomgibara.pronto.util.Arguments;
24
25 /**
26 * Instances of this class can compute accurate values for lastModified from
27 * property maps alone.
28 *
29 * The property maps supplied to these objects are not modified and are copied
30 * if their values need to be recorded by this object. The copies made in this
31 * way are available via the getProperties() method.
32 *
33 * @author Tom Gibara
34 *
35 */
36
37
38 public final class LastModifiedCalculator {
39
40 /** The properties as they were when last changed. */
41 private Map<String, String> properties;
42
43 /** The time at which the properties were last changed. */
44 private long lastModified;
45
46 /**
47 * Initializes the object without a known last modified date or known
48 * properties. The update method must be called before these fields are
49 * accessed.
50 */
51
52 public LastModifiedCalculator() {
53 properties = null;
54 lastModified = 0L;
55 }
56
57 /**
58 * After calling this constructor, the lastModified field will equal the
59 * supplied lastModified date and the properties field will contain a copy
60 * of the supplied properties.
61 *
62 * @param properties
63 * the initial properties for this object, not null
64 * @param lastModified
65 * the known last modification date for the supplied properties,
66 * not negative
67 */
68
69 public LastModifiedCalculator(final Map<String, String> properties, final long lastModified) {
70 Arguments.notNull(properties, "properties");
71 Arguments.notNegative(lastModified, "lastModified");
72 this.properties = new HashMap<String, String>(properties);
73 this.lastModified = lastModified;
74 }
75
76 /**
77 * Computes the lastModified field of this object based on the supplied map.
78 *
79 * This method will persist a copy of the supplied properties if the
80 * properties differ from the last call to this method (or if this is the
81 * first call to the method).
82 *
83 * @param properties a new collection of properties
84 */
85
86 public void update(final Map<String, String> properties) {
87 Arguments.notNull(properties, "properties");
88 if (this.properties == null) {
89 doUpdate(properties);
90 } else if (properties == this.properties) {
91
92
93 } else if (properties.equals(this.properties)) {
94
95 } else {
96 doUpdate(properties);
97 }
98 }
99
100 /**
101 * Returns a copy of the last supplied properties which had changed.
102 *
103 * @return the properties recorded by this object, never null
104 * @throws IllegalStateException
105 * if the update method has not yet been called
106 */
107
108 public Map<String, String> getProperties() throws IllegalStateException {
109 if (properties == null) throw new IllegalStateException("Last modified time requested before update.");
110 return properties;
111 }
112
113 /**
114 * Returns the lastModified date maintained by this object.
115 *
116 * @return the time at which the properties stored by this object were last
117 * modified
118 * @throws IllegalStateException
119 * if the update method has not yet been called
120 */
121
122 public long getLastModified() throws IllegalStateException {
123 if (properties == null) throw new IllegalStateException("Properties requested before update.");
124 return lastModified;
125 }
126
127
128
129 /**
130 * Update the fields of this object based on the supplied map.
131 *
132 * @param properties
133 * the properties to record
134 */
135
136 private void doUpdate(final Map<String, String> properties) {
137 this.properties = new HashMap<String, String>(properties);
138 long lastModified = System.currentTimeMillis();
139
140
141 if (this.lastModified < lastModified) this.lastModified = lastModified;
142 }
143
144 }