blob: cb42c94d9696e94ded5a72c33a467425067e1e8a [file] [log] [blame]
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 2000-2002,2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.util;
import java.util.Hashtable;
import java.util.Enumeration;
import com.sun.org.apache.xerces.internal.xni.Augmentations;
/**
* This class provides an implementation for Augmentations interface.
* Augmentations interface defines a hashtable of additional data that could
* be passed along the document pipeline. The information can contain extra
* arguments or infoset augmentations, for example PSVI. This additional
* information is identified by a String key.
* <p>
*
* @author Elena Litani, IBM
*/
public class AugmentationsImpl implements Augmentations{
private AugmentationsItemsContainer fAugmentationsContainer =
new SmallContainer();
/**
* Add additional information identified by a key to the Augmentations structure.
*
* @param key Identifier, can't be <code>null</code>
* @param item Additional information
*
* @return the previous value of the specified key in the Augmentations strucutre,
* or <code>null</code> if it did not have one.
*/
public Object putItem (String key, Object item){
Object oldValue = fAugmentationsContainer.putItem(key, item);
if (oldValue == null && fAugmentationsContainer.isFull()) {
fAugmentationsContainer = fAugmentationsContainer.expand();
}
return oldValue;
}
/**
* Get information identified by a key from the Augmentations structure
*
* @param key Identifier, can't be <code>null</code>
*
* @return the value to which the key is mapped in the Augmentations structure;
* <code>null</code> if the key is not mapped to any value.
*/
public Object getItem(String key){
return fAugmentationsContainer.getItem(key);
}
/**
* Remove additional info from the Augmentations structure
*
* @param key Identifier, can't be <code>null</code>
*/
public Object removeItem (String key){
return fAugmentationsContainer.removeItem(key);
}
/**
* Returns an enumeration of the keys in the Augmentations structure
*
*/
public Enumeration keys (){
return fAugmentationsContainer.keys();
}
/**
* Remove all objects from the Augmentations structure.
*/
public void removeAllItems() {
fAugmentationsContainer.clear();
}
public String toString() {
return fAugmentationsContainer.toString();
}
abstract class AugmentationsItemsContainer {
abstract public Object putItem(Object key, Object item);
abstract public Object getItem(Object key);
abstract public Object removeItem(Object key);
abstract public Enumeration keys();
abstract public void clear();
abstract public boolean isFull();
abstract public AugmentationsItemsContainer expand();
}
class SmallContainer extends AugmentationsItemsContainer {
final static int SIZE_LIMIT = 10;
final Object[] fAugmentations = new Object[SIZE_LIMIT*2];
int fNumEntries = 0;
public Enumeration keys() {
return new SmallContainerKeyEnumeration();
}
public Object getItem(Object key) {
for (int i = 0; i < fNumEntries*2; i = i + 2) {
if (fAugmentations[i].equals(key)) {
return fAugmentations[i+1];
}
}
return null;
}
public Object putItem(Object key, Object item) {
for (int i = 0; i < fNumEntries*2; i = i + 2) {
if (fAugmentations[i].equals(key)) {
Object oldValue = fAugmentations[i+1];
fAugmentations[i+1] = item;
return oldValue;
}
}
fAugmentations[fNumEntries*2] = key;
fAugmentations[fNumEntries*2+1] = item;
fNumEntries++;
return null;
}
public Object removeItem(Object key) {
for (int i = 0; i < fNumEntries*2; i = i + 2) {
if (fAugmentations[i].equals(key)) {
Object oldValue = fAugmentations[i+1];
for (int j = i; j < fNumEntries*2 - 2; j = j + 2) {
fAugmentations[j] = fAugmentations[j+2];
fAugmentations[j+1] = fAugmentations[j+3];
}
fAugmentations[fNumEntries*2-2] = null;
fAugmentations[fNumEntries*2-1] = null;
fNumEntries--;
return oldValue;
}
}
return null;
}
public void clear() {
for (int i = 0; i < fNumEntries*2; i = i + 2) {
fAugmentations[i] = null;
fAugmentations[i+1] = null;
}
fNumEntries = 0;
}
public boolean isFull() {
return (fNumEntries == SIZE_LIMIT);
}
public AugmentationsItemsContainer expand() {
LargeContainer expandedContainer = new LargeContainer();
for (int i = 0; i < fNumEntries*2; i = i + 2) {
expandedContainer.putItem(fAugmentations[i],
fAugmentations[i+1]);
}
return expandedContainer;
}
public String toString() {
StringBuffer buff = new StringBuffer();
buff.append("SmallContainer - fNumEntries == " + fNumEntries);
for (int i = 0; i < SIZE_LIMIT*2; i=i+2) {
buff.append("\nfAugmentations[");
buff.append(i);
buff.append("] == ");
buff.append(fAugmentations[i]);
buff.append("; fAugmentations[");
buff.append(i+1);
buff.append("] == ");
buff.append(fAugmentations[i+1]);
}
return buff.toString();
}
class SmallContainerKeyEnumeration implements Enumeration {
Object [] enumArray = new Object[fNumEntries];
int next = 0;
SmallContainerKeyEnumeration() {
for (int i = 0; i < fNumEntries; i++) {
enumArray[i] = fAugmentations[i*2];
}
}
public boolean hasMoreElements() {
return next < enumArray.length;
}
public Object nextElement() {
if (next >= enumArray.length) {
throw new java.util.NoSuchElementException();
}
Object nextVal = enumArray[next];
enumArray[next] = null;
next++;
return nextVal;
}
}
}
class LargeContainer extends AugmentationsItemsContainer {
final Hashtable fAugmentations = new Hashtable();
public Object getItem(Object key) {
return fAugmentations.get(key);
}
public Object putItem(Object key, Object item) {
return fAugmentations.put(key, item);
}
public Object removeItem(Object key) {
return fAugmentations.remove(key);
}
public Enumeration keys() {
return fAugmentations.keys();
}
public void clear() {
fAugmentations.clear();
}
public boolean isFull() {
return false;
}
public AugmentationsItemsContainer expand() {
return this;
}
public String toString() {
StringBuffer buff = new StringBuffer();
buff.append("LargeContainer");
Enumeration keys = fAugmentations.keys();
while (keys.hasMoreElements()) {
Object key = keys.nextElement();
buff.append("\nkey == ");
buff.append(key);
buff.append("; value == ");
buff.append(fAugmentations.get(key));
}
return buff.toString();
}
}
}