001: /*
002: Copyright (c) 2005-2006, Dennis M. Sosnoski
003: All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without modification,
006: are permitted provided that the following conditions are met:
007:
008: * Redistributions of source code must retain the above copyright notice, this
009: list of conditions and the following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright notice,
011: this list of conditions and the following disclaimer in the documentation
012: and/or other materials provided with the distribution.
013: * Neither the name of JiBX nor the names of its contributors may be used
014: to endorse or promote products derived from this software without specific
015: prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
018: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
019: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
021: ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028:
029: package org.jibx.binding.util;
030:
031: import org.jibx.runtime.IntStack;
032:
033: /**
034: * Stack for values that depend on the level of nesting, where only some of the
035: * levels change the current value.
036: *
037: * @author Dennis M. Sosnoski
038: */
039: public class SparseStack {
040: /** Current item. */
041: private Object m_current;
042:
043: /** Current nesting level. */
044: private int m_level;
045:
046: /** Levels with different items (paired with m_items stack). */
047: private IntStack m_levels;
048:
049: /** Stack of different items (paired with m_levels stack). */
050: private ObjectStack m_items;
051:
052: /**
053: * Constructor with initial value.
054: *
055: * @param current initial value
056: */
057: public SparseStack(Object current) {
058:
059: // initialize so peek always works
060: m_levels = new IntStack();
061: m_levels.push(-1);
062: m_items = new ObjectStack();
063: m_items.push(current);
064: m_current = current;
065: }
066:
067: /**
068: * Constructor with no initial value.
069: */
070: public SparseStack() {
071: this (null);
072: }
073:
074: /**
075: * Get current object.
076: *
077: * @return current
078: */
079: public Object getCurrent() {
080: return m_current;
081: }
082:
083: /**
084: * Set current object.
085: *
086: * @param obj set the current object
087: */
088: public void setCurrent(Object obj) {
089: m_current = obj;
090: }
091:
092: /**
093: * Enter a level of nesting.
094: */
095: public void enter() {
096: if (m_current != m_items.peek()) {
097: m_levels.push(m_level);
098: m_items.push(m_current);
099: }
100: m_level++;
101: }
102:
103: /**
104: * Exit a level of nesting with changed item returned.
105: *
106: * @return item that was active until this exit, or <code>null</code> if
107: * same item still active
108: */
109: public Object exit() {
110: m_level--;
111: if (m_level == m_levels.peek()) {
112: Object obj = m_current;
113: m_levels.pop();
114: m_current = m_items.pop();
115: return obj;
116: } else {
117: return null;
118: }
119: }
120: }
|