1/*
2 * reserved comment block
3 * DO NOT REMOVE OR ALTER!
4 */
5/*
6 * Licensed to the Apache Software Foundation (ASF) under one or more
7 * contributor license agreements.  See the NOTICE file distributed with
8 * this work for additional information regarding copyright ownership.
9 * The ASF licenses this file to You under the Apache License, Version 2.0
10 * (the "License"); you may not use this file except in compliance with
11 * the License.  You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 */
21
22package com.sun.org.apache.xerces.internal.dom;
23
24import org.w3c.dom.DocumentFragment;
25import org.w3c.dom.Node;
26import org.w3c.dom.Text;
27
28/**
29 * DocumentFragment is a "lightweight" or "minimal" Document
30 * object. It is very common to want to be able to extract a portion
31 * of a document's tree or to create a new fragment of a
32 * document. Imagine implementing a user command like cut or
33 * rearranging a document by moving fragments around. It is desirable
34 * to have an object which can hold such fragments and it is quite
35 * natural to use a Node for this purpose. While it is true that a
36 * Document object could fulfil this role, a Document object can
37 * potentially be a heavyweight object, depending on the underlying
38 * implementation... and in DOM Level 1, nodes aren't allowed to cross
39 * Document boundaries anyway. What is really needed for this is a
40 * very lightweight object.  DocumentFragment is such an object.
41 * <P>
42 * Furthermore, various operations -- such as inserting nodes as
43 * children of another Node -- may take DocumentFragment objects as
44 * arguments; this results in all the child nodes of the
45 * DocumentFragment being moved to the child list of this node.
46 * <P>
47 * The children of a DocumentFragment node are zero or more nodes
48 * representing the tops of any sub-trees defining the structure of
49 * the document.  DocumentFragment do not need to be well-formed XML
50 * documents (although they do need to follow the rules imposed upon
51 * well-formed XML parsed entities, which can have multiple top
52 * nodes). For example, a DocumentFragment might have only one child
53 * and that child node could be a Text node. Such a structure model
54 * represents neither an HTML document nor a well-formed XML document.
55 * <P>
56 * When a DocumentFragment is inserted into a Document (or indeed any
57 * other Node that may take children) the children of the
58 * DocumentFragment and not the DocumentFragment itself are inserted
59 * into the Node. This makes the DocumentFragment very useful when the
60 * user wishes to create nodes that are siblings; the DocumentFragment
61 * acts as the parent of these nodes so that the user can use the
62 * standard methods from the Node interface, such as insertBefore()
63 * and appendChild().
64 *
65 * @xerces.internal
66 *
67 * @since  PR-DOM-Level-1-19980818.
68 */
69public class DocumentFragmentImpl
70    extends ParentNode
71    implements DocumentFragment {
72
73    //
74    // Constants
75    //
76
77    /** Serialization version. */
78    static final long serialVersionUID = -7596449967279236746L;
79
80    //
81    // Constructors
82    //
83
84    /** Factory constructor. */
85    public DocumentFragmentImpl(CoreDocumentImpl ownerDoc) {
86        super(ownerDoc);
87    }
88
89    /** Constructor for serialization. */
90    public DocumentFragmentImpl() {}
91
92    //
93    // Node methods
94    //
95
96    /**
97     * A short integer indicating what type of node this is. The named
98     * constants for this value are defined in the org.w3c.dom.Node interface.
99     */
100    public short getNodeType() {
101        return Node.DOCUMENT_FRAGMENT_NODE;
102    }
103
104    /** Returns the node name. */
105    public String getNodeName() {
106        return "#document-fragment";
107    }
108
109    /**
110     * Override default behavior to call normalize() on this Node's
111     * children. It is up to implementors or Node to override normalize()
112     * to take action.
113     */
114    public void normalize() {
115        // No need to normalize if already normalized.
116        if (isNormalized()) {
117            return;
118        }
119        if (needsSyncChildren()) {
120            synchronizeChildren();
121        }
122        ChildNode kid, next;
123
124        for (kid = firstChild; kid != null; kid = next) {
125            next = kid.nextSibling;
126
127            // If kid is a text node, we need to check for one of two
128            // conditions:
129            //   1) There is an adjacent text node
130            //   2) There is no adjacent text node, but kid is
131            //      an empty text node.
132            if ( kid.getNodeType() == Node.TEXT_NODE )
133            {
134                // If an adjacent text node, merge it with kid
135                if ( next!=null && next.getNodeType() == Node.TEXT_NODE )
136                {
137                    ((Text)kid).appendData(next.getNodeValue());
138                    removeChild( next );
139                    next = kid; // Don't advance; there might be another.
140                }
141                else
142                {
143                    // If kid is empty, remove it
144                    if ( kid.getNodeValue() == null || kid.getNodeValue().length() == 0 ) {
145                        removeChild( kid );
146                    }
147                }
148            }
149
150            kid.normalize();
151        }
152
153        isNormalized(true);
154    }
155
156} // class DocumentFragmentImpl
157