Re-implemented remaining config options for HS.
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / common / OriginConfig.java
1 /*
2  * The Shibboleth License, Version 1. Copyright (c) 2002 University Corporation
3  * for Advanced Internet Development, Inc. All rights reserved
4  * 
5  * 
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  * 
9  * Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  * 
12  * Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution, if any, must include
15  * the following acknowledgment: "This product includes software developed by
16  * the University Corporation for Advanced Internet Development
17  * <http://www.ucaid.edu> Internet2 Project. Alternately, this acknowledegement
18  * may appear in the software itself, if and wherever such third-party
19  * acknowledgments normally appear.
20  * 
21  * Neither the name of Shibboleth nor the names of its contributors, nor
22  * Internet2, nor the University Corporation for Advanced Internet Development,
23  * Inc., nor UCAID may be used to endorse or promote products derived from this
24  * software without specific prior written permission. For written permission,
25  * please contact shibboleth@shibboleth.org
26  * 
27  * Products derived from this software may not be called Shibboleth, Internet2,
28  * UCAID, or the University Corporation for Advanced Internet Development, nor
29  * may Shibboleth appear in their name, without prior written permission of the
30  * University Corporation for Advanced Internet Development.
31  * 
32  * 
33  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
34  * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
35  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
36  * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
37  * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
38  * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
39  * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY
40  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
41  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
45  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46  */
47
48 package edu.internet2.middleware.shibboleth.common;
49
50 import java.io.IOException;
51 import java.io.InputStream;
52 import java.util.StringTokenizer;
53
54 import javax.servlet.http.HttpServlet;
55 import javax.servlet.ServletContext;
56
57 import org.apache.log4j.Logger;
58 import org.apache.xerces.parsers.DOMParser;
59 import org.xml.sax.EntityResolver;
60 import org.xml.sax.ErrorHandler;
61 import org.xml.sax.InputSource;
62 import org.xml.sax.SAXException;
63 import org.xml.sax.SAXParseException;
64 import org.w3c.dom.Document;
65
66 /**
67  * Constructs a DOM tree for the origin configuration XML file.
68  * 
69  * @author Walter Hoehn
70  * @author Noah Levitt
71  */
72 public class OriginConfig {
73
74         private static Logger log = Logger.getLogger(OriginConfig.class);
75         private static Document originConfig = null;
76         private static String originConfigFile = null;
77
78         // never returns null
79         private static String getOriginConfigFile(ServletContext context)
80         {
81                 if (context.getInitParameter("OriginConfigFile") != null)
82                 {
83                         return context.getInitParameter("OriginConfigFile");
84                 }
85                 else
86                 {
87                         return "/conf/origin.xml";
88                 }
89         }
90
91         /**
92          * Loads the Origin Configuration file into a DOM tree.
93          * 
94          * @return the DOM Document
95          * @throws ShibbolethConfigurationException
96          *             if there was an error loading the file
97          */
98         public static synchronized Document getOriginConfig(ServletContext context) throws ShibbolethConfigurationException 
99         {
100                 if (getOriginConfigFile(context).equals(originConfigFile))
101                 {
102                         return originConfig;
103                 }
104                 else if (originConfigFile == null)
105                 {
106                         originConfigFile = getOriginConfigFile(context);
107                 }
108                 else 
109                 {
110                         log.error("Previously read origin configuration from (" + originConfigFile + "), re-reading from (" + getOriginConfigFile(context) + "). This probably indicates a bug in shibboleth.");
111                         originConfigFile = getOriginConfigFile(context);
112                 }
113
114                 originConfigFile = context.getInitParameter("OriginConfigFile");
115
116                 DOMParser parser = new DOMParser();
117
118                 try {
119                         parser.setFeature("http://xml.org/sax/features/validation", true);
120                         parser.setFeature("http://apache.org/xml/features/validation/schema", true);
121
122                         parser.setEntityResolver(new EntityResolver() {
123                                 public InputSource resolveEntity(String publicId, String systemId) throws SAXException {
124                                         log.debug("Resolving entity for System ID: " + systemId);
125                                         if (systemId != null) {
126                                                 StringTokenizer tokenString = new StringTokenizer(systemId, "/");
127                                                 String xsdFile = "";
128                                                 while (tokenString.hasMoreTokens()) {
129                                                         xsdFile = tokenString.nextToken();
130                                                 }
131                                                 if (xsdFile.endsWith(".xsd")) {
132                                                         InputStream stream;
133                                                         try {
134                                                                 stream = new ShibResource("/schemas/" + xsdFile, OriginConfig.class).getInputStream();
135                                                         } catch (IOException ioe) {
136                                                                 log.error("Error loading schema: " + xsdFile + ": " + ioe);
137                                                                 return null;
138                                                         }
139                                                         if (stream != null) {
140                                                                 return new InputSource(stream);
141                                                         }
142                                                 }
143                                         }
144                                         return null;
145                                 }
146                         });
147
148                         parser.setErrorHandler(new ErrorHandler() {
149                                 public void error(SAXParseException arg0) throws SAXException {
150                                         throw new SAXException("Error parsing xml file: " + arg0);
151                                 }
152                                 public void fatalError(SAXParseException arg0) throws SAXException {
153                                         throw new SAXException("Error parsing xml file: " + arg0);
154                                 }
155                                 public void warning(SAXParseException arg0) throws SAXException {
156                                         throw new SAXException("Error parsing xml file: " + arg0);
157                                 }
158                         });
159
160                 } catch (SAXException e) {
161                         log.error("Unable to setup a workable XML parser: " + e);
162                         throw new ShibbolethConfigurationException("Unable to setup a workable XML parser.");
163                 }
164
165                 log.debug("Loading Configuration from (" + originConfigFile + ").");
166
167                 try {
168                         parser.parse(new InputSource(new ShibResource(originConfigFile, OriginConfig.class).getInputStream()));
169                 } catch (SAXException e) {
170                         log.error("Error while parsing origin configuration: " + e);
171                         throw new ShibbolethConfigurationException("Error while parsing origin configuration:" + e);
172                 } catch (IOException e) {
173                         log.error("Could not load origin configuration: " + e);
174                         throw new ShibbolethConfigurationException("Could not load origin configuration.");
175                 }
176
177                 originConfig = parser.getDocument();
178
179                 return originConfig;
180         }
181 }