1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xerces" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 1999, International
  53. * Business Machines, Inc., http://www.apache.org. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package com.sun.org.apache.xerces.internal.jaxp.validation.xs;
  58. import java.io.IOException;
  59. import java.util.Locale;
  60. import javax.xml.XMLConstants;
  61. import javax.xml.transform.Source;
  62. import javax.xml.validation.Schema;
  63. import javax.xml.validation.SchemaFactory;
  64. import com.sun.org.apache.xerces.internal.impl.Constants;
  65. import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader;
  66. import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter;
  67. import com.sun.org.apache.xerces.internal.jaxp.validation.ReadonlyGrammarPool;
  68. import com.sun.org.apache.xerces.internal.jaxp.validation.Util;
  69. import com.sun.org.apache.xerces.internal.jaxp.validation.XercesConstants;
  70. import com.sun.org.apache.xerces.internal.util.DOMEntityResolverWrapper;
  71. import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper;
  72. import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter;
  73. import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl;
  74. import com.sun.org.apache.xerces.internal.xni.XNIException;
  75. import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
  76. import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
  77. import org.w3c.dom.ls.LSResourceResolver;
  78. import org.xml.sax.ErrorHandler;
  79. import org.xml.sax.SAXException;
  80. import org.xml.sax.SAXParseException;
  81. import com.sun.org.apache.xerces.internal.util.SecurityManager;
  82. import org.xml.sax.SAXNotRecognizedException;
  83. import org.xml.sax.SAXNotSupportedException;
  84. /**
  85. * {@link SchemaFactory} for XML Schema.
  86. *
  87. * @author
  88. * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
  89. */
  90. public class SchemaFactoryImpl extends SchemaFactory {
  91. private final XMLSchemaLoader loader = new XMLSchemaLoader();
  92. private static XSMessageFormatter messageFormatter = new XSMessageFormatter();
  93. /**
  94. * User-specified ErrorHandler. can be null.
  95. */
  96. private ErrorHandler errorHandler;
  97. private LSResourceResolver resourceResolver;
  98. private SAXParseException lastException;
  99. private final SecurityManager secureProcessing ;
  100. private boolean enableSP;
  101. public SchemaFactoryImpl() {
  102. secureProcessing = new SecurityManager();
  103. // intercept error report and remember the last thrown exception.
  104. loader.setErrorHandler(new ErrorHandlerWrapper(new ErrorHandler() {
  105. public void warning(SAXParseException exception) throws SAXException {
  106. if( errorHandler!=null ) errorHandler.warning(exception);
  107. }
  108. public void error(SAXParseException exception) throws SAXException {
  109. lastException = exception;
  110. if( errorHandler!=null ) errorHandler.error(exception);
  111. else throw exception;
  112. }
  113. public void fatalError(SAXParseException exception) throws SAXException {
  114. lastException = exception;
  115. if( errorHandler!=null ) errorHandler.fatalError(exception);
  116. else throw exception;
  117. }
  118. }));
  119. }
  120. /**
  121. * <p>Is specified schema supported by this <code>SchemaFactory</code>?</p>
  122. *
  123. * @param schemaLanguage Specifies the schema language which the returned <code>SchemaFactory</code> will understand.
  124. * <code>schemaLanguage</code> must specify a <a href="#schemaLanguage">valid</a> schema language.
  125. *
  126. * @return <code>true</code> if <code>SchemaFactory</code> supports <code>schemaLanguage</code>, else <code>false</code>.
  127. *
  128. * @throws NullPointerException If <code>schemaLanguage</code> is <code>null</code>.
  129. * @throws IllegalArgumentException If <code>schemaLanguage.length() == 0</code>
  130. * or <code>schemaLanguage</code> does not specify a <a href="#schemaLanguage">valid</a> schema language.
  131. */
  132. public boolean isSchemaLanguageSupported(String schemaLanguage) {
  133. if (schemaLanguage == null) {
  134. throw new NullPointerException(
  135. messageFormatter.formatMessage(Locale.getDefault(),
  136. "SchemaLanguageSupportedErrorWhenNull",
  137. new Object [] {this.getClass().getName()}));
  138. }
  139. if (schemaLanguage.length() == 0) {
  140. throw new IllegalArgumentException(
  141. messageFormatter.formatMessage(Locale.getDefault(),
  142. "SchemaLanguageSupportedErrorWhenLength",
  143. new Object [] {this.getClass().getName()}));
  144. }
  145. // understand W3C Schema and RELAX NG
  146. if (schemaLanguage.equals(XMLConstants.W3C_XML_SCHEMA_NS_URI)
  147. || schemaLanguage.equals(XMLConstants.RELAXNG_NS_URI)) {
  148. return true;
  149. }
  150. // don't know how to validate anything else
  151. return false;
  152. }
  153. public LSResourceResolver getResourceResolver() {
  154. return resourceResolver;
  155. }
  156. public void setResourceResolver(LSResourceResolver resourceResolver) {
  157. this.resourceResolver = resourceResolver;
  158. loader.setEntityResolver(new DOMEntityResolverWrapper(resourceResolver));
  159. }
  160. public ErrorHandler getErrorHandler() {
  161. return errorHandler;
  162. }
  163. public void setErrorHandler(ErrorHandler errorHandler) {
  164. this.errorHandler = errorHandler;
  165. }
  166. public Schema newSchema( Source[] schemas ) throws SAXException {
  167. lastException = null;
  168. // this will let the loader store parsed Grammars into the pool.
  169. XMLGrammarPool pool = new XMLGrammarPoolImpl();
  170. loader.setProperty(XercesConstants.XMLGRAMMAR_POOL,pool);
  171. loader.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_FULL_CHECKING,true);
  172. if(enableSP)
  173. loader.setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY,secureProcessing);
  174. else
  175. loader.setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY,null);
  176. for( int i=0; i<schemas.length; i++ ) {
  177. try {
  178. loader.loadGrammar(schemas[i]);
  179. } catch (XNIException e) {
  180. // this should have been reported to users already.
  181. throw Util.toSAXException(e);
  182. } catch (IOException e) {
  183. // this hasn't been reported, so do so now.
  184. SAXParseException se = new SAXParseException(e.getMessage(),null,e);
  185. errorHandler.error(se);
  186. throw se; // and we must throw it.
  187. }
  188. }
  189. // if any error had been reported, throw it.
  190. if( lastException!=null )
  191. throw lastException;
  192. // make sure no further grammars are added by making it read-only.
  193. return new SchemaImpl(new ReadonlyGrammarPool(pool),true);
  194. }
  195. public Schema newSchema() throws SAXException {
  196. // use a pool that uses the system id as the equality source.
  197. return new SchemaImpl(new XMLGrammarPoolImpl() {
  198. public boolean equals(XMLGrammarDescription desc1, XMLGrammarDescription desc2) {
  199. String sid1 = desc1.getExpandedSystemId();
  200. String sid2 = desc2.getExpandedSystemId();
  201. if( sid1!=null && sid2!=null )
  202. return sid1.equals(sid2);
  203. if( sid1==null && sid2==null )
  204. return true;
  205. return false;
  206. }
  207. public int hashCode(XMLGrammarDescription desc) {
  208. String s = desc.getExpandedSystemId();
  209. if(s!=null) return s.hashCode();
  210. return 0;
  211. }
  212. }, false);
  213. }
  214. public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException {
  215. if(name==null) throw new NullPointerException(SAXMessageFormatter.formatMessage(Locale.getDefault(),
  216. "nullparameter",new Object[] {"setFeature(String,boolean)"}));
  217. if(name.equals(Constants.FEATURE_SECURE_PROCESSING)){
  218. enableSP = value;
  219. }else throw new SAXNotRecognizedException(SAXMessageFormatter.formatMessage(Locale.getDefault(),
  220. "feature-not-supported", new Object [] {name}));
  221. }
  222. public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
  223. if(name==null) throw new NullPointerException(SAXMessageFormatter.formatMessage(Locale.getDefault(),
  224. "nullparameter",new Object[] {"getFeature(String)"}));
  225. if(name.equals(Constants.FEATURE_SECURE_PROCESSING))
  226. return enableSP;
  227. else throw new SAXNotRecognizedException(SAXMessageFormatter.formatMessage(Locale.getDefault(),
  228. "feature-not-supported", new Object [] {name}));
  229. }
  230. }