1 package jsdsi;
2
3 import java.util.Iterator;
4
5 import jsdsi.sexp.Sexp;
6 import jsdsi.sexp.SexpList;
7 import jsdsi.sexp.SexpParseException;
8 import jsdsi.sexp.SexpUtil;
9
10 /***
11 * A subject that can delegate authority to any K of N specified
12 * subjects. For example, if K is 2, N is 3, and the subjects are
13 * Alice, Bob, and Carol, any two of those subjects can pass on any
14 * authority granted to this subject (if delegation is permitted).
15 *
16 * @author Sameer Ajmani
17 * @author Sean Radford
18 * @version $Revision: 1.3.2.1 $ $Date: 2005/11/08 03:12:52 $
19 */
20 public class Threshold extends Obj implements Subject {
21
22 private static final long serialVersionUID = 3335226567408806884L;
23
24 /***
25 * The subjects involved in this <code>Threshold</code>.
26 */
27 private transient final Subject[] subjects;
28 // TODO: replace with Set (unordered)
29
30 /***
31 * The threshold number of subjects required for this authorization
32 * (at most subject.length, of course).
33 */
34 private transient final int threshold; // at most subjects.length
35
36 /***
37 * Creates a new <code>Threshold</code> from an array of subjects and a
38 * threshold.
39 *
40 * @param s array of subjects.
41 * @param t threshold number (at most subjects.length).
42 */
43 public Threshold(Subject[] s, int t) {
44 assert(s != null) : "null subject array";
45 assert(t <= s.length) : "threshold > num subjects";
46 subjects = s;
47 threshold = t;
48 }
49
50 /***
51 * @return the threshold number of this <code>Threshold</code>.
52 */
53 public int getThreshold() {
54 return threshold;
55 }
56
57 /***
58 * @return the array of subjects of this <code>Threshold</code>.
59 */
60 public Subject[] getSubjects() {
61 return subjects;
62 }
63
64 /***
65 * @see java.lang.Object#equals(Object)
66 */
67 public boolean equals(Object o) {
68 if (o instanceof Threshold) {
69 Threshold t = (Threshold) o;
70 return (threshold == t.threshold)
71 && Util.equals(subjects, t.subjects);
72 }
73 return false;
74 }
75
76 /***
77 * @see java.lang.Object#hashCode()
78 */
79 public int hashCode() {
80 return Util.hashCode(subjects) ^ threshold;
81 }
82
83 public SexpList toSexp() {
84 return toSexp((Principal) null);
85 }
86
87 public SexpList toSexp(Principal iss) {
88 Sexp[] ss = new Sexp[subjects.length + 2];
89 ss[0] = SexpUtil.toSexp(String.valueOf(getThreshold()));
90 ss[1] = SexpUtil.toSexp(String.valueOf(subjects.length));
91 for (int i = 0; i < subjects.length; i++) {
92 // FIXME: can we eliminate these downcasts?
93 if (subjects[i] instanceof Name) {
94 // tell name about issuer
95 ss[i + 2] = ((Name) subjects[i]).toSexp(iss);
96 } else if (subjects[i] instanceof Threshold) {
97 // tell nested names about issuer
98 ss[i + 2] = ((Threshold) subjects[i]).toSexp(iss);
99 } else {
100 ss[i + 2] = subjects[i].toSexp();
101 }
102 }
103 return SexpUtil.toSexp("k-of-n", ss);
104 }
105
106 static Threshold parseThreshold(SexpList l) throws SexpParseException {
107 return parseThreshold(l, null);
108 }
109
110 static Threshold parseThreshold(SexpList l, Principal issuer)
111 throws SexpParseException {
112 Iterator tbody = SexpUtil.getBody(l);
113 try {
114 int k = Integer.parseInt(SexpUtil.getNextString(tbody, "k"));
115 int n = Integer.parseInt(SexpUtil.getNextString(tbody, "n"));
116 Subject[] subjects = new Subject[n];
117 for (int i = 0; i < subjects.length; i++) {
118 subjects[i] = Subject.Default.parseSubject(
119 SexpUtil.getNextList(tbody, "threshold subject #" + i),
120 issuer);
121 }
122 SexpUtil.checkDone(tbody, "threshold");
123 return new Threshold(subjects, k);
124 } catch (NumberFormatException e) {
125 throw new SexpParseException(
126 "badly formatted number in threshold");
127 }
128 }
129 }
This page was automatically generated by Maven