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