1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.opensaml.xml.encryption;
18
19 import java.util.ArrayList;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.NoSuchElementException;
23
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27
28
29
30
31 public class ChainingEncryptedKeyResolver extends AbstractEncryptedKeyResolver {
32
33
34 private final List<EncryptedKeyResolver> resolvers;
35
36
37 private final Logger log = LoggerFactory.getLogger(ChainingEncryptedKeyResolver.class);
38
39
40 public ChainingEncryptedKeyResolver() {
41 resolvers = new ArrayList<EncryptedKeyResolver>();
42 }
43
44
45
46
47
48
49 public List<EncryptedKeyResolver> getResolverChain() {
50 return resolvers;
51 }
52
53
54 public Iterable<EncryptedKey> resolve(EncryptedData encryptedData) {
55 if (resolvers.isEmpty()) {
56 log.warn("Chaining encrypted key resolver resolution was attempted with an empty resolver chain");
57 throw new IllegalStateException("The resolver chain is empty");
58 }
59 return new ChainingIterable(this, encryptedData);
60 }
61
62
63
64
65 public class ChainingIterable implements Iterable<EncryptedKey> {
66
67
68 private ChainingEncryptedKeyResolver parent;
69
70
71 private EncryptedData encryptedData;
72
73
74
75
76
77
78
79 public ChainingIterable(ChainingEncryptedKeyResolver resolver, EncryptedData encData) {
80 parent = resolver;
81 encryptedData = encData;
82 }
83
84
85 public Iterator<EncryptedKey> iterator() {
86 return new ChainingIterator(parent, encryptedData);
87 }
88
89 }
90
91
92
93
94
95 public class ChainingIterator implements Iterator<EncryptedKey> {
96
97
98 private final Logger log = LoggerFactory.getLogger(ChainingEncryptedKeyResolver.ChainingIterator.class);
99
100
101 private ChainingEncryptedKeyResolver parent;
102
103
104 private EncryptedData encryptedData;
105
106
107 private Iterator<EncryptedKeyResolver> resolverIterator;
108
109
110 private Iterator<EncryptedKey> keyIterator;
111
112
113 private EncryptedKeyResolver currentResolver;
114
115
116 private EncryptedKey nextKey;
117
118
119
120
121
122
123
124 public ChainingIterator(ChainingEncryptedKeyResolver resolver, EncryptedData encData) {
125 parent = resolver;
126 encryptedData = encData;
127 resolverIterator = parent.getResolverChain().iterator();
128 keyIterator = getNextKeyIterator();
129 nextKey = null;
130 }
131
132
133 public boolean hasNext() {
134 if (nextKey != null) {
135 return true;
136 }
137 nextKey = getNextKey();
138 if (nextKey != null) {
139 return true;
140 }
141 return false;
142 }
143
144
145 public EncryptedKey next() {
146 EncryptedKey tempKey;
147 if (nextKey != null) {
148 tempKey = nextKey;
149 nextKey = null;
150 return tempKey;
151 }
152 tempKey = getNextKey();
153 if (tempKey != null) {
154 return tempKey;
155 } else {
156 throw new NoSuchElementException("No more EncryptedKey elements are available");
157 }
158 }
159
160
161 public void remove() {
162 throw new UnsupportedOperationException("Remove operation is not supported by this iterator");
163 }
164
165
166
167
168
169
170 private Iterator<EncryptedKey> getNextKeyIterator() {
171 if (resolverIterator.hasNext()) {
172 currentResolver = resolverIterator.next();
173 log.debug("Getting key iterator from next resolver: {}", currentResolver.getClass().toString());
174 return currentResolver.resolve(encryptedData).iterator();
175 } else {
176 log.debug("No more resolvers available in the resolver chain");
177 currentResolver = null;
178 return null;
179 }
180 }
181
182
183
184
185
186
187 private EncryptedKey getNextKey() {
188 EncryptedKey tempKey;
189
190 if (keyIterator != null) {
191 while (keyIterator.hasNext()) {
192 tempKey = keyIterator.next();
193 if (parent.matchRecipient(tempKey.getRecipient())) {
194 log.debug("Found matching encrypted key: {}", tempKey.toString());
195 return tempKey;
196 }
197 }
198 }
199
200 keyIterator = getNextKeyIterator();
201 while (keyIterator != null) {
202 while (keyIterator.hasNext()) {
203 tempKey = keyIterator.next();
204 if (parent.matchRecipient(tempKey.getRecipient())) {
205 log.debug("Found matching encrypted key: {}", tempKey.toString());
206 return tempKey;
207 }
208 }
209 keyIterator = getNextKeyIterator();
210 }
211
212 return null;
213 }
214
215 }
216
217 }