/*******************************************************************************
 * Copyright (c) 2001, 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.dtd.core.internal.contentmodel;

import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.ibm.icu.util.StringTokenizer;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.wst.dtd.core.internal.emf.DTDAnyContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDAttribute;
import org.eclipse.wst.dtd.core.internal.emf.DTDBasicType;
import org.eclipse.wst.dtd.core.internal.emf.DTDBasicTypeKind;
import org.eclipse.wst.dtd.core.internal.emf.DTDDefaultKind;
import org.eclipse.wst.dtd.core.internal.emf.DTDElement;
import org.eclipse.wst.dtd.core.internal.emf.DTDElementContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDElementReferenceContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDEmptyContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDEntity;
import org.eclipse.wst.dtd.core.internal.emf.DTDEnumerationType;
import org.eclipse.wst.dtd.core.internal.emf.DTDFile;
import org.eclipse.wst.dtd.core.internal.emf.DTDGroupContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDGroupKind;
import org.eclipse.wst.dtd.core.internal.emf.DTDInternalEntity;
import org.eclipse.wst.dtd.core.internal.emf.DTDOccurrenceType;
import org.eclipse.wst.dtd.core.internal.emf.DTDPCDataContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDRepeatableContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDType;
import org.eclipse.wst.dtd.core.internal.emf.impl.DTDBasicTypeImpl;
import org.eclipse.wst.dtd.core.internal.emf.impl.DTDPackageImpl;
import org.eclipse.wst.dtd.core.internal.emf.util.DTDMetrics;
import org.eclipse.wst.dtd.core.internal.emf.util.DTDUtil;
import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMContent;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDataType;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocumentation;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMEntityDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMGroup;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNamespace;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNodeList;
import org.eclipse.wst.xml.core.internal.contentmodel.annotation.AnnotationMap;
import org.eclipse.wst.xml.core.internal.contentmodel.basic.CMDataTypeImpl;
import org.eclipse.wst.xml.core.internal.contentmodel.basic.CMEntityDeclarationImpl;
import org.eclipse.wst.xml.core.internal.contentmodel.basic.CMNamedNodeMapImpl;
import org.eclipse.wst.xml.core.internal.contentmodel.basic.CMNodeListImpl;
import org.eclipse.wst.xml.core.internal.contentmodel.util.CMDescriptionBuilder;


public class DTDImpl {
	static {
		// Call init on the DTD package to avoid strange initialization bugs
		//
		DTDPackageImpl.init();
	}

	protected static DTDAdapterFactoryImpl dtdAdapterFactoryImpl = new DTDAdapterFactoryImpl();
	protected static CMDataTypeInfoTable cmDataTypeInfoTable = new CMDataTypeInfoTable();

	public static CMDocument buildCMDocument(String uri) {
		DTDFile dtdFile = buildDTDModel(uri);
		CMDocument cmDocument = (CMDocument) getAdapter(dtdFile);
		
		return cmDocument;
	}

	public static DTDFile buildDTDModel(String uri) {
		DTDUtil dtdUtil = new DTDUtil();
		dtdUtil.setexpandEntityReferences(true);
		dtdUtil.parse(new ResourceSetImpl(), uri);
		return dtdUtil.getDTDFile();
	}

	public static CMDocument buildCMDocument(DTDFile dtdFile) {
		return (CMDocument) getAdapter(dtdFile);
	}

	public static CMNode getAdapter(Notifier o) {
		return (CMNode) dtdAdapterFactoryImpl.adapt(o);
	}

	public static int getMinOccurHelper(DTDRepeatableContent content) {
		int occurence = content.getOccurrence().getValue();
		boolean isOptional = (occurence == DTDOccurrenceType.OPTIONAL || occurence == DTDOccurrenceType.ZERO_OR_MORE);
		return isOptional ? 0 : 1;
	}

	public static int getMaxOccurHelper(DTDRepeatableContent content) {
		int occurence = content.getOccurrence().getValue();
		boolean isMulti = (occurence == DTDOccurrenceType.ONE_OR_MORE || occurence == DTDOccurrenceType.ZERO_OR_MORE);
		return isMulti ? -1 : 1;
	}

	public static class DTDAdapterFactoryImpl extends AdapterFactoryImpl {
		public Adapter createAdapter(Notifier target) {
			Adapter result = null;
			if (target != null) {
				if (target instanceof DTDAttribute) {
					result = new DTDAttributeAdapter((DTDAttribute) target);
				}
				else if (target instanceof DTDElement) {
					result = new DTDElementAdapter((DTDElement) target);
				}
				else if (target instanceof DTDElementReferenceContent) {
					result = new DTDElementReferenceContentAdapter((DTDElementReferenceContent) target);
				}
				else if (target instanceof DTDFile) {
					result = new DTDFileAdapter((DTDFile) target);
				}
				else if (target instanceof DTDGroupContent) {
					result = new DTDGroupContentAdapter((DTDGroupContent) target);
				}
				else if (target instanceof DTDEntity) {
					result = new DTDEntityAdapter((DTDEntity) target);
				}
			}
			return result;
		}

		public Adapter adapt(Notifier target) {
			return adapt(target, this);
		}
	}

	/**
	 * DTDBaseAdapter
	 */
	public static abstract class DTDBaseAdapter extends CMNodeImpl {
		public String getNodeName() {
			return ""; //$NON-NLS-1$
		}

		public boolean isAdapterForType(Object type) {
			return type == dtdAdapterFactoryImpl;
		}

		public Object getProperty(String propertyName) {
			Object result = null;
			if (propertyName.equals("CMDocument")) { //$NON-NLS-1$
				result = getCMDocument();
			}
			else if (propertyName.equals(PROPERTY_DOCUMENTATION)) {
				result = getDocumentation();
			}
			else if (propertyName.equals(PROPERTY_DEFINITION_INFO)) {
				result = getDefinitionInfo();
			}
			else if (propertyName.equals(PROPERTY_DEFINITION)) {
				result = getDefinition();
			}
			else if (propertyName.equals(PROPERTY_MOF_NOTIFIER)) {
				result = getKey();
			}
			else if (propertyName.equals("spec")) { //$NON-NLS-1$
				result = getSpec();
			}
			else {
				result = super.getProperty(propertyName);
				if (result == null) {
					CMDocument cmDocument = getCMDocument();
					if (cmDocument instanceof DTDFileAdapter) {
						AnnotationMap map = ((DTDFileAdapter) cmDocument).annotationMap;
						if (map != null) {
							String spec = getSpec();
							if (spec != null) {
								result = map.getProperty(getSpec(), propertyName);
							}
						}
						if (result == null) {
							Map globalPropertyMap = ((DTDFileAdapter) cmDocument).globalPropertyMap;
							result = globalPropertyMap.get(propertyName);
						}
					}
				}
			}
			return result;
		}

		public CMDocument getCMDocument() {
			return null;
		}

		protected CMNodeList getDocumentation() {
			return new CMNodeListImpl();
		}

		public String getDefinitionInfo() {
			return null;
		}

		public CMNode getDefinition() {
			return null;
		}

		public String getSpec() {
			return getNodeName();
		}
	}

	/**
	 * DTDAttributeAdapter
	 */
	public static class DTDAttributeAdapter extends DTDBaseAdapter implements CMAttributeDeclaration {
		protected DTDAttribute attribute;
		protected CMDataType dataType;

		public DTDAttributeAdapter(DTDAttribute attribute) {
			this.attribute = attribute;
			dataType = new DataTypeImpl();
		}

		public Object getKey() {
			return attribute;
		}

		public String getSpec() {
			return attribute.getDTDElement().getName() + "/@" + attribute.getName(); //$NON-NLS-1$
		}

		public int getNodeType() {
			return ATTRIBUTE_DECLARATION;
		}

		public String getNodeName() {
			return attribute.getName();
		}

		public String getAttrName() {
			return attribute.getName();
		}

		public CMDataType getAttrType() {
			return dataType;
		}

		public String getDefaultValue() {
			return attribute.getDefaultValueString();
		}

		public Enumeration getEnumAttr() {
			return Collections.enumeration(attribute.getEnumeratedValues());
		}

		public int getUsage() {
			int usage = OPTIONAL;
			switch (attribute.getDefaultKind().getValue()) {
				case DTDDefaultKind.REQUIRED : {
					usage = REQUIRED;
					break;
				}
				case DTDDefaultKind.FIXED : {
					usage = FIXED;
					break;
				}
			}
			return usage;
		}

		public CMDocument getCMDocument() {
			DTDFile dtdFile = attribute.getDTDElement().getDTDFile();
			return dtdFile != null ? (CMDocument) getAdapter(dtdFile) : null;
		}

		public class DataTypeImpl implements CMDataType {
			public int getNodeType() {
				return CMNode.DATA_TYPE;
			}

			public String getNodeName() {
				return getDataTypeName();
			}

			public boolean supports(String propertyName) {
				return false;
			}

			public Object getProperty(String propertyName) {
				Object result = null;
				if (propertyName.equals("isValidEmptyValue")) { //$NON-NLS-1$
					String dataTypeName = getDataTypeName();
					result = (dataTypeName == null || dataTypeName.equals(CMDataType.CDATA)) ? "true" : "false"; //$NON-NLS-1$ //$NON-NLS-2$
				}
				return result;
			}

			public String getDataTypeName() {
				return cmDataTypeInfoTable.getDataTypeName(attribute.getDTDType());
			}

			public String generateInstanceValue() {
				return cmDataTypeInfoTable.getInstanceValue(attribute.getDTDType());
			}

			public int getImpliedValueKind() {
				int result = IMPLIED_VALUE_NONE;
				int defaultValueKind = attribute.getDefaultKind().getValue();
				if (defaultValueKind == DTDDefaultKind.NOFIXED) {
					result = IMPLIED_VALUE_DEFAULT;
				}
				else if (defaultValueKind == DTDDefaultKind.FIXED) {
					result = IMPLIED_VALUE_FIXED;
				}
				return result;
			}

			public String getImpliedValue() {
				return attribute.getDefaultValueString();
			}

			public String[] getEnumeratedValues() {
				Object[] objectList = attribute.getEnumeratedValues().toArray();
				String[] result = new String[objectList.length];
				for (int i = 0; i < objectList.length; i++) {
					result[i] = objectList[i].toString();
				}
				return result;
			}
		}
	}


	/**
	 * DTDElementBaseAdapter
	 */
	public static abstract class DTDElementBaseAdapter extends DTDBaseAdapter implements CMElementDeclaration {
		protected CMDataType dataType;

		protected abstract DTDElement getDTDElement();

		protected CMDocumentation documentation = null;

		public int getNodeType() {
			return ELEMENT_DECLARATION;
		}

		public String getNodeName() {
			return getDTDElement().getName();
		}

		public CMNamedNodeMap getAttributes() {
			CMNamedNodeMapImpl result = new CMNamedNodeMapImpl();
			List attributeList = getDTDElement().getDTDAttribute();
			for (Iterator i = attributeList.iterator(); i.hasNext();) {
				DTDAttribute attribute = (DTDAttribute) i.next();
				result.getHashtable().put(attribute.getName(), getAdapter(attribute));
			}
			return result;
		}

		public CMContent getContent() {
			return (CMContent) getAdapter(getDTDElement().getContent());
		}

		public int getContentType() {
			// todo
			int result = ELEMENT;
			DTDElementContent dtdElementContent = getDTDElement().getContent();
			if (dtdElementContent instanceof DTDPCDataContent) {
				result = PCDATA;
			}
			else if (dtdElementContent instanceof DTDGroupContent) {
				DTDGroupContent groupContent = (DTDGroupContent) dtdElementContent;
				int groupKind = groupContent.getGroupKind().getValue();
				if (groupKind == DTDGroupKind.CHOICE) {
					List list = groupContent.getContent();
					if (list.size() > 0 && list.get(0) instanceof DTDPCDataContent) {
						result = MIXED;
					}
				}
			}
			else if (dtdElementContent instanceof DTDAnyContent) {
				result = ANY;
			}
			else if (dtdElementContent instanceof DTDEmptyContent) {
				result = EMPTY;
			}

			return result;
		}

		public String getElementName() {
			return getDTDElement().getName();
		}

		public CMDataType getDataType() {
			int contentType = getContentType();
			boolean hasDataType = contentType == PCDATA || contentType == MIXED;
			return hasDataType ? dataType : null;
		}

		public CMNamedNodeMap getLocalElements() {
			return CMNamedNodeMapImpl.EMPTY_NAMED_NODE_MAP;
		}

		public CMDocument getCMDocument() {
			DTDFile dtdFile = getDTDElement().getDTDFile();
			return dtdFile != null ? (CMDocument) getAdapter(dtdFile) : null;
		}

		protected CMNodeList getDocumentation() {
			CMNodeListImpl nodeList = new CMNodeListImpl();
			if (documentation == null) {
				String comment = getDTDElement().getComment();
				if (comment != null) {
					String value = ""; //$NON-NLS-1$
					StringTokenizer st = new StringTokenizer(comment, "\n"); //$NON-NLS-1$
					while (st.hasMoreTokens()) {
						value += st.nextToken().trim() + "\n"; //$NON-NLS-1$
					}
					documentation = new CMDocumentationImpl(value);
				}
			}
			if (documentation != null) {
				nodeList.getList().add(documentation);
			}
			return nodeList;
		}
	}


	public static class CMDocumentationImpl implements CMDocumentation {
		protected String value;

		public CMDocumentationImpl(String value) {
			this.value = value;
		}

		public String getNodeName() {
			return ""; //$NON-NLS-1$
		}

		public int getNodeType() {
			return DOCUMENTATION;
		}

		public boolean supports(String propertyName) {
			return false;
		}

		public Object getProperty(String propertyName) {
			return null;
		}

		public String getValue() {
			return value;
		}

		public String getLanguage() {
			return null;
		}

		public String getSource() {
			return null;
		}
	}


	/**
	 * DTDElementAdapter
	 */
	public static class DTDElementAdapter extends DTDElementBaseAdapter {
		protected DTDElement element;

		public DTDElementAdapter(DTDElement element) {
			this.element = element;
			dataType = new CMDataTypeImpl("#PCDATA", getDTDElement().getName()); //$NON-NLS-1$
		}

		public Object getKey() {
			return element;
		}

		protected DTDElement getDTDElement() {
			return element;
		}

		public int getMinOccur() {
			return 1;
		}

		public int getMaxOccur() {
			return 1;
		}

		public String getDefinitionInfo() {
			return "global"; //$NON-NLS-1$
		}

		public CMNode getDefinition() {
			return this;
		}
	}


	/**
	 * DTDElementReferenceContentAdapter
	 */
	public static class DTDElementReferenceContentAdapter extends DTDElementBaseAdapter {
		protected DTDElementReferenceContent content;

		public DTDElementReferenceContentAdapter(DTDElementReferenceContent content) {
			this.content = content;
			dataType = new CMDataTypeImpl("#PCDATA", getDTDElement().getName()); //$NON-NLS-1$
		}

		public Object getKey() {
			return content;
		}

		protected DTDElement getDTDElement() {
			return content.getReferencedElement();
		}

		public int getMinOccur() {
			return getMinOccurHelper(content);
		}

		public int getMaxOccur() {
			return getMaxOccurHelper(content);
		}


		public CMNode getDefinition() {
			return getAdapter(getDTDElement());
		}
	}


	/**
	 * DTDEntityAdapter
	 */
	public static class DTDEntityAdapter extends DTDBaseAdapter implements CMEntityDeclaration {
		protected DTDEntity dtdEntity;

		public DTDEntityAdapter(DTDEntity dtdEntity) {
			this.dtdEntity = dtdEntity;
		}

		public int getNodeType() {
			return ENTITY_DECLARATION;
		}

		public Object getKey() {
			return dtdEntity;
		}

		public String getName() {
			return dtdEntity.getName();
		}

		public String getValue() {
			String value = ""; //$NON-NLS-1$
			if (dtdEntity.getContent() instanceof DTDInternalEntity) {
				DTDInternalEntity content = (DTDInternalEntity) dtdEntity.getContent();
				value = content.getValue();
			}
			return value;
		}
	}


	/**
	 * DTDGroupContentAdapter
	 */
	public static class DTDGroupContentAdapter extends DTDBaseAdapter implements CMGroup {
		protected DTDGroupContent content;

		public DTDGroupContentAdapter(DTDGroupContent content) {
			this.content = content;
		}

		public Object getKey() {
			return content;
		}

		public int getNodeType() {
			return GROUP;
		}

		public String getNodeName() {
			CMDescriptionBuilder descriptionBuilder = new CMDescriptionBuilder();
			return descriptionBuilder.buildDescription(this);
		}

		public CMNodeList getChildNodes() {
			List list = content.getContent();
			CMNodeListImpl result = new CMNodeListImpl();
			for (Iterator i = list.iterator(); i.hasNext();) {
				CMNode node = getAdapter((Notifier) i.next());
				if (node != null) {
					result.getList().add(node);
				}
			}
			return result;
		}


		public int getMaxOccur() {
			return getMaxOccurHelper(content);
		}

		public int getMinOccur() {
			return getMinOccurHelper(content);
		}

		public int getOperator() {
			// todo... handle ALONE case by checkig if child count == 1
			int groupKind = content.getGroupKind().getValue();
			return (groupKind == DTDGroupKind.CHOICE) ? CHOICE : SEQUENCE;
		}
	}

	/**
	 * DTDFileAdapter
	 */
	public static class DTDFileAdapter extends DTDBaseAdapter implements CMDocument {
		protected final String DEFAULT_ROOT_NAME = "http://org.eclipse.wst/cm/properties/defaultRootName"; //$NON-NLS-1$

		protected DTDFile dtdFile;
		protected CMNamedNodeMapImpl namedNodeMap;
		protected CMNamedNodeMapImpl entityNodeMap;

		protected AnnotationMap annotationMap = new AnnotationMap();
		protected Map globalPropertyMap = new HashMap();

		public DTDFileAdapter(DTDFile dtdFile) {
			this.dtdFile = dtdFile;
		}

		public Object getKey() {
			return dtdFile;
		}

		public AnnotationMap getAnnotationMap() {
			return annotationMap;
		}

		public CMNamedNodeMap getElements() {
			if (namedNodeMap == null) {
				namedNodeMap = new CMNamedNodeMapImpl();
				for (Iterator iterator = dtdFile.listDTDElement().iterator(); iterator.hasNext();) {
					DTDElement dtdElement = (DTDElement) iterator.next();
					namedNodeMap.getHashtable().put(dtdElement.getName(), getAdapter(dtdElement));
				}
			}
			return namedNodeMap;
		}

		public CMNamedNodeMap getEntities() {
			if (entityNodeMap == null) {
				entityNodeMap = new CMNamedNodeMapImpl();

				// add the built in entity declarations
				//
				entityNodeMap.getHashtable().put("amp", new CMEntityDeclarationImpl("amp", "&")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				entityNodeMap.getHashtable().put("lt", new CMEntityDeclarationImpl("lt", "<")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				entityNodeMap.getHashtable().put("gt", new CMEntityDeclarationImpl("gt", ">")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				entityNodeMap.getHashtable().put("quot", new CMEntityDeclarationImpl("quot", "\"")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				entityNodeMap.getHashtable().put("apos", new CMEntityDeclarationImpl("apos", "'")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

				for (Iterator i = dtdFile.listDTDEntity().iterator(); i.hasNext();) {
					DTDEntity dtdEntity = (DTDEntity) i.next();
					if (!dtdEntity.isParameterEntity() && dtdEntity.getName() != null) {
						// for now... just handle DTDInternalEntity
						//
						if (dtdEntity.getContent() instanceof DTDInternalEntity) {
							entityNodeMap.getHashtable().put(dtdEntity.getName(), getAdapter(dtdEntity));
						}
					}
				}
			}
			return entityNodeMap;
		}

		public CMNamespace getNamespace() {
			return null;
		}

		public int getNodeType() {
			return DOCUMENT;
		}

		public String getNodeName() {
			return dtdFile.getName() + ".dtd"; //$NON-NLS-1$
		}

		public Object getProperty(String propertyName) {
			Object result = null;
			if (propertyName.equals(DEFAULT_ROOT_NAME)) {
				DTDMetrics metrics = new DTDMetrics(dtdFile);
				DTDElement dtdElement = metrics.getLeastReferencedElement();
				if (dtdElement != null) {
					result = dtdElement.getName();
				}
			}
			else if (propertyName.equals("annotationMap")) { //$NON-NLS-1$
				result = annotationMap;
			}
			else if (propertyName.equals("globalPropertyMap")) { //$NON-NLS-1$
				result = globalPropertyMap;
			}
			else {
				result = super.getProperty(propertyName);
			}
			return result;
		}
	}


	public static class CMDataTypeInfoTable {
		protected String[] instanceValueTable;
		protected String[] dataTypeNameTable;

		public CMDataTypeInfoTable() {
			// hashtable.put(DTDType.CDATA, null));
			instanceValueTable = new String[DTDBasicTypeImpl.basicTypeKinds.length];
			instanceValueTable[DTDBasicTypeKind.ENTITY] = "entity"; //$NON-NLS-1$
			instanceValueTable[DTDBasicTypeKind.ENTITIES] = "entities"; //$NON-NLS-1$
			instanceValueTable[DTDBasicTypeKind.NMTOKEN] = "nmtoken"; //$NON-NLS-1$
			instanceValueTable[DTDBasicTypeKind.NMTOKENS] = "nmtokens"; //$NON-NLS-1$

			dataTypeNameTable = new String[DTDBasicTypeImpl.basicTypeKinds.length];
			dataTypeNameTable[DTDBasicTypeKind.CDATA] = CMDataType.CDATA;
			dataTypeNameTable[DTDBasicTypeKind.ID] = CMDataType.ID;
			dataTypeNameTable[DTDBasicTypeKind.IDREF] = CMDataType.IDREF;
			dataTypeNameTable[DTDBasicTypeKind.ENTITY] = CMDataType.ENTITY;
			dataTypeNameTable[DTDBasicTypeKind.ENTITIES] = CMDataType.ENTITIES;
			dataTypeNameTable[DTDBasicTypeKind.NMTOKEN] = CMDataType.NMTOKEN;
			dataTypeNameTable[DTDBasicTypeKind.NMTOKENS] = CMDataType.NMTOKENS;
		}

		public String getInstanceValue(DTDType dtdType) {
			String result = null;
			if (dtdType instanceof DTDBasicType) {
				int kind = ((DTDBasicType) dtdType).getKind().getValue();
				if (kind >= 0 && kind < DTDBasicTypeImpl.basicTypeDescriptions.length) {
					result = instanceValueTable[kind];
				}
			}
			return result;
		}

		public String getDataTypeName(DTDType dtdType) {
			String result = null;
			if (dtdType instanceof DTDBasicType) {
				int kind = ((DTDBasicType) dtdType).getKind().getValue();
				if (kind >= 0 && kind < DTDBasicTypeImpl.basicTypeDescriptions.length) {
					result = dataTypeNameTable[kind];
				}
			}
			else if (dtdType instanceof DTDEnumerationType) {
				result = CMDataType.ENUM;
			}
			return result;
		}
	}
}
