View Javadoc
1   package org.exolab.castor.xml.parsing;
2   
3   import org.exolab.castor.xml.UnmarshalHandler;
4   
5   /**
6    * A helper class for {@link UnmarshalHandler}.
7    * 
8    * Keeps track if elements, which appear in XML but for which there is no
9    * mapping, should be allowed.
10   * 
11   * @author <a href="mailto:philipp DOT erlacher AT gmail DOT com">Philipp
12   *         Erlacher</a>
13   * 
14   * @since 1.3.2
15   */
16  public class StrictElementHandler {
17  
18      /**
19       * A boolean that indicates element processing should be strict and an error
20       * should be flagged if any extra elements exist.
21       **/
22      private boolean _strictElements = true;
23  
24      /**
25       * A depth counter that increases as we skip elements ( in startElement )
26       * and decreases as we process and endElement. Only active if _strictElements is 
27       * set.
28       */
29      private int _ignoreElementDepth = 0;
30  
31      /**
32       * Sets whether or not elements that do not match a specific field should
33       * simply be ignored or reported as an error. By default, extra elements 
34       * are ignored.
35       * 
36       * @param ignoreExtraElems
37       *            a boolean that when true will allow non-matched attributes to
38       *            simply be ignored.
39       **/
40      public void setIgnoreExtraElements(boolean ignoreExtraElems) {
41          _strictElements = (!ignoreExtraElems);
42      }
43  
44      /**
45       * Checks if extra elements will be ignored.
46       * 
47       * @return true if we ignore extra elements, false otherwise
48       */
49      public boolean areElementsIgnorable() {
50          return !_strictElements;
51      }
52  
53      /**
54       * Skip element that appear in XML but for which we have no mapping
55       * 
56       * @return
57       */
58      public boolean skipElement() {
59          return _ignoreElementDepth > 0;
60      }
61  
62      /**
63       * Checks if a start element can be skipped
64       * 
65       * @return true if start element can be skipped, false otherwise
66       */
67      public boolean skipStartElement() {
68          if (areElementsIgnorable() && skipElement()) {
69              addIgnorableElement();
70              return true;
71          }
72          return false;
73      }
74  
75      /**
76       * Checks if a start element can be skipped omitting current value of element depth.
77       *
78       * @return true if start element can be skipped, false otherwise
79       */
80      public boolean skipStartElementIgnoringDepth() {
81          if (areElementsIgnorable()) {
82              addIgnorableElement();
83              return true;
84          }
85          return false;
86      }
87  
88      /**
89       * Checks if an end element can be skipped.
90       * 
91       * @return true if end element can be skipped, false otherwise
92       */
93      public boolean skipEndElement() {
94          if (skipElement()) {
95              remIgnorableElement();
96              return true;
97          }
98          return false;
99      }
100 
101     /**
102      * Decreases the depth counter for elements which should be skipped.
103      */
104     private void remIgnorableElement() {
105         --_ignoreElementDepth;
106     }
107 
108     /**
109      * Increases the depth counter for elements for which we have no mapping.
110      */
111     private void addIgnorableElement() {
112         ++_ignoreElementDepth;
113     }
114 }