001/* 002 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved. 003 * 004 * This software is open source. 005 * See the bottom of this file for the licence. 006 * 007 * $Id: DatatypeDocumentFactory.java,v 1.2 2001/11/22 12:54:09 jstrachan Exp $ 008 */ 009 010package org.dom4j.datatype; 011 012import com.sun.msv.datatype.xsd.XSDatatype; 013 014import java.util.HashMap; 015import java.util.Map; 016 017import org.dom4j.Attribute; 018import org.dom4j.Document; 019import org.dom4j.DocumentFactory; 020import org.dom4j.Element; 021import org.dom4j.Namespace; 022import org.dom4j.QName; 023import org.dom4j.io.SAXReader; 024 025import org.xml.sax.EntityResolver; 026import org.xml.sax.InputSource; 027 028/** <p><code>DatatypeDocumentFactory</code> is a factory of XML objects which 029 * support the 030 * <a href="http://www.w3.org/TR/xmlschema-2/">XML Schema Data Types</a> 031 * specification.</p> 032 * 033 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a> 034 * @version $Revision: 1.2 $ 035 */ 036public class DatatypeDocumentFactory extends DocumentFactory { 037 038 039 // XXXX: I don't think interning of QNames is necessary 040 private static final boolean DO_INTERN_QNAME = false; 041 042 043 /** The Singleton instance */ 044 static transient DatatypeDocumentFactory singleton = new DatatypeDocumentFactory(); 045 046 private static final Namespace XSI_NAMESPACE 047 = Namespace.get( "xsi", "http://www.w3.org/2001/XMLSchema-instance" ); 048 049 private static final QName XSI_SCHEMA_LOCATION 050 = QName.get( "schemaLocation", XSI_NAMESPACE ); 051 052 private static final QName XSI_NO_SCHEMA_LOCATION 053 = QName.get( "noNamespaceSchemaLocation", XSI_NAMESPACE ); 054 055 056 /** The builder of XML Schemas */ 057 private SchemaParser schemaBuilder; 058 059 /** reader of XML Schemas */ 060 private SAXReader xmlSchemaReader = new SAXReader(); 061 062 063 /** If schemas are automatically loaded when parsing instance documents */ 064 private boolean autoLoadSchema = true; 065 066 067 /** <p>Access to the singleton instance of this factory.</p> 068 * 069 * @return the default singleon instance 070 */ 071 public static DocumentFactory getInstance() { 072 return singleton; 073 } 074 075 public DatatypeDocumentFactory() { 076 schemaBuilder = new SchemaParser(this); 077 } 078 079 080 /** Loads the given XML Schema document into this factory so 081 * schema-aware Document, Elements and Attributes will be created 082 * by this factory. 083 * 084 * @param schemaDocument is an XML Schema Document instance. 085 */ 086 public void loadSchema(Document schemaDocument) { 087 schemaBuilder.build( schemaDocument ); 088 } 089 090 /** Registers the given <code>DatatypeElementFactory</code> for the given 091 * <element> schema element 092 */ 093 public DatatypeElementFactory getElementFactory( QName elementQName ) { 094 if ( DO_INTERN_QNAME ) { 095 elementQName = intern( elementQName ); 096 } 097 DocumentFactory factory = elementQName.getDocumentFactory(); 098 return (factory instanceof DatatypeElementFactory) 099 ? (DatatypeElementFactory) factory : null; 100 } 101 102 103 // DocumentFactory methods 104 //------------------------------------------------------------------------- 105/* 106 public Element createElement(QName qname) { 107 DocumentFactory elementFactory = qname.getDocumentFactory(); 108 if ( elementFactory != null ) { 109 return elementFactory.createElement(qname); 110 } 111 return super.createElement(qname); 112 } 113*/ 114 public Attribute createAttribute(Element owner, QName qname, String value) { 115 if ( autoLoadSchema && qname.equals( XSI_NO_SCHEMA_LOCATION ) ) { 116 Document document = (owner != null) ? owner.getDocument() : null; 117 loadSchema( document, value ); 118 } 119 return super.createAttribute( owner, qname, value ); 120 } 121 122 123 124 // Implementation methods 125 //------------------------------------------------------------------------- 126 protected void loadSchema( Document document, String schemaInstanceURI ) { 127 try { 128 EntityResolver resolver = document.getEntityResolver(); 129 if ( resolver == null ) { 130 throw new InvalidSchemaException( "No EntityResolver available so could not resolve the schema URI: " + schemaInstanceURI ); 131 } 132 InputSource inputSource = resolver.resolveEntity( null, schemaInstanceURI ); 133 if ( resolver == null ) { 134 throw new InvalidSchemaException( "Could not resolve the schema URI: " + schemaInstanceURI ); 135 } 136 Document schemaDocument = xmlSchemaReader.read( inputSource ); 137 loadSchema( schemaDocument ); 138 } 139 catch (Exception e) { 140 System.out.println( "Failed to load schema: " + schemaInstanceURI ); 141 System.out.println( "Caught: " + e ); 142 e.printStackTrace(); 143 throw new InvalidSchemaException( "Failed to load schema: " + schemaInstanceURI ); 144 } 145 } 146 147} 148 149 150 151 152/* 153 * Redistribution and use of this software and associated documentation 154 * ("Software"), with or without modification, are permitted provided 155 * that the following conditions are met: 156 * 157 * 1. Redistributions of source code must retain copyright 158 * statements and notices. Redistributions must also contain a 159 * copy of this document. 160 * 161 * 2. Redistributions in binary form must reproduce the 162 * above copyright notice, this list of conditions and the 163 * following disclaimer in the documentation and/or other 164 * materials provided with the distribution. 165 * 166 * 3. The name "DOM4J" must not be used to endorse or promote 167 * products derived from this Software without prior written 168 * permission of MetaStuff, Ltd. For written permission, 169 * please contact dom4j-info@metastuff.com. 170 * 171 * 4. Products derived from this Software may not be called "DOM4J" 172 * nor may "DOM4J" appear in their names without prior written 173 * permission of MetaStuff, Ltd. DOM4J is a registered 174 * trademark of MetaStuff, Ltd. 175 * 176 * 5. Due credit should be given to the DOM4J Project 177 * (http://dom4j.org/). 178 * 179 * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS 180 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 181 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 182 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 183 * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 184 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 185 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 186 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 187 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 188 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 189 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 190 * OF THE POSSIBILITY OF SUCH DAMAGE. 191 * 192 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved. 193 * 194 * $Id: DatatypeDocumentFactory.java,v 1.2 2001/11/22 12:54:09 jstrachan Exp $ 195 */