blob: c9449fd6bf513c4e49cc4c23b285fda24d5caf9b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.html.core.contentmodel;
import java.util.HashMap;
import java.util.Iterator;
import org.eclipse.wst.common.contentmodel.CMNamedNodeMap;
import org.eclipse.wst.common.contentmodel.CMNode;
/**
*/
abstract class DeclCollection implements CMNamedNodeMap {
protected class DualMap {
public DualMap() {
super();
}
public DualMap(Object[] objects) {
super();
initialize(objects);
}
public int size() {
return table.length;
}
public Object getValue(int key) {
if (!isValidIndex(key))
return null;
return table[key];
}
public int getKey(Object value) {
Integer keyObj = (Integer) map.get(value);
if (keyObj == null)
return ID_UNKNOWN;
return keyObj.intValue();
}
protected void initialize(Object[] objects) {
if (objects == null)
return;
table = objects;
map = new HashMap();
for (int key = 0; key < objects.length; key++) {
Object value = table[key];
map.put(value, new Integer(key));
}
}
private Object[] table = null;
private HashMap map = null;
private boolean isValidIndex(int index) {
return index >= 0 && index < table.length;
}
}
protected class TolerantStringDualMap extends DualMap {
public TolerantStringDualMap(String[] names) {
super();
Object[] objects = new Object[names.length];
for (int i = 0; i < names.length; i++) {
objects[i] = makeCanonicalForm(names[i]);
}
initialize(objects);
}
public int getKey(Object value) {
try {
String name = (String) value;
return super.getKey(makeCanonicalForm(name));
}
catch (ClassCastException e) {
return ID_UNKNOWN;
}
}
private String makeCanonicalForm(String raw) {
return raw.toUpperCase();
}
}
private class DeclIterator implements Iterator {
public DeclIterator() {
maxid = fDecls.length - 1;
}
public boolean hasNext() {
return id < maxid;
}
public Object next() {
if (!hasNext())
return null;
return item(++id);
}
public void remove() { /* nothing should be done. */
}
private int id = -1;
private int maxid = -1;
}
CMNode[] fDecls = null;
protected final static boolean STRICT_CASE = false;
protected final static boolean TOLERANT_CASE = true;
protected final static int ID_UNKNOWN = -1;
private DualMap fMap = null;
/**
*/
public DeclCollection(String[] names, boolean tolerant) {
super();
fDecls = new CMNode[names.length];
if (tolerant) {
fMap = new TolerantStringDualMap(names);
}
else {
fMap = new DualMap(names);
}
}
/**
* @return org.eclipse.wst.common.contentmodel.CMNode
* @param id int
*/
protected abstract CMNode create(String name);
/**
*/
public CMNamedNodeMap getDeclarations(String[] names) {
CMNamedNodeMapImpl map = new CMNamedNodeMapImpl();
for (int i = 0; i < names.length; i++) {
String name = names[i];
CMNode node = getNamedItem(name);
if (node == null)
continue;
map.putNamedItem(name, node);
}
return map;
}
/**
* @param declarations com.ibm.sed.contentmodel.html.CMGroupImpl
* @param names java.util.Iterator
*/
public void getDeclarations(CMGroupImpl group, Iterator names) {
while (names.hasNext()) {
String entityName = (String) names.next();
CMNode dec = getNamedItem(entityName);
if (dec != null)
group.appendChild(dec);
}
}
/**
* Map name to id.
* @return int
* @param name java.lang.String
*/
protected int getID(String name) {
return fMap.getKey(name);
}
/**
* getLength method
* @return int
*/
public int getLength() {
return fDecls.length;
}
/**
* @return java.lang.String
* @param id int
*/
protected String getName(int id) {
return (String) fMap.getValue(id);
}
/**
* getNamedItem method
* @return CMNode
* @param name java.lang.String
*/
public CMNode getNamedItem(String name) {
int id = getID(name);
if (!isValidID(id))
return null;
return item(id);
}
/**
* @return boolean
* @param id int
*/
private boolean isValidID(int id) {
return id >= 0 && id < fDecls.length;
}
/**
* item method
* @return CMNode
* @param index int
*/
public CMNode item(int index) {
if (!isValidID(index))
return null;
CMNode decl = fDecls[index];
if (decl != null)
return decl; // already exist.
decl = create(getName(index));
fDecls[index] = decl;
return decl;
}
/**
*/
public Iterator iterator() {
return new DeclIterator();
}
}