de2252f22872615b37535f5b326f84e33147035b
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / xml / SchemaStore.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 /*
18  * Load and compile a bunch of XSD files from some repository. Schemas may be stored in a directory on disk, as
19  * resources in the Java classpath, in columns of an XML aware database, or in an XML "catalog" respository. This
20  * interface describes the functions that a SchemaStore must provide. Implementations will have additional properties or
21  * constructor arguments that define file paths, URL's (database, jdbc, jar, ...).
22  */
23
24 package edu.internet2.middleware.shibboleth.xml;
25
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.Map;
29
30 import javax.xml.XMLConstants;
31 import javax.xml.transform.Source;
32 import javax.xml.transform.dom.DOMSource;
33 import javax.xml.validation.Schema;
34 import javax.xml.validation.SchemaFactory;
35
36 import org.apache.log4j.Logger;
37 import org.w3c.dom.Document;
38 import org.xml.sax.SAXException;
39
40 /**
41  * Compile a Schema object from a Map of DOM objects representing XSD files keyed by the Namespace that the XSD defines.
42  * <p>
43  * This class is typically subclassed by implementations that obtain the Map of XSD DOMs from some external source.
44  * </p>
45  * 
46  * @author Howard Gilbert
47  */
48 public class SchemaStore {
49
50         private static Logger log = Logger.getLogger(SchemaStore.class);
51
52         protected Map/* <String,Document> */bucket = new HashMap/* <String,Document> */();
53
54         /**
55          * You can create the Map through a subclass and then just get a copy of the Map without compiling. This is useful
56          * when merging sources.
57          * 
58          * @return
59          */
60         public Map/* <String,Document> */getSchemaMap() {
61
62                 return bucket;
63         }
64
65         /**
66          * Can only construct this class from a Map.
67          * 
68          * @param bucket
69          */
70         public SchemaStore(Map/* <String,Document> */bucket) {
71
72                 super();
73                 this.bucket = bucket;
74         }
75
76         protected SchemaStore() {
77
78         }
79
80         /**
81          * Create JAXP 1.3 Schema object from list of namespaces and resource dir
82          * <p>
83          * This is an alternate approach to the Schema building logic used in org.opensaml.XML. That module is driven off a
84          * list of file names. This code reads in all the *.xsd files in a directory, indexes them by the namespace the
85          * schema defines, and then is driven off a list of namespaces. This is more more indirect and requires a bit more
86          * code, but it is more in line with the actual XSD standard where files and filenames are incidental. It can also
87          * be quickly ported to some other schema storage medium (LDAP, Database, ...).
88          * </p>
89          * 
90          * @param namespaces
91          *            Array of required XML namespaces for validation
92          * @param resourcedir
93          *            Resource directory with schema files ("/schemas/")
94          * @return Schema object combining all namespaces.
95          */
96         public Schema compileSchema(String[] namespaces) {
97
98                 Schema schema = null;
99                 ArrayList sources = new ArrayList();
100                 for (int i = 0; i < namespaces.length; i++) {
101                         Document doc = (Document) bucket.get(namespaces[i]);
102                         if (doc == null) {
103                                 log.error("Schema missing for namespace (" + namespaces[i] + ").");
104                         } else {
105                                 sources.add(new DOMSource(doc));
106                         }
107                 }
108                 // Now compile all the XSD files into a single composite Schema object
109                 SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
110                 try {
111                         schema = factory.newSchema((Source[]) sources.toArray(new Source[0]));
112                 } catch (SAXException e) {
113                         log.error("Schemas failed to compile, dependencies may be corrupt: " + e);
114                 }
115                 return schema;
116         }
117
118 }