/******************************************************************************* * Copyright (c) 2006, 2008 Oracle. 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: * Oracle - initial API and implementation ******************************************************************************/ package org.eclipse.jpt.db.internal; import java.text.Collator; import org.eclipse.datatools.modelbase.dbdefinition.PredefinedDataTypeDefinition; import org.eclipse.datatools.modelbase.sql.datatypes.DataType; import org.eclipse.datatools.modelbase.sql.datatypes.PredefinedDataType; import org.eclipse.datatools.modelbase.sql.datatypes.PrimitiveType; import org.eclipse.jpt.db.Column; import org.eclipse.jpt.utility.JavaType; import org.eclipse.jpt.utility.internal.ClassTools; import org.eclipse.jpt.utility.internal.SimpleJavaType; /** * Wrap a DTP Column */ final class DTPColumnWrapper extends DTPDatabaseObjectWrapper implements Column { // the wrapped DTP column private final org.eclipse.datatools.modelbase.sql.tables.Column dtpColumn; // ********** constructor ********** DTPColumnWrapper(DTPTableWrapper table, org.eclipse.datatools.modelbase.sql.tables.Column dtpColumn) { super(table, dtpColumn); this.dtpColumn = dtpColumn; } // ********** DTPWrapper implementation ********** @Override synchronized void catalogObjectChanged() { super.catalogObjectChanged(); this.getConnectionProfile().columnChanged(this); } // ********** Column implementation ********** public String getName() { return this.dtpColumn.getName(); } public DTPTableWrapper getTable() { return (DTPTableWrapper) this.getParent(); } public boolean isPrimaryKeyColumn() { return this.getTable().primaryKeyColumnsContains(this); } public boolean isForeignKeyColumn() { return this.getTable().foreignKeyBaseColumnsContains(this); } public String getDataTypeName() { DataType dataType = this.dtpColumn.getDataType(); return (dataType == null) ? null : dataType.getName(); } public String getJavaTypeDeclaration() { return this.getJavaType().declaration(); } public JavaType getJavaType() { DataType dataType = this.dtpColumn.getDataType(); return (dataType instanceof PredefinedDataType) ? convertToJPAJavaType(this.getJavaType((PredefinedDataType) dataType)) : DEFAULT_JAVA_TYPE; } public String getPrimaryKeyJavaTypeDeclaration() { return this.getPrimaryKeyJavaType().declaration(); } public JavaType getPrimaryKeyJavaType() { return convertToJPAPrimaryKeyJavaType(this.getJavaType()); } private JavaType getJavaType(PredefinedDataType dataType) { // this is just a bit hacky: moving from a type declaration to a class name to a type declaration... String dtpJavaClassName = this.getDefinition(dataType).getJavaClassName(); return new SimpleJavaType(ClassTools.classNameForTypeDeclaration(dtpJavaClassName)); } private PredefinedDataTypeDefinition getDefinition(PredefinedDataType dataType) { return this.getDatabase().getDTPDefinition().getPredefinedDataTypeDefinition(dataType.getName()); } public boolean dataTypeIsLOB() { DataType dataType = this.dtpColumn.getDataType(); return (dataType instanceof PredefinedDataType) ? primitiveTypeIsLob(((PredefinedDataType) dataType).getPrimitiveType()) : false; } // ********** Comparable implementation ********** public int compareTo(Column column) { return Collator.getInstance().compare(this.getName(), column.getName()); } // ********** internal methods ********** boolean wraps(org.eclipse.datatools.modelbase.sql.tables.Column column) { return this.dtpColumn == column; } @Override void clear() { // no state to clear } // ********** static methods ********** /** * The JDBC spec says JDBC drivers should be able to map BLOBs and CLOBs * directly, but the JPA spec does not allow them. */ private static JavaType convertToJPAJavaType(JavaType javaType) { if (javaType.equals(BLOB_JAVA_TYPE)) { return BYTE_ARRAY_JAVA_TYPE; } if (javaType.equals(CLOB_JAVA_TYPE)) { return STRING_JAVA_TYPE; } return javaType; } /** * The JPA spec [2.1.4] says only the following types are allowed in * primary key fields: * [variable] primitives * [variable] primitive wrappers * java.lang.String * java.util.Date * java.sql.Date */ private static JavaType convertToJPAPrimaryKeyJavaType(JavaType javaType) { if (javaType.isVariablePrimitive() || javaType.isVariablePrimitiveWrapper() || javaType.equals(STRING_JAVA_TYPE) || javaType.equals(UTIL_DATE_JAVA_TYPE) || javaType.equals(SQL_DATE_JAVA_TYPE)) { return javaType; } if (javaType.equals(BIG_DECIMAL_JAVA_TYPE)) { return LONG_JAVA_TYPE; // ?? } if (javaType.equals(SQL_TIME_JAVA_TYPE)) { return UTIL_DATE_JAVA_TYPE; // ??? } if (javaType.equals(SQL_TIMESTAMP_JAVA_TYPE)) { return UTIL_DATE_JAVA_TYPE; // ??? } // all the other typical types are pretty much un-mappable - return String(?) return STRING_JAVA_TYPE; } private static boolean primitiveTypeIsLob(PrimitiveType primitiveType) { return (primitiveType == PrimitiveType.BINARY_LARGE_OBJECT_LITERAL) || (primitiveType == PrimitiveType.CHARACTER_LARGE_OBJECT_LITERAL) || (primitiveType == PrimitiveType.NATIONAL_CHARACTER_LARGE_OBJECT_LITERAL); } // ***** some constants used when converting the column to a Java attribute // TODO Object is the default? private static final JavaType DEFAULT_JAVA_TYPE = new SimpleJavaType(java.lang.Object.class); private static final JavaType BLOB_JAVA_TYPE = new SimpleJavaType(java.sql.Blob.class); private static final JavaType BYTE_ARRAY_JAVA_TYPE = new SimpleJavaType(byte[].class); private static final JavaType CLOB_JAVA_TYPE = new SimpleJavaType(java.sql.Clob.class); private static final JavaType STRING_JAVA_TYPE = new SimpleJavaType(java.lang.String.class); private static final JavaType UTIL_DATE_JAVA_TYPE = new SimpleJavaType(java.util.Date.class); private static final JavaType SQL_DATE_JAVA_TYPE = new SimpleJavaType(java.sql.Date.class); private static final JavaType SQL_TIME_JAVA_TYPE = new SimpleJavaType(java.sql.Time.class); private static final JavaType SQL_TIMESTAMP_JAVA_TYPE = new SimpleJavaType(java.sql.Timestamp.class); private static final JavaType BIG_DECIMAL_JAVA_TYPE = new SimpleJavaType(java.math.BigDecimal.class); private static final JavaType LONG_JAVA_TYPE = new SimpleJavaType(long.class); }