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