/* * 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.metamodels.relational.util; import java.lang.reflect.Field; import java.sql.Types; import java.util.HashMap; import java.util.Map; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.ecore.EObject; import org.teiid.core.designer.ModelerCoreException; import org.teiid.core.designer.ModelerCoreRuntimeException; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.metamodel.aspect.sql.SqlAspect; import org.teiid.designer.core.metamodel.aspect.sql.SqlDatatypeAspect; import org.teiid.designer.core.types.DatatypeConstants; import org.teiid.designer.core.types.DatatypeManager; import org.teiid.designer.metadata.runtime.api.DataType; import org.teiid.designer.metamodels.relational.RelationalPlugin; import org.teiid.designer.metamodels.relational.SearchabilityType; import org.teiid.designer.query.IQueryService; /** * This class provides a mapping between the built-in types and the JDBC types. * * @since 8.0 */ public class RelationalTypeMappingImpl implements RelationalTypeMapping { /** * Set of CAPITALIZED reserved words for checking whether a string is a reserved word. */ private static final Map<String, Integer> SQL_TYPE_MAPPING = new HashMap<String, Integer>(); // This is a poor man's enum. static { Field[] fields = Types.class.getDeclaredFields(); for (Field field : fields) { if (field.getType() == int.class) { try { SQL_TYPE_MAPPING.put(field.getName(), field.getInt(null)); } catch (Exception e) { } } } } private static RelationalTypeMapping instance; public static RelationalTypeMapping getInstance() { if (RelationalTypeMappingImpl.instance == null) { RelationalTypeMappingImpl.instance = new RelationalTypeMappingImpl(); } return RelationalTypeMappingImpl.instance; } protected static DatatypeManager getStandardDatatypeManager() { try { return ModelerCore.getWorkspaceDatatypeManager(); } catch (ModelerCoreRuntimeException e) { RelationalPlugin.Util.log(e); } return null; } private final DatatypeManager datatypeManager; /** * Construct an instance of RelationalTypeMapping. */ public RelationalTypeMappingImpl() { this(RelationalTypeMappingImpl.getStandardDatatypeManager()); } /** * Construct an instance of RelationalTypeMapping. */ public RelationalTypeMappingImpl( final DatatypeManager datatypeManager ) { super(); this.datatypeManager = datatypeManager; if (this.datatypeManager == null) { final String msg = RelationalPlugin.Util.getString("RelationalTypeMapping.No_DatatypeManager"); //$NON-NLS-1$ RelationalPlugin.Util.log(IStatus.ERROR, msg); } } protected EObject findDatatype( final String identifier ) throws ModelerCoreException { EObject result = this.datatypeManager.getBuiltInDatatype(identifier); if (result == null) { result = this.datatypeManager.findDatatype(identifier); } return result; } protected String getIdentifier( final EObject datatype ) { CoreArgCheck.isNotNull(datatype); final SqlAspect sqlAspect = (SqlAspect)ModelerCore.getMetamodelRegistry().getMetamodelAspect(datatype, SqlAspect.class); if (sqlAspect == null) { return this.datatypeManager.getName(datatype); } if (sqlAspect instanceof SqlDatatypeAspect) { final SqlDatatypeAspect datatypeAspect = (SqlDatatypeAspect)sqlAspect; final String id = datatypeAspect.getDatatypeID(datatype); return id; } final Object id = sqlAspect.getObjectID(datatype); if (id != null) { return id.toString(); } return null; } /** * Find the {@link DataType} that corresponds to the supplied type name from a JDBC data source. * * @param jdbcTypeName the name of the JDBC type * @return the {@link DataType} that best corresponds to the JDBC type name * @throws ModelerCoreException if there is a problem with the {@link DatatypeManager} */ @Override public EObject getDatatype( final String jdbcTypeName ) throws ModelerCoreException { EObject result = null; if (jdbcTypeName != null) { Integer typeCode = SQL_TYPE_MAPPING.get(jdbcTypeName.toUpperCase()); if (typeCode != null) { result = getDatatype(typeCode); } } if (result == null) { result = findDatatype(DatatypeConstants.BuiltInNames.OBJECT); } return result; } /** * Find the {@link DataType} that corresponds to the supplied {@link java.sql.Types JDBC type}. * * @param jdbcType the JDBC type * @return the {@link DataType} that best corresponds to the JDBC type, or null if no {@link DataType} could be found or if the type is * ambiguous (such as {@link Types#OTHER}). * @throws ModelerCoreException if there is a problem with the {@link DatatypeManager} */ @Override public EObject getDatatype( final int jdbcType ) throws ModelerCoreException { if (jdbcType == Types.JAVA_OBJECT) { return findDatatype(DatatypeConstants.BuiltInNames.OBJECT); } IQueryService service = ModelerCore.getTeiidQueryService(); String typeName = service.getJDBCSQLTypeName(jdbcType); String builtinName = DatatypeConstants.getDatatypeNamefromRuntimeType(typeName); if (builtinName == null || DatatypeConstants.BuiltInNames.OBJECT.equals(builtinName)) { return null; //not a known sql type } return findDatatype(builtinName); } @Override public SearchabilityType getSearchabilityType( final EObject datatype ) { if (datatype == null) { return SearchabilityType.UNSEARCHABLE_LITERAL; } EObject dt = datatype; while (dt != null && !this.datatypeManager.isBuiltInDatatype(dt)) { final EObject baseType = this.datatypeManager.getBaseType(dt); dt = this.datatypeManager.isSimpleDatatype(baseType) ? baseType : null; } final String typeName = this.datatypeManager.getName(dt); // These are SEARCHABLE if (DatatypeConstants.BuiltInNames.STRING.equals(typeName)) { return SearchabilityType.SEARCHABLE_LITERAL; } if (DatatypeConstants.BuiltInNames.CHAR.equals(typeName)) { return SearchabilityType.SEARCHABLE_LITERAL; } if (DatatypeConstants.BuiltInNames.CLOB.equals(typeName)) { return SearchabilityType.LIKE_ONLY_LITERAL; // per defect 10501 } // These are UNSEARCHABLE ... if (DatatypeConstants.BuiltInNames.BLOB.equals(typeName)) { return SearchabilityType.UNSEARCHABLE_LITERAL; } if (DatatypeConstants.BuiltInNames.XML_LITERAL.equals(typeName)) { return SearchabilityType.UNSEARCHABLE_LITERAL; } if (DatatypeConstants.BuiltInNames.OBJECT.equals(typeName)) { return SearchabilityType.UNSEARCHABLE_LITERAL; } // The rest are numbers or dates ... return SearchabilityType.ALL_EXCEPT_LIKE_LITERAL; } }