1 package jsdsi;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Date;
6 import java.util.Iterator;
7 import java.util.List;
8
9 import jsdsi.sexp.Sexp;
10 import jsdsi.sexp.SexpList;
11 import jsdsi.sexp.SexpParseException;
12 import jsdsi.sexp.SexpUtil;
13
14 /***
15 * A validity period and a set of online tests.
16 *
17 * @author Sameer Ajmani
18 * @author Sean Radford
19 * @version $Revision: 1.4.2.1 $ $Date: 2005/11/08 03:12:52 $
20 *
21 * @todo Change tests from OnlineTest[] to java.util.Set
22 */
23 public class Validity extends Obj {
24
25 private static final long serialVersionUID = 6865522911895159585L;
26
27 /***
28 * Valid not before ... (may be <code>null</code>).
29 */
30 private transient final Date notBefore;
31
32 /***
33 * Valid not after ... (may be <code>null</code>).
34 */
35 private transient final Date notAfter;
36
37 /***
38 * Array of online tests (my be <code>null</code>).
39 */
40 private transient final OnlineTest[] tests;
41
42 /***
43 * Creates a new <code>Validity</code> from two given date bounds
44 * and an array of online tests.
45 *
46 * @param b not-before-bound.
47 * @param a not-after-bound.
48 * @param t array of onlie tests (may be <code>null</code>).
49 */
50 public Validity(Date b, Date a, OnlineTest[] t) {
51 if( t==null ) {
52 t = new OnlineTest[0];
53 }
54 notBefore = b;
55 notAfter = a;
56 tests = t;
57 }
58
59 /***
60 * Creates a new <code>Validity</code> from two given date bounds.
61 *
62 * @param b not-before-bound.
63 * @param a not-after-bound.
64 */
65 public Validity(Date b, Date a) {
66 this(b, a, new OnlineTest[0]);
67 }
68
69 /***
70 * Checks if this <code>Validity</code> is valid now.
71 *
72 * @return <code>true</code> if this <code>Validity</code> is valid at
73 * this juncture, <code>false</code> otherwise.
74 */
75 public boolean valid() {
76 // FIXME: needs to run online tests (parameters?)
77 Date now = new Date();
78 return (notBefore == null || notBefore.before(now))
79 && (notAfter == null || notAfter.after(now));
80 }
81
82 /***
83 * @return the not-before date.
84 */
85 public Date getNotBefore() {
86 return notBefore;
87 }
88
89 /***
90 * @return the not-after date.
91 */
92 public Date getNotAfter() {
93 return notAfter;
94 }
95
96 /***
97 * @return an array of online tests.
98 */
99 public OnlineTest[] getOnlineTests() {
100 return tests;
101 }
102
103 /***
104 * Intersects this <code>Validity</code> with another and returns the
105 * resulting <code>Validity</code>.
106 *
107 * @param v <code>Validity</code> to intersect this
108 * <code>Validity</code> with.
109 * @return the intersection of this and <code>v</code>.
110 */
111 public Validity intersect(Validity v) {
112 Date nb = notBefore;
113 if ((nb == null) || (v.notBefore != null && v.notBefore.after(nb))) {
114 nb = v.notBefore;
115 }
116 Date na = notAfter;
117 if ((na == null) || (v.notAfter != null && v.notAfter.before(na))) {
118 na = v.notAfter;
119 }
120 // combine lists of tests
121 OnlineTest[] ts = new OnlineTest[tests.length + v.tests.length];
122 System.arraycopy(tests, 0, ts, 0, tests.length);
123 System.arraycopy(v.tests, 0, ts, tests.length, v.tests.length);
124 return new Validity(nb, na, ts);
125 }
126
127 /***
128 * @see java.lang.Object#equals(Object)
129 */
130 public boolean equals(Object o) {
131 if (o instanceof Validity) {
132 Validity v = (Validity) o;
133 return Util.equals(notBefore, v.notBefore)
134 && Util.equals(notAfter, v.notAfter)
135 && Util.equals(tests, v.tests);
136 }
137 return false;
138 }
139
140 /***
141 * @return true iff a Validity with not-before d1 is valid whenever
142 * a validity with not-before d2 is valid (all else equal).
143 */
144 private static boolean impliesNB(Date d1, Date d2) {
145 if (d1 == null) {
146 return true; // null not-before is always valid
147 }
148 if (d2 == null) {
149 return false; // d1 is non-null, so it's weaker
150 }
151 return d1.equals(d2) || d1.before(d2);
152 }
153
154 /***
155 * @return true iff a Validity with not-after d1 is valid whenever
156 * a Validity with not-after d2 is valid (all else equal).
157 */
158 private static boolean impliesNA(Date d1, Date d2) {
159 if (d1 == null) {
160 return true; // null not-after is always valid
161 }
162 if (d2 == null) {
163 return false; // d1 is non-null, so it's weaker
164 }
165 return d1.equals(d2) || d1.after(d2);
166 }
167
168 /***
169 * @return true iff a Validity with tests t1 is valid whenever
170 * a Validity with tests t2 is valid (all else equal).
171 */
172 private static boolean impliesTests(OnlineTest[] t1, OnlineTest[] t2) {
173 if (t1 == null) {
174 return true; // null tests is always valid
175 }
176 if (t2 == null) {
177 return false; // t1 is non-null, so it's weaker
178 }
179 return Arrays.asList(t1).containsAll(Arrays.asList(t2));
180 }
181
182 /***
183 * @return true iff v1 is valid whenever v2 is valid
184 */
185 public static boolean implies(Validity v1, Validity v2) {
186 if (v1 == null) {
187 return true; // null validity is always valid
188 }
189 if (v2 == null) {
190 return false; // v1 is non-null, so it's weaker
191 }
192 return impliesNB(v1.notBefore, v2.notBefore)
193 && impliesNA(v1.notAfter, v2.notAfter)
194 && impliesTests(v1.tests, v2.tests);
195 }
196
197 /***
198 * @see java.lang.Object#hashCode()
199 */
200 public int hashCode() {
201 return Util.hashCode(notBefore)
202 ^ Util.hashCode(notAfter)
203 ^ Util.hashCode(tests);
204 }
205
206 public SexpList toSexp() {
207 List l = new ArrayList(2);
208 if (getNotBefore() != null) {
209 Sexp[] ss = new Sexp[1];
210 ss[0] = SexpUtil.toSexp(getNotBefore());
211 l.add(SexpUtil.toSexp("not-before", ss));
212 }
213 if (getNotAfter() != null) {
214 Sexp[] ss = new Sexp[1];
215 ss[0] = SexpUtil.toSexp(getNotAfter());
216 l.add(SexpUtil.toSexp("not-after", ss));
217 }
218 for (int i = 0; i < tests.length; i++) {
219 l.add(tests[i].toSexp());
220 }
221 return SexpUtil.toSexp("valid", l);
222 }
223
224 static Validity parseValidity(SexpList l) throws SexpParseException {
225 Iterator vbody = SexpUtil.getBody(l);
226 SexpList check = SexpUtil.getNextList(vbody, "validity check");
227 String type = check.getType();
228 Date notBefore = null;
229 Date notAfter = null;
230 int numOnlineTests = l.size() - 1;
231 if (type.equals("not-before")) {
232 numOnlineTests--;
233 Iterator nb = SexpUtil.getBody(check);
234 notBefore = SexpUtil.parseDate(
235 SexpUtil.getNextString(nb, "not-before date"));
236 SexpUtil.checkDone(nb, "not-before");
237 if (vbody.hasNext()) {
238 check = SexpUtil.getNextList(vbody, "validity check");
239 type = check.getType();
240 }
241 }
242 if (type.equals("not-after")) {
243 numOnlineTests--;
244 Iterator na = SexpUtil.getBody(check);
245 notAfter = SexpUtil.parseDate(
246 SexpUtil.getNextString(na, "not-after date"));
247 SexpUtil.checkDone(na, "not-after");
248 if (vbody.hasNext()) {
249 check = SexpUtil.getNextList(vbody, "validity check");
250 type = check.getType();
251 }
252 }
253 OnlineTest[] tests = new OnlineTest[numOnlineTests];
254 for (int i = 0; i < tests.length; i++) {
255 tests[i] = OnlineTest.parseOnlineTest(
256 SexpUtil.getNextList(
257 vbody,
258 "online test " + (i + 1) + "/" + tests.length));
259 }
260 SexpUtil.checkDone(vbody, "valid");
261 return new Validity(notBefore, notAfter, tests);
262 }
263 }
This page was automatically generated by Maven