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: DatatypeElement.java,v 1.3 2001/11/30 12:12:32 jstrachan Exp $
008 */
009
010package org.dom4j.datatype;
011
012import com.sun.msv.datatype.DatabindableDatatype;
013
014import org.dom4j.Element;
015import org.dom4j.Namespace;
016import org.dom4j.Node;
017import org.dom4j.QName;
018import org.dom4j.tree.DefaultElement;
019
020import com.sun.msv.datatype.SerializationContext;
021import com.sun.msv.datatype.xsd.XSDatatype;
022import org.relaxng.datatype.DatatypeException;
023import org.relaxng.datatype.ValidationContext;
024
025import org.xml.sax.Attributes;
026
027/** <p><code>DatatypeElement</code> represents an Element which supports the
028  * <a href="http://www.w3.org/TR/xmlschema-2/">XML Schema Data Types</a>
029  * specification.</p>
030  *
031  * @author <a href="mailto:james.strachan@metastuff.com">James Strachan</a>
032  * @version $Revision: 1.3 $
033  */
034public class DatatypeElement extends DefaultElement implements SerializationContext, ValidationContext {
035
036    /** The <code>XSDatatype</code> of the <code>Attribute</code> */
037    private XSDatatype datatype;
038    
039    /** The data (Object) value of the <code>Attribute</code> */
040    private Object data;
041
042
043    
044    public DatatypeElement(QName qname,XSDatatype datatype) {
045        super(qname);
046        this.datatype = datatype;
047    }
048
049    public DatatypeElement(QName qname,int attributeCount,XSDatatype datatype) { 
050        super(qname, attributeCount);
051        this.datatype = datatype;
052    }
053
054    public String toString() {
055        return getClass().getName() + hashCode() 
056            + " [Element: <" + getQualifiedName() 
057            + " attributes: " + attributeList() 
058            + " data: " + getData() + " />]";
059    }
060    
061    /** Returns the MSV XSDatatype for this node */
062    public XSDatatype getXSDatatype() {
063        return datatype;
064    }
065    
066    // SerializationContext interface
067    //-------------------------------------------------------------------------  
068    public String getNamespacePrefix(String uri) {
069        Namespace namespace = getNamespaceForURI(uri);
070        return (namespace != null) ? namespace.getPrefix() : null;
071    }
072    
073    // ValidationContext interface
074    //-------------------------------------------------------------------------    
075    public String getBaseUri() {
076        // XXXX: could we use a Document for this?
077        return null;
078    }
079    
080    public boolean isNotation(String notationName) {
081        // XXXX: no way to do this yet in dom4j so assume false
082        return false;
083    }
084        
085    public boolean isUnparsedEntity(String entityName) {
086        // XXXX: no way to do this yet in dom4j so assume valid
087        return true;
088    }
089    
090    public String resolveNamespacePrefix(String prefix) {
091        Namespace namespace = getNamespaceForPrefix( prefix );
092        if ( namespace != null ) {
093            return namespace.getURI();
094        }
095        return null;
096    }
097    
098    
099    // Element interface
100    //-------------------------------------------------------------------------
101    public Object getData() {
102        if ( data == null ) {
103            String text = getTextTrim();
104            if ( text != null && text.length() > 0 ) {
105                if ( datatype instanceof DatabindableDatatype ) {
106                    DatabindableDatatype bindable = (DatabindableDatatype) datatype;
107                    data = bindable.createJavaObject( text, this );
108                }
109                else {
110                    data = datatype.createValue( text, this );
111                }
112            }
113        }
114        return data;
115    }
116    
117    public void setData(Object data) {
118        String s = datatype.convertToLexicalValue( data, this );
119        validate(s);
120        this.data = data;
121        setText( s );
122    }    
123
124    public Element addText(String text) {
125        validate(text);
126        return super.addText(text);
127    }
128    
129    public void setText(String text) {
130        validate(text);
131        super.setText(text);
132    }
133    // Implementation methods
134    //-------------------------------------------------------------------------    
135    /** Override to force lazy recreation of data object */
136    protected void childAdded(Node node) {
137        data = null;
138        super.childAdded(node);
139    }
140    
141    /** Override to force lazy recreation of data object */    
142    protected void childRemoved(Node node) {
143        data = null;
144        super.childRemoved(node);
145    }
146
147    protected void validate(String text) throws IllegalArgumentException {
148        try {
149            datatype.checkValid(text, this);
150        }
151        catch (DatatypeException e) {
152            throw new IllegalArgumentException( e.getMessage() );
153        }
154    }
155}
156
157
158
159
160/*
161 * Redistribution and use of this software and associated documentation
162 * ("Software"), with or without modification, are permitted provided
163 * that the following conditions are met:
164 *
165 * 1. Redistributions of source code must retain copyright
166 *    statements and notices.  Redistributions must also contain a
167 *    copy of this document.
168 *
169 * 2. Redistributions in binary form must reproduce the
170 *    above copyright notice, this list of conditions and the
171 *    following disclaimer in the documentation and/or other
172 *    materials provided with the distribution.
173 *
174 * 3. The name "DOM4J" must not be used to endorse or promote
175 *    products derived from this Software without prior written
176 *    permission of MetaStuff, Ltd.  For written permission,
177 *    please contact dom4j-info@metastuff.com.
178 *
179 * 4. Products derived from this Software may not be called "DOM4J"
180 *    nor may "DOM4J" appear in their names without prior written
181 *    permission of MetaStuff, Ltd. DOM4J is a registered
182 *    trademark of MetaStuff, Ltd.
183 *
184 * 5. Due credit should be given to the DOM4J Project
185 *    (http://dom4j.org/).
186 *
187 * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
188 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
189 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
190 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
191 * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
192 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
193 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
194 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
195 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
196 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
197 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
198 * OF THE POSSIBILITY OF SUCH DAMAGE.
199 *
200 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
201 *
202 * $Id: DatatypeElement.java,v 1.3 2001/11/30 12:12:32 jstrachan Exp $
203 */