001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.xerces.dom;
019:
020: import org.w3c.dom.DocumentFragment;
021: import org.w3c.dom.Node;
022: import org.w3c.dom.Text;
023:
024: /**
025: * DocumentFragment is a "lightweight" or "minimal" Document
026: * object. It is very common to want to be able to extract a portion
027: * of a document's tree or to create a new fragment of a
028: * document. Imagine implementing a user command like cut or
029: * rearranging a document by moving fragments around. It is desirable
030: * to have an object which can hold such fragments and it is quite
031: * natural to use a Node for this purpose. While it is true that a
032: * Document object could fulfil this role, a Document object can
033: * potentially be a heavyweight object, depending on the underlying
034: * implementation... and in DOM Level 1, nodes aren't allowed to cross
035: * Document boundaries anyway. What is really needed for this is a
036: * very lightweight object. DocumentFragment is such an object.
037: * <P>
038: * Furthermore, various operations -- such as inserting nodes as
039: * children of another Node -- may take DocumentFragment objects as
040: * arguments; this results in all the child nodes of the
041: * DocumentFragment being moved to the child list of this node.
042: * <P>
043: * The children of a DocumentFragment node are zero or more nodes
044: * representing the tops of any sub-trees defining the structure of
045: * the document. DocumentFragment do not need to be well-formed XML
046: * documents (although they do need to follow the rules imposed upon
047: * well-formed XML parsed entities, which can have multiple top
048: * nodes). For example, a DocumentFragment might have only one child
049: * and that child node could be a Text node. Such a structure model
050: * represents neither an HTML document nor a well-formed XML document.
051: * <P>
052: * When a DocumentFragment is inserted into a Document (or indeed any
053: * other Node that may take children) the children of the
054: * DocumentFragment and not the DocumentFragment itself are inserted
055: * into the Node. This makes the DocumentFragment very useful when the
056: * user wishes to create nodes that are siblings; the DocumentFragment
057: * acts as the parent of these nodes so that the user can use the
058: * standard methods from the Node interface, such as insertBefore()
059: * and appendChild().
060: *
061: * @xerces.internal
062: *
063: * @version $Id: DocumentFragmentImpl.java 447266 2006-09-18 05:57:49Z mrglavas $
064: * @since PR-DOM-Level-1-19980818.
065: */
066: public class DocumentFragmentImpl extends ParentNode implements
067: DocumentFragment {
068:
069: //
070: // Constants
071: //
072:
073: /** Serialization version. */
074: static final long serialVersionUID = -7596449967279236746L;
075:
076: //
077: // Constructors
078: //
079:
080: /** Factory constructor. */
081: public DocumentFragmentImpl(CoreDocumentImpl ownerDoc) {
082: super (ownerDoc);
083: }
084:
085: /** Constructor for serialization. */
086: public DocumentFragmentImpl() {
087: }
088:
089: //
090: // Node methods
091: //
092:
093: /**
094: * A short integer indicating what type of node this is. The named
095: * constants for this value are defined in the org.w3c.dom.Node interface.
096: */
097: public short getNodeType() {
098: return Node.DOCUMENT_FRAGMENT_NODE;
099: }
100:
101: /** Returns the node name. */
102: public String getNodeName() {
103: return "#document-fragment";
104: }
105:
106: /**
107: * Override default behavior to call normalize() on this Node's
108: * children. It is up to implementors or Node to override normalize()
109: * to take action.
110: */
111: public void normalize() {
112: // No need to normalize if already normalized.
113: if (isNormalized()) {
114: return;
115: }
116: if (needsSyncChildren()) {
117: synchronizeChildren();
118: }
119: ChildNode kid, next;
120:
121: for (kid = firstChild; kid != null; kid = next) {
122: next = kid.nextSibling;
123:
124: // If kid is a text node, we need to check for one of two
125: // conditions:
126: // 1) There is an adjacent text node
127: // 2) There is no adjacent text node, but kid is
128: // an empty text node.
129: if (kid.getNodeType() == Node.TEXT_NODE) {
130: // If an adjacent text node, merge it with kid
131: if (next != null
132: && next.getNodeType() == Node.TEXT_NODE) {
133: ((Text) kid).appendData(next.getNodeValue());
134: removeChild(next);
135: next = kid; // Don't advance; there might be another.
136: } else {
137: // If kid is empty, remove it
138: if (kid.getNodeValue() == null
139: || kid.getNodeValue().length() == 0) {
140: removeChild(kid);
141: }
142: }
143: }
144:
145: kid.normalize();
146: }
147:
148: isNormalized(true);
149: }
150:
151: } // class DocumentFragmentImpl
|