1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.opensaml.saml2.metadata.provider;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22 import java.util.Set;
23 import java.util.concurrent.locks.Lock;
24 import java.util.concurrent.locks.ReadWriteLock;
25 import java.util.concurrent.locks.ReentrantReadWriteLock;
26
27 import javax.xml.namespace.QName;
28
29 import org.joda.time.DateTime;
30 import org.opensaml.saml2.common.Extensions;
31 import org.opensaml.saml2.metadata.EntitiesDescriptor;
32 import org.opensaml.saml2.metadata.EntityDescriptor;
33 import org.opensaml.saml2.metadata.RoleDescriptor;
34 import org.opensaml.xml.Namespace;
35 import org.opensaml.xml.XMLObject;
36 import org.opensaml.xml.signature.Signature;
37 import org.opensaml.xml.util.IDIndex;
38 import org.opensaml.xml.util.LazySet;
39 import org.opensaml.xml.validation.ValidationException;
40 import org.opensaml.xml.validation.Validator;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43 import org.w3c.dom.Element;
44
45
46
47
48
49
50
51
52
53
54
55
56 public class ChainingMetadataProvider extends BaseMetadataProvider implements ObservableMetadataProvider {
57
58
59 private final Logger log = LoggerFactory.getLogger(ChainingMetadataProvider.class);
60
61
62 private ArrayList<Observer> observers;
63
64
65 private ArrayList<MetadataProvider> providers;
66
67
68 private ReadWriteLock providerLock;
69
70
71 public ChainingMetadataProvider() {
72 super();
73 observers = new ArrayList<Observer>();
74 providers = new ArrayList<MetadataProvider>();
75 providerLock = new ReentrantReadWriteLock(true);
76 }
77
78
79
80
81
82
83 public List<MetadataProvider> getProviders() {
84 return Collections.unmodifiableList(providers);
85 }
86
87
88
89
90
91
92
93
94 public void setProviders(List<MetadataProvider> newProviders) throws MetadataProviderException {
95 providers.clear();
96 for (MetadataProvider provider : newProviders) {
97 addMetadataProvider(provider);
98 }
99 }
100
101
102
103
104
105
106
107
108 public void addMetadataProvider(MetadataProvider newProvider) throws MetadataProviderException {
109 if (newProvider != null) {
110 newProvider.setRequireValidMetadata(requireValidMetadata());
111
112 if (newProvider instanceof ObservableMetadataProvider) {
113 ((ObservableMetadataProvider) newProvider).getObservers().add(new ContainedProviderObserver());
114 }
115
116 providers.add(newProvider);
117 }
118 }
119
120
121
122
123
124
125 public void removeMetadataProvider(MetadataProvider provider) {
126
127 providers.remove(provider);
128 }
129
130
131 public void setRequireValidMetadata(boolean requireValidMetadata) {
132 super.setRequireValidMetadata(requireValidMetadata);
133
134 Lock writeLock = providerLock.writeLock();
135 writeLock.lock();
136 for (MetadataProvider provider : providers) {
137 provider.setRequireValidMetadata(requireValidMetadata);
138 }
139 writeLock.unlock();
140 }
141
142
143 public MetadataFilter getMetadataFilter() {
144 log.warn("Attempt to access unsupported MetadataFilter property on ChainingMetadataProvider");
145 return null;
146 }
147
148
149 public void setMetadataFilter(MetadataFilter newFilter) throws MetadataProviderException {
150 throw new UnsupportedOperationException("Metadata filter is not allowed on ChainingMetadataProvider");
151 }
152
153
154
155
156
157
158 public XMLObject getMetadata() throws MetadataProviderException {
159 return new ChainingEntitiesDescriptor();
160 }
161
162
163 public EntitiesDescriptor getEntitiesDescriptor(String name) throws MetadataProviderException {
164 Lock readLock = providerLock.readLock();
165 readLock.lock();
166
167 EntitiesDescriptor descriptor = null;
168 try {
169 for (MetadataProvider provider : providers) {
170 log.debug("Checking child metadata provider for entities descriptor with name: {}", name);
171 descriptor = provider.getEntitiesDescriptor(name);
172 if (descriptor != null) {
173 break;
174 }
175 }
176 } catch (MetadataProviderException e) {
177 throw e;
178 } finally {
179 readLock.unlock();
180 }
181
182 return descriptor;
183 }
184
185
186 public EntityDescriptor getEntityDescriptor(String entityID) throws MetadataProviderException {
187 Lock readLock = providerLock.readLock();
188 readLock.lock();
189
190 EntityDescriptor descriptor = null;
191 try {
192 for (MetadataProvider provider : providers) {
193 log.debug("Checking child metadata provider for entity descriptor with entity ID: {}", entityID);
194 descriptor = provider.getEntityDescriptor(entityID);
195 if (descriptor != null) {
196 break;
197 }
198 }
199 } catch (MetadataProviderException e) {
200 throw e;
201 } finally {
202 readLock.unlock();
203 }
204
205 return descriptor;
206 }
207
208
209 public List<RoleDescriptor> getRole(String entityID, QName roleName) throws MetadataProviderException {
210 EntityDescriptor entityMetadata = getEntityDescriptor(entityID);
211 if (entityMetadata == null) {
212 return null;
213 }
214
215 return entityMetadata.getRoleDescriptors(roleName);
216 }
217
218
219 public RoleDescriptor getRole(String entityID, QName roleName, String supportedProtocol)
220 throws MetadataProviderException {
221 EntityDescriptor entityMetadata = getEntityDescriptor(entityID);
222 if (entityMetadata == null) {
223 return null;
224 }
225
226 List<RoleDescriptor> roles = entityMetadata.getRoleDescriptors(roleName, supportedProtocol);
227 if (roles != null && !roles.isEmpty()) {
228 return roles.get(0);
229 }
230
231 return null;
232 }
233
234
235 public List<Observer> getObservers() {
236 return observers;
237 }
238
239
240
241
242
243
244 protected void emitChangeEvent() {
245 if (observers == null || observers.size() == 0) {
246 return;
247 }
248
249 List<Observer> tempObserverList = new ArrayList<Observer>(observers);
250 for (Observer observer : tempObserverList) {
251 if (observer != null) {
252 observer.onEvent(this);
253 }
254 }
255 }
256
257
258
259
260 private class ContainedProviderObserver implements Observer {
261
262
263 public void onEvent(MetadataProvider provider) {
264 emitChangeEvent();
265 }
266 }
267
268
269 private class ChainingEntitiesDescriptor implements EntitiesDescriptor {
270
271
272 private ArrayList<XMLObject> childDescriptors;
273
274
275 public ChainingEntitiesDescriptor() {
276 childDescriptors = new ArrayList<XMLObject>();
277
278 Lock readLock = providerLock.readLock();
279 readLock.lock();
280 try {
281 for (MetadataProvider provider : providers) {
282 childDescriptors.add(provider.getMetadata());
283 }
284 } catch (MetadataProviderException e) {
285 log.error("Unable to get metadata from child metadata provider", e);
286 } finally {
287 readLock.unlock();
288 }
289 }
290
291
292 public List<EntitiesDescriptor> getEntitiesDescriptors() {
293 ArrayList<EntitiesDescriptor> descriptors = new ArrayList<EntitiesDescriptor>();
294 for (XMLObject descriptor : childDescriptors) {
295 if (descriptor instanceof EntitiesDescriptor) {
296 descriptors.add((EntitiesDescriptor) descriptor);
297 }
298 }
299
300 return descriptors;
301 }
302
303
304 public List<EntityDescriptor> getEntityDescriptors() {
305 ArrayList<EntityDescriptor> descriptors = new ArrayList<EntityDescriptor>();
306 for (XMLObject descriptor : childDescriptors) {
307 if (descriptor instanceof EntityDescriptor) {
308 descriptors.add((EntityDescriptor) descriptor);
309 }
310 }
311
312 return descriptors;
313 }
314
315
316 public Extensions getExtensions() {
317 return null;
318 }
319
320
321 public String getID() {
322 return null;
323 }
324
325
326 public String getName() {
327 return null;
328 }
329
330
331 public void setExtensions(Extensions extensions) {
332
333 }
334
335
336 public void setID(String newID) {
337
338 }
339
340
341 public void setName(String name) {
342
343 }
344
345
346 public String getSignatureReferenceID() {
347 return null;
348 }
349
350
351 public Signature getSignature() {
352 return null;
353 }
354
355
356 public boolean isSigned() {
357 return false;
358 }
359
360
361 public void setSignature(Signature newSignature) {
362
363 }
364
365
366 public void addNamespace(Namespace namespace) {
367
368 }
369
370
371 public void detach() {
372
373 }
374
375
376 public Element getDOM() {
377 return null;
378 }
379
380
381 public QName getElementQName() {
382 return EntitiesDescriptor.DEFAULT_ELEMENT_NAME;
383 }
384
385
386 public IDIndex getIDIndex() {
387 return null;
388 }
389
390
391 public Set<Namespace> getNamespaces() {
392 return new LazySet<Namespace>();
393 }
394
395
396 public String getNoNamespaceSchemaLocation() {
397 return null;
398 }
399
400
401 public List<XMLObject> getOrderedChildren() {
402 ArrayList<XMLObject> descriptors = new ArrayList<XMLObject>();
403 try {
404 for (MetadataProvider provider : providers) {
405 descriptors.add(provider.getMetadata());
406 }
407 } catch (MetadataProviderException e) {
408 log.error("Unable to generate list of child descriptors", e);
409 }
410
411 return descriptors;
412 }
413
414
415 public XMLObject getParent() {
416 return null;
417 }
418
419
420 public String getSchemaLocation() {
421 return null;
422 }
423
424
425 public QName getSchemaType() {
426 return EntitiesDescriptor.TYPE_NAME;
427 }
428
429
430 public boolean hasChildren() {
431 return !getOrderedChildren().isEmpty();
432 }
433
434
435 public boolean hasParent() {
436 return false;
437 }
438
439
440 public void releaseChildrenDOM(boolean propagateRelease) {
441
442 }
443
444
445 public void releaseDOM() {
446
447 }
448
449
450 public void releaseParentDOM(boolean propagateRelease) {
451
452 }
453
454
455 public void removeNamespace(Namespace namespace) {
456
457 }
458
459
460 public XMLObject resolveID(String id) {
461 return null;
462 }
463
464
465 public XMLObject resolveIDFromRoot(String id) {
466 return null;
467 }
468
469
470 public void setDOM(Element dom) {
471
472 }
473
474
475 public void setNoNamespaceSchemaLocation(String location) {
476
477 }
478
479
480 public void setParent(XMLObject parent) {
481
482 }
483
484
485 public void setSchemaLocation(String location) {
486
487 }
488
489
490 public void deregisterValidator(Validator validator) {
491
492 }
493
494
495 public List<Validator> getValidators() {
496 return new ArrayList<Validator>();
497 }
498
499
500 public void registerValidator(Validator validator) {
501 }
502
503
504 public void validate(boolean validateDescendants) throws ValidationException {
505 }
506
507
508 public DateTime getValidUntil() {
509 return null;
510 }
511
512
513 public boolean isValid() {
514 return true;
515 }
516
517
518 public void setValidUntil(DateTime validUntil) {
519
520 }
521
522
523 public Long getCacheDuration() {
524 return null;
525 }
526
527
528 public void setCacheDuration(Long duration) {
529
530 }
531
532 }
533 }