001: /**
002: * org/ozone-db/xml/dom/AttrImpl.java
003: *
004: * The contents of this file are subject to the OpenXML Public
005: * License Version 1.0; you may not use this file except in compliance
006: * with the License. You may obtain a copy of the License at
007: * http://www.openxml.org/license.html
008: *
009: * THIS SOFTWARE IS DISTRIBUTED ON AN "AS IS" BASIS WITHOUT WARRANTY
010: * OF ANY KIND, EITHER EXPRESSED OR IMPLIED. THE INITIAL DEVELOPER
011: * AND ALL CONTRIBUTORS SHALL NOT BE LIABLE FOR ANY DAMAGES AS A
012: * RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
013: * DERIVATIVES. SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING
014: * RIGHTS AND LIMITATIONS UNDER THE LICENSE.
015: *
016: * The Initial Developer of this code under the License is Assaf Arkin.
017: * Portions created by Assaf Arkin are Copyright (C) 1998, 1999.
018: * All Rights Reserved.
019: */
020:
021: /**
022: * Changes for Persistent DOM running with ozone are
023: * Copyright 1999 by SMB GmbH. All rights reserved.
024: */package org.ozoneDB.xml.dom;
025:
026: import java.io.*;
027: import org.w3c.dom.*;
028: import org.w3c.dom.html.HTMLDocument;
029:
030: /**
031: * Represents an attribute in an {@link org.w3c.dom.Element} node.
032: * <P>
033: * Attributes are not real nodes, they are not children in their parent element
034: * and the methods {@link AttrImpl#getParentNode}, {@link AttrImpl#getNextSibling}
035: * and {@link #getPreviousSibling} always return null.
036: * <P>
037: * Attributes in XML documents support children, but only of the type {@link
038: * org.w3c.dom.Text} and {@link org.w3c.dom.EntityReference}.
039: * <P>
040: * The specified value of an attribute indicates whether it's value has been
041: * changed since it was constructed with the default value. The specified value
042: * is not used when cloning an attribute or testing for equality.
043: * <P>
044: * To speed up implementation, all attributes are implemented as double-linked
045: * list using {@link NodeImpl#_parent}, {@link NodeImpl#_nextNode} and
046: * {@link NodeImpl#_prevNode}.
047: *
048: *
049: * @version $Revision: 1.1 $ $Date: 2001/12/18 11:03:24 $
050: * @author <a href="mailto:arkin@trendline.co.il">Assaf Arkin</a>
051: * @see org.w3c.dom.Attr
052: * @see NodeImpl
053: * @see ElementImpl
054: */
055: public final class AttrImpl extends NodeImpl implements AttrProxy,
056: Externalizable {
057:
058: final static long serialVersionUID = 1;
059:
060: public Element getOwnerElement() {
061: return (Element) getParentNode();
062: }
063:
064: public final short getNodeType() {
065: return ATTRIBUTE_NODE;
066: }
067:
068: public final String getName() {
069: return getNodeName();
070: }
071:
072: public final boolean getSpecified() {
073: return _specified;
074: }
075:
076: public void setSpecified(boolean value) {
077: _specified = value;
078: }
079:
080: public String getValue() {
081: return getNodeValue();
082: }
083:
084: public void setNodeValue(String value) {
085: super .setNodeValue(value);
086: _specified = true;
087: }
088:
089: public void setValue(String value) {
090: super .setNodeValue(value);
091: _specified = true;
092: }
093:
094: // public Node getParentNode() {
095: // // Must return null per DOM spec.
096: // return null;
097: // }
098: //
099: // public Node getPreviousSibling() {
100: // // Must return null per DOM spec.
101: // return null;
102: // }
103: //
104: // public Node getNextSibling() {
105: // // Must return null per DOM spec.
106: // return null;
107: // }
108:
109: public String toString() {
110: String value;
111:
112: value = getValue();
113: if (value.length() > 32) {
114: value = value.substring(0, 32) + "..";
115: }
116: return "Attribute node: [" + getName() + "] [" + value
117: + (_specified ? "] SPECIFIED" : "]");
118: }
119:
120: protected boolean supportsChildern() {
121: return true;
122: }
123:
124: public final Object clone() {
125: AttrProxy clone = null;
126: try {
127: clone = (AttrProxy) database().createObject(
128: AttrImpl.class.getName());
129: clone.init(_ownerDocument, getNodeName(), getNodeValue());
130: cloneInto((NodeProxy) clone, true);
131: } catch (Exception except) {
132: throw new DOMExceptionImpl(DOMExceptionImpl.PDOM_ERR,
133: except.getMessage());
134: }
135: return clone;
136: }
137:
138: public final Node cloneNode(boolean deep) {
139: AttrProxy clone = null;
140: try {
141: clone = (AttrProxy) database().createObject(
142: AttrImpl.class.getName());
143: clone.init(_ownerDocument, getNodeName(), getNodeValue());
144: cloneInto((NodeProxy) clone, deep);
145: } catch (Exception except) {
146: throw new DOMExceptionImpl(DOMExceptionImpl.PDOM_ERR,
147: except.getMessage());
148: }
149: return clone;
150: }
151:
152: public synchronized void cloneInto(NodeProxy into, boolean deep) {
153: super .cloneInto(into, deep);
154: ((AttrProxy) into).setSpecified(getSpecified());
155: }
156:
157: /**
158: * Assures that the children of an attribute are either {@link
159: * org.w3c.dom.Text} or {@link org.w3c.dom.EntityReference}.
160: *
161: * @see NodeImpl#castNewChild
162: */
163: protected Node castNewChild(Node newChild) throws DOMException {
164: Node result;
165:
166: if (newChild == null) {
167: throw new DOMExceptionImpl(
168: DOMException.HIERARCHY_REQUEST_ERR,
169: "Child reference is null.");
170: }
171: if (!(newChild instanceof Text || newChild instanceof EntityReference)) {
172: throw new DOMExceptionImpl(
173: DOMException.HIERARCHY_REQUEST_ERR,
174: "Child is not a compatible type for this node.");
175: }
176: return (Node) newChild;
177: }
178:
179: /** */
180: public void writeExternal(ObjectOutput out) throws IOException {
181: super .writeExternal(out);
182: out.writeBoolean(_specified);
183: }
184:
185: /** */
186: public void readExternal(ObjectInput in) throws IOException,
187: ClassNotFoundException {
188: super .readExternal(in);
189: _specified = in.readBoolean();
190: }
191:
192: /**
193: * Hidden constructor for attribute. Note that <TT>value</TT> is the DTD's
194: * default value for this attribute, it is not the value specified in the XML
195: * document. The value specified in the XML document should be passed by
196: * calling {@link #setValue} explicitly.
197: * <P>
198: * The attribute name is case sensitive for XML, but is case insensitive and
199: * all lower case for HTML documents. <TT>owner</TT> must point to a valid
200: * document object.
201: *
202: * @param owner The owner document
203: * @param name The attribute's name
204: * @param value The attribute's value as specified in the DTD or null
205: */
206: AttrImpl(DocumentImpl owner, String name, String defValue) {
207: super (owner, owner instanceof HTMLDocument ? name.toLowerCase()
208: : name, defValue, true);
209: // Make sure that all attribute names are converted to lower case
210: // for HTML documents.
211: // Specified is always false. If a value was specified, it was the
212: // default.
213: _specified = false;
214: }
215:
216: public AttrImpl() {
217: super ();
218: _specified = false;
219: }
220:
221: public final void init(DocumentProxy owner, String name,
222: String value) {
223: super .init(owner, owner instanceof HTMLDocument ? name
224: .toLowerCase() : name, value, true);
225: }
226:
227: /**
228: * True if a value has been specified for this node in the document.
229: * This value is not used when cloning or testing for equality.
230: */
231: private boolean _specified;
232:
233: }
|