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 }