View Javadoc
1 /* 2 * XmlParser.java 3 * Created on August 3, 2003 4 * 5 * The Blues Framework - A lightweight application framework 6 * Copyright (C) 2003 Lonnie Pryor 7 * http://blues.lonniepryor.com 8 * 9 * This library is free software; you can redistribute it and/or modify it under the 10 * terms of the GNU Lesser General Public License as published by the Free Software 11 * Foundation; either version 2.1 of the License, or (at your option) any later 12 * version. 13 * 14 * This library is distributed in the hope that it will be useful, but WITHOUT ANY 15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 16 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public License along 19 * with this library; if not, write to: 20 * 21 * The Free Software Foundation, Inc. 22 * 59 Temple Place, Suite 330 23 * Boston, MA 02111-1307 USA 24 * 25 */ 26 package com.lonniepryor.blues.xml; 27 28 import java.io.IOException; 29 import java.io.InputStream; 30 31 import java.net.URL; 32 33 import java.util.ArrayList; 34 import java.util.Collection; 35 import java.util.Enumeration; 36 import java.util.HashMap; 37 import java.util.Iterator; 38 import java.util.Map; 39 import java.util.Properties; 40 41 import javax.xml.parsers.SAXParser; 42 import javax.xml.parsers.SAXParserFactory; 43 44 import com.lonniepryor.blues.cfg.ApplicationCfg; 45 import com.lonniepryor.blues.cfg.IncludeCfg; 46 import com.lonniepryor.blues.cfg.ModuleCfg; 47 48 /*** 49 * Responsible for loading XML Schemas and parsing application and module 50 * configurations. NOTE: this class is NOT thread-safe and instances may only be 51 * used on a single thread at a time. 52 * 53 * @author Lonnie Pryor 54 * @version $Revision: 1.2 $ 55 */ 56 public class XmlParser { 57 /*** JAXP schema language property. */ 58 private static final String jaxpSchemaLanguage = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; 59 /*** JAXP schema source property. */ 60 private static final String jaxpSchemaSource = "http://java.sun.com/xml/jaxp/properties/schemaSource"; 61 /*** URI of the XML Schema namespace. */ 62 private static final String xmlSchemaNamespaceUri = "http://www.w3.org/2001/XMLSchema"; 63 /*** Path to schema index documents. */ 64 private static final String schemaIndexPath = "META-INF/schemas.blues.properties"; 65 /*** The class loader to use. */ 66 private final ClassLoader classLoader; 67 /*** The SAX parser to parse documents with. */ 68 private final SAXParser schemaValidatingParser; 69 70 /*** 71 * Creates a new XmlParser object. 72 * 73 * @param classLoader The class loader to use. 74 */ 75 public XmlParser (ClassLoader classLoader) { 76 this( 77 classLoader, 78 createSchemaValidatingParser(classLoader, SAXParserFactory.newInstance())); 79 } 80 81 /*** 82 * Creates a new XmlParser object. 83 * 84 * @param classLoader The class loader to use. 85 * @param saxParserFactory FIXME 86 */ 87 public XmlParser (ClassLoader classLoader, SAXParserFactory saxParserFactory) { 88 this(classLoader, createSchemaValidatingParser(classLoader, saxParserFactory)); 89 } 90 91 /*** 92 * Creates a new XmlParser object. 93 * 94 * @param classLoader The class loader to use. 95 * @param schemaValidatingParser FIXME 96 */ 97 protected XmlParser (ClassLoader classLoader, SAXParser schemaValidatingParser) { 98 if (classLoader == null) 99 throw new NullPointerException("classLoader"); 100 if (schemaValidatingParser == null) 101 throw new NullPointerException("schemaValidatingParser"); 102 this.classLoader = classLoader; 103 this.schemaValidatingParser = schemaValidatingParser; 104 } 105 106 /*** 107 * Creates a JAXP 1.2 parser that validates according to XML Schema. 108 * 109 * @param classLoader The class loader to load schemas from. 110 * @param saxParserFactory The sax parser factory to construct a parser with. 111 * 112 * @return A JAXP 1.2 parser that validates according to XML Schema. 113 */ 114 public static SAXParser createSchemaValidatingParser ( 115 ClassLoader classLoader, SAXParserFactory saxParserFactory) { 116 SAXParser schemaValidatingParser = null; 117 try { 118 schemaValidatingParser = saxParserFactory.newSAXParser(); 119 } catch (Exception e) { 120 throw new XmlException("Error creating parser instance", e); 121 } 122 try { 123 schemaValidatingParser.setProperty(jaxpSchemaLanguage, xmlSchemaNamespaceUri); 124 schemaValidatingParser.setProperty( 125 jaxpSchemaSource, openAllSchemas(classLoader).toArray()); 126 } catch (Exception e) { 127 throw new XmlException("Error initalizing XML schemas", e); 128 } 129 return schemaValidatingParser; 130 } 131 132 /*** 133 * Opens an XML Schema document for every namespace uri declared in the schema 134 * index files. 135 * 136 * @param classLoader The class loader to load schemas from. 137 * 138 * @return A Collection of InputStreams pointing to all of the schema documents. 139 * 140 * @throws IOException If the schema loading fails. 141 */ 142 private static Collection openAllSchemas (ClassLoader classLoader) 143 throws IOException { 144 Map allSchemas = new HashMap(); 145 Properties props = new Properties(); 146 for ( 147 Enumeration enum = classLoader.getResources(schemaIndexPath); 148 enum.hasMoreElements();) { 149 InputStream in = ((URL)enum.nextElement()).openStream(); 150 try { 151 props.load(in); 152 } finally { 153 in.close(); 154 } 155 for (Iterator iter = props.entrySet().iterator(); iter.hasNext();) { 156 Map.Entry entry = (Map.Entry)iter.next(); 157 if (!allSchemas.containsKey(entry.getValue())) 158 allSchemas.put(entry.getValue(), entry.getKey()); 159 } 160 props.clear(); 161 } 162 Collection allInputStreams = new ArrayList(); 163 try { 164 for (Iterator iter = allSchemas.values().iterator(); iter.hasNext();) 165 allInputStreams.add( 166 classLoader.getResource((String)iter.next()).openStream()); 167 } catch (IOException ioe) { 168 for (Iterator iter = allInputStreams.iterator(); iter.hasNext();) { 169 try { 170 ((InputStream)iter.next()).close(); 171 } catch (IOException ignore) { 172 ; 173 } 174 } 175 throw ioe; 176 } 177 return allInputStreams; 178 } 179 180 /*** 181 * Parses a Blues application configuration file. 182 * 183 * @param documentPath The location of the configuration file. 184 * 185 * @return The assembled application configuration. 186 */ 187 public ApplicationCfg parseApplication (String documentPath) { 188 if (documentPath == null) 189 throw new NullPointerException("documentPath"); 190 GraphBuilder builder = new GraphBuilder(classLoader); 191 ApplicationCfg appCfg = (ApplicationCfg)builder.buildGraph( 192 schemaValidatingParser, documentPath); 193 ModuleCfg modCfg = appCfg.getRootModule(); 194 if (modCfg != null) 195 parseIncludedModules(builder, modCfg, documentPath); 196 return appCfg; 197 } 198 199 /*** 200 * Parses a Blues module configuration file. 201 * 202 * @param documentPath The location of the configuration file. 203 * 204 * @return The assembled module configuration. 205 */ 206 public ModuleCfg parseModule (String documentPath) { 207 if (documentPath == null) 208 throw new NullPointerException("documentPath"); 209 GraphBuilder builder = new GraphBuilder(classLoader); 210 ModuleCfg modCfg = (ModuleCfg)builder.buildGraph( 211 schemaValidatingParser, documentPath); 212 parseIncludedModules(builder, modCfg, documentPath); 213 return modCfg; 214 } 215 216 /*** 217 * Loads and initalizes all included modules. 218 * 219 * @param builder The graph builder to use. 220 * @param modCfg The module config to inialize. 221 * @param docPath The path of the document the module was declared in. 222 */ 223 private void parseIncludedModules ( 224 GraphBuilder builder, ModuleCfg modCfg, String docPath) { 225 String pathBase = docPath.substring(0, docPath.lastIndexOf('/') + 1); 226 IncludeCfg[] includes = modCfg.getIncludes(); 227 for (int i = 0; i < includes.length; ++i) { 228 String includedModPath = includes[i].getModulePath().startsWith("/") 229 ? includes[i].getModulePath().substring(1) 230 : (pathBase + includes[i].getModulePath()); 231 ModuleCfg includedMod = (ModuleCfg)builder.buildGraph( 232 schemaValidatingParser, includedModPath); 233 parseIncludedModules(builder, includedMod, includedModPath); 234 includes[i].initIncludedModule(includedMod); 235 } 236 } 237 }

This page was automatically generated by Maven