1/* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5/* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22package com.sun.org.apache.xerces.internal.impl.xs; 23 24import com.sun.org.apache.xerces.internal.impl.xs.util.XSGrammarPool; 25import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; 26import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription; 27import com.sun.org.apache.xerces.internal.xni.grammars.XSGrammar; 28import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; 29import com.sun.org.apache.xerces.internal.xs.LSInputList; 30import com.sun.org.apache.xerces.internal.xs.StringList; 31import com.sun.org.apache.xerces.internal.xs.XSConstants; 32import com.sun.org.apache.xerces.internal.xs.XSLoader; 33import com.sun.org.apache.xerces.internal.xs.XSModel; 34import com.sun.org.apache.xerces.internal.xs.XSNamedMap; 35import com.sun.org.apache.xerces.internal.xs.XSObjectList; 36import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; 37import org.w3c.dom.DOMConfiguration; 38import org.w3c.dom.DOMException; 39import org.w3c.dom.DOMStringList; 40import org.w3c.dom.ls.LSInput; 41 42/** 43 * <p>An implementation of XSLoader which wraps XMLSchemaLoader.</p> 44 * 45 * @xerces.internal 46 * 47 * @author Michael Glavassevich, IBM 48 * 49 */ 50public final class XSLoaderImpl implements XSLoader, DOMConfiguration { 51 52 /** 53 * Grammar pool. Need this to prevent us from 54 * getting two grammars from the same namespace. 55 */ 56 private final XSGrammarPool fGrammarPool = new XSGrammarMerger(); 57 58 /** Schema loader. **/ 59 private final XMLSchemaLoader fSchemaLoader = new XMLSchemaLoader(); 60 61 /** 62 * No-args constructor. 63 */ 64 public XSLoaderImpl() { 65 fSchemaLoader.setProperty(XMLSchemaLoader.XMLGRAMMAR_POOL, fGrammarPool); 66 } 67 68 /** 69 * The configuration of a document. It maintains a table of recognized 70 * parameters. Using the configuration, it is possible to change the 71 * behavior of the load methods. The configuration may support the 72 * setting of and the retrieval of the following non-boolean parameters 73 * defined on the <code>DOMConfiguration</code> interface: 74 * <code>error-handler</code> (<code>DOMErrorHandler</code>) and 75 * <code>resource-resolver</code> (<code>LSResourceResolver</code>). 76 * <br> The following list of boolean parameters is defined: 77 * <dl> 78 * <dt> 79 * <code>"validate"</code></dt> 80 * <dd> 81 * <dl> 82 * <dt><code>true</code></dt> 83 * <dd>[required] (default) Validate an XML 84 * Schema during loading. If validation errors are found, the error 85 * handler is notified. </dd> 86 * <dt><code>false</code></dt> 87 * <dd>[optional] Do not 88 * report errors during the loading of an XML Schema document. </dd> 89 * </dl></dd> 90 * </dl> 91 */ 92 public DOMConfiguration getConfig() { 93 return this; 94 } 95 96 /** 97 * Parses the content of XML Schema documents specified as the list of URI 98 * references. If the URI contains a fragment identifier, the behavior 99 * is not defined by this specification. 100 * @param uriList The list of URI locations. 101 * @return An XSModel representing the schema documents. 102 */ 103 public XSModel loadURIList(StringList uriList) { 104 int length = uriList.getLength(); 105 try { 106 fGrammarPool.clear(); 107 for (int i = 0; i < length; ++i) { 108 fSchemaLoader.loadGrammar(new XMLInputSource(null, uriList.item(i), null, false)); 109 } 110 return fGrammarPool.toXSModel(); 111 } 112 catch (Exception e) { 113 fSchemaLoader.reportDOMFatalError(e); 114 return null; 115 } 116 } 117 118 /** 119 * Parses the content of XML Schema documents specified as a list of 120 * <code>LSInput</code>s. 121 * @param is The list of <code>LSInput</code>s from which the XML 122 * Schema documents are to be read. 123 * @return An XSModel representing the schema documents. 124 */ 125 public XSModel loadInputList(LSInputList is) { 126 final int length = is.getLength(); 127 try { 128 fGrammarPool.clear(); 129 for (int i = 0; i < length; ++i) { 130 fSchemaLoader.loadGrammar(fSchemaLoader.dom2xmlInputSource(is.item(i))); 131 } 132 return fGrammarPool.toXSModel(); 133 } 134 catch (Exception e) { 135 fSchemaLoader.reportDOMFatalError(e); 136 return null; 137 } 138 } 139 140 /** 141 * Parse an XML Schema document from a location identified by a URI 142 * reference. If the URI contains a fragment identifier, the behavior is 143 * not defined by this specification. 144 * @param uri The location of the XML Schema document to be read. 145 * @return An XSModel representing this schema. 146 */ 147 public XSModel loadURI(String uri) { 148 try { 149 fGrammarPool.clear(); 150 return ((XSGrammar) fSchemaLoader.loadGrammar(new XMLInputSource(null, uri, null, false))).toXSModel(); 151 } 152 catch (Exception e){ 153 fSchemaLoader.reportDOMFatalError(e); 154 return null; 155 } 156 } 157 158 /** 159 * Parse an XML Schema document from a resource identified by a 160 * <code>LSInput</code> . 161 * @param is The <code>LSInput</code> from which the source 162 * document is to be read. 163 * @return An XSModel representing this schema. 164 */ 165 public XSModel load(LSInput is) { 166 try { 167 fGrammarPool.clear(); 168 return ((XSGrammar) fSchemaLoader.loadGrammar(fSchemaLoader.dom2xmlInputSource(is))).toXSModel(); 169 } 170 catch (Exception e) { 171 fSchemaLoader.reportDOMFatalError(e); 172 return null; 173 } 174 } 175 176 /* (non-Javadoc) 177 * @see com.sun.org.apache.xerces.internal.dom3.DOMConfiguration#setParameter(java.lang.String, java.lang.Object) 178 */ 179 public void setParameter(String name, Object value) throws DOMException { 180 fSchemaLoader.setParameter(name, value); 181 } 182 183 /* (non-Javadoc) 184 * @see com.sun.org.apache.xerces.internal.dom3.DOMConfiguration#getParameter(java.lang.String) 185 */ 186 public Object getParameter(String name) throws DOMException { 187 return fSchemaLoader.getParameter(name); 188 } 189 190 /* (non-Javadoc) 191 * @see com.sun.org.apache.xerces.internal.dom3.DOMConfiguration#canSetParameter(java.lang.String, java.lang.Object) 192 */ 193 public boolean canSetParameter(String name, Object value) { 194 return fSchemaLoader.canSetParameter(name, value); 195 } 196 197 /* (non-Javadoc) 198 * @see com.sun.org.apache.xerces.internal.dom3.DOMConfiguration#getParameterNames() 199 */ 200 public DOMStringList getParameterNames() { 201 return fSchemaLoader.getParameterNames(); 202 } 203 204 /** 205 * Grammar pool which merges grammars from the same namespace into one. This eliminates 206 * duplicate named components. It doesn't ensure that the grammar is consistent, however 207 * this no worse than than the behaviour of XMLSchemaLoader alone when used as an XSLoader. 208 */ 209 private static final class XSGrammarMerger extends XSGrammarPool { 210 211 public XSGrammarMerger () {} 212 213 public void putGrammar(Grammar grammar) { 214 SchemaGrammar cachedGrammar = 215 toSchemaGrammar(super.getGrammar(grammar.getGrammarDescription())); 216 if (cachedGrammar != null) { 217 SchemaGrammar newGrammar = toSchemaGrammar(grammar); 218 if (newGrammar != null) { 219 mergeSchemaGrammars(cachedGrammar, newGrammar); 220 } 221 } 222 else { 223 super.putGrammar(grammar); 224 } 225 } 226 227 private SchemaGrammar toSchemaGrammar (Grammar grammar) { 228 return (grammar instanceof SchemaGrammar) ? (SchemaGrammar) grammar : null; 229 } 230 231 private void mergeSchemaGrammars(SchemaGrammar cachedGrammar, SchemaGrammar newGrammar) { 232 233 /** Add new top-level element declarations. **/ 234 XSNamedMap map = newGrammar.getComponents(XSConstants.ELEMENT_DECLARATION); 235 int length = map.getLength(); 236 for (int i = 0; i < length; ++i) { 237 XSElementDecl decl = (XSElementDecl) map.item(i); 238 if (cachedGrammar.getGlobalElementDecl(decl.getName()) == null) { 239 cachedGrammar.addGlobalElementDecl(decl); 240 } 241 } 242 243 /** Add new top-level attribute declarations. **/ 244 map = newGrammar.getComponents(XSConstants.ATTRIBUTE_DECLARATION); 245 length = map.getLength(); 246 for (int i = 0; i < length; ++i) { 247 XSAttributeDecl decl = (XSAttributeDecl) map.item(i); 248 if (cachedGrammar.getGlobalAttributeDecl(decl.getName()) == null) { 249 cachedGrammar.addGlobalAttributeDecl(decl); 250 } 251 } 252 253 /** Add new top-level type definitions. **/ 254 map = newGrammar.getComponents(XSConstants.TYPE_DEFINITION); 255 length = map.getLength(); 256 for (int i = 0; i < length; ++i) { 257 XSTypeDefinition decl = (XSTypeDefinition) map.item(i); 258 if (cachedGrammar.getGlobalTypeDecl(decl.getName()) == null) { 259 cachedGrammar.addGlobalTypeDecl(decl); 260 } 261 } 262 263 /** Add new top-level attribute group definitions. **/ 264 map = newGrammar.getComponents(XSConstants.ATTRIBUTE_GROUP); 265 length = map.getLength(); 266 for (int i = 0; i < length; ++i) { 267 XSAttributeGroupDecl decl = (XSAttributeGroupDecl) map.item(i); 268 if (cachedGrammar.getGlobalAttributeGroupDecl(decl.getName()) == null) { 269 cachedGrammar.addGlobalAttributeGroupDecl(decl); 270 } 271 } 272 273 /** Add new top-level model group definitions. **/ 274 map = newGrammar.getComponents(XSConstants.MODEL_GROUP); 275 length = map.getLength(); 276 for (int i = 0; i < length; ++i) { 277 XSGroupDecl decl = (XSGroupDecl) map.item(i); 278 if (cachedGrammar.getGlobalGroupDecl(decl.getName()) == null) { 279 cachedGrammar.addGlobalGroupDecl(decl); 280 } 281 } 282 283 /** Add new top-level notation declarations. **/ 284 map = newGrammar.getComponents(XSConstants.NOTATION_DECLARATION); 285 length = map.getLength(); 286 for (int i = 0; i < length; ++i) { 287 XSNotationDecl decl = (XSNotationDecl) map.item(i); 288 if (cachedGrammar.getGlobalNotationDecl(decl.getName()) == null) { 289 cachedGrammar.addGlobalNotationDecl(decl); 290 } 291 } 292 293 /** 294 * Add all annotations. Since these components are not named it's 295 * possible we'll add duplicate components. There isn't much we can 296 * do. It's no worse than XMLSchemaLoader when used as an XSLoader. 297 */ 298 XSObjectList annotations = newGrammar.getAnnotations(); 299 length = annotations.getLength(); 300 for (int i = 0; i < length; ++i) { 301 cachedGrammar.addAnnotation((XSAnnotationImpl) annotations.item(i)); 302 } 303 304 } 305 306 public boolean containsGrammar(XMLGrammarDescription desc) { 307 return false; 308 } 309 310 public Grammar getGrammar(XMLGrammarDescription desc) { 311 return null; 312 } 313 314 public Grammar retrieveGrammar(XMLGrammarDescription desc) { 315 return null; 316 } 317 318 public Grammar [] retrieveInitialGrammarSet (String grammarType) { 319 return new Grammar[0]; 320 } 321 } 322} 323