KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > dtree > DataTreeWriter


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.dtree;
12
13 import java.io.DataOutput JavaDoc;
14 import java.io.IOException JavaDoc;
15 import org.eclipse.core.runtime.*;
16
17 /**
18  * Class for writing a single data tree (no parents) to an output stream.
19  */

20 public class DataTreeWriter {
21     /**
22      * Callback for serializing tree data
23      */

24     protected IDataFlattener flatener;
25
26     /**
27      * The stream to write output to
28      */

29     protected DataOutput JavaDoc output;
30
31     /**
32      * Constant representing infinite recursion depth
33      */

34     public static final int D_INFINITE = -1;
35
36     /**
37      * Creates a new DeltaTreeWriter.
38      */

39     public DataTreeWriter(IDataFlattener f) {
40         flatener = f;
41     }
42
43     /**
44      * Writes the subtree rooted at the given node.
45      * @param node The subtree to write.
46      * @param path The path of the current node.
47      * @param depth The depth of the subtree to write.
48      */

49     protected void writeNode(AbstractDataTreeNode node, IPath path, int depth) throws IOException JavaDoc {
50         int type = node.type();
51
52         /* write the node name */
53         String JavaDoc name = node.getName();
54         if (name == null) {
55             name = ""; //$NON-NLS-1$
56
}
57         output.writeUTF(name);
58
59         /* write the node type */
60         writeNumber(type);
61
62         /* maybe write the data */
63         if (node.hasData()) {
64             Object JavaDoc data = node.getData();
65
66             /**
67              * Write a flag indicating whether or not the data field is null.
68              * Zero means data is null, non-zero means data is present
69              */

70             if (data == null) {
71                 writeNumber(0);
72             } else {
73                 writeNumber(1);
74                 flatener.writeData(path, node.getData(), output);
75             }
76
77         }
78
79         /* maybe write the children */
80         if (depth > 0 || depth == D_INFINITE) {
81             AbstractDataTreeNode[] children = node.getChildren();
82
83             /* write the number of children */
84             writeNumber(children.length);
85
86             /* write the children */
87             int newDepth = (depth == D_INFINITE) ? D_INFINITE : depth - 1;
88             for (int i = 0, imax = children.length; i < imax; i++) {
89                 writeNode(children[i], path.append(children[i].getName()), newDepth);
90             }
91         } else {
92             /* write the number of children */
93             writeNumber(0);
94         }
95     }
96
97     /**
98      * Writes an integer in a compact format biased towards
99      * small non-negative numbers. Numbers between
100      * 0 and 254 inclusive occupy 1 byte; other numbers occupy 5 bytes.
101      */

102     protected void writeNumber(int number) throws IOException JavaDoc {
103         if (number >= 0 && number < 0xff) {
104             output.writeByte(number);
105         } else {
106             output.writeByte(0xff);
107             output.writeInt(number);
108         }
109     }
110
111     /**
112      * Writes a single node to the output. Does not recurse
113      * on child nodes, and does not write the number of children.
114      */

115     protected void writeSingleNode(AbstractDataTreeNode node, IPath path) throws IOException JavaDoc {
116         /* write the node name */
117         String JavaDoc name = node.getName();
118         if (name == null) {
119             name = ""; //$NON-NLS-1$
120
}
121         output.writeUTF(name);
122
123         /* write the node type */
124         writeNumber(node.type());
125
126         /* maybe write the data */
127         if (node.hasData()) {
128             Object JavaDoc data = node.getData();
129
130             /**
131              * Write a flag indicating whether or not the data field is null.
132              * Zero means data is null, non-zero means data is present
133              */

134             if (data == null) {
135                 writeNumber(0);
136             } else {
137                 writeNumber(1);
138                 flatener.writeData(path, node.getData(), output);
139             }
140         }
141     }
142
143     /**
144      * Writes the given AbstractDataTree to the given stream. This
145      * writes a single DataTree or DeltaDataTree, ignoring parent
146      * trees.
147      *
148      * @param path Only writes data for the subtree rooted at the given path, and
149      * for all nodes directly between the root and the subtree.
150      * @param depth In the subtree rooted at the given path,
151      * only write up to this depth. A depth of infinity is given
152      * by the constant D_INFINITE.
153      */

154     public void writeTree(AbstractDataTree tree, IPath path, int depth, DataOutput JavaDoc output) throws IOException JavaDoc {
155         this.output = output;
156         /* tunnel down relevant path */
157         AbstractDataTreeNode node = tree.getRootNode();
158         IPath currentPath = Path.ROOT;
159         String JavaDoc[] segments = path.segments();
160         for (int i = 0; i < segments.length; i++) {
161             String JavaDoc nextSegment = segments[i];
162
163             /* write this node to the output */
164             writeSingleNode(node, currentPath);
165
166             currentPath = currentPath.append(nextSegment);
167             node = node.childAtOrNull(nextSegment);
168
169             /* write the number of children for this node */
170             if (node != null) {
171                 writeNumber(1);
172             } else {
173                 /* can't navigate down the path, just give up with what we have so far */
174                 writeNumber(0);
175                 return;
176             }
177         }
178
179         Assert.isTrue(currentPath.equals(path), "dtree.navigationError"); //$NON-NLS-1$
180

181         /* recursively write the subtree we're interested in */
182         writeNode(node, path, depth);
183     }
184 }
185
Popular Tags