001: /*
002: * The Apache Software License, Version 1.1
003: *
004: *
005: * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
006: * reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * 1. Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * 2. Redistributions in binary form must reproduce the above copyright
016: * notice, this list of conditions and the following disclaimer in
017: * the documentation and/or other materials provided with the
018: * distribution.
019: *
020: * 3. The end-user documentation included with the redistribution,
021: * if any, must include the following acknowledgment:
022: * "This product includes software developed by the
023: * Apache Software Foundation (http://www.apache.org/)."
024: * Alternately, this acknowledgment may appear in the software itself,
025: * if and wherever such third-party acknowledgments normally appear.
026: *
027: * 4. The names "Xerces" and "Apache Software Foundation" must
028: * not be used to endorse or promote products derived from this
029: * software without prior written permission. For written
030: * permission, please contact apache@apache.org.
031: *
032: * 5. Products derived from this software may not be called "Apache",
033: * nor may "Apache" appear in their name, without prior written
034: * permission of the Apache Software Foundation.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
040: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: * ====================================================================
049: *
050: * This software consists of voluntary contributions made by many
051: * individuals on behalf of the Apache Software Foundation and was
052: * originally based on software copyright (c) 1999, International
053: * Business Machines, Inc., http://www.apache.org. For more
054: * information on the Apache Software Foundation, please see
055: * <http://www.apache.org/>.
056: */
057:
058: package com.sun.xml.stream.xerces.util;
059:
060: import java.util.Hashtable;
061: import java.util.Enumeration;
062:
063: import com.sun.xml.stream.xerces.xni.Augmentations;
064:
065: /**
066: * This class provides an implementation for Augmentations interface.
067: * Augmentations interface defines a hashtable of additional data that could
068: * be passed along the document pipeline. The information can contain extra
069: * arguments or infoset augmentations, for example PSVI. This additional
070: * information is identified by a String key.
071: * <p>
072: *
073: * @author Elena Litani, IBM
074: * @version $Id: AugmentationsImpl.java,v 1.2 2006/04/01 06:01:40 jeffsuttor Exp $
075: */
076: public class AugmentationsImpl implements Augmentations {
077:
078: private AugmentationsItemsContainer fAugmentationsContainer = new SmallContainer();
079:
080: /**
081: * Add additional information identified by a key to the Augmentations structure.
082: *
083: * @param key Identifier, can't be <code>null</code>
084: * @param item Additional information
085: *
086: * @return the previous value of the specified key in the Augmentations strucutre,
087: * or <code>null</code> if it did not have one.
088: */
089: public Object putItem(String key, Object item) {
090: Object oldValue = fAugmentationsContainer.putItem(key, item);
091:
092: if (oldValue == null && fAugmentationsContainer.isFull()) {
093: fAugmentationsContainer = fAugmentationsContainer.expand();
094: }
095:
096: return oldValue;
097: }
098:
099: /**
100: * Get information identified by a key from the Augmentations structure
101: *
102: * @param key Identifier, can't be <code>null</code>
103: *
104: * @return the value to which the key is mapped in the Augmentations structure;
105: * <code>null</code> if the key is not mapped to any value.
106: */
107: public Object getItem(String key) {
108: return fAugmentationsContainer.getItem(key);
109: }
110:
111: /**
112: * Remove additional info from the Augmentations structure
113: *
114: * @param key Identifier, can't be <code>null</code>
115: */
116: public Object removeItem(String key) {
117: return fAugmentationsContainer.removeItem(key);
118: }
119:
120: /**
121: * Returns an enumeration of the keys in the Augmentations structure
122: *
123: */
124: public Enumeration keys() {
125: return fAugmentationsContainer.keys();
126: }
127:
128: /**
129: * Remove all objects from the Augmentations structure.
130: */
131: public void removeAllItems() {
132: fAugmentationsContainer.clear();
133: }
134:
135: public String toString() {
136: return fAugmentationsContainer.toString();
137: }
138:
139: abstract class AugmentationsItemsContainer {
140: abstract public Object putItem(Object key, Object item);
141:
142: abstract public Object getItem(Object key);
143:
144: abstract public Object removeItem(Object key);
145:
146: abstract public Enumeration keys();
147:
148: abstract public void clear();
149:
150: abstract public boolean isFull();
151:
152: abstract public AugmentationsItemsContainer expand();
153: }
154:
155: class SmallContainer extends AugmentationsItemsContainer {
156: final static int SIZE_LIMIT = 10;
157: final Object[] fAugmentations = new Object[SIZE_LIMIT * 2];
158: int fNumEntries = 0;
159:
160: public Enumeration keys() {
161: return new SmallContainerKeyEnumeration();
162: }
163:
164: public Object getItem(Object key) {
165: for (int i = 0; i < fNumEntries * 2; i = i + 2) {
166: if (fAugmentations[i].equals(key)) {
167: return fAugmentations[i + 1];
168: }
169: }
170:
171: return null;
172: }
173:
174: public Object putItem(Object key, Object item) {
175: for (int i = 0; i < fNumEntries * 2; i = i + 2) {
176: if (fAugmentations[i].equals(key)) {
177: Object oldValue = fAugmentations[i + 1];
178: fAugmentations[i + 1] = item;
179:
180: return oldValue;
181: }
182: }
183:
184: fAugmentations[fNumEntries * 2] = key;
185: fAugmentations[fNumEntries * 2 + 1] = item;
186: fNumEntries++;
187:
188: return null;
189: }
190:
191: public Object removeItem(Object key) {
192: for (int i = 0; i < fNumEntries * 2; i = i + 2) {
193: if (fAugmentations[i].equals(key)) {
194: Object oldValue = fAugmentations[i + 1];
195:
196: for (int j = i; j < fNumEntries * 2 - 2; j = j + 2) {
197: fAugmentations[j] = fAugmentations[j + 2];
198: fAugmentations[j + 1] = fAugmentations[j + 3];
199: }
200:
201: fAugmentations[fNumEntries * 2 - 2] = null;
202: fAugmentations[fNumEntries * 2 - 1] = null;
203: fNumEntries--;
204:
205: return oldValue;
206: }
207: }
208:
209: return null;
210: }
211:
212: public void clear() {
213: for (int i = 0; i < fNumEntries * 2; i = i + 2) {
214: fAugmentations[i] = null;
215: fAugmentations[i + 1] = null;
216: }
217:
218: fNumEntries = 0;
219: }
220:
221: public boolean isFull() {
222: return (fNumEntries == SIZE_LIMIT);
223: }
224:
225: public AugmentationsItemsContainer expand() {
226: LargeContainer expandedContainer = new LargeContainer();
227:
228: for (int i = 0; i < fNumEntries * 2; i = i + 2) {
229: expandedContainer.putItem(fAugmentations[i],
230: fAugmentations[i + 1]);
231: }
232:
233: return expandedContainer;
234: }
235:
236: public String toString() {
237: StringBuffer buff = new StringBuffer();
238: buff.append("SmallContainer - fNumEntries == "
239: + fNumEntries);
240:
241: for (int i = 0; i < SIZE_LIMIT * 2; i = i + 2) {
242: buff.append("\nfAugmentations[");
243: buff.append(i);
244: buff.append("] == ");
245: buff.append(fAugmentations[i]);
246: buff.append("; fAugmentations[");
247: buff.append(i + 1);
248: buff.append("] == ");
249: buff.append(fAugmentations[i + 1]);
250: }
251:
252: return buff.toString();
253: }
254:
255: class SmallContainerKeyEnumeration implements Enumeration {
256: Object[] enumArray = new Object[fNumEntries];
257: int next = 0;
258:
259: SmallContainerKeyEnumeration() {
260: for (int i = 0; i < fNumEntries; i++) {
261: enumArray[i] = fAugmentations[i * 2];
262: }
263: }
264:
265: public boolean hasMoreElements() {
266: return next < enumArray.length;
267: }
268:
269: public Object nextElement() {
270: if (next >= enumArray.length) {
271: throw new java.util.NoSuchElementException();
272: }
273:
274: Object nextVal = enumArray[next];
275: enumArray[next] = null;
276: next++;
277:
278: return nextVal;
279: }
280: }
281: }
282:
283: class LargeContainer extends AugmentationsItemsContainer {
284: final Hashtable fAugmentations = new Hashtable();
285:
286: public Object getItem(Object key) {
287: return fAugmentations.get(key);
288: }
289:
290: public Object putItem(Object key, Object item) {
291: return fAugmentations.put(key, item);
292: }
293:
294: public Object removeItem(Object key) {
295: return fAugmentations.remove(key);
296: }
297:
298: public Enumeration keys() {
299: return fAugmentations.keys();
300: }
301:
302: public void clear() {
303: fAugmentations.clear();
304: }
305:
306: public boolean isFull() {
307: return false;
308: }
309:
310: public AugmentationsItemsContainer expand() {
311: return this ;
312: }
313:
314: public String toString() {
315: StringBuffer buff = new StringBuffer();
316: buff.append("LargeContainer");
317: Enumeration keys = fAugmentations.keys();
318:
319: while (keys.hasMoreElements()) {
320: Object key = keys.nextElement();
321: buff.append("\nkey == ");
322: buff.append(key);
323: buff.append("; value == ");
324: buff.append(fAugmentations.get(key));
325: }
326:
327: return buff.toString();
328: }
329: }
330: }
|