/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.sdt.types;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDPackage;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.XSDTypeDefinition;
import org.eclipse.xsd.XSDVariety;
import org.eclipse.xsd.impl.XSDSchemaImpl;
import org.eclipse.xsd.util.XSDConstants;
import org.eclipse.xsd.util.XSDResourceImpl;
import org.teiid.core.designer.ModelerCoreException;
import org.teiid.core.designer.id.ObjectID;
import org.teiid.core.designer.id.UUID;
import org.teiid.core.designer.util.CoreArgCheck;
import org.teiid.core.designer.util.CoreStringUtil;
import org.teiid.designer.core.ModelerCore;
import org.teiid.designer.core.TransactionRunnable;
import org.teiid.designer.core.metamodel.aspect.sql.SqlDatatypeAspect;
import org.teiid.designer.core.transaction.UnitOfWork;
import org.teiid.designer.core.types.DatatypeConstants;
import org.teiid.designer.core.types.DatatypeManager;
import org.teiid.designer.core.types.EnterpriseDatatypeInfo;
import org.teiid.designer.sdt.ModelerSdtPlugin;
/**
* DatatypeManagerImpl
*
* @since 8.0
*/
public class BuiltInTypesManager extends AbstractDatatypeManager {
// http://www.w3.org/2001/XMLSchema
protected static final String XSD_SCHEMA_URI_STRING = ModelerCore.XML_SCHEMA_GENERAL_URI;
// http://www.w3.org/2001/MagicXMLSchema
protected static final String MAGIC_SCHEMA_URI_STRING = ModelerCore.XML_MAGIC_SCHEMA_GENERAL_URI;
// platform:/plugin/org.eclipse.xsd_1.1.1/cache/www.w3.org/2001/MagicXMLSchema.xsd#//anyType;XSDSimpleTypeDefinition
protected static final String ANY_TYPE_NAME = "anyType"; //$NON-NLS-1$
protected static final String ANY_TYPE_URI_STRING = ModelerCore.XML_MAGIC_SCHEMA_ECLIPSE_PLATFORM_URI
+ "#//anyType;XSDSimpleTypeDefinition"; //$NON-NLS-1$
protected static final URI ANY_TYPE_URI = URI.createURI(ANY_TYPE_URI_STRING);
// platform:/plugin/org.eclipse.xsd_1.1.1/cache/www.w3.org/2001/MagicXMLSchema.xsd#//anySimpleType;XSDSimpleTypeDefinition=1
protected static final String ANY_SIMPLE_TYPE_NAME = "anySimpleType"; //$NON-NLS-1$
protected static final String ANY_SIMPLE_TYPE_URI_STRING = ModelerCore.XML_MAGIC_SCHEMA_ECLIPSE_PLATFORM_URI
+ "#//anySimpleType;XSDSimpleTypeDefinition=1"; //$NON-NLS-1$
protected static final URI ANY_SIMPLE_TYPE_URI = URI.createURI(ANY_SIMPLE_TYPE_URI_STRING);
/**
* Defines the expected built-in datatypes target namespace - must be consistent with the values found in
* org.teiid.designer.sdt plugin.xml
*/
public static final String BUILTIN_DATATYPES_URI_STRING = DatatypeConstants.BUILTIN_DATATYPES_URI;
public static final URI BUILTIN_DATATYPES_URI = URI.createURI(DatatypeConstants.BUILTIN_DATATYPES_URI);
// Map, keyed on datatype name, of EMF's built-in datatypes as defined in the org.eclipse.xsd plugin.
Map emfDatatypeMap;
// Map, keyed on datatype name, of built-in datatypes as defined in the modeler.sdt plugin.
Map mmDatatypeMap;
// Map, keyed on uuid string, of built-in datatypes as defined in the modeler.sdt plugin.
private Map uuidToMmTypeMap;
// DEFECT 23839 - Maps keyed to mmType. Caching these types improves performance because getting the type from the SqlAspect
// is more
// expensive
private Map mmTypeToUuidStringMap;
private Map mmTypeToRuntimeTypeNameMap;
// References to the ur-types
private EObject anyType;
private EObject anySimpleType;
// The unmodifiable list of built-in primitive types
private List primitiveTypes;
// The Emf and Teiid Designer resources for the built-in datatype model
private Resource emfResource;
private Resource mmResource;
private boolean hasEMFEnterpriseInfoInit;
/**
* Construct an instance of DatatypeManagerImpl.
*/
public BuiltInTypesManager() {
super();
}
@Override
protected void doInitialize() {
init();
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getBuiltInTypeManager()
* @since 4.3
*/
@Override
public DatatypeManager getBuiltInTypeManager() {
return this;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getUUID(org.eclipse.emf.ecore.EObject)
*/
@Override
public ObjectID getUuid( final EObject type ) {
// Use the Teiid Designer built-in datatype reference to get the UUID
final EObject mmType = this.getMmType(type);
final SqlDatatypeAspect aspect = getSqlAspect(mmType);
if (aspect != null) {
return (ObjectID)aspect.getObjectID(mmType);
}
return null;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getUuidString(org.eclipse.emf.ecore.EObject)
*/
@Override
public String getUuidString( EObject type ) {
String uuidString = null;
// Use the Teiid Designer built-in datatype reference to get the UUID
final EObject mmType = this.getMmType(type);
// Defect 23839 - check for cached type-UUID
uuidString = (String)mmTypeToUuidStringMap.get(mmType);
// Defect 23839 - if NOT cached, get the aspect, then UUID and add to cache.
if (uuidString == null) {
final SqlDatatypeAspect aspect = getSqlAspect(mmType);
if (aspect != null) {
uuidString = aspect.getUuidString(mmType);
mmTypeToUuidStringMap.put(mmType, uuidString);
}
}
return uuidString;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getRuntimeTypeName(org.eclipse.emf.ecore.EObject)
*/
@Override
public String getRuntimeTypeName( final EObject type ) {
// If the datatype is a ur-type return a predefined runtime type
if (type == this.anySimpleType || type == this.anyType) {
return DatatypeConstants.RuntimeTypeNames.OBJECT;
}
// Use the Teiid Designer built-in datatype reference to get the runtime type
final EObject mmType = this.getMmType(type);
// Defect 23839 - check for cached type-runtimeType
String theRuntimeTypeName = (String)mmTypeToRuntimeTypeNameMap.get(mmType);
// Defect 23839 - if NOT found, get the aspect, runtimeType name and put in map
if (theRuntimeTypeName == null) {
final SqlDatatypeAspect aspect = getSqlAspect(mmType);
if (aspect != null) {
theRuntimeTypeName = aspect.getRuntimeTypeName(mmType);
mmTypeToRuntimeTypeNameMap.put(mmType, theRuntimeTypeName);
}
}
return theRuntimeTypeName;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getRuntimeTypeFixed(org.eclipse.emf.ecore.EObject)
*/
@Override
public Boolean getRuntimeTypeFixed( final EObject type ) {
Boolean result = null;
// If the datatype is a ur-type return a predefined runtime type
if (type == this.anySimpleType || type == this.anyType) {
result = Boolean.FALSE;
}
// Use the Teiid Designer built-in datatype reference to get the runtime type
final EObject mmType = this.getMmType(type);
final SqlDatatypeAspect aspect = getSqlAspect(mmType);
if (aspect != null) {
result = aspect.getRuntimeTypeFixed(mmType);
}
return result;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getEnterpriseExtensionsMap(org.eclipse.emf.ecore.EObject)
*/
@Override
public Map getEnterpriseExtensionsMap( EObject type ) {
// Use the Teiid Designer built-in datatype reference to get the extension map
final EObject mmType = this.getMmType(type);
final SqlDatatypeAspect aspect = getSqlAspect(mmType);
if (aspect != null) {
return aspect.getEnterpriseExtensionsMap(mmType);
}
return Collections.EMPTY_MAP;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getName(org.eclipse.emf.ecore.EObject)
*/
@Override
public String getName( EObject type ) {
final SqlDatatypeAspect aspect = getSqlAspect(type);
if (aspect != null) {
return aspect.getName(type);
}
return null;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#isSimpleDatatype(org.eclipse.emf.ecore.EObject)
*/
@Override
public boolean isSimpleDatatype( EObject type ) {
final SqlDatatypeAspect aspect = getSqlAspect(type);
if (aspect != null) {
return aspect.isSimpleDatatype(type);
}
return false;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getAnySimpleType()
*/
@Override
public EObject getAnySimpleType() {
if (this.anySimpleType == null) {
this.anySimpleType = XSDSchemaImpl.getGlobalResourceSet().getEObject(ANY_SIMPLE_TYPE_URI, true);
}
return this.anySimpleType;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getAnyType()
*/
@Override
public EObject getAnyType() {
if (this.anyType == null) {
this.anyType = XSDSchemaImpl.getGlobalResourceSet().getEObject(ANY_TYPE_URI, true);
}
return this.anyType;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getDefaultDatatypeForRuntimeTypeName(java.lang.String)
*/
@Override
public EObject getDefaultDatatypeForRuntimeTypeName( final String runtimeTypeName ) {
final String builtInTypeName = DatatypeConstants.getDatatypeNamefromRuntimeType(runtimeTypeName);
if (builtInTypeName != null) {
return this.getBuiltInDatatype(builtInTypeName);
}
return null;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#isBuiltInDatatype(org.eclipse.emf.ecore.EObject)
*/
@Override
public boolean isBuiltInDatatype( final EObject datatype ) {
final SqlDatatypeAspect aspect = getSqlAspect(datatype);
if (aspect != null) {
return aspect.isBuiltInDatatype(datatype);
}
return false;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getBaseType(org.eclipse.emf.ecore.EObject)
*/
@Override
public EObject getBaseType( final EObject datatype ) {
final SqlDatatypeAspect aspect = getSqlAspect(datatype);
if (aspect != null) {
// If the entity is either anyType or anySimpleType then return null
if (aspect.isURType(datatype)) {
return null;
}
// If the basetype has no identity then return anySimpleType
XSDSimpleTypeDefinition entity = (XSDSimpleTypeDefinition)datatype;
XSDSimpleTypeDefinition basetype = (XSDSimpleTypeDefinition)aspect.getBasetype(entity);
try {
// If the datatype is of a list variety then return the itemtype as the basetype
final XSDVariety variety = entity.getVariety();
if (variety == XSDVariety.LIST_LITERAL) {
basetype = entity.getItemTypeDefinition();
}
// If the datatype is of a union variety then return "anySimpleType" as the basetype
else if (variety == XSDVariety.UNION_LITERAL) {
basetype = (XSDSimpleTypeDefinition)this.getAnySimpleType();
}
// If the basetype is null then return "anySimpleType" as the basetype
if (basetype == null) {
basetype = (XSDSimpleTypeDefinition)this.getAnySimpleType();
}
// If the basetype is anonymous then return "anySimpleType" as the basetype
else if (basetype.getName() == null) {
basetype = (XSDSimpleTypeDefinition)this.getAnySimpleType();
}
if (XSDConstants.isAnySimpleType(basetype)) {
basetype = (XSDSimpleTypeDefinition)this.getAnySimpleType();
}
} catch (Throwable e) {
ModelerSdtPlugin.Util.log(IStatus.ERROR,
e,
ModelerSdtPlugin.Util.getString("DatatypeManagerImpl.Error_retrieving_the_basetype_for_datatype_1", datatype)); //$NON-NLS-1$
basetype = null;
}
// If the basetype is a built-in datatype then return the EMF XSD built-in
// instead of the Teiid Designer built-in type.
final XSDSimpleTypeDefinition emfType = (XSDSimpleTypeDefinition)this.getEmfType(basetype);
if (emfType != null) {
basetype = emfType;
}
return basetype;
}
return null;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getDatatypeForXsdType
*/
@Override
public EObject getDatatypeForXsdType( final EObject eObject ) {
CoreArgCheck.isNotNull(eObject);
// If the object is a simple type ...
if (eObject instanceof XSDSimpleTypeDefinition) {
return getDatatypeForXsdType((XSDSimpleTypeDefinition)eObject);
}
// Check if the object is a complex type ...
if (eObject instanceof XSDComplexTypeDefinition) {
return getDatatypeForXsdType((XSDComplexTypeDefinition)eObject);
}
return null;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getAllDatatypes()
*/
@Override
public EObject[] getAllDatatypes() {
// Add "anySimpleType" to the top of the results
List tmp = new ArrayList();
tmp.add(this.getAnySimpleType());
// Added in all the EMF XSD built-in datatypes and the Teiid Designer
// extensions to the built-in dataytpes
for (Iterator iter = this.mmDatatypeMap.values().iterator(); iter.hasNext();) {
final XSDTypeDefinition mmType = (XSDTypeDefinition)iter.next();
final String mmTypeName = mmType.getName().toLowerCase();
final XSDTypeDefinition emfType = (XSDTypeDefinition)this.emfDatatypeMap.get(mmTypeName);
if (emfType != null) {
tmp.add(emfType);
} else {
tmp.add(mmType);
}
}
// Remove any duplicates
removeDuplicates(tmp);
// Sort the results by name
sortByName(tmp);
return (EObject[])tmp.toArray(new EObject[tmp.size()]);
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getAllowableBaseTypeValues(org.eclipse.emf.ecore.EObject)
*/
@Override
public EObject[] getAllowableBaseTypeValues( final EObject datatype ) {
// Get the array of all possible datatypes
List tmp = new ArrayList();
tmp.addAll(Arrays.asList(this.getAllDatatypes()));
// Remove the ur-type "anySimpleType" which is not allowed as a
// basetype outside the schema of schemas
tmp.remove(this.getAnySimpleType());
// Remove the datatype itself as an allowable basetype
tmp.remove(datatype);
return (EObject[])tmp.toArray(new EObject[tmp.size()]);
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getAllowableItemTypeValues(org.eclipse.emf.ecore.EObject)
*/
@Override
public EObject[] getAllowableItemTypeValues( final EObject datatype ) {
// Get the array of all possible datatypes
List tmp = new ArrayList();
tmp.addAll(Arrays.asList(this.getAllDatatypes()));
// Remove the datatype itself as an allowable basetype
tmp.remove(datatype);
return (EObject[])tmp.toArray(new EObject[tmp.size()]);
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getAllowableMemberTypeValues(org.eclipse.emf.ecore.EObject)
*/
@Override
public EObject[] getAllowableMemberTypeValues( final EObject datatype ) {
// Get the array of all possible datatypes
List tmp = new ArrayList();
tmp.addAll(Arrays.asList(this.getAllDatatypes()));
// Remove the datatype itself as an allowable basetype
tmp.remove(datatype);
return (EObject[])tmp.toArray(new EObject[tmp.size()]);
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getAllowableTypeValues(org.eclipse.emf.ecore.EObject,
* org.eclipse.emf.ecore.EStructuralFeature)
*/
@Override
public EObject[] getAllowableTypeValues( final EObject eObject,
final EStructuralFeature feature ) {
if (feature == null || eObject == null) {
return this.getAllDatatypes();
} else if (eObject instanceof XSDSimpleTypeDefinition
&& feature.getFeatureID() == XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__BASE_TYPE_DEFINITION) {
return this.getAllowableBaseTypeValues(eObject);
} else if (eObject instanceof XSDSimpleTypeDefinition
&& feature.getFeatureID() == XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__ITEM_TYPE_DEFINITION) {
return this.getAllowableItemTypeValues(eObject);
} else if (eObject instanceof XSDSimpleTypeDefinition
&& feature.getFeatureID() == XSDPackage.XSD_SIMPLE_TYPE_DEFINITION__MEMBER_TYPE_DEFINITIONS) {
return this.getAllowableMemberTypeValues(eObject);
}
return this.getAllDatatypes();
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getBuiltInDatatype(java.lang.String)
*/
@Override
public EObject getBuiltInDatatype( final String name ) {
CoreArgCheck.isNotNull(name);
String id = name;
// If the name is the URI of an XMLSchema built-in datatype like
// "http://www.w3.org/2001/XMLSchema#string" then extract the name
// of the built-in datatype ...
if (id.startsWith(XSD_SCHEMA_URI_STRING) && id.indexOf(DatatypeConstants.URI_REFERENCE_DELIMITER) >= 0) {
int beginIndex = id.indexOf(DatatypeConstants.URI_REFERENCE_DELIMITER) + 1;
id = id.substring(beginIndex);
if (id.startsWith("//") && id.indexOf(';') > 0) { //$NON-NLS-1$
id = id.substring(2, id.indexOf(';'));
}
}
// If the name is the URI of an XMLSchema built-in datatype like
// "http://www.metamatrix.com/metamodels/SimpleDatatypes-instance#string"
// then extract the name of the built-in datatype ...
if (id.startsWith(BUILTIN_DATATYPES_URI_STRING) && id.indexOf(DatatypeConstants.URI_REFERENCE_DELIMITER) >= 0) {
int beginIndex = id.indexOf(DatatypeConstants.URI_REFERENCE_DELIMITER) + 1;
id = id.substring(beginIndex);
if (id.startsWith("//") && id.indexOf(';') > 0) { //$NON-NLS-1$
id = id.substring(2, id.indexOf(';'));
}
}
// If the name is one of the ur-types, "anyType" or "anySimpleType" ...
if (id.equalsIgnoreCase(ANY_TYPE_NAME)) {
return this.getAnyType();
}
if (id.equalsIgnoreCase(ANY_SIMPLE_TYPE_NAME)) {
return this.getAnySimpleType();
}
// Lookup the Teiid Designer built-in datatype by UUID
EObject mmType = null;
if (id.startsWith(UUID.PROTOCOL)) {
mmType = (EObject)this.uuidToMmTypeMap.get(id);
}
// Lookup the Teiid Designer built-in datatype by name
else {
mmType = (EObject)this.mmDatatypeMap.get(id.toLowerCase());
}
// Get the corresponding EMF XSD built-in datatype ...
if (mmType != null) {
return this.getEmfType(mmType);
}
return mmType;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#findDatatype(java.lang.String)
*/
@Override
public EObject findDatatype( final String id ) {
// Check the built-in types manager first ...
EObject result = this.getBuiltInDatatype(id);
if (result != null) {
return result;
}
// Try to find an EObject with this identifier in the built-in datatype resources
EObject rv = this.findEObject(id);
if (rv instanceof XSDSimpleTypeDefinition) {
return rv;
} // endif
return null;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getRuntimeTypeJavaClassName(java.lang.String)
*/
@Override
public String getRuntimeTypeJavaClassName( final String id ) {
// Use the Teiid Designer built-in datatype reference to get the java class name
final EObject type = this.getBuiltInDatatype(id);
final EObject mmType = this.getMmType(type);
final SqlDatatypeAspect aspect = getSqlAspect(mmType);
if (aspect != null) {
return aspect.getJavaClassName(mmType);
}
return null;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getRuntimeTypeName(java.lang.String)
*/
@Override
public String getRuntimeTypeName( final String id ) {
final EObject type = this.getBuiltInDatatype(id);
return this.getRuntimeTypeName(type);
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getSubtypes(org.eclipse.emf.ecore.EObject)
*/
@Override
public EObject[] getSubtypes( final EObject datatype ) {
List tmp = new ArrayList();
final EObject[] allTypes = this.getAllDatatypes();
for (int i = 0; i < allTypes.length; i++) {
final EObject type = allTypes[i];
final EObject baseType = this.getBaseType(type);
if (baseType == datatype) {
tmp.add(type);
}
}
// If the basetype is "anyType" add in "anySimpleType" as a sub-type
if (datatype == this.getAnyType()) {
if (!tmp.contains(this.getAnySimpleType())) {
tmp.add(this.getAnySimpleType());
}
}
// Remove any duplicates
removeDuplicates(tmp);
// Sort the results by name
sortByName(tmp);
return (EObject[])tmp.toArray(new EObject[tmp.size()]);
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getBuiltInPrimitiveTypes()
*/
@Override
public EObject[] getBuiltInPrimitiveTypes() {
final List primTypes = this.getPrimitiveTypesList();
return (EObject[])primTypes.toArray(new EObject[primTypes.size()]);
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getBuiltInPrimitiveType(org.eclipse.emf.ecore.EObject)
*/
@Override
public EObject getBuiltInPrimitiveType( final EObject type ) {
CoreArgCheck.isNotNull(type);
// While the datatype type is not a built-in primitive type ...
final List primTypes = this.getPrimitiveTypesList();
EObject simpleType = type;
while (!primTypes.contains(simpleType)) {
final EObject baseType = this.getBaseType(simpleType);
if (simpleType == baseType) {
return null; // this would end up being recursion ...
}
simpleType = baseType;
}
return simpleType;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#isBinary(org.eclipse.emf.ecore.EObject)
*/
@Override
public boolean isBinary( final EObject type ) {
CoreArgCheck.isNotNull(type);
XSDSimpleTypeDefinition simpleType = (XSDSimpleTypeDefinition)this.getExtendedBuiltInBaseType(type);
if (simpleType != null) {
final String typeName = simpleType.getName();
if (DatatypeConstants.BuiltInNames.OBJECT.equals(typeName) || DatatypeConstants.BuiltInNames.BLOB.equals(typeName)
|| DatatypeConstants.BuiltInNames.CLOB.equals(typeName)) {
return true;
}
}
simpleType = (XSDSimpleTypeDefinition)this.getBuiltInPrimitiveType(type);
if (simpleType != null) {
final String typeName = simpleType.getName();
if (DatatypeConstants.BuiltInNames.BASE64_BINARY.equals(typeName)
|| DatatypeConstants.BuiltInNames.HEX_BINARY.equals(typeName)) {
return true;
}
}
return false;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#isCharacter(org.eclipse.emf.ecore.EObject)
*/
@Override
public boolean isCharacter( final EObject type ) {
CoreArgCheck.isNotNull(type);
final XSDSimpleTypeDefinition simpleType = (XSDSimpleTypeDefinition)this.getBuiltInPrimitiveType(type);
if (simpleType != null && DatatypeConstants.BuiltInNames.STRING.equals(simpleType.getName())) {
return true;
}
return false;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#isNumeric(org.eclipse.emf.ecore.EObject)
*/
@Override
public boolean isNumeric( final EObject type ) {
CoreArgCheck.isNotNull(type);
final XSDSimpleTypeDefinition simpleType = (XSDSimpleTypeDefinition)this.getBuiltInPrimitiveType(type);
if (simpleType != null && simpleType.getNumericFacet().isValue()) {
return true;
}
return false;
}
@Override
public boolean isBounded( final EObject type ) {
CoreArgCheck.isNotNull(type);
final XSDSimpleTypeDefinition simpleType = (XSDSimpleTypeDefinition)this.getBuiltInPrimitiveType(type);
if (simpleType != null && simpleType.getBoundedFacet().isValue()) {
return true;
}
return false;
}
@Override
public boolean isEnumeration( final EObject type ) {
CoreArgCheck.isNotNull(type);
if (type instanceof XSDSimpleTypeDefinition) {
final XSDSimpleTypeDefinition simpleType = (XSDSimpleTypeDefinition)type;
if (simpleType.getEnumerationFacets().size() > 0) {
return true;
}
}
return false;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getDescription(org.eclipse.emf.ecore.EObject)
*/
@Override
public String getDescription( final EObject type ) {
String description = null;
final SqlDatatypeAspect aspect = getSqlAspect(type);
if (aspect != null) {
description = aspect.getDescription(type);
}
return (description == null ? CoreStringUtil.Constants.EMPTY_STRING : description);
}
public EObject getDatatypeForXsdType( final XSDSimpleTypeDefinition simpleType ) {
CoreArgCheck.isNotNull(simpleType);
// While the simple type is not a built-in simple type (i.e., one in the schema of schemas) ...
EObject builtInType = simpleType;
while (!this.isBuiltInDatatype(builtInType)) {
final EObject baseType = this.getBaseType(simpleType);
if (builtInType == baseType) {
builtInType = null;
break; // this would end up being recursion ...
}
builtInType = baseType;
}
// Should only be null if its a simple type ...
if (builtInType == null) {
return getAnySimpleType();
}
// Here, the type is a built-in, so find the appropriate Datatype ...
return this.getBuiltInDatatype(((XSDSimpleTypeDefinition)builtInType).getName());
}
public EObject getDatatypeForXsdType( final XSDComplexTypeDefinition complexType ) {
CoreArgCheck.isNotNull(complexType);
// See if this can have character content ...
// mtkTODO: Implement getDatatypeForXsdType(XSDComplexTypeDefinition)
// If not, then there is no corresponding SimpleDatatype for a ComplexType with no content ...
return null;
}
/**
* Return the EObject instance corresponding to the extended built-in type that the specified type restricts. If no extended
* type exists anywhere in the type hierarchy for this datatype then null is returned.
*
* @param type
* @return
*/
public EObject getExtendedBuiltInBaseType( final EObject type ) {
CoreArgCheck.isNotNull(type);
CoreArgCheck.isInstanceOf(XSDSimpleTypeDefinition.class, type);
// Check the type hierarchy for a extended built-in type ...
final List mmExtendedTypes = this.getExtendedTypesList();
final EObject[] typeHierarchy = this.getTypeHierarchy(type);
for (int i = 0; i != typeHierarchy.length; ++i) {
if (mmExtendedTypes.contains(typeHierarchy[i])) {
return typeHierarchy[i];
}
}
return null;
}
/**
* Return the list of all Teiid Designer built-in types. These types represent extensions to the XML Schema of schema
* built-in types.
*/
public List getExtendedTypesList() {
final List mmExtendedTypes = new ArrayList();
final Collection mmExtendedTypeNames = DatatypeConstants.getMetaMatrixExtendedBuiltInTypeNames();
for (Iterator iter = mmExtendedTypeNames.iterator(); iter.hasNext();) {
String extendedTypeName = (String)iter.next();
EObject extendedType = (EObject)this.mmDatatypeMap.get(extendedTypeName.toLowerCase());
if (extendedType != null) {
mmExtendedTypes.add(extendedType);
}
}
return mmExtendedTypes;
}
/**
* @see org.teiid.designer.sdt.types.AbstractDatatypeManager#getDatatypeResources()
* @since 4.2
*/
@Override
protected List getDatatypeResources() {
if (mmResource != null) {
return Collections.singletonList(mmResource);
}
return Collections.EMPTY_LIST;
}
/**
* If the specified XSDTypeDefinition is a built-in datatype then return the EMF XSD built-in datatype as defined in the
* org.eclipse.xsd plugin. If specified type is not a built-in datatype then null is returned.
*
* @param type
* @return
*/
protected EObject getEmfType( final EObject type ) {
final SqlDatatypeAspect aspect = getSqlAspect(type);
if (aspect != null && aspect.isBuiltInDatatype(type)) {
// Lookup the EMF XSD built-in datatype by name
final String typeName = ((XSDTypeDefinition)type).getName();
final EObject emfType = (EObject)this.emfDatatypeMap.get(typeName.toLowerCase());
// If found in the map then return the reference
if (emfType != null) {
return emfType;
}
// If not found in the EMF XSD built-in datatypes map then the
// type is probably one of the extended built-in datatypes
return type;
}
return null;
}
/**
* If the specified XSDTypeDefinition is a built-in datatype then return the Teiid Designer built-in datatype as defined in
* the modeler.sdt plugin. If specified type is not a built-in datatype then null is returned.
*
* @param type
* @return
*/
protected EObject getMmType( final EObject type ) {
final SqlDatatypeAspect aspect = getSqlAspect(type);
if (aspect != null && aspect.isBuiltInDatatype(type)) {
// Lookup the Teiid Designer built-in datatype by name
final String typeName = ((XSDTypeDefinition)type).getName();
final EObject emfType = (EObject)this.mmDatatypeMap.get(typeName.toLowerCase());
// If found in the map then return the reference
if (emfType != null) {
return emfType;
}
}
return null;
}
/**
* Return the EObject instance corresponding to the specified identifier string
*
* @param id
* @return
* @throws ModelerCoreException
*/
protected EObject findEObject( final String id ) {
if (id == null) {
return null;
}
if (this.emfResource instanceof XSDResourceImpl && id.startsWith(UUID.PROTOCOL)) {
return (EObject)this.uuidToMmTypeMap.get(id);
}
EObject result = this.emfResource.getEObject(id);
if (result == null) {
result = this.mmResource.getEObject(id);
}
return result;
}
protected void init() {
this.primitiveTypes = null;
this.emfResource = null;
this.mmResource = null;
this.emfDatatypeMap = new HashMap();
this.mmDatatypeMap = new HashMap();
this.uuidToMmTypeMap = new HashMap();
this.mmTypeToUuidStringMap = new HashMap();
this.mmTypeToRuntimeTypeNameMap = new HashMap();
this.initializeEmfDatatypeMap();
this.initializeMmDatatypeMap();
this.initializeUuidToMmTypeMap();
}
/**
* Return the list of built-in primitive types. A primitive type is one whose basetype is one of the ur-types.
*/
private List getPrimitiveTypesList() {
if (this.primitiveTypes == null) {
this.primitiveTypes = new ArrayList();
try {
final EObject[] allTypes = this.getAllDatatypes();
for (int i = 0; i < allTypes.length; i++) {
final EObject type = allTypes[i];
final EObject baseType = this.getBaseType(type);
if (baseType == this.getAnySimpleType() || baseType == this.getAnyType()) {
this.primitiveTypes.add(type);
}
}
} catch (Throwable e) {
final String msg = ModelerSdtPlugin.Util.getString("BuiltInTypesManager.Error_constructing_the_list_of_built-in_primitive_types_1"); //$NON-NLS-1$
ModelerSdtPlugin.Util.log(IStatus.ERROR, e, msg);
}
// Remove any duplicates
removeDuplicates(this.primitiveTypes);
// Sort the results by name
sortByName(this.primitiveTypes);
}
return this.primitiveTypes;
}
private void initializeEmfDatatypeMap() {
// Populate the xsdBuiltInDatatypeMap map with all XML Schema built-in datatypes
final XSDSchema schema = XSDSchemaImpl.getSchemaForSchema(XSD_SCHEMA_URI_STRING);
for (Iterator iterator = schema.getContents().iterator(); iterator.hasNext();) {
final EObject eObject = (EObject)iterator.next();
if (eObject instanceof XSDSimpleTypeDefinition) {
final XSDSimpleTypeDefinition type = (XSDSimpleTypeDefinition)eObject;
final String typeName = type.getName();
if (DatatypeConstants.getBuiltInTypeNames().contains(typeName)) {
this.emfDatatypeMap.put(typeName.toLowerCase(), type);
// } else {
// System.out.println("name not found = "+typeName)
}
}
}
// Set the reference to the Emf resource
this.emfResource = schema.eResource();
}
private void initializeMmDatatypeMap() {
try {
// Retrieve the built-in datatype resource from the model container
final Resource resource = this.getContainer().getResource(BUILTIN_DATATYPES_URI, false);
if (resource == null) {
final Object[] params = new Object[] {BUILTIN_DATATYPES_URI};
final String msg = ModelerSdtPlugin.Util.getString("BuiltInTypesManager.Error_obtain_the_built-in_datatypes_resource_from_the_container_using_URI_1", params); //$NON-NLS-1$
throw new RuntimeException(msg);
}
// Set the reference to the Emf resource
this.mmResource = resource;
// Populate the sdtBuiltInDatatypeMap map with all built-in datatypes
// Populate the mmDatatypeMap map with all built-in datatypes
// keyed by lower case name
for (Iterator iter = resource.getContents().iterator(); iter.hasNext();) {
EObject eObject = (EObject)iter.next();
if (eObject != null && eObject instanceof XSDSchema) {
// Found the schema now gather all the global simple types ...
for (Iterator iter2 = eObject.eContents().iterator(); iter2.hasNext();) {
eObject = (EObject)iter2.next();
if (eObject != null && eObject instanceof XSDSimpleTypeDefinition) {
final XSDSimpleTypeDefinition type = (XSDSimpleTypeDefinition)eObject;
final String typeName = type.getName();
this.mmDatatypeMap.put(typeName.toLowerCase(), type);
}
}
}
}
} catch (Throwable e) {
final Object[] params = new Object[] {BUILTIN_DATATYPES_URI};
final String msg = ModelerSdtPlugin.Util.getString("BuiltInTypesManager.Error_obtain_the_built-in_datatypes_resource_from_the_container_using_URI_2", params); //$NON-NLS-1$
ModelerSdtPlugin.Util.log(IStatus.ERROR, e, msg);
}
}
private void initializeUuidToMmTypeMap() {
for (Iterator iter = this.mmDatatypeMap.values().iterator(); iter.hasNext();) {
final EObject type = (EObject)iter.next();
final String uuid = this.getUuidString(type);
if (uuid != null) {
this.uuidToMmTypeMap.put(uuid, type);
}
}
}
private void initializeEnterpriseDataForEmfResource() {
hasEMFEnterpriseInfoInit = true;
// defect 19183 -- These changes are not undoable. Wrap them
// in their own transaction to prevent 5000 undo entries from
// getting created:
final TransactionRunnable runnable = new TransactionRunnable() {
@Override
public Object run( final UnitOfWork uow ) {
for (Iterator iter = mmDatatypeMap.values().iterator(); iter.hasNext();) {
final XSDSimpleTypeDefinition mmType = (XSDSimpleTypeDefinition)iter.next();
final String typeName = mmType.getName().toLowerCase();
final XSDSimpleTypeDefinition emfType = (XSDSimpleTypeDefinition)emfDatatypeMap.get(typeName);
if (emfType != null) {
if (!getSqlAspect(mmType).isEnterpriseDataType(emfType)) {
EnterpriseDatatypeInfo edt = new EnterpriseDatatypeInfo(getUuidString(mmType),
getRuntimeTypeName(mmType),
getRuntimeTypeFixed(mmType));
getSqlAspect(mmType).setEnterpriseDataAttributes(emfType, edt);
} // endif -- is Enterprise
} // endif -- not null
} // endfor -- over built-in types
return null;
}
}; // endanon transaction
try {
ModelerCore.getModelEditor().executeAsTransaction(runnable,
"updating built-in type enterprise info", false, false, this); //$NON-NLS-1$ // not visible to users...
} catch (ModelerCoreException mce) {
ModelerSdtPlugin.Util.log(mce);
} // endtry
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getBuiltInDatatypes()
* @since 4.3
*/
@Override
public EObject[] getBuiltInDatatypes() {
return getAllDatatypes();
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#isEnterpriseDatatype(org.eclipse.emf.ecore.EObject)
* @since 4.3
*/
@Override
public boolean isEnterpriseDatatype( EObject simpleType ) {
final SqlDatatypeAspect aspect = getSqlAspect(simpleType);
if (aspect != null) {
if (!hasEMFEnterpriseInfoInit) {
initializeEnterpriseDataForEmfResource();
} // endif
return aspect.isEnterpriseDataType(simpleType);
}
return false;
}
/**
* @see org.teiid.designer.core.types.DatatypeManager#getEnterpriseDatatypeInfo(org.eclipse.xsd.XSDSimpleTypeDefinition)
* @since 4.3
*/
@Override
public EnterpriseDatatypeInfo getEnterpriseDatatypeInfo( XSDSimpleTypeDefinition simpleType ) {
if (!hasEMFEnterpriseInfoInit) {
initializeEnterpriseDataForEmfResource();
} // endif
return getSqlAspect(simpleType).getEnterpriseDatatypeInfo(simpleType);
}
/**
* Should not allow modification of built-in datatypes
*
* @see org.teiid.designer.core.types.DatatypeManager#setBasetypeDefinition(org.eclipse.xsd.XSDSimpleTypeDefinition)
* @since 4.3
*/
@Override
public void setBasetypeDefinition( final XSDSimpleTypeDefinition simpleType,
final XSDSimpleTypeDefinition baseType ) {
throw new UnsupportedOperationException();
}
}