Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Winkler2010-05-11 07:03:17 +0000
committerStefan Winkler2010-05-11 07:03:17 +0000
commit4eca2fa7dfb3f099b3ddbebd34ded2ecc098385d (patch)
treec22c7d38a45ed7ce7404af7e9985a80bd00d8081
parentd5f887579008f09c6455ff6375297027c0814b8f (diff)
downloadcdo-4eca2fa7dfb3f099b3ddbebd34ded2ecc098385d.tar.gz
cdo-4eca2fa7dfb3f099b3ddbebd34ded2ecc098385d.tar.xz
cdo-4eca2fa7dfb3f099b3ddbebd34ded2ecc098385d.zip
[285426] [DB] Implement user-defined typeMapping support
https://bugs.eclipse.org/bugs/show_bug.cgi?id=285426
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/plugin.xml1
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/schema/typeMappings.exsd123
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStore.java5
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/ITypeMappingRegistry.java31
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/AbstractTypeMapping.java273
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMappingFactory.java24
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBAnnotation.java3
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java16
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/CoreTypeMappings.java (renamed from plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMapping.java)472
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingFactory.java328
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingRegistry.java310
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java9
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMappingWithRanges.java9
14 files changed, 1040 insertions, 566 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.db/plugin.xml b/plugins/org.eclipse.emf.cdo.server.db/plugin.xml
index b4668f1b3e..c58775b3c6 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/plugin.xml
+++ b/plugins/org.eclipse.emf.cdo.server.db/plugin.xml
@@ -14,6 +14,7 @@
<plugin>
<extension-point id="mappingStrategies" name="%extension-point.name" schema="schema/mappingStrategies.exsd"/>
+ <extension-point id="typeMappings" name="TypeMappings" schema="schema/typeMappings.exsd"/>
<extension
point="org.eclipse.net4j.util.factories">
diff --git a/plugins/org.eclipse.emf.cdo.server.db/schema/typeMappings.exsd b/plugins/org.eclipse.emf.cdo.server.db/schema/typeMappings.exsd
new file mode 100644
index 0000000000..784458445f
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/schema/typeMappings.exsd
@@ -0,0 +1,123 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.emf.cdo.server.db" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.emf.cdo.server.db" id="typeMappings" name="TypeMappings"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="typeMapping" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="typeMapping">
+ <complexType>
+ <attribute name="packageURI" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="dataTypeName" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="dbType" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.emf.cdo.server.db.mapping.AbstractTypeMapping:"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 3.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStore.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStore.java
index 55b783163c..b6b46194cd 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStore.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/IDBStore.java
@@ -63,4 +63,9 @@ public interface IDBStore extends IStore
* @since 2.0
*/
public IDBStoreAccessor getWriter(ITransaction transaction);
+
+ /**
+ * @since 3.0
+ */
+ public ITypeMappingRegistry getTypeMappingRegistry();
}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/ITypeMappingRegistry.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/ITypeMappingRegistry.java
new file mode 100644
index 0000000000..cd699d912c
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/ITypeMappingRegistry.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) 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:
+ * Stefan Winkler - initial API and implementation
+ */
+package org.eclipse.emf.cdo.server.db;
+
+import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
+
+import org.eclipse.net4j.db.DBType;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.util.Collection;
+
+/**
+ * @since 3.0
+ * @author Stefan Winkler
+ */
+public interface ITypeMappingRegistry
+{
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature);
+
+ public Collection<DBType> getDefaultFeatureMapDBTypes();
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/AbstractTypeMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/AbstractTypeMapping.java
new file mode 100644
index 0000000000..6f1cb7111d
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/AbstractTypeMapping.java
@@ -0,0 +1,273 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) 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:
+ * Eike Stepper - initial API and implementation
+ * Stefan Winkler - bug 271444: [DB] Multiple refactorings
+ * Stefan Winkler - bug 275303: [DB] DBStore does not handle BIG_INTEGER and BIG_DECIMAL
+ * Kai Schlamp - bug 282976: [DB] Influence Mappings through EAnnotations
+ * Stefan Winkler - bug 282976: [DB] Influence Mappings through EAnnotations
+ * Stefan Winkler - bug 285270: [DB] Support XSD based models
+ */
+package org.eclipse.emf.cdo.server.db.mapping;
+
+import org.eclipse.emf.cdo.common.revision.CDORevisionData;
+import org.eclipse.emf.cdo.server.internal.db.DBAnnotation;
+import org.eclipse.emf.cdo.server.internal.db.MetaDataManager;
+import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+
+import org.eclipse.net4j.db.DBType;
+import org.eclipse.net4j.db.ddl.IDBField;
+import org.eclipse.net4j.db.ddl.IDBTable;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * This is a default implementation for the {@link ITypeMapping} interface which provides default behavor for all common
+ * types.
+ *
+ * @author Eike Stepper
+ */
+public abstract class AbstractTypeMapping implements ITypeMapping
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, AbstractTypeMapping.class);
+
+ private IMappingStrategy mappingStrategy;
+
+ private EStructuralFeature feature;
+
+ private IDBField field;
+
+ private DBType dbType;
+
+ /**
+ * Create a new type mapping
+ */
+ public AbstractTypeMapping()
+ {
+ super();
+ }
+
+ /**
+ * Create a new type mapping
+ *
+ * @param mappingStrategy
+ * the associated mapping strategy.
+ * @param feature
+ * the feature to be mapped.
+ */
+ protected AbstractTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
+ {
+ this.mappingStrategy = mappingStrategy;
+ this.feature = feature;
+ dbType = type;
+ }
+
+ protected final void setMappingStrategy(IMappingStrategy mappingStrategy)
+ {
+ this.mappingStrategy = mappingStrategy;
+ }
+
+ public final IMappingStrategy getMappingStrategy()
+ {
+ return mappingStrategy;
+ }
+
+ protected final void setFeature(EStructuralFeature feature)
+ {
+ this.feature = feature;
+ }
+
+ public final EStructuralFeature getFeature()
+ {
+ return feature;
+ }
+
+ public final void setValueFromRevision(PreparedStatement stmt, int index, InternalCDORevision revision)
+ throws SQLException
+ {
+ setValue(stmt, index, getRevisionValue(revision));
+ }
+
+ public void setDefaultValue(PreparedStatement stmt, int index) throws SQLException
+ {
+ setValue(stmt, index, getDefaultValue());
+ }
+
+ public final void setValue(PreparedStatement stmt, int index, Object value) throws SQLException
+ {
+ if (value == CDORevisionData.NIL)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("TypeMapping for {0}: converting Revision.NIL to DB-null", feature.getName()); //$NON-NLS-1$
+ }
+
+ stmt.setNull(index, getSqlType());
+ }
+ else if (value == null)
+ {
+ if (feature.isMany() || getDefaultValue() == null)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("TypeMapping for {0}: writing Revision.null as DB.null", feature.getName()); //$NON-NLS-1$
+ }
+
+ stmt.setNull(index, getSqlType());
+ }
+ else
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("TypeMapping for {0}: converting Revision.null to default value", feature.getName()); //$NON-NLS-1$
+ }
+
+ setDefaultValue(stmt, index);
+ }
+ }
+ else
+ {
+ doSetValue(stmt, index, value);
+ }
+ }
+
+ public final void createDBField(IDBTable table)
+ {
+ createDBField(table, mappingStrategy.getFieldName(feature));
+ }
+
+ public final void createDBField(IDBTable table, String fieldName)
+ {
+ DBType fieldType = getDBType();
+ int fieldLength = getDBLength(fieldType);
+ field = table.addField(fieldName, fieldType, fieldLength);
+ }
+
+ public final void setDBField(IDBTable table, String fieldName)
+ {
+ field = table.getField(fieldName);
+ }
+
+ public final IDBField getField()
+ {
+ return field;
+ }
+
+ public final void readValueToRevision(ResultSet resultSet, InternalCDORevision revision) throws SQLException
+ {
+ Object value = readValue(resultSet);
+ revision.setValue(getFeature(), value);
+ }
+
+ public final Object readValue(ResultSet resultSet) throws SQLException
+ {
+ Object value = getResultSetValue(resultSet);
+ if (resultSet.wasNull())
+ {
+ if (feature.isMany())
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("TypeMapping for {0}: read db.null - setting Revision.null", feature.getName()); //$NON-NLS-1$
+ }
+
+ value = null;
+ }
+ else
+ {
+ if (getDefaultValue() == null)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format(
+ "TypeMapping for {0}: read db.null - setting Revision.null, because of default", feature.getName()); //$NON-NLS-1$
+ }
+
+ value = null;
+ }
+ else
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("TypeMapping for {0}: read db.null - setting Revision.NIL", feature.getName()); //$NON-NLS-1$
+ }
+
+ value = CDORevisionData.NIL;
+ }
+ }
+ }
+
+ return value;
+ }
+
+ protected Object getDefaultValue()
+ {
+ return feature.getDefaultValue();
+ }
+
+ protected final Object getRevisionValue(InternalCDORevision revision)
+ {
+ return revision.getValue(getFeature());
+ }
+
+ protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException
+ {
+ stmt.setObject(index, value, getSqlType());
+ }
+
+ /**
+ * Returns the SQL type of this TypeMapping. The default implementation considers the type map hold by the meta-data
+ * manager (@see {@link MetaDataManager#getDBType(org.eclipse.emf.ecore.EClassifier)} Subclasses may override.
+ *
+ * @return The sql type of this TypeMapping.
+ */
+ protected int getSqlType()
+ {
+ return getDBType().getCode();
+ }
+
+ protected final void setDBType(DBType dbType)
+ {
+ this.dbType = dbType;
+ }
+
+ public DBType getDBType()
+ {
+ return dbType;
+ }
+
+ protected int getDBLength(DBType type)
+ {
+ String value = DBAnnotation.COLUMN_LENGTH.getValue(feature);
+ if (value != null)
+ {
+ try
+ {
+ return Integer.parseInt(value);
+ }
+ catch (NumberFormatException e)
+ {
+ OM.LOG.error("Illegal columnLength annotation of feature " + feature.getName());
+ }
+ }
+
+ // TODO: implement DBAdapter.getDBLength
+ // mappingStrategy.getStore().getDBAdapter().getDBLength(type);
+ // which should then return the correct default field length for the db type
+ return type == DBType.VARCHAR ? 32672 : IDBField.DEFAULT;
+ }
+
+ protected abstract Object getResultSetValue(ResultSet resultSet) throws SQLException;
+
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMappingFactory.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMappingFactory.java
new file mode 100644
index 0000000000..1b5ac1dd17
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMappingFactory.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) 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:
+ * Stefan Winkler - initial API and implementation
+ */
+package org.eclipse.emf.cdo.server.db.mapping;
+
+import org.eclipse.net4j.db.DBType;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+/**
+ * @author Stefan Winkler
+ * @since 3.0
+ */
+public interface ITypeMappingFactory
+{
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType);
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBAnnotation.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBAnnotation.java
index 64f59970a5..dd3f93b038 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBAnnotation.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBAnnotation.java
@@ -25,7 +25,8 @@ public enum DBAnnotation
TABLE_NAME("tableName"), //
COLUMN_NAME("columnName"), //
COLUMN_TYPE("columnType"), //
- COLUMN_LENGTH("columnLength");
+ COLUMN_LENGTH("columnLength"), //
+ TYPE_MAPPING("typeMapping");
public final static String SOURCE_URI = "http://www.eclipse.org/CDO/DBStore";
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java
index 48036885cd..f6c6f144f8 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStore.java
@@ -27,8 +27,10 @@ import org.eclipse.emf.cdo.server.db.IDBStore;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IExternalReferenceManager;
import org.eclipse.emf.cdo.server.db.IMetaDataManager;
+import org.eclipse.emf.cdo.server.db.ITypeMappingRegistry;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
+import org.eclipse.emf.cdo.server.internal.db.mapping.TypeMappingRegistry;
import org.eclipse.emf.cdo.server.internal.db.messages.Messages;
import org.eclipse.emf.cdo.spi.server.LongIDStore;
import org.eclipse.emf.cdo.spi.server.StoreAccessorPool;
@@ -91,6 +93,8 @@ public class DBStore extends LongIDStore implements IDBStore, CDOAllRevisionsPro
private IMappingStrategy mappingStrategy;
+ private ITypeMappingRegistry typeMappingRegistry;
+
private IDBSchema dbSchema;
private IDBAdapter dbAdapter;
@@ -135,6 +139,11 @@ public class DBStore extends LongIDStore implements IDBStore, CDOAllRevisionsPro
return mappingStrategy;
}
+ public ITypeMappingRegistry getTypeMappingRegistry()
+ {
+ return typeMappingRegistry;
+ }
+
public void setMappingStrategy(IMappingStrategy mappingStrategy)
{
this.mappingStrategy = mappingStrategy;
@@ -436,6 +445,10 @@ public class DBStore extends LongIDStore implements IDBStore, CDOAllRevisionsPro
Connection connection = getConnection();
LifecycleUtil.activate(mappingStrategy);
+ // XXX Open issue: how to programmatically register typeMappings?
+ typeMappingRegistry = new TypeMappingRegistry();
+ LifecycleUtil.activate(typeMappingRegistry);
+
try
{
Set<IDBTable> createdTables = CDODBSchema.INSTANCE.create(dbAdapter, connection);
@@ -469,6 +482,9 @@ public class DBStore extends LongIDStore implements IDBStore, CDOAllRevisionsPro
LifecycleUtil.deactivate(externalReferenceManager);
externalReferenceManager = null;
+ LifecycleUtil.deactivate(typeMappingRegistry);
+ typeMappingRegistry = null;
+
LifecycleUtil.deactivate(mappingStrategy);
mappingStrategy = null;
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java
index 81084bbdfd..28f3204893 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java
@@ -464,7 +464,7 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp
public ITypeMapping createValueMapping(EStructuralFeature feature)
{
- return TypeMappingFactory.createTypeMapping(this, feature);
+ return getStore().getTypeMappingRegistry().createTypeMapping(this, feature);
}
public final IListMapping createListMapping(EClass containingClass, EStructuralFeature feature)
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/CoreTypeMappings.java
index 4f825238af..d622ac1b0a 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/CoreTypeMappings.java
@@ -24,17 +24,12 @@ import org.eclipse.emf.cdo.server.db.CDODBUtil;
import org.eclipse.emf.cdo.server.db.IDBStore;
import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
import org.eclipse.emf.cdo.server.db.IExternalReferenceManager;
+import org.eclipse.emf.cdo.server.db.mapping.AbstractTypeMapping;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
-import org.eclipse.emf.cdo.server.internal.db.DBAnnotation;
-import org.eclipse.emf.cdo.server.internal.db.MetaDataManager;
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.server.db.mapping.ITypeMappingFactory;
import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.db.ddl.IDBField;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.ecore.EEnum;
@@ -47,6 +42,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
+import java.util.Calendar;
import java.util.Date;
/**
@@ -55,220 +51,25 @@ import java.util.Date;
*
* @author Eike Stepper
*/
-public abstract class TypeMapping implements ITypeMapping
+public class CoreTypeMappings
{
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, TypeMapping.class);
-
- private IMappingStrategy mappingStrategy;
-
- private EStructuralFeature feature;
-
- private IDBField field;
-
- private DBType dbType;
-
- /**
- * Create a new type mapping
- *
- * @param mappingStrategy
- * the associated mapping strategy.
- * @param feature
- * the feature to be mapped.
- */
- protected TypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- this.mappingStrategy = mappingStrategy;
- this.feature = feature;
- dbType = type;
- }
-
- public final IMappingStrategy getMappingStrategy()
- {
- return mappingStrategy;
- }
-
- public final EStructuralFeature getFeature()
- {
- return feature;
- }
-
- public final void setValueFromRevision(PreparedStatement stmt, int index, InternalCDORevision revision)
- throws SQLException
- {
- setValue(stmt, index, getRevisionValue(revision));
- }
-
- public void setDefaultValue(PreparedStatement stmt, int index) throws SQLException
- {
- setValue(stmt, index, getDefaultValue());
- }
-
- public final void setValue(PreparedStatement stmt, int index, Object value) throws SQLException
- {
- if (value == CDORevisionData.NIL)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("TypeMapping for {0}: converting Revision.NIL to DB-null", feature.getName()); //$NON-NLS-1$
- }
-
- stmt.setNull(index, getSqlType());
- }
- else if (value == null)
- {
- if (feature.isMany() || getDefaultValue() == null)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("TypeMapping for {0}: writing Revision.null as DB.null", feature.getName()); //$NON-NLS-1$
- }
-
- stmt.setNull(index, getSqlType());
- }
- else
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("TypeMapping for {0}: converting Revision.null to default value", feature.getName()); //$NON-NLS-1$
- }
-
- setDefaultValue(stmt, index);
- }
- }
- else
- {
- doSetValue(stmt, index, value);
- }
- }
-
- public final void createDBField(IDBTable table)
- {
- createDBField(table, mappingStrategy.getFieldName(feature));
- }
-
- public final void createDBField(IDBTable table, String fieldName)
- {
- DBType fieldType = getDBType();
- int fieldLength = getDBLength(fieldType);
- field = table.addField(fieldName, fieldType, fieldLength);
- }
-
- public final void setDBField(IDBTable table, String fieldName)
- {
- field = table.getField(fieldName);
- }
-
- public final IDBField getField()
- {
- return field;
- }
-
- public final void readValueToRevision(ResultSet resultSet, InternalCDORevision revision) throws SQLException
- {
- Object value = readValue(resultSet);
- revision.setValue(getFeature(), value);
- }
-
- public final Object readValue(ResultSet resultSet) throws SQLException
- {
- Object value = getResultSetValue(resultSet);
- if (resultSet.wasNull())
- {
- if (feature.isMany())
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("TypeMapping for {0}: read db.null - setting Revision.null", feature.getName()); //$NON-NLS-1$
- }
-
- value = null;
- }
- else
- {
- if (getDefaultValue() == null)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format(
- "TypeMapping for {0}: read db.null - setting Revision.null, because of default", feature.getName()); //$NON-NLS-1$
- }
-
- value = null;
- }
- else
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("TypeMapping for {0}: read db.null - setting Revision.NIL", feature.getName()); //$NON-NLS-1$
- }
-
- value = CDORevisionData.NIL;
- }
- }
- }
-
- return value;
- }
-
- protected Object getDefaultValue()
- {
- return feature.getDefaultValue();
- }
-
- protected final Object getRevisionValue(InternalCDORevision revision)
- {
- return revision.getValue(getFeature());
- }
-
- protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException
- {
- stmt.setObject(index, value, getSqlType());
- }
+ public static final String ID_PREFIX = "org.eclipse.emf.cdo.db.CoreTypeMappings.";
/**
- * Returns the SQL type of this TypeMapping. The default implementation considers the type map hold by the meta-data
- * manager (@see {@link MetaDataManager#getDBType(org.eclipse.emf.ecore.EClassifier)} Subclasses may override.
- *
- * @return The sql type of this TypeMapping.
+ * @author Eike Stepper
*/
- protected int getSqlType()
+ public static class TMEnum extends AbstractTypeMapping
{
- return getDBType().getCode();
- }
+ public static final String ID = ID_PREFIX + "Enum";
- public DBType getDBType()
- {
- return dbType;
- }
-
- protected int getDBLength(DBType type)
- {
- String value = DBAnnotation.COLUMN_LENGTH.getValue(feature);
- if (value != null)
+ public static class Factory implements ITypeMappingFactory
{
- try
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
{
- return Integer.parseInt(value);
- }
- catch (NumberFormatException e)
- {
- OM.LOG.error("Illegal columnLength annotation of feature " + feature.getName());
+ return new TMEnum(mappingStrategy, feature, dbType);
}
}
- // TODO: implement DBAdapter.getDBLength
- // mappingStrategy.getStore().getDBAdapter().getDBLength(type);
- // which should then return the correct default field length for the db type
- return type == DBType.VARCHAR ? 32672 : IDBField.DEFAULT;
- }
-
- protected abstract Object getResultSetValue(ResultSet resultSet) throws SQLException;
-
- /**
- * @author Eike Stepper
- */
- public static class TMEnum extends TypeMapping
- {
public TMEnum(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
{
super(strategy, feature, type);
@@ -304,8 +105,18 @@ public abstract class TypeMapping implements ITypeMapping
/**
* @author Eike Stepper
*/
- public static class TMString extends TypeMapping
+ public static class TMString extends AbstractTypeMapping
{
+ public static final String ID = ID_PREFIX + "String";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMString(mappingStrategy, feature, dbType);
+ }
+ }
+
public TMString(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
{
super(strategy, feature, type);
@@ -316,13 +127,24 @@ public abstract class TypeMapping implements ITypeMapping
{
return resultSet.getString(getField().getName());
}
+
}
/**
* @author Eike Stepper
*/
- public static class TMShort extends TypeMapping
+ public static class TMShort extends AbstractTypeMapping
{
+ public static final String ID = ID_PREFIX + "Short";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMShort(mappingStrategy, feature, dbType);
+ }
+ }
+
public TMShort(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
{
super(strategy, feature, type);
@@ -333,13 +155,24 @@ public abstract class TypeMapping implements ITypeMapping
{
return resultSet.getShort(getField().getName());
}
+
}
/**
* @author Eike Stepper <br>
*/
- public static class TMObject extends TypeMapping
+ public static class TMObject extends AbstractTypeMapping
{
+ public static final String ID = ID_PREFIX + "Object";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMObject(mappingStrategy, feature, dbType);
+ }
+ }
+
public TMObject(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
{
super(strategy, feature, type);
@@ -379,13 +212,24 @@ public abstract class TypeMapping implements ITypeMapping
return (IDBStoreAccessor)accessor;
}
+
}
/**
* @author Eike Stepper
*/
- public static class TMLong extends TypeMapping
+ public static class TMLong extends AbstractTypeMapping
{
+ public static final String ID = ID_PREFIX + "Long";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMLong(mappingStrategy, feature, dbType);
+ }
+ }
+
public TMLong(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
{
super(strategy, feature, type);
@@ -396,13 +240,24 @@ public abstract class TypeMapping implements ITypeMapping
{
return resultSet.getLong(getField().getName());
}
+
}
/**
* @author Eike Stepper
*/
- public static class TMInteger extends TypeMapping
+ public static class TMInteger extends AbstractTypeMapping
{
+ public static final String ID = ID_PREFIX + "Integer";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMInteger(mappingStrategy, feature, dbType);
+ }
+ }
+
public TMInteger(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
{
super(strategy, feature, type);
@@ -413,13 +268,24 @@ public abstract class TypeMapping implements ITypeMapping
{
return resultSet.getInt(getField().getName());
}
+
}
/**
* @author Eike Stepper
*/
- public static class TMFloat extends TypeMapping
+ public static class TMFloat extends AbstractTypeMapping
{
+ public static final String ID = ID_PREFIX + "Float";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMFloat(mappingStrategy, feature, dbType);
+ }
+ }
+
public TMFloat(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
{
super(strategy, feature, type);
@@ -430,13 +296,24 @@ public abstract class TypeMapping implements ITypeMapping
{
return resultSet.getFloat(getField().getName());
}
+
}
/**
* @author Eike Stepper
*/
- public static class TMDouble extends TypeMapping
+ public static class TMDouble extends AbstractTypeMapping
{
+ public static final String ID = ID_PREFIX + "Double";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMDouble(mappingStrategy, feature, dbType);
+ }
+ }
+
public TMDouble(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
{
super(strategy, feature, type);
@@ -447,14 +324,25 @@ public abstract class TypeMapping implements ITypeMapping
{
return resultSet.getDouble(getField().getName());
}
+
}
/**
* @author Eike Stepper
*/
- public static class TMDate extends TypeMapping
+ public static class TMDate2Timestamp extends AbstractTypeMapping
{
- public TMDate(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
+ public static final String ID = ID_PREFIX + "Timestamp";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMDate2Timestamp(mappingStrategy, feature, dbType);
+ }
+ }
+
+ public TMDate2Timestamp(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
{
super(strategy, feature, type);
}
@@ -473,10 +361,76 @@ public abstract class TypeMapping implements ITypeMapping
}
/**
+ * @author Heiko Ahlig
+ */
+ public static class TMDate2Date extends AbstractTypeMapping
+ {
+ public static final String ID = ID_PREFIX + "Date";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMDate2Date(mappingStrategy, feature, dbType);
+ }
+ }
+
+ public TMDate2Date(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
+ {
+ super(strategy, feature, type);
+ }
+
+ @Override
+ public Object getResultSetValue(ResultSet resultSet) throws SQLException
+ {
+ return resultSet.getDate(getField().getName(), Calendar.getInstance());
+ }
+
+ }
+
+ /**
+ * @author Heiko Ahlig
+ */
+ public static class TMDate2Time extends AbstractTypeMapping
+ {
+ public static final String ID = ID_PREFIX + "Time";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMDate2Time(mappingStrategy, feature, dbType);
+ }
+ }
+
+ public TMDate2Time(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
+ {
+ super(strategy, feature, type);
+ }
+
+ @Override
+ public Object getResultSetValue(ResultSet resultSet) throws SQLException
+ {
+ return resultSet.getTime(getField().getName(), Calendar.getInstance());
+ }
+
+ }
+
+ /**
* @author Eike Stepper
*/
- public static class TMCharacter extends TypeMapping
+ public static class TMCharacter extends AbstractTypeMapping
{
+ public static final String ID = ID_PREFIX + "Character";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMCharacter(mappingStrategy, feature, dbType);
+ }
+ }
+
public TMCharacter(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
{
super(strategy, feature, type);
@@ -499,13 +453,24 @@ public abstract class TypeMapping implements ITypeMapping
{
stmt.setString(index, ((Character)value).toString());
}
+
}
/**
* @author Eike Stepper
*/
- public static class TMByte extends TypeMapping
+ public static class TMByte extends AbstractTypeMapping
{
+ public static final String ID = ID_PREFIX + "Byte";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMByte(mappingStrategy, feature, dbType);
+ }
+ }
+
public TMByte(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
{
super(strategy, feature, type);
@@ -516,13 +481,24 @@ public abstract class TypeMapping implements ITypeMapping
{
return resultSet.getByte(getField().getName());
}
+
}
/**
* @author Eike Stepper
*/
- public static class TMBytes extends TypeMapping
+ public static class TMBytes extends AbstractTypeMapping
{
+ public static final String ID = ID_PREFIX + "ByteArray";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMBytes(mappingStrategy, feature, dbType);
+ }
+ }
+
public TMBytes(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
{
super(strategy, feature, type);
@@ -533,13 +509,24 @@ public abstract class TypeMapping implements ITypeMapping
{
return resultSet.getBytes(getField().getName());
}
+
}
/**
* @author Eike Stepper
*/
- public static class TMBoolean extends TypeMapping
+ public static class TMBoolean extends AbstractTypeMapping
{
+ public static final String ID = ID_PREFIX + "Boolean";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMBoolean(mappingStrategy, feature, dbType);
+ }
+ }
+
public TMBoolean(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
{
super(strategy, feature, type);
@@ -550,13 +537,24 @@ public abstract class TypeMapping implements ITypeMapping
{
return resultSet.getBoolean(getField().getName());
}
+
}
/**
* @author Stefan Winkler
*/
- public static class TMBigInteger extends TypeMapping
+ public static class TMBigInteger extends AbstractTypeMapping
{
+ public static final String ID = ID_PREFIX + "BigInteger";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMBigInteger(mappingStrategy, feature, dbType);
+ }
+ }
+
public TMBigInteger(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
{
super(strategy, feature, type);
@@ -580,13 +578,24 @@ public abstract class TypeMapping implements ITypeMapping
{
stmt.setString(index, ((BigInteger)value).toString());
}
+
}
/**
* @author Stefan Winkler
*/
- public static class TMBigDecimal extends TypeMapping
+ public static class TMBigDecimal extends AbstractTypeMapping
{
+ public static final String ID = ID_PREFIX + "BigDecimal";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMBigDecimal(mappingStrategy, feature, dbType);
+ }
+ }
+
public TMBigDecimal(IMappingStrategy strategy, EStructuralFeature feature, DBType type)
{
super(strategy, feature, type);
@@ -610,13 +619,24 @@ public abstract class TypeMapping implements ITypeMapping
{
stmt.setString(index, ((BigDecimal)value).toPlainString());
}
+
}
/**
* @author Stefan Winkler
*/
- public static class TMCustom extends TypeMapping
+ public static class TMCustom extends AbstractTypeMapping
{
+ public static final String ID = ID_PREFIX + "Custom";
+
+ public static class Factory implements ITypeMappingFactory
+ {
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType dbType)
+ {
+ return new TMCustom(mappingStrategy, feature, dbType);
+ }
+ }
+
public TMCustom(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
{
super(mappingStrategy, feature, type);
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingFactory.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingFactory.java
deleted file mode 100644
index 87923798a7..0000000000
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingFactory.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/**
- * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) 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:
- * Stefan Winkler - initial API and implementation
- * Eike Stepper - maintenance
- * Stefan Winkler - bug 285270: [DB] Support XSD based models
- * Stefan Winkler - Bug 289445
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping;
-
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
-import org.eclipse.emf.cdo.common.model.CDOType;
-import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
-import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
-import org.eclipse.emf.cdo.server.internal.db.DBAnnotation;
-
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.db.IDBAdapter;
-import org.eclipse.net4j.util.collection.Pair;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EClassifier;
-import org.eclipse.emf.ecore.EEnum;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.EcorePackage;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author Stefan Winkler
- */
-public enum TypeMappingFactory
-{
- BOOLEAN_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMBoolean(mappingStrategy, feature, type);
- }
- },
-
- BYTE_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMByte(mappingStrategy, feature, type);
- }
- },
-
- CHARACTER_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMCharacter(mappingStrategy, feature, type);
- }
- },
-
- DATE_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMDate(mappingStrategy, feature, type);
- }
- },
-
- DOUBLE_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMDouble(mappingStrategy, feature, type);
- }
- },
-
- FLOAT_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMFloat(mappingStrategy, feature, type);
- }
- },
-
- INT_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMInteger(mappingStrategy, feature, type);
- }
- },
-
- LONG_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMLong(mappingStrategy, feature, type);
- }
- },
-
- OBJECT_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMObject(mappingStrategy, feature, type);
- }
- },
-
- SHORT_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMShort(mappingStrategy, feature, type);
- }
- },
-
- ENUM_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMEnum(mappingStrategy, feature, type);
- }
- },
-
- STRING_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMString(mappingStrategy, feature, type);
- }
- },
-
- BIG_INT_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMBigInteger(mappingStrategy, feature, type);
- }
- },
-
- BIG_DECIMAL_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMBigDecimal(mappingStrategy, feature, type);
- }
- },
-
- BYTES_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMBytes(mappingStrategy, feature, type);
- }
- },
-
- CUSTOM_MAPPING
- {
- @Override
- public ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature, DBType type)
- {
- return new TypeMapping.TMCustom(mappingStrategy, feature, type);
- }
- };
-
- private static Map<EClassifier, DBType> defaultTypeMap = new HashMap<EClassifier, DBType>();
-
- private static Map<Pair<CDOType, DBType>, TypeMappingFactory> mappingTable = new HashMap<Pair<CDOType, DBType>, TypeMappingFactory>();
-
- private static Set<DBType> defaultFeatureMapDBTypes;
-
- static
- {
- /* --- initialize default types --- */
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEDate(), DBType.TIMESTAMP);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEString(), DBType.VARCHAR);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEByteArray(), DBType.BLOB);
-
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEBoolean(), DBType.BOOLEAN);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEByte(), DBType.SMALLINT);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEChar(), DBType.CHAR);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEDouble(), DBType.DOUBLE);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEFloat(), DBType.FLOAT);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEInt(), DBType.INTEGER);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getELong(), DBType.BIGINT);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEShort(), DBType.SMALLINT);
-
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEBooleanObject(), DBType.BOOLEAN);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEByteObject(), DBType.SMALLINT);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getECharacterObject(), DBType.CHAR);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEDoubleObject(), DBType.DOUBLE);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEFloatObject(), DBType.FLOAT);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEIntegerObject(), DBType.INTEGER);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getELongObject(), DBType.BIGINT);
- defaultTypeMap.put(EcorePackage.eINSTANCE.getEShortObject(), DBType.SMALLINT);
-
- /* --- register type mappings --- */
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.BIG_INTEGER, DBType.VARCHAR), BIG_INT_MAPPING);
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.BIG_DECIMAL, DBType.VARCHAR), BIG_DECIMAL_MAPPING);
-
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.BOOLEAN, DBType.BOOLEAN), BOOLEAN_MAPPING);
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.BOOLEAN_OBJECT, DBType.BOOLEAN), BOOLEAN_MAPPING);
-
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.BYTE, DBType.SMALLINT), BYTE_MAPPING);
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.BYTE_OBJECT, DBType.SMALLINT), BYTE_MAPPING);
-
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.BYTE_ARRAY, DBType.BLOB), BYTES_MAPPING);
-
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.CHAR, DBType.CHAR), CHARACTER_MAPPING);
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.CHARACTER_OBJECT, DBType.CHAR), CHARACTER_MAPPING);
-
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.DATE, DBType.TIMESTAMP), DATE_MAPPING);
-
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.DOUBLE, DBType.DOUBLE), DOUBLE_MAPPING);
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.DOUBLE_OBJECT, DBType.DOUBLE), DOUBLE_MAPPING);
-
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.ENUM_ORDINAL, DBType.INTEGER), ENUM_MAPPING);
-
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.FLOAT, DBType.FLOAT), FLOAT_MAPPING);
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.FLOAT_OBJECT, DBType.FLOAT), FLOAT_MAPPING);
-
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.INT, DBType.INTEGER), INT_MAPPING);
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.INTEGER_OBJECT, DBType.INTEGER), INT_MAPPING);
-
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.LONG, DBType.BIGINT), LONG_MAPPING);
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.LONG_OBJECT, DBType.BIGINT), LONG_MAPPING);
-
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.OBJECT, DBType.BIGINT), OBJECT_MAPPING);
-
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.SHORT, DBType.SMALLINT), SHORT_MAPPING);
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.SHORT_OBJECT, DBType.SMALLINT), SHORT_MAPPING);
-
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.STRING, DBType.VARCHAR), STRING_MAPPING);
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.STRING, DBType.CLOB), STRING_MAPPING);
-
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.CUSTOM, DBType.VARCHAR), CUSTOM_MAPPING);
- mappingTable.put(new Pair<CDOType, DBType>(CDOType.CUSTOM, DBType.CLOB), CUSTOM_MAPPING);
-
- defaultFeatureMapDBTypes = new HashSet<DBType>(defaultTypeMap.values());
- }
-
- protected abstract ITypeMapping doCreateTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature,
- DBType type);
-
- public static ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature)
- {
- CDOType cdoType = CDOModelUtil.getType(feature);
- DBType dbType = getDBType(feature, mappingStrategy.getStore().getDBAdapter());
-
- TypeMappingFactory concreteFactory = mappingTable.get(new Pair<CDOType, DBType>(cdoType, dbType));
- if (concreteFactory == null)
- {
- throw new IllegalArgumentException("No suitable mapping found from EMF type " + cdoType.getName()
- + " to DB type " + dbType.getClass().getSimpleName());
- }
-
- return concreteFactory.doCreateTypeMapping(mappingStrategy, feature, dbType);
- }
-
- private static DBType getDBType(EStructuralFeature feature, IDBAdapter dbAdapter)
- {
- String typeKeyword = DBAnnotation.COLUMN_TYPE.getValue(feature);
- if (typeKeyword != null)
- {
- DBType dbType = DBType.getTypeByKeyword(typeKeyword);
- if (dbType == null)
- {
- throw new IllegalArgumentException("Unsupported columnType (" + typeKeyword + ") annotation of feature "
- + feature.getName());
- }
-
- return dbType;
- }
-
- // No annotation present - lookup default DB type.
- return getDefaultDBType(feature.getEType(), dbAdapter);
- }
-
- private static DBType getDefaultDBType(EClassifier type, IDBAdapter dbAdapter)
- {
- // Fallback (e.g., for CUSTOM types)
- DBType result = DBType.VARCHAR;
- if (type instanceof EClass)
- {
- result = DBType.BIGINT;
- }
-
- if (type instanceof EEnum)
- {
- result = DBType.INTEGER;
- }
-
- DBType dbType = defaultTypeMap.get(type);
- if (dbType != null)
- {
- result = dbType;
- }
-
- // Give the DBAdapter a chance to override the default type, if it's not supported
- return dbAdapter.adaptType(result);
- }
-
- public static Collection<DBType> getDefaultFeatureMapDBTypes()
- {
- return defaultFeatureMapDBTypes;
- }
-}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingRegistry.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingRegistry.java
new file mode 100644
index 0000000000..8c5a9bfa54
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/TypeMappingRegistry.java
@@ -0,0 +1,310 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping;
+
+import org.eclipse.emf.cdo.server.db.ITypeMappingRegistry;
+import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
+import org.eclipse.emf.cdo.server.db.mapping.ITypeMappingFactory;
+import org.eclipse.emf.cdo.server.internal.db.DBAnnotation;
+import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
+
+import org.eclipse.net4j.db.DBType;
+import org.eclipse.net4j.db.IDBAdapter;
+import org.eclipse.net4j.util.WrappedException;
+import org.eclipse.net4j.util.collection.Pair;
+import org.eclipse.net4j.util.lifecycle.Lifecycle;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EPackage.Registry;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Eike Stepper
+ */
+public class TypeMappingRegistry extends Lifecycle implements ITypeMappingRegistry
+{
+
+ public static final String EXT_POINT_CUSTOM_TYPE_MAPPINGS = "typeMappings"; //$NON-NLS-1$
+
+ @Override
+ protected void doActivate() throws Exception
+ {
+ super.doActivate();
+
+ defaultFeatureMapDBTypes = new HashSet<DBType>();
+ typeMappings = new HashMap<String, ITypeMappingFactory>();
+ typeMappingByClassifier = new HashMap<Pair<EClassifier, DBType>, String>();
+ classifierDefaultMapping = new HashMap<EClassifier, DBType>();
+
+ registerCoreMappings();
+ registerCustomMappings();
+ }
+
+ private void registerCoreMappings()
+ {
+ registerTypeMapping(CoreTypeMappings.TMEnum.ID, EcorePackage.eINSTANCE.getEEnum(), DBType.INTEGER,
+ new CoreTypeMappings.TMEnum.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMDate2Timestamp.ID, EcorePackage.eINSTANCE.getEDate(), DBType.TIMESTAMP,
+ new CoreTypeMappings.TMDate2Timestamp.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMDate2Date.ID, EcorePackage.eINSTANCE.getEDate(), DBType.DATE,
+ new CoreTypeMappings.TMDate2Date.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMDate2Time.ID, EcorePackage.eINSTANCE.getEDate(), DBType.TIME,
+ new CoreTypeMappings.TMDate2Time.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMString.ID, EcorePackage.eINSTANCE.getEString(), DBType.VARCHAR,
+ new CoreTypeMappings.TMString.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMString.ID, EcorePackage.eINSTANCE.getEString(), DBType.CLOB,
+ new CoreTypeMappings.TMString.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMBytes.ID, EcorePackage.eINSTANCE.getEByteArray(), DBType.BLOB,
+ new CoreTypeMappings.TMBytes.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMBoolean.ID, EcorePackage.eINSTANCE.getEBoolean(), DBType.BOOLEAN,
+ new CoreTypeMappings.TMBoolean.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMBoolean.ID, EcorePackage.eINSTANCE.getEBooleanObject(), DBType.BOOLEAN,
+ new CoreTypeMappings.TMBoolean.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMByte.ID, EcorePackage.eINSTANCE.getEByte(), DBType.SMALLINT,
+ new CoreTypeMappings.TMByte.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMByte.ID, EcorePackage.eINSTANCE.getEByteObject(), DBType.SMALLINT,
+ new CoreTypeMappings.TMByte.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMCharacter.ID, EcorePackage.eINSTANCE.getEChar(), DBType.CHAR,
+ new CoreTypeMappings.TMCharacter.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMCharacter.ID, EcorePackage.eINSTANCE.getECharacterObject(), DBType.CHAR,
+ new CoreTypeMappings.TMCharacter.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMInteger.ID, EcorePackage.eINSTANCE.getEInt(), DBType.INTEGER,
+ new CoreTypeMappings.TMInteger.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMInteger.ID, EcorePackage.eINSTANCE.getEIntegerObject(), DBType.INTEGER,
+ new CoreTypeMappings.TMInteger.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMLong.ID, EcorePackage.eINSTANCE.getELong(), DBType.BIGINT,
+ new CoreTypeMappings.TMLong.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMLong.ID, EcorePackage.eINSTANCE.getELongObject(), DBType.BIGINT,
+ new CoreTypeMappings.TMLong.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMShort.ID, EcorePackage.eINSTANCE.getEShort(), DBType.SMALLINT,
+ new CoreTypeMappings.TMShort.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMShort.ID, EcorePackage.eINSTANCE.getEShortObject(), DBType.SMALLINT,
+ new CoreTypeMappings.TMShort.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMDouble.ID, EcorePackage.eINSTANCE.getEDouble(), DBType.DOUBLE,
+ new CoreTypeMappings.TMDouble.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMDouble.ID, EcorePackage.eINSTANCE.getEDoubleObject(), DBType.DOUBLE,
+ new CoreTypeMappings.TMDouble.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMFloat.ID, EcorePackage.eINSTANCE.getEFloat(), DBType.FLOAT,
+ new CoreTypeMappings.TMFloat.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMFloat.ID, EcorePackage.eINSTANCE.getEFloatObject(), DBType.FLOAT,
+ new CoreTypeMappings.TMFloat.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMBigDecimal.ID, EcorePackage.eINSTANCE.getEBigDecimal(), DBType.VARCHAR,
+ new CoreTypeMappings.TMBigDecimal.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMBigInteger.ID, EcorePackage.eINSTANCE.getEBigInteger(), DBType.VARCHAR,
+ new CoreTypeMappings.TMBigInteger.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMObject.ID, EcorePackage.eINSTANCE.getEClass(), DBType.BIGINT,
+ new CoreTypeMappings.TMObject.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMCustom.ID, EcorePackage.eINSTANCE.getEDataType(), DBType.VARCHAR,
+ new CoreTypeMappings.TMCustom.Factory());
+
+ registerTypeMapping(CoreTypeMappings.TMCustom.ID, EcorePackage.eINSTANCE.getEDataType(), DBType.CLOB,
+ new CoreTypeMappings.TMCustom.Factory());
+ }
+
+ private void registerCustomMappings()
+ {
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+
+ if (registry != null)
+ {
+
+ IConfigurationElement[] elements = registry.getConfigurationElementsFor(OM.BUNDLE_ID,
+ EXT_POINT_CUSTOM_TYPE_MAPPINGS);
+ for (final IConfigurationElement element : elements)
+ {
+ if ("typeMapping".equals(element.getName())) //$NON-NLS-1$
+ {
+ String id = element.getAttribute("id"); //$NON-NLS-1$
+ String packageUri = element.getAttribute("packageURI"); //$NON-NLS-1$
+ String dataTypeName = element.getAttribute("dataTypeName"); //$NON-NLS-1$
+ String dbTypeKeyword = element.getAttribute("dbType"); //$NON-NLS-1$
+ EPackage ePackage = null;
+ EClassifier eClassifier = null;
+ DBType dbType = null;
+
+ // XXX Error handling and reporting!
+ if ((ePackage = Registry.INSTANCE.getEPackage(packageUri)) != null
+ && (eClassifier = ePackage.getEClassifier(dataTypeName)) != null && eClassifier instanceof EDataType
+ && (dbType = DBType.getTypeByKeyword(dbTypeKeyword)) != null)
+ {
+ try
+ {
+ ITypeMappingFactory typeMappingFactory = (ITypeMappingFactory)element.createExecutableExtension("class"); //$NON-NLS-1$
+ registerTypeMapping(id, eClassifier, dbType, typeMappingFactory);
+ }
+ catch (CoreException ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private Set<DBType> defaultFeatureMapDBTypes;
+
+ private Map<EClassifier, DBType> classifierDefaultMapping;
+
+ private Map<Pair<EClassifier, DBType>, String> typeMappingByClassifier;
+
+ private Map<String, ITypeMappingFactory> typeMappings;
+
+ public void registerTypeMapping(String id, EClassifier eClassifier, DBType dbType, ITypeMappingFactory mappingFactory)
+ {
+ typeMappings.put(id, mappingFactory);
+ typeMappingByClassifier.put(new Pair<EClassifier, DBType>(eClassifier, dbType), id);
+
+ // register first dbType for classifier as default
+ if (!classifierDefaultMapping.containsKey(eClassifier))
+ {
+ classifierDefaultMapping.put(eClassifier, dbType);
+ }
+ }
+
+ public ITypeMapping createTypeMapping(IMappingStrategy mappingStrategy, EStructuralFeature feature)
+ {
+ EClassifier classifier = getEClassifier(feature);
+ DBType dbType = getDBType(feature, mappingStrategy.getStore().getDBAdapter());
+
+ String typeMappingID = DBAnnotation.TYPE_MAPPING.getValue(feature);
+
+ ITypeMappingFactory factory = null;
+
+ if (typeMappingID != null)
+ {
+ // lookup annotated mapping
+ factory = typeMappings.get(typeMappingID);
+ }
+
+ if (factory == null)
+ {
+ // try to find suitable mapping by type
+ factory = getMappingByType(classifier, dbType);
+ }
+
+ if (factory == null)
+ {
+ // XXX i18n
+ throw new IllegalStateException("No typeMapping factory found for feature " + feature + " (type "
+ + classifier.getName() + ", DB type " + dbType.getClass().getSimpleName() + ")");
+ }
+
+ return factory.createTypeMapping(mappingStrategy, feature, dbType);
+ }
+
+ private EClassifier getEClassifier(EStructuralFeature feature)
+ {
+ EClassifier classifier = feature.getEType();
+ if (classifier instanceof EEnum)
+ {
+ return EcorePackage.eINSTANCE.getEEnum();
+ }
+
+ if (classifier instanceof EClass)
+ {
+ return EcorePackage.eINSTANCE.getEClass();
+ }
+
+ return classifier;
+ }
+
+ private DBType getDBType(EStructuralFeature feature, IDBAdapter dbAdapter)
+ {
+ String typeKeyword = DBAnnotation.COLUMN_TYPE.getValue(feature);
+ if (typeKeyword != null)
+ {
+ DBType dbType = DBType.getTypeByKeyword(typeKeyword);
+ if (dbType == null)
+ {
+ throw new IllegalArgumentException("Unsupported columnType (" + typeKeyword + ") annotation of feature "
+ + feature.getName());
+ }
+ return dbType;
+ }
+
+ // No annotation present - lookup default DB type.
+ return getDefaultDBType(getEClassifier(feature), dbAdapter);
+ }
+
+ private DBType getDefaultDBType(EClassifier type, IDBAdapter dbAdapter)
+ {
+ DBType result = classifierDefaultMapping.get(type);
+
+ if (result == null)
+ {
+ result = DBType.VARCHAR;
+ }
+
+ // Give the DBAdapter a chance to override the default type, if it's not supported
+ return dbAdapter.adaptType(result);
+ }
+
+ private ITypeMappingFactory getMappingByType(EClassifier classifier, DBType dbType)
+ {
+ String factoryId = typeMappingByClassifier.get(new Pair<EClassifier, DBType>(classifier, dbType));
+
+ if (factoryId == null)
+ {
+ return null;
+ }
+
+ return typeMappings.get(factoryId);
+ }
+
+ public Collection<DBType> getDefaultFeatureMapDBTypes()
+ {
+ return defaultFeatureMapDBTypes;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java
index 07b7c0631e..423e2e62c0 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractFeatureMapTableMapping.java
@@ -26,8 +26,6 @@ import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.server.internal.db.mapping.TypeMapping;
-import org.eclipse.emf.cdo.server.internal.db.mapping.TypeMappingFactory;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDOList;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
@@ -35,8 +33,8 @@ import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBType;
import org.eclipse.net4j.db.DBUtil;
import org.eclipse.net4j.db.ddl.IDBField;
-import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.db.ddl.IDBIndex.Type;
+import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.util.collection.MoveableList;
import org.eclipse.net4j.util.om.trace.ContextTracer;
@@ -107,7 +105,8 @@ public abstract class AbstractFeatureMapTableMapping extends BasicAbstractListTa
private void initDBTypes()
{
// TODO add annotation processing here ...
- dbTypes = new ArrayList<DBType>(TypeMappingFactory.getDefaultFeatureMapDBTypes());
+ dbTypes = new ArrayList<DBType>(getMappingStrategy().getStore().getTypeMappingRegistry()
+ .getDefaultFeatureMapDBTypes());
}
private void initTable()
@@ -367,7 +366,7 @@ public abstract class AbstractFeatureMapTableMapping extends BasicAbstractListTa
{
EStructuralFeature modelFeature = getFeatureByTag(tag);
- TypeMapping typeMapping = (TypeMapping)getMappingStrategy().createValueMapping(modelFeature);
+ ITypeMapping typeMapping = getMappingStrategy().createValueMapping(modelFeature);
String column = CDODBSchema.FEATUREMAP_VALUE + "_" + typeMapping.getDBType();
tagMap.put(tag, column);
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMappingWithRanges.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMappingWithRanges.java
index 4aac2585c7..dc14d14e74 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMappingWithRanges.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AuditFeatureMapTableMappingWithRanges.java
@@ -43,8 +43,6 @@ import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.server.internal.db.mapping.TypeMapping;
-import org.eclipse.emf.cdo.server.internal.db.mapping.TypeMappingFactory;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDOList;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
@@ -52,8 +50,8 @@ import org.eclipse.net4j.db.DBException;
import org.eclipse.net4j.db.DBType;
import org.eclipse.net4j.db.DBUtil;
import org.eclipse.net4j.db.ddl.IDBField;
-import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.db.ddl.IDBIndex.Type;
+import org.eclipse.net4j.db.ddl.IDBTable;
import org.eclipse.net4j.util.ImplementationError;
import org.eclipse.net4j.util.collection.MoveableList;
import org.eclipse.net4j.util.om.trace.ContextTracer;
@@ -152,7 +150,8 @@ public class AuditFeatureMapTableMappingWithRanges extends BasicAbstractListTabl
private void initDBTypes()
{
// TODO add annotation processing here ...
- dbTypes = new ArrayList<DBType>(TypeMappingFactory.getDefaultFeatureMapDBTypes());
+ dbTypes = new ArrayList<DBType>(getMappingStrategy().getStore().getTypeMappingRegistry()
+ .getDefaultFeatureMapDBTypes());
}
private void initTable()
@@ -487,7 +486,7 @@ public class AuditFeatureMapTableMappingWithRanges extends BasicAbstractListTabl
{
EStructuralFeature modelFeature = getFeatureByTag(tag);
- TypeMapping typeMapping = (TypeMapping)getMappingStrategy().createValueMapping(modelFeature);
+ ITypeMapping typeMapping = getMappingStrategy().createValueMapping(modelFeature);
String column = CDODBSchema.FEATUREMAP_VALUE + "_" + typeMapping.getDBType(); //$NON-NLS-1$
tagMap.put(tag, column);

Back to the top