001: /**
002: * org/ozone-db/xml/dom/EntityImpl.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:
029: /**
030: * Implements an entity.
031: * <P>
032: * Notes:
033: * <OL>
034: * <LI>Node type is {@link org.w3c.dom.Node#ENTITY_NODE}
035: * <LI>Node supports childern
036: * <LI>Node does not have a value
037: * <LI>Node only accessible from {@link org.w3c.dom.DocumentType}
038: * </OL>
039: *
040: *
041: * @version $Revision: 1.1 $ $Date: 2001/12/18 11:03:24 $
042: * @author <a href="mailto:arkin@trendline.co.il">Assaf Arkin</a>
043: * @see org.w3c.dom.Entity
044: * @see NodeImpl
045: */
046: public class EntityImpl extends NodeImpl implements EntityProxy,
047: Externalizable {
048:
049: final static long serialVersionUID = 1;
050:
051: public short getNodeType() {
052: return ENTITY_NODE;
053: }
054:
055: public final void setNodeValue(String value) {
056: throw new DOMExceptionImpl(DOMException.NO_DATA_ALLOWED_ERR,
057: "This node type does not support values.");
058: }
059:
060: public String getPublicId() {
061: return _publicId;
062: }
063:
064: public void setPublicId(String publicId) {
065: _publicId = publicId;
066: }
067:
068: public String getSystemId() {
069: return _systemId;
070: }
071:
072: public void setSystemId(String systemId) {
073: _systemId = systemId;
074: }
075:
076: public String getNotationName() {
077: return _notation;
078: }
079:
080: public void setNotationName(String notation) {
081: _notation = notation;
082: }
083:
084: public final String getInternal() {
085: return _internalValue;
086: }
087:
088: /**
089: * Returns true if entity is an unparsed general entity. An unparsed entity
090: * is one for which a notation has been specified.
091: *
092: * @return True if unparsed general entity
093: */
094: public boolean isUnparsed() {
095: return _notation != null;
096: }
097:
098: /**
099: * Returns true if entity is an internal general entity. An internal entity
100: * is one for which a value has been defined. An external entity is one for
101: * which an external entity has been assigned through either system or
102: * public identifiers.
103: * <P>
104: * If true is returned, then {@link #getInternal} will return a string
105: * (might be empty).
106: *
107: * @return True if internal general entity
108: */
109: public boolean isInternal() {
110: return _internalValue != null;
111: }
112:
113: public void setInternal(String internalValue) {
114: _internalValue = internalValue;
115: }
116:
117: /**
118: * Returns the parsing state of this entity.
119: *
120: * @return State of entity
121: */
122: public short getState() {
123: return _state;
124: }
125:
126: /**
127: * Changes the parsing state of this entity. Note that only some changes
128: * are allowed: from declared to parsing, parsed or not found; from parsing
129: * to parsed or not found; from not found to declared.
130: *
131: * @param newState New state of entity
132: */
133: public void setState(short newState) {
134: if (_state == STATE_DECLARED && newState == STATE_PARSING
135: || _state == STATE_NOT_FOUND
136: && newState == STATE_DECLARED) {
137: _state = newState;
138: } else if ((_state == STATE_DECLARED || _state == STATE_PARSING)
139: && (newState == STATE_PARSED || newState == STATE_NOT_FOUND)) {
140: _state = newState;
141: } else {
142: throw new IllegalStateException("Cannot switch from state "
143: + _state + " to state " + newState + ".");
144: }
145: }
146:
147: public synchronized boolean equals(Object other) {
148: EntityProxy otherX;
149:
150: // Test for node equality (this covers entity name and all its children)
151: // and then test for specific entity qualities.
152: if (super .equals(other)) {
153: otherX = (EntityProxy) other;
154: // If this entity is internal, both entities must be internal and have
155: // equal internal value.
156: if (this .isInternal()) {
157: return otherX.isInternal()
158: && this .getInternal().equals(
159: otherX.getInternal());
160: }
161: // External or unparsed: either public id are both null, or public id
162: // equals in both (and same for system id and notation).
163: return (this .getPublicId() == null
164: && otherX.getPublicId() == null || this
165: .getPublicId() != null
166: && this .getPublicId().equals(otherX.getPublicId()))
167: && (this .getSystemId() == null
168: && otherX.getSystemId() == null || this
169: .getSystemId() != null
170: && this .getSystemId().equals(
171: otherX.getSystemId()))
172: && (this .getNotationName() == null
173: && otherX.getNotationName() == null || this
174: .getNotationName() != null
175: && this .getNotationName().equals(
176: otherX.getNotationName()));
177: }
178: return false;
179: }
180:
181: public final Object clone() {
182: EntityProxy clone = null;
183: try {
184: clone = (EntityProxy) database().createObject(
185: EntityImpl.class.getName());
186: clone.init(_ownerDocument, getNodeName());
187: cloneInto(clone, true);
188: } catch (Exception except) {
189: throw new DOMExceptionImpl(DOMExceptionImpl.PDOM_ERR,
190: except.getMessage());
191: }
192: return clone;
193: }
194:
195: public final Node cloneNode(boolean deep) {
196: EntityProxy clone = null;
197: try {
198: clone = (EntityProxy) database().createObject(
199: EntityImpl.class.getName());
200: clone.init(_ownerDocument, getNodeName());
201: cloneInto(clone, deep);
202: } catch (Exception except) {
203: throw new DOMExceptionImpl(DOMExceptionImpl.PDOM_ERR,
204: except.getMessage());
205: }
206: return clone;
207: }
208:
209: public String toString() {
210: String name;
211: String value;
212:
213: name = getNodeName();
214: if (name.length() > 32) {
215: name = name.substring(0, 32) + "..";
216: }
217: if (isInternal()) {
218: value = getInternal();
219: if (value.length() > 64) {
220: value = value.substring(0, 64) + "..";
221: }
222: name = name + "] [" + value;
223: } else {
224: if (getSystemId() != null) {
225: name = name + "] SYSTEM [" + getSystemId();
226: }
227: if (getPublicId() != null) {
228: name = name + "] PUBLIC [" + getPublicId();
229: }
230: if (getNotationName() != null) {
231: name = name + "] NDECL [" + getNotationName();
232: }
233: }
234: return "Entity decl: [" + name + "]";
235: }
236:
237: protected final boolean supportsChildern() {
238: return true;
239: }
240:
241: public synchronized void cloneInto(NodeProxy into, boolean deep) {
242: super .cloneInto(into, deep);
243: ((EntityProxy) into).setSystemId(this ._systemId);
244: ((EntityProxy) into).setPublicId(this ._publicId);
245: ((EntityProxy) into).setNotationName(this ._notation);
246: ((EntityProxy) into).setInternal(this ._internalValue);
247: ((EntityProxy) into).setState(this ._state);
248: }
249:
250: /**
251: * Constructs an unparsed general entity. Entity system identifier and notation
252: * name must be provided, public identifier is optional.
253: *
254: * @param owner The owner document
255: * @param name The entity name
256: * @param systemId The system identifier
257: * @param publicId The public identifier, if specified
258: * @param notation The notation, if specified
259: */
260: public EntityImpl(DocumentImpl owner, String name, String systemId,
261: String publicId, String notation) {
262: super (owner, name, null, true);
263: if (notation == null) {
264: throw new NullPointerException(
265: "Argument 'notation' cannot be null.");
266: } else {
267: init(owner, name, systemId, publicId, notation);
268: }
269: }
270:
271: /**
272: * Constructs an external general entity. Entity system identifier must be
273: * provided, public identifier is optional.
274: *
275: * @param owner The owner document
276: * @param name The entity name
277: * @param systemId The system identifier
278: * @param publicId The public identifier, if specified
279: */
280: public EntityImpl(DocumentImpl owner, String name, String systemId,
281: String publicId) {
282: super (owner, name, null, true);
283: if (systemId == null) {
284: throw new NullPointerException(
285: "Argument 'systemId' cannot be null.");
286: } else {
287: init(owner, name, systemId, publicId);
288: }
289: }
290:
291: /**
292: * Constructs an internal general entity. Entity value must be provided.
293: *
294: * @param owner The owner document
295: * @param name The entity name
296: * @param internalValue The unparsed entity value
297: */
298: public EntityImpl(DocumentImpl owner, String name,
299: String internalValue) {
300: super (owner, name, null, true);
301: if (internalValue == null) {
302: throw new NullPointerException(
303: "Argument 'internalValue' cannot be null.");
304: } else {
305: init(owner, name, internalValue);
306: }
307: }
308:
309: private EntityImpl(DocumentImpl owner, String name) {
310: super (owner, name, null, true);
311: }
312:
313: public EntityImpl() {
314: super ();
315: }
316:
317: public void init(DocumentProxy owner, String name) {
318: super .init(owner, name, null, true);
319: }
320:
321: public void init(DocumentProxy owner, String name, String value) {
322: _systemId = null;
323: _publicId = null;
324: _notation = null;
325: _state = STATE_DECLARED;
326: _internalValue = value;
327: }
328:
329: public void init(DocumentProxy owner, String name, String systemId,
330: String publicId) {
331: _systemId = systemId;
332: _publicId = publicId;
333: _notation = null;
334: _state = STATE_DECLARED;
335: }
336:
337: public void init(DocumentProxy owner, String name, String systemId,
338: String publicId, String notation) {
339: _systemId = systemId;
340: _publicId = publicId;
341: }
342:
343: /** */
344: public void writeExternal(ObjectOutput out) throws IOException {
345: super .writeExternal(out);
346: out.writeObject(_notation);
347: out.writeObject(_systemId);
348: out.writeObject(_publicId);
349: out.writeShort(_state);
350: out.writeObject(_internalValue);
351: }
352:
353: /** */
354: public void readExternal(ObjectInput in) throws IOException,
355: ClassNotFoundException {
356: super .readExternal(in);
357: _notation = (String) in.readObject();
358: _systemId = (String) in.readObject();
359: _publicId = (String) in.readObject();
360: _state = in.readShort();
361: _internalValue = (String) in.readObject();
362: }
363:
364: /**
365: * The notation of this entity, if specified.
366: */
367: protected String _notation;
368:
369: /**
370: * The system identifier of this entity, if specified.
371: */
372: protected String _systemId;
373:
374: /**
375: * The public identifier of this entity, if specified.
376: */
377: protected String _publicId;
378:
379: /**
380: * Identifies the state of this entity as yet to be parsed, being parsed,
381: * has been parsed, or cannot be found.
382: */
383: private short _state;
384:
385: /**
386: * Holds the internal value of the entity.
387: */
388: private String _internalValue;
389:
390: /**
391: * Entity has been declared but not parsed. This is the initial state for
392: * an entity after it has been declared in the DTD but before it is used
393: * in the document contents.
394: */
395: public final static short STATE_DECLARED = 0;
396:
397: /**
398: * Entity is being parsed. This state designates that the entity is being
399: * parsed right now. State is used to identify circular references.
400: */
401: public final static short STATE_PARSING = 1;
402:
403: /**
404: * Entity has been parsed. This state indicates that entity has been parsed
405: * and it's parsed contents is contained in its child nodes.
406: */
407: public final static short STATE_PARSED = 2;
408:
409: /**
410: * Entity not found. The entity could not be parsed before.
411: */
412: public final static short STATE_NOT_FOUND = 3;
413:
414: }
|