001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.xerces.util;
019:
020: import java.util.Hashtable;
021: import java.util.Enumeration;
022:
023: import org.apache.xerces.xni.Augmentations;
024:
025: /**
026: * This class provides an implementation for Augmentations interface.
027: * Augmentations interface defines a hashtable of additional data that could
028: * be passed along the document pipeline. The information can contain extra
029: * arguments or infoset augmentations, for example PSVI. This additional
030: * information is identified by a String key.
031: * <p>
032: *
033: * @author Elena Litani, IBM
034: * @version $Id: AugmentationsImpl.java 447241 2006-09-18 05:12:57Z mrglavas $
035: */
036: public class AugmentationsImpl implements Augmentations {
037:
038: private AugmentationsItemsContainer fAugmentationsContainer = new SmallContainer();
039:
040: /**
041: * Add additional information identified by a key to the Augmentations structure.
042: *
043: * @param key Identifier, can't be <code>null</code>
044: * @param item Additional information
045: *
046: * @return the previous value of the specified key in the Augmentations strucutre,
047: * or <code>null</code> if it did not have one.
048: */
049: public Object putItem(String key, Object item) {
050: Object oldValue = fAugmentationsContainer.putItem(key, item);
051:
052: if (oldValue == null && fAugmentationsContainer.isFull()) {
053: fAugmentationsContainer = fAugmentationsContainer.expand();
054: }
055:
056: return oldValue;
057: }
058:
059: /**
060: * Get information identified by a key from the Augmentations structure
061: *
062: * @param key Identifier, can't be <code>null</code>
063: *
064: * @return the value to which the key is mapped in the Augmentations structure;
065: * <code>null</code> if the key is not mapped to any value.
066: */
067: public Object getItem(String key) {
068: return fAugmentationsContainer.getItem(key);
069: }
070:
071: /**
072: * Remove additional info from the Augmentations structure
073: *
074: * @param key Identifier, can't be <code>null</code>
075: */
076: public Object removeItem(String key) {
077: return fAugmentationsContainer.removeItem(key);
078: }
079:
080: /**
081: * Returns an enumeration of the keys in the Augmentations structure
082: *
083: */
084: public Enumeration keys() {
085: return fAugmentationsContainer.keys();
086: }
087:
088: /**
089: * Remove all objects from the Augmentations structure.
090: */
091: public void removeAllItems() {
092: fAugmentationsContainer.clear();
093: }
094:
095: public String toString() {
096: return fAugmentationsContainer.toString();
097: }
098:
099: abstract class AugmentationsItemsContainer {
100: abstract public Object putItem(Object key, Object item);
101:
102: abstract public Object getItem(Object key);
103:
104: abstract public Object removeItem(Object key);
105:
106: abstract public Enumeration keys();
107:
108: abstract public void clear();
109:
110: abstract public boolean isFull();
111:
112: abstract public AugmentationsItemsContainer expand();
113: }
114:
115: class SmallContainer extends AugmentationsItemsContainer {
116: final static int SIZE_LIMIT = 10;
117: final Object[] fAugmentations = new Object[SIZE_LIMIT * 2];
118: int fNumEntries = 0;
119:
120: public Enumeration keys() {
121: return new SmallContainerKeyEnumeration();
122: }
123:
124: public Object getItem(Object key) {
125: for (int i = 0; i < fNumEntries * 2; i = i + 2) {
126: if (fAugmentations[i].equals(key)) {
127: return fAugmentations[i + 1];
128: }
129: }
130:
131: return null;
132: }
133:
134: public Object putItem(Object key, Object item) {
135: for (int i = 0; i < fNumEntries * 2; i = i + 2) {
136: if (fAugmentations[i].equals(key)) {
137: Object oldValue = fAugmentations[i + 1];
138: fAugmentations[i + 1] = item;
139:
140: return oldValue;
141: }
142: }
143:
144: fAugmentations[fNumEntries * 2] = key;
145: fAugmentations[fNumEntries * 2 + 1] = item;
146: fNumEntries++;
147:
148: return null;
149: }
150:
151: public Object removeItem(Object key) {
152: for (int i = 0; i < fNumEntries * 2; i = i + 2) {
153: if (fAugmentations[i].equals(key)) {
154: Object oldValue = fAugmentations[i + 1];
155:
156: for (int j = i; j < fNumEntries * 2 - 2; j = j + 2) {
157: fAugmentations[j] = fAugmentations[j + 2];
158: fAugmentations[j + 1] = fAugmentations[j + 3];
159: }
160:
161: fAugmentations[fNumEntries * 2 - 2] = null;
162: fAugmentations[fNumEntries * 2 - 1] = null;
163: fNumEntries--;
164:
165: return oldValue;
166: }
167: }
168:
169: return null;
170: }
171:
172: public void clear() {
173: for (int i = 0; i < fNumEntries * 2; i = i + 2) {
174: fAugmentations[i] = null;
175: fAugmentations[i + 1] = null;
176: }
177:
178: fNumEntries = 0;
179: }
180:
181: public boolean isFull() {
182: return (fNumEntries == SIZE_LIMIT);
183: }
184:
185: public AugmentationsItemsContainer expand() {
186: LargeContainer expandedContainer = new LargeContainer();
187:
188: for (int i = 0; i < fNumEntries * 2; i = i + 2) {
189: expandedContainer.putItem(fAugmentations[i],
190: fAugmentations[i + 1]);
191: }
192:
193: return expandedContainer;
194: }
195:
196: public String toString() {
197: StringBuffer buff = new StringBuffer();
198: buff.append("SmallContainer - fNumEntries == ").append(
199: fNumEntries);
200:
201: for (int i = 0; i < SIZE_LIMIT * 2; i = i + 2) {
202: buff.append("\nfAugmentations[");
203: buff.append(i);
204: buff.append("] == ");
205: buff.append(fAugmentations[i]);
206: buff.append("; fAugmentations[");
207: buff.append(i + 1);
208: buff.append("] == ");
209: buff.append(fAugmentations[i + 1]);
210: }
211:
212: return buff.toString();
213: }
214:
215: class SmallContainerKeyEnumeration implements Enumeration {
216: Object[] enumArray = new Object[fNumEntries];
217: int next = 0;
218:
219: SmallContainerKeyEnumeration() {
220: for (int i = 0; i < fNumEntries; i++) {
221: enumArray[i] = fAugmentations[i * 2];
222: }
223: }
224:
225: public boolean hasMoreElements() {
226: return next < enumArray.length;
227: }
228:
229: public Object nextElement() {
230: if (next >= enumArray.length) {
231: throw new java.util.NoSuchElementException();
232: }
233:
234: Object nextVal = enumArray[next];
235: enumArray[next] = null;
236: next++;
237:
238: return nextVal;
239: }
240: }
241: }
242:
243: class LargeContainer extends AugmentationsItemsContainer {
244: final Hashtable fAugmentations = new Hashtable();
245:
246: public Object getItem(Object key) {
247: return fAugmentations.get(key);
248: }
249:
250: public Object putItem(Object key, Object item) {
251: return fAugmentations.put(key, item);
252: }
253:
254: public Object removeItem(Object key) {
255: return fAugmentations.remove(key);
256: }
257:
258: public Enumeration keys() {
259: return fAugmentations.keys();
260: }
261:
262: public void clear() {
263: fAugmentations.clear();
264: }
265:
266: public boolean isFull() {
267: return false;
268: }
269:
270: public AugmentationsItemsContainer expand() {
271: return this ;
272: }
273:
274: public String toString() {
275: StringBuffer buff = new StringBuffer();
276: buff.append("LargeContainer");
277: Enumeration keys = fAugmentations.keys();
278:
279: while (keys.hasMoreElements()) {
280: Object key = keys.nextElement();
281: buff.append("\nkey == ");
282: buff.append(key);
283: buff.append("; value == ");
284: buff.append(fAugmentations.get(key));
285: }
286:
287: return buff.toString();
288: }
289: }
290: }
|