Converting to OpenSAML metadata implementation.
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / metadata / provider / XMLMetadata.java
1 /*
2  * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package edu.internet2.middleware.shibboleth.metadata.provider;
18
19 import java.io.IOException;
20
21 import org.apache.log4j.Logger;
22 import org.opensaml.SAMLException;
23 import org.opensaml.XML;
24 import org.opensaml.artifact.Artifact;
25 import org.w3c.dom.Document;
26 import org.w3c.dom.Element;
27 import org.w3c.dom.NodeList;
28 import org.xml.sax.InputSource;
29 import org.xml.sax.SAXException;
30
31 import edu.internet2.middleware.shibboleth.common.ResourceWatchdog;
32 import edu.internet2.middleware.shibboleth.common.ResourceWatchdogExecutionException;
33 import edu.internet2.middleware.shibboleth.common.ShibResource;
34 import edu.internet2.middleware.shibboleth.common.ShibResource.ResourceNotAvailableException;
35 import edu.internet2.middleware.shibboleth.metadata.EntitiesDescriptor;
36 import edu.internet2.middleware.shibboleth.metadata.EntityDescriptor;
37 import edu.internet2.middleware.shibboleth.metadata.Metadata;
38 import edu.internet2.middleware.shibboleth.metadata.MetadataException;
39 import edu.internet2.middleware.shibboleth.xml.Parser;
40
41 /**
42  * @author Walter Hoehn (wassa@columbia.edu)
43  */
44 public class XMLMetadata extends ResourceWatchdog implements Metadata {
45
46         private static Logger log = Logger.getLogger(XMLMetadataLoadWrapper.class.getName());
47         private Metadata currentMeta;
48
49         public XMLMetadata(Element configuration) throws MetadataException, ResourceNotAvailableException {
50
51                 super(new ShibResource(configuration.getAttribute("uri"), XMLMetadata.class));
52
53                 try {
54
55                         if (configuration.getAttribute("uri") != null && !configuration.getAttribute("uri").equals("")) {
56                                 // The configuration points to a metadata file
57                                 InputSource src = new InputSource(resource.getInputStream());
58                                 src.setSystemId(resource.getURL().toString());
59                                 Document doc = Parser.loadDom(src, true);
60                                 currentMeta = new XMLMetadataProvider(doc.getDocumentElement());
61
62                                 // Start checking for metadata updates
63                                 start();
64
65                         } else {
66                                 // Hopefully, the configuration is inline (don't reload in this case)
67                                 NodeList children = configuration.getChildNodes();
68                                 for (int i = 0; i < children.getLength(); i++) {
69
70                                         if ((children.item(i) instanceof Element)
71                                                         && (XML.isElementNamed((Element) children.item(i),
72                                                                         edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS, "EntitiesDescriptor") || XML
73                                                                         .isElementNamed((Element) children.item(i),
74                                                                                         edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,
75                                                                                         "EntityDescriptor"))) {
76                                                 currentMeta = new XMLMetadataProvider((Element) children.item(i));
77                                                 return;
78                                         }
79                                 }
80                                 // We didn't find a uri pointer or inline metadata, bail out
81                                 log.error("Encountered a problem reading metadata: <MetadataProvider/> configuration must "
82                                                 + "include either a (uri) attribute or inline metadata.");
83                                 throw new MetadataException("Unable to read metadata.");
84                         }
85
86                 } catch (IOException e) {
87                         log.error("Encountered a problem reading metadata source: " + e);
88                         throw new MetadataException("Unable to read metadata: " + e);
89                 } catch (SAXException e) {
90                         log.error("Encountered a problem parsing metadata source: " + e);
91                         throw new MetadataException("Unable to read metadata: " + e);
92                 } catch (SAMLException e) {
93                         log.error("Encountered a problem processing metadata source: " + e);
94                         throw new MetadataException("Unable to read metadata: " + e);
95                 }
96
97         }
98
99         public XMLMetadata(String sitesFileLocation) throws MetadataException, ResourceNotAvailableException {
100
101                 super(new ShibResource(sitesFileLocation, XMLMetadata.class));
102                 try {
103                         InputSource src = new InputSource(resource.getInputStream());
104                         src.setSystemId(resource.getURL().toString());
105                         Document doc = Parser.loadDom(src, true);
106                         currentMeta = new XMLMetadataProvider(doc.getDocumentElement());
107                 } catch (IOException e) {
108                         log.error("Encountered a problem reading metadata source: " + e);
109                         throw new MetadataException("Unable to read metadata: " + e);
110                 } catch (SAXException e) {
111                         log.error("Encountered a problem parsing metadata source: " + e);
112                         throw new MetadataException("Unable to read metadata: " + e);
113                 } catch (SAMLException e) {
114                         log.error("Encountered a problem processing metadata source: " + e);
115                         throw new MetadataException("Unable to read metadata: + e");
116                 }
117
118                 // Start checking for metadata updates
119                 start();
120
121         }
122
123         public EntityDescriptor lookup(String providerId) {
124                 return lookup(providerId, true);
125         }
126
127         public EntityDescriptor lookup(Artifact artifact) {
128                 return lookup(artifact, true);
129         }
130
131         public EntityDescriptor lookup(String id, boolean strict) {
132                 synchronized (currentMeta) {
133                         return currentMeta.lookup(id, strict);
134                 }
135         }
136
137         public EntityDescriptor lookup(Artifact artifact, boolean strict) {
138                 synchronized (currentMeta) {
139                         return currentMeta.lookup(artifact, strict);
140                 }
141         }
142
143         public EntityDescriptor getRootEntity() {
144                 synchronized (currentMeta) {
145                         return currentMeta.getRootEntity();
146                 }
147         }
148
149         public EntitiesDescriptor getRootEntities() {
150                 synchronized (currentMeta) {
151                         return currentMeta.getRootEntities();
152                 }
153         }
154
155         protected void doOnChange() throws ResourceWatchdogExecutionException {
156
157                 Metadata newMeta = null;
158
159                 try {
160                         log.info("Detected a change in the metadata. Reloading from (" + resource.getURL().toString() + ").");
161                         newMeta = new XMLMetadataProvider(XML.parserPool.parse(resource.getInputStream()).getDocumentElement());
162                 } catch (IOException e) {
163                         log.error("Encountered an error retrieving updated SAML metadata, continuing to use stale copy: " + e);
164                         return;
165                 } catch (SAXException e) {
166                         log.error("Encountered an error retrieving updated SAML metadata, continuing to use stale copy: " + e);
167                         return;
168                 } catch (SAMLException e) {
169                         log.error("Encountered an error retrieving updated SAML metadata, continuing to use stale copy: " + e);
170                         return;
171                 }
172
173                 if (newMeta != null) {
174                         synchronized (currentMeta) {
175                                 currentMeta = newMeta;
176                         }
177                 }
178         }
179 }