View Javadoc
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>&lt;node xsi:nil="true"/&gt;</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 }