1 package com.atlassian.dbexporter.node;
2
3 import com.atlassian.activeobjects.spi.ImportExportException;
4
5 import java.io.Writer;
6 import java.math.BigDecimal;
7 import java.math.BigInteger;
8 import java.util.Date;
9
10 /**
11 * Represents a node in streaming XML documents. This is a small abstraction
12 * layer over StAX that allows other streaming data formats to be used (JSON,
13 * ASN.1, ?) and make it easier to deal with StAX, of which the API can be a bit
14 * tedious. This interface also provides type conversion instead of just strings.
15 * This interface only provides read access to a streaming node graph.
16 *
17 * @author Erik van Zijst
18 * @see NodeCreator counterpart of this interface that provides the ability to
19 * write node graphs.
20 * @see NodeStreamReader
21 */
22 public interface NodeParser {
23
24 /**
25 * Retrieves the value of an attribute of the current node. If the attribute
26 * does not exist, <code>null</code> is returned.
27 *
28 * @param key the name of the attribute
29 * @return the value of the attribute, or <code>null</code> if the attribute does not exist
30 * @throws ImportExportException when the input could not be parsed
31 * @throws IllegalStateException when this method was called after one of
32 * the <code>getContent...</code>, or the {@link NodeParser#getNextNode()}
33 * method was called
34 */
35 String getAttribute(String key) throws IllegalStateException;
36
37 /**
38 * Retrieves the value of an attribute of the current node. If the attribute
39 * does not exist, a {@link ImportExportException} is thrown.
40 *
41 * @param key the name of the attribute
42 * @return the value of the attribute (can be an empty string, or even
43 * <code>null</code> if the attribute is present, but has no value - think
44 * <code>xsi:nil="true"</code>)
45 * @throws ImportExportException when the input could not be parsed
46 * @throws IllegalStateException when this method was called after one of
47 * the <code>getContent...</code>, or the {@link NodeParser#getNextNode()}
48 * method was called
49 */
50 String getRequiredAttribute(String key) throws IllegalStateException;
51
52 /**
53 * Returns the name of the current entity.
54 *
55 * @return the name of the current entity
56 * @throws ImportExportException when the input could not be parsed
57 */
58 String getName();
59
60 /**
61 * Returns <code>true</code> if this instance represents the end of a node
62 * (closing tag in XML).
63 * If this is the case, {@link NodeParser#getNextNode()} will return a
64 * reference to the parent node. Also, when the end of a node is reached,
65 * {@link NodeParser#getAttribute(String)}, {@link NodeParser#getRequiredAttribute(String)}
66 * and the various getContent() methods can no longer be invoked. Doing so
67 * will raise a {@link ImportExportException}.
68 *
69 * @return <code>true</code> if this instance represents the end of a node
70 * @throws ImportExportException when the input could not be parsed
71 */
72 boolean isClosed();
73
74 /**
75 * Returns the next node in the graph. This could be:
76 * <ul>
77 * <li>a child node (in which case {@link NodeParser#isClosed()} will be
78 * <code>false</code> on the returned instance);</li>
79 * <li>the close tag of the current node ({@link NodeParser#isClosed()}
80 * will be <code>true</code> on the returned instance;</li>
81 * <li>the end of the document ({@link NodeParser#isClosed()} is
82 * <code>true</code> on the current instance), then <code>null</code> will
83 * be returned.</li>
84 * </ul>
85 *
86 * @return the next node in the graph
87 * @throws ImportExportException when the input could not be parsed
88 */
89 NodeParser getNextNode();
90
91 /**
92 * Returns the content of the current node as a string. A node either
93 * contains content, child nodes, or nothing at all. If the current node
94 * does not contain content, a {@link ImportExportException} is thrown. When the
95 * current node is a content node, but contains no data (e.g.
96 * <code><node xsi:nil="true"/></code> in XML), <code>null</code> is returned.
97 * <p>
98 * When this method returns, the current node will be closed. Calling this
99 * method again will raise an {@link IllegalStateException}.
100 *
101 * @return the content of the current node
102 * @throws ImportExportException when the current node is not a content node, or
103 * when the input could not be parsed
104 * @throws IllegalStateException if the current node cannot contain
105 * content (for instance because {@link NodeParser#isClosed()} is true
106 */
107 String getContentAsString() throws IllegalStateException;
108
109 /**
110 * Similar to {@link NodeParser#getContentAsString()}, but converts content
111 * to a boolean value.
112 *
113 * @return the content of the current node as a boolean value
114 * @throws IllegalStateException if the current node cannot contain
115 * content (for instance because {@link NodeParser#isClosed()} is true
116 */
117 Boolean getContentAsBoolean() throws IllegalStateException;
118
119 /**
120 * Similar to {@link NodeParser#getContentAsString()}, but converts content
121 * to a {@link java.util.Date} instance.
122 *
123 * @return the content of the current node as a {@link java.util.Date} instance
124 * @throws ImportExportException when the current node is not a content node, or
125 * when the input could not be parsed, or when the content does not conform
126 * to the standardized date format
127 * @throws IllegalStateException if the current node cannot contain
128 * content (for instance because {@link NodeParser#isClosed()} is true
129 */
130 Date getContentAsDate() throws IllegalStateException;
131
132 /**
133 * Similar to {@link NodeParser#getContentAsString()}, but converts content
134 * to a {@link java.math.BigInteger} instance.
135 *
136 * @return the content of the current node as a {@link java.math.BigInteger} instance
137 * @throws ImportExportException when the current node is not a content node, or
138 * when the input could not be parsed, or the content does not contain a
139 * numeric integer value
140 * @throws IllegalStateException if the current node cannot contain
141 * content (for instance because {@link NodeParser#isClosed()} is true
142 */
143 BigInteger getContentAsBigInteger() throws IllegalStateException;
144
145 BigDecimal getContentAsBigDecimal() throws IllegalStateException;
146
147 /**
148 * Similar to {@link NodeParser#getContentAsString()}, but writes the contents
149 * to the specified {@link java.io.Writer} instance. Useful for reading large lumps
150 * of content in a memory-efficient way. The writer is not closed.
151 *
152 * @param writer the writer to write the contents to
153 * @throws ImportExportException when the current node is not a content node, or
154 * when the input could not be parsed
155 * @throws IllegalStateException if the current node cannot contain
156 * content (for instance because {@link NodeParser#isClosed()} is true
157 */
158 void getContent(Writer writer) throws IllegalStateException;
159 }