diff options
author | Stefan Winkler | 2010-01-12 12:46:48 +0000 |
---|---|---|
committer | Stefan Winkler | 2010-01-12 12:46:48 +0000 |
commit | a0e6ea22cba6c46f2120ba511f4bcb08f9a6030e (patch) | |
tree | ed4030e21831dcbe5af96ad9389001df1f457472 /plugins | |
parent | 7e973586ca3d6da16db8fef911b2fd160ce32479 (diff) | |
download | cdo-a0e6ea22cba6c46f2120ba511f4bcb08f9a6030e.tar.gz cdo-a0e6ea22cba6c46f2120ba511f4bcb08f9a6030e.tar.xz cdo-a0e6ea22cba6c46f2120ba511f4bcb08f9a6030e.zip |
[284110] [DB] Problems with eIsSet()
https://bugs.eclipse.org/bugs/show_bug.cgi?id=284110
Diffstat (limited to 'plugins')
9 files changed, 630 insertions, 58 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMapping.java index 29fda89ea8..692f38e60d 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/db/mapping/ITypeMapping.java @@ -94,6 +94,20 @@ public interface ITypeMapping public void setValue(PreparedStatement stmt, int index, Object value) throws SQLException; /** + * Set the feature's default value to the JDBC {@link PreparedStatement} using an appropriate <code>setXxx</code> + * method. + * + * @param stmt + * the prepared statement to set the value + * @param index + * the index to use for the <code>setXxx</code> method. + * @throws SQLException + * if the <code>setXxx</code> throws it. + * @since 3.0 + */ + public void setDefaultValue(PreparedStatement stmt, int index) throws SQLException; + + /** * Set a value of the given revision to the JDBC {@link PreparedStatement} using an appropriate <code>setXxx</code> * method. The feature from which the value is taken is determined by {@link #getFeature()}. * 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 477c5e15ca..838a51f7ea 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 @@ -80,6 +80,11 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp protected static final String TYPE_PREFIX_PACKAGE = "P"; //$NON-NLS-1$ + /** + * Prefix for unsettable feature helper columns + */ + protected static final String CDO_SET_PREFIX = "cdo_set_"; //$NON-NLS-1$ + protected static final String FEATEURE_TABLE_SUFFIX = "_list"; //$NON-NLS-1$ private IDBStore store; @@ -292,6 +297,19 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp return name; } + public String getUnsettableFieldName(EStructuralFeature feature) + { + String name = DBAnnotation.COLUMN_NAME.getValue(feature); + if(name != null) { + return CDO_SET_PREFIX + name; + } + else + { + return getName(CDO_SET_PREFIX + feature.getName(), TYPE_PREFIX_FEATURE + getMetaDataManager().getMetaID(feature), + getMaxFieldNameLength()); + } + } + private String getName(String name, String suffix, int maxLength) { boolean forceNamesWithID = isForceNamesWithID(); 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/TypeMapping.java index dac547598b..d444649a4b 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/TypeMapping.java @@ -16,6 +16,7 @@ package org.eclipse.emf.cdo.server.internal.db.mapping; import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.revision.CDORevisionData; import org.eclipse.emf.cdo.server.IStoreAccessor; import org.eclipse.emf.cdo.server.StoreThreadLocal; import org.eclipse.emf.cdo.server.db.CDODBUtil; @@ -33,6 +34,7 @@ import org.eclipse.net4j.db.ddl.IDBField; import org.eclipse.net4j.db.ddl.IDBTable; import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EEnumLiteral; import org.eclipse.emf.ecore.EFactory; import org.eclipse.emf.ecore.EStructuralFeature; @@ -91,9 +93,14 @@ public abstract class TypeMapping implements ITypeMapping setValue(stmt, index, getRevisionValue(revision)); } + public void setDefaultValue(PreparedStatement stmt, int index) throws SQLException + { + setValue(stmt, index, feature.getDefaultValue()); + } + public final void setValue(PreparedStatement stmt, int index, Object value) throws SQLException { - if (value == null) + if (value == null || value == CDORevisionData.NIL) { stmt.setNull(index, getSqlType()); } @@ -136,7 +143,7 @@ public abstract class TypeMapping implements ITypeMapping Object value = getResultSetValue(resultSet); if (resultSet.wasNull()) { - value = null; + value = feature.isUnsettable() ? CDORevisionData.NIL : null; } return value; @@ -212,6 +219,13 @@ public abstract class TypeMapping implements ITypeMapping } @Override + public void setDefaultValue(PreparedStatement stmt, int index) throws SQLException + { + EEnumLiteral defaultValue = (EEnumLiteral)getFeature().getDefaultValue(); + setValue(stmt, index, defaultValue.getValue()); + } + + @Override protected void doSetValue(PreparedStatement stmt, int index, Object value) throws SQLException { super.doSetValue(stmt, index, value); @@ -268,7 +282,7 @@ public abstract class TypeMapping implements ITypeMapping long id = resultSet.getLong(getField().getName()); if (resultSet.wasNull()) { - return null; + return getFeature().isUnsettable() ? CDORevisionData.NIL : null; } IExternalReferenceManager externalRefs = getMappingStrategy().getStore().getExternalReferenceManager(); @@ -401,7 +415,7 @@ public abstract class TypeMapping implements ITypeMapping String str = resultSet.getString(getField().getName()); if (resultSet.wasNull()) { - return null; + return getFeature().isUnsettable() ? CDORevisionData.NIL : null; } return str.charAt(0); @@ -482,7 +496,7 @@ public abstract class TypeMapping implements ITypeMapping if (resultSet.wasNull()) { - return null; + return getFeature().isUnsettable() ? CDORevisionData.NIL : null; } return new BigInteger(val); @@ -512,7 +526,7 @@ public abstract class TypeMapping implements ITypeMapping if (resultSet.wasNull()) { - return null; + return getFeature().isUnsettable() ? CDORevisionData.NIL : null; } return new BigDecimal(val); @@ -554,7 +568,7 @@ public abstract class TypeMapping implements ITypeMapping String val = resultSet.getString(getField().getName()); if (resultSet.wasNull()) { - return null; + return getFeature().isUnsettable() ? CDORevisionData.NIL : null; } return factory.createFromString(dataType, val); diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java index accd732704..d7d43ef58f 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/AbstractHorizontalClassMapping.java @@ -48,7 +48,9 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; /** * @author Eike Stepper @@ -68,6 +70,8 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping private List<IListMapping> listMappings; + private Map<EStructuralFeature, String> unsettableFields; + public AbstractHorizontalClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass) { this.mappingStrategy = mappingStrategy; @@ -121,6 +125,26 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping ITypeMapping mapping = mappingStrategy.createValueMapping(feature); mapping.createDBField(getTable()); mappings.add(mapping); + + if (feature.isUnsettable()) + { + String fieldName = mappingStrategy.getUnsettableFieldName(feature); + if (unsettableFields == null) + { + unsettableFields = new LinkedHashMap<EStructuralFeature, String>(); + } + + unsettableFields.put(feature, fieldName); + } + } + } + + // add unsettable fields to end of table + if (unsettableFields != null) + { + for (String fieldName : unsettableFields.values()) + { + table.addField(fieldName, DBType.BOOLEAN, 1); } } @@ -190,6 +214,18 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping for (ITypeMapping mapping : valueMappings) { + EStructuralFeature feature = mapping.getFeature(); + if (feature.isUnsettable()) + { + if (!resultSet.getBoolean(unsettableFields.get(feature))) + { + + // isSet==false -- setValue: null + revision.setValue(feature, null); + continue; + } + } + mapping.readValueToRevision(resultSet, revision); } @@ -255,6 +291,11 @@ public abstract class AbstractHorizontalClassMapping implements IClassMapping return eClass; } + protected final Map<EStructuralFeature, String> getUnsettableFields() + { + return unsettableFields; + } + public final List<ITypeMapping> getValueMappings() { return valueMappings; diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java index ac645fe2ea..2a01364ab0 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalAuditClassMapping.java @@ -35,6 +35,7 @@ import org.eclipse.emf.ecore.EStructuralFeature; import java.sql.PreparedStatement; import java.sql.SQLException; +import java.util.Map; /** * TODO use async monitors @@ -68,6 +69,8 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping private void initSqlStrings() { + Map<EStructuralFeature, String> unsettableFields = getUnsettableFields(); + // ----------- Select Revision --------------------------- StringBuilder builder = new StringBuilder(); @@ -90,6 +93,15 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping builder.append(singleMapping.getField().getName()); } + if (unsettableFields != null) + { + for (String fieldName : unsettableFields.values()) + { + builder.append(", "); + builder.append(fieldName); + } + } + builder.append(" FROM "); //$NON-NLS-1$ builder.append(getTable().getName()); builder.append(" WHERE "); //$NON-NLS-1$ @@ -149,6 +161,15 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping builder.append(singleMapping.getField().getName()); } + if (unsettableFields != null) + { + for (String fieldName : unsettableFields.values()) + { + builder.append(", "); + builder.append(fieldName); + } + } + builder.append(") VALUES (?, ?, ?, ?, ?, ?, ?, ?"); //$NON-NLS-1$ for (int i = 0; i < getValueMappings().size(); i++) @@ -156,6 +177,14 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping builder.append(", ?"); //$NON-NLS-1$ } + if (unsettableFields != null) + { + for (int i = 0; i < unsettableFields.size(); i++) + { + builder.append(", ?"); //$NON-NLS-1$ + } + } + builder.append(")"); //$NON-NLS-1$ sqlInsertAttributes = builder.toString(); @@ -387,8 +416,27 @@ public class HorizontalAuditClassMapping extends AbstractHorizontalClassMapping .getContainerID())); stmt.setInt(col++, revision.getContainingFeatureID()); + int isSetCol = col + getValueMappings().size(); + for (ITypeMapping mapping : getValueMappings()) { + EStructuralFeature feature = mapping.getFeature(); + if (feature.isUnsettable()) + { + if (revision.getValue(feature) == null) + { + stmt.setBoolean(isSetCol++, false); + + // also set value column to default value + mapping.setDefaultValue(stmt, col++); + + continue; + } + else + { + stmt.setBoolean(isSetCol++, true); + } + } mapping.setValueFromRevision(stmt, col++, revision); } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java index 9488926599..6cceee2eb7 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalNonAuditClassMapping.java @@ -52,6 +52,7 @@ import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * @author Eike Stepper @@ -94,6 +95,8 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi private void initSqlStrings() { + Map<EStructuralFeature, String> unsettableFields = getUnsettableFields(); + // ----------- Select Revision --------------------------- StringBuilder builder = new StringBuilder(); @@ -116,6 +119,15 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi builder.append(singleMapping.getField().getName()); } + if (unsettableFields != null) + { + for (String fieldName : unsettableFields.values()) + { + builder.append(", "); + builder.append(fieldName); + } + } + builder.append(" FROM "); //$NON-NLS-1$ builder.append(getTable().getName()); builder.append(" WHERE "); //$NON-NLS-1$ @@ -152,6 +164,15 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi builder.append(singleMapping.getField().getName()); } + if (unsettableFields != null) + { + for (String fieldName : unsettableFields.values()) + { + builder.append(", "); + builder.append(fieldName); + } + } + builder.append(") VALUES (?, ?, "); //$NON-NLS-1$ builder.append("?, ?, ?, ?, ?, ?"); //$NON-NLS-1$ for (int i = 0; i < getValueMappings().size(); i++) @@ -159,6 +180,14 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi builder.append(", ?"); //$NON-NLS-1$ } + if (unsettableFields != null) + { + for (int i = 0; i < unsettableFields.size(); i++) + { + builder.append(", ?"); //$NON-NLS-1$ + } + } + builder.append(")"); //$NON-NLS-1$ sqlInsertAttributes = builder.toString(); @@ -223,8 +252,27 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi .getContainerID())); stmt.setInt(col++, revision.getContainingFeatureID()); + int isSetCol = col + getValueMappings().size(); + for (ITypeMapping mapping : getValueMappings()) { + EStructuralFeature feature = mapping.getFeature(); + if (feature.isUnsettable()) + { + if (revision.getValue(feature) == null) + { + stmt.setBoolean(isSetCol++, false); + + // also set value column to default value + mapping.setDefaultValue(stmt, col++); + continue; + } + else + { + stmt.setBoolean(isSetCol++, true); + } + } + mapping.setValueFromRevision(stmt, col++, revision); } @@ -517,10 +565,7 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi stmt.setLong(col++, CDODBUtil.convertCDOIDToLong(getExternalReferenceManager(), accessor, newContainerId)); stmt.setInt(col++, newContainingFeatureId); - for (Pair<ITypeMapping, Object> change : attributeChanges) - { - change.getElement1().setValue(stmt, col++, change.getElement2()); - } + col = setUpdateAttributeValues(attributeChanges, stmt, col); stmt.setLong(col++, CDOIDUtil.getLong(id)); @@ -536,6 +581,38 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi } } + private int setUpdateAttributeValues(List<Pair<ITypeMapping, Object>> attributeChanges, PreparedStatement stmt, + int col) throws SQLException + { + for (Pair<ITypeMapping, Object> change : attributeChanges) + { + ITypeMapping typeMapping = change.getElement1(); + Object value = change.getElement2(); + if (typeMapping.getFeature().isUnsettable()) + { + // feature is unsettable + if (value == null) + { + // feature is unset + typeMapping.setDefaultValue(stmt, col++); + stmt.setBoolean(col++, false); + } + else + { + // feature is set + typeMapping.setValue(stmt, col++, value); + stmt.setBoolean(col++, true); + } + } + else + { + typeMapping.setValue(stmt, col++, change.getElement2()); + } + } + + return col; + } + public void updateAttributes(IDBStoreAccessor accessor, CDOID id, int newVersion, long created, List<Pair<ITypeMapping, Object>> attributeChanges) { @@ -551,10 +628,7 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi stmt.setInt(col++, newVersion); stmt.setLong(col++, created); - for (Pair<ITypeMapping, Object> change : attributeChanges) - { - change.getElement1().setValue(stmt, col++, change.getElement2()); - } + col = setUpdateAttributeValues(attributeChanges, stmt, col); stmt.setLong(col++, CDOIDUtil.getLong(id)); @@ -581,8 +655,16 @@ public class HorizontalNonAuditClassMapping extends AbstractHorizontalClassMappi for (Pair<ITypeMapping, Object> change : attributeChanges) { builder.append(", "); //$NON-NLS-1$ - builder.append(change.getElement1().getField().getName()); + ITypeMapping typeMapping = change.getElement1(); + builder.append(typeMapping.getField().getName()); builder.append(" =? "); //$NON-NLS-1$ + + if (typeMapping.getFeature().isUnsettable()) + { + builder.append(", "); //$NON-NLS-1$ + builder.append(getUnsettableFields().get(typeMapping.getFeature())); + builder.append(" =? "); //$NON-NLS-1$ + } } builder.append(sqlUpdateAffix); diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DBConfigs.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DBConfigs.java index 6a73d8accc..de3b57d560 100644 --- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DBConfigs.java +++ b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DBConfigs.java @@ -15,7 +15,6 @@ import org.eclipse.emf.cdo.tests.AttributeTest; import org.eclipse.emf.cdo.tests.ExternalReferenceTest; import org.eclipse.emf.cdo.tests.FeatureMapTest; import org.eclipse.emf.cdo.tests.XATransactionTest; -import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_258933_Test; import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_259869_Test; import org.eclipse.emf.cdo.tests.config.impl.ConfigTest; @@ -38,10 +37,6 @@ public abstract class DBConfigs extends AllTestsAllConfigs testClasses.remove(XATransactionTest.class); testClasses.add(DISABLE_XATransactionTest.class); - // fails because of Bug 284110 - testClasses.remove(Bugzilla_258933_Test.class); - testClasses.add(DISABLE_Bugzilla_258933_Test.class); - // ------------ tests below only fail for PostgreSQL // ------------ therefore they are overridden and // ------------ skipConfig for PSQL is used temporarily diff --git a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DISABLE_Bugzilla_258933_Test.java b/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DISABLE_Bugzilla_258933_Test.java deleted file mode 100644 index 40ab34c661..0000000000 --- a/plugins/org.eclipse.emf.cdo.tests.db/src/org/eclipse/emf/cdo/tests/db/DISABLE_Bugzilla_258933_Test.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) 2004 - 2009 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.tests.db; - -import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_258933_Test; - -/** - * @author Eike Stepper - */ -public class DISABLE_Bugzilla_258933_Test extends Bugzilla_258933_Test -{ - @Override - public void testBugzilla_258933_String() throws Exception - { - // XXX test disabled - } - - @Override - public void testBugzilla_258933_String_SetToNull() throws Exception - { - // XXX test disabled - } - - @Override - public void testBugzilla_258933_String_SetToNull_unsettable() throws Exception - { - // XXX test disabled - } -} diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/UnsetTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/UnsetTest.java index e99e25e527..d923e40c62 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/UnsetTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/UnsetTest.java @@ -10,11 +10,15 @@ */ package org.eclipse.emf.cdo.tests; +import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.common.model.EMFUtil; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.tests.model1.Supplier; +import org.eclipse.emf.cdo.tests.model1.VAT; import org.eclipse.emf.cdo.tests.model2.Unsettable1; import org.eclipse.emf.cdo.transaction.CDOTransaction; +import org.eclipse.emf.cdo.util.CDOUtil; import org.eclipse.emf.cdo.view.CDOView; import org.eclipse.emf.common.util.URI; @@ -22,17 +26,31 @@ import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecore.xmi.impl.EcoreResourceFactoryImpl; +import java.util.Date; + /** * @author Eike Stepper */ public class UnsetTest extends AbstractCDOTest { + + /** + * needed for {@link #commitAndLoadTx(CDOObject)} + */ + private CDOSession commitAndLoadSession; + + /** + * needed for {@link #commitAndLoadTx(CDOObject)} + */ + private CDOTransaction commitAndLoadTransaction; + /** * Ensures that properly typed (i.e. usable) default values can be read from dynamic packages. * <p> @@ -135,11 +153,362 @@ public class UnsetTest extends AbstractCDOTest assertEquals(false, result.isSetUnsettableInt()); assertEquals(false, result.isSetUnsettableLong()); assertEquals(false, result.isSetUnsettableShort()); + assertEquals(false, result.isSetUnsettableString()); + assertEquals(false, result.isSetUnsettableVAT()); + } + + public void testIsSetBoolean() throws Exception + { + Unsettable1 unsettable = getModel2Factory().createUnsettable1(); + unsettable.setUnsettableBoolean(true); + + Unsettable1 result = commitAndLoad(unsettable); + assertEquals(true, result.isSetUnsettableBoolean()); + assertEquals(false, result.isSetUnsettableByte()); + assertEquals(false, result.isSetUnsettableChar()); + assertEquals(false, result.isSetUnsettableDate()); + assertEquals(false, result.isSetUnsettableDouble()); + assertEquals(false, result.isSetUnsettableFloat()); + assertEquals(false, result.isSetUnsettableInt()); + assertEquals(false, result.isSetUnsettableLong()); + assertEquals(false, result.isSetUnsettableShort()); + assertEquals(false, result.isSetUnsettableString()); + assertEquals(false, result.isSetUnsettableVAT()); + } + + public void testIsSetByte() throws Exception + { + Unsettable1 unsettable = getModel2Factory().createUnsettable1(); + unsettable.setUnsettableByte(Byte.MAX_VALUE); + Unsettable1 result = commitAndLoad(unsettable); + assertEquals(false, result.isSetUnsettableBoolean()); + assertEquals(true, result.isSetUnsettableByte()); + assertEquals(false, result.isSetUnsettableChar()); + assertEquals(false, result.isSetUnsettableDate()); + assertEquals(false, result.isSetUnsettableDouble()); + assertEquals(false, result.isSetUnsettableFloat()); + assertEquals(false, result.isSetUnsettableInt()); + assertEquals(false, result.isSetUnsettableLong()); + assertEquals(false, result.isSetUnsettableShort()); + assertEquals(false, result.isSetUnsettableString()); + assertEquals(false, result.isSetUnsettableVAT()); + } + + public void testIsSetChar() throws Exception + { + Unsettable1 unsettable = getModel2Factory().createUnsettable1(); + unsettable.setUnsettableChar('a'); + + Unsettable1 result = commitAndLoad(unsettable); + assertEquals(false, result.isSetUnsettableBoolean()); + assertEquals(false, result.isSetUnsettableByte()); + assertEquals(true, result.isSetUnsettableChar()); + assertEquals(false, result.isSetUnsettableDate()); + assertEquals(false, result.isSetUnsettableDouble()); + assertEquals(false, result.isSetUnsettableFloat()); + assertEquals(false, result.isSetUnsettableInt()); + assertEquals(false, result.isSetUnsettableLong()); assertEquals(false, result.isSetUnsettableShort()); assertEquals(false, result.isSetUnsettableString()); assertEquals(false, result.isSetUnsettableVAT()); } + public void testIsSetDate() throws Exception + { + Unsettable1 unsettable = getModel2Factory().createUnsettable1(); + unsettable.setUnsettableDate(new Date()); + + Unsettable1 result = commitAndLoad(unsettable); + assertEquals(false, result.isSetUnsettableBoolean()); + assertEquals(false, result.isSetUnsettableByte()); + assertEquals(false, result.isSetUnsettableChar()); + assertEquals(true, result.isSetUnsettableDate()); + assertEquals(false, result.isSetUnsettableDouble()); + assertEquals(false, result.isSetUnsettableFloat()); + assertEquals(false, result.isSetUnsettableInt()); + assertEquals(false, result.isSetUnsettableLong()); + assertEquals(false, result.isSetUnsettableShort()); + assertEquals(false, result.isSetUnsettableString()); + assertEquals(false, result.isSetUnsettableVAT()); + } + + public void testIsSetDouble() throws Exception + { + Unsettable1 unsettable = getModel2Factory().createUnsettable1(); + unsettable.setUnsettableDouble(42.34d); + + Unsettable1 result = commitAndLoad(unsettable); + assertEquals(false, result.isSetUnsettableBoolean()); + assertEquals(false, result.isSetUnsettableByte()); + assertEquals(false, result.isSetUnsettableChar()); + assertEquals(false, result.isSetUnsettableDate()); + assertEquals(true, result.isSetUnsettableDouble()); + assertEquals(false, result.isSetUnsettableFloat()); + assertEquals(false, result.isSetUnsettableInt()); + assertEquals(false, result.isSetUnsettableLong()); + assertEquals(false, result.isSetUnsettableShort()); + assertEquals(false, result.isSetUnsettableString()); + assertEquals(false, result.isSetUnsettableVAT()); + } + + public void testIsSetFloat() throws Exception + { + Unsettable1 unsettable = getModel2Factory().createUnsettable1(); + unsettable.setUnsettableFloat(42.34f); + + Unsettable1 result = commitAndLoad(unsettable); + assertEquals(false, result.isSetUnsettableBoolean()); + assertEquals(false, result.isSetUnsettableByte()); + assertEquals(false, result.isSetUnsettableChar()); + assertEquals(false, result.isSetUnsettableDate()); + assertEquals(false, result.isSetUnsettableDouble()); + assertEquals(true, result.isSetUnsettableFloat()); + assertEquals(false, result.isSetUnsettableInt()); + assertEquals(false, result.isSetUnsettableLong()); + assertEquals(false, result.isSetUnsettableShort()); + assertEquals(false, result.isSetUnsettableString()); + assertEquals(false, result.isSetUnsettableVAT()); + } + + public void testIsSetLong() throws Exception + { + Unsettable1 unsettable = getModel2Factory().createUnsettable1(); + unsettable.setUnsettableLong(42L); + + Unsettable1 result = commitAndLoad(unsettable); + assertEquals(false, result.isSetUnsettableBoolean()); + assertEquals(false, result.isSetUnsettableByte()); + assertEquals(false, result.isSetUnsettableChar()); + assertEquals(false, result.isSetUnsettableDate()); + assertEquals(false, result.isSetUnsettableDouble()); + assertEquals(false, result.isSetUnsettableFloat()); + assertEquals(false, result.isSetUnsettableInt()); + assertEquals(true, result.isSetUnsettableLong()); + assertEquals(false, result.isSetUnsettableShort()); + assertEquals(false, result.isSetUnsettableString()); + assertEquals(false, result.isSetUnsettableVAT()); + } + + public void testIsSetShort() throws Exception + { + Unsettable1 unsettable = getModel2Factory().createUnsettable1(); + unsettable.setUnsettableShort(Short.MAX_VALUE); + + Unsettable1 result = commitAndLoad(unsettable); + assertEquals(false, result.isSetUnsettableBoolean()); + assertEquals(false, result.isSetUnsettableByte()); + assertEquals(false, result.isSetUnsettableChar()); + assertEquals(false, result.isSetUnsettableDate()); + assertEquals(false, result.isSetUnsettableDouble()); + assertEquals(false, result.isSetUnsettableFloat()); + assertEquals(false, result.isSetUnsettableInt()); + assertEquals(false, result.isSetUnsettableLong()); + assertEquals(true, result.isSetUnsettableShort()); + assertEquals(false, result.isSetUnsettableString()); + assertEquals(false, result.isSetUnsettableVAT()); + } + + public void testIsSetString() throws Exception + { + Unsettable1 unsettable = getModel2Factory().createUnsettable1(); + unsettable.setUnsettableString("42"); + + Unsettable1 result = commitAndLoad(unsettable); + assertEquals(false, result.isSetUnsettableBoolean()); + assertEquals(false, result.isSetUnsettableByte()); + assertEquals(false, result.isSetUnsettableChar()); + assertEquals(false, result.isSetUnsettableDate()); + assertEquals(false, result.isSetUnsettableDouble()); + assertEquals(false, result.isSetUnsettableFloat()); + assertEquals(false, result.isSetUnsettableInt()); + assertEquals(false, result.isSetUnsettableLong()); + assertEquals(false, result.isSetUnsettableShort()); + assertEquals(true, result.isSetUnsettableString()); + assertEquals(false, result.isSetUnsettableVAT()); + } + + public void testIsSetVAT() throws Exception + { + Unsettable1 unsettable = getModel2Factory().createUnsettable1(); + unsettable.setUnsettableVAT(VAT.VAT15); + + Unsettable1 result = commitAndLoad(unsettable); + assertEquals(false, result.isSetUnsettableBoolean()); + assertEquals(false, result.isSetUnsettableByte()); + assertEquals(false, result.isSetUnsettableChar()); + assertEquals(false, result.isSetUnsettableDate()); + assertEquals(false, result.isSetUnsettableDouble()); + assertEquals(false, result.isSetUnsettableFloat()); + assertEquals(false, result.isSetUnsettableInt()); + assertEquals(false, result.isSetUnsettableLong()); + assertEquals(false, result.isSetUnsettableShort()); + assertEquals(false, result.isSetUnsettableShort()); + assertEquals(false, result.isSetUnsettableString()); + assertEquals(true, result.isSetUnsettableVAT()); + } + + public void testIsSetMultipleTimes() throws Exception + { + Unsettable1 unsettable = getModel2Factory().createUnsettable1(); + unsettable.setUnsettableInt(42); + + Unsettable1 result = commitAndLoadTx(unsettable); + assertEquals(false, result.isSetUnsettableBoolean()); + assertEquals(false, result.isSetUnsettableByte()); + assertEquals(false, result.isSetUnsettableChar()); + assertEquals(false, result.isSetUnsettableDate()); + assertEquals(false, result.isSetUnsettableDouble()); + assertEquals(false, result.isSetUnsettableFloat()); + assertEquals(true, result.isSetUnsettableInt()); + assertEquals(false, result.isSetUnsettableLong()); + assertEquals(false, result.isSetUnsettableShort()); + assertEquals(false, result.isSetUnsettableShort()); + assertEquals(false, result.isSetUnsettableString()); + assertEquals(false, result.isSetUnsettableVAT()); + + result.setUnsettableByte(Byte.MAX_VALUE); + result = commitAndLoadTx(result); + + assertEquals(false, result.isSetUnsettableBoolean()); + assertEquals(true, result.isSetUnsettableByte()); + assertEquals(false, result.isSetUnsettableChar()); + assertEquals(false, result.isSetUnsettableDate()); + assertEquals(false, result.isSetUnsettableDouble()); + assertEquals(false, result.isSetUnsettableFloat()); + assertEquals(true, result.isSetUnsettableInt()); + assertEquals(false, result.isSetUnsettableLong()); + assertEquals(false, result.isSetUnsettableShort()); + assertEquals(false, result.isSetUnsettableShort()); + assertEquals(false, result.isSetUnsettableString()); + assertEquals(false, result.isSetUnsettableVAT()); + + result.unsetUnsettableByte(); + result.unsetUnsettableInt(); + result.setUnsettableString("blah"); + + result = commitAndLoadTx(result); + + assertEquals(false, result.isSetUnsettableBoolean()); + assertEquals(false, result.isSetUnsettableByte()); + assertEquals(false, result.isSetUnsettableChar()); + assertEquals(false, result.isSetUnsettableDate()); + assertEquals(false, result.isSetUnsettableDouble()); + assertEquals(false, result.isSetUnsettableFloat()); + assertEquals(false, result.isSetUnsettableInt()); + assertEquals(false, result.isSetUnsettableLong()); + assertEquals(false, result.isSetUnsettableShort()); + assertEquals(false, result.isSetUnsettableShort()); + assertEquals(true, result.isSetUnsettableString()); + assertEquals(false, result.isSetUnsettableVAT()); + } + + public void testUnsettableBaseTypeVsObjectType() throws Exception + { + EPackage pkg = EMFUtil.createEPackage("unsettablePackage", "unset", + "http://cdo.eclipse.org/unsettablePackage.ecore"); + EClass cls = EMFUtil.createEClass(pkg, "unsettableClass", false, false); + EAttribute baseElement = EMFUtil.createEAttribute(cls, "baseElement", EcorePackage.eINSTANCE.getEInt()); + baseElement.setUnsettable(true); + baseElement.setDefaultValue(23); + + EAttribute objectElement = EMFUtil.createEAttribute(cls, "objectElement", EcorePackage.eINSTANCE + .getEIntegerObject()); + objectElement.setUnsettable(true); + objectElement.setDefaultValue(42); + + CDOUtil.prepareDynamicEPackage(pkg); + + { + EObject test1 = EcoreUtil.create(cls); + test1.eSet(baseElement, 1); + test1.eSet(objectElement, 2); + + EObject test2 = EcoreUtil.create(cls); + test2.eSet(baseElement, 23); + test2.eSet(objectElement, 42); + + EObject test3 = EcoreUtil.create(cls); + test3.eSet(baseElement, null); + test3.eSet(objectElement, null); + + EObject test4 = EcoreUtil.create(cls); + test4.eUnset(baseElement); + test4.eUnset(objectElement); + + assertTrue(test1.eIsSet(baseElement)); + assertTrue(test1.eIsSet(objectElement)); + assertEquals(1, test1.eGet(baseElement)); + assertEquals(2, test1.eGet(objectElement)); + + assertTrue(test2.eIsSet(baseElement)); + assertTrue(test2.eIsSet(objectElement)); + assertEquals(23, test2.eGet(baseElement)); + assertEquals(42, test2.eGet(objectElement)); + + // for basetypes, setting value null seems to be equivalent + // to unset. + assertFalse(test3.eIsSet(baseElement)); + assertTrue(test3.eIsSet(objectElement)); + assertEquals(23, test3.eGet(baseElement)); + assertNull(test3.eGet(objectElement)); + + assertFalse(test4.eIsSet(baseElement)); + assertFalse(test4.eIsSet(objectElement)); + assertEquals(23, test4.eGet(baseElement)); + assertEquals(42, test4.eGet(objectElement)); + + CDOSession session = openSession(pkg); + CDOTransaction transaction = session.openTransaction(); + CDOResource res = transaction.createResource("/test1"); + + res.getContents().add(test1); + res.getContents().add(test2); + res.getContents().add(test3); + res.getContents().add(test4); + + transaction.commit(); + transaction.close(); + session.close(); + } + + clearCache(getRepository().getRevisionManager()); + + { + CDOSession session = openSession(pkg); + CDOView view = session.openTransaction(); + CDOResource res = view.getResource("/test1"); + + assertEquals(4, res.getContents().size()); + EObject test1 = res.getContents().get(0); + EObject test2 = res.getContents().get(1); + EObject test3 = res.getContents().get(2); + EObject test4 = res.getContents().get(3); + + assertTrue(test1.eIsSet(baseElement)); + assertTrue(test1.eIsSet(objectElement)); + assertEquals(1, test1.eGet(baseElement)); + assertEquals(2, test1.eGet(objectElement)); + + assertTrue(test2.eIsSet(baseElement)); + assertTrue(test2.eIsSet(objectElement)); + assertEquals(23, test2.eGet(baseElement)); + assertEquals(42, test2.eGet(objectElement)); + + assertFalse(test3.eIsSet(baseElement)); + assertTrue(test3.eIsSet(objectElement)); + assertEquals(23, test3.eGet(baseElement)); + assertNull(test3.eGet(objectElement)); + + assertFalse(test4.eIsSet(baseElement)); + assertFalse(test4.eIsSet(objectElement)); + assertEquals(23, test4.eGet(baseElement)); + assertEquals(42, test4.eGet(objectElement)); + + view.close(); + session.close(); + } + } + private <T extends EObject> T commitAndLoad(T object) throws Exception { CDOSession session = openSession(); @@ -150,6 +519,8 @@ public class UnsetTest extends AbstractCDOTest transaction.commit(); session.close(); + clearCache(getRepository().getRevisionManager()); + session = openSession(); CDOView view = session.openView(); resource = view.getResource("/test1"); @@ -158,4 +529,30 @@ public class UnsetTest extends AbstractCDOTest T result = (T)resource.getContents().get(0); return result; } + + private <T extends EObject> T commitAndLoadTx(T object) throws Exception + { + if (commitAndLoadSession == null) + { + commitAndLoadSession = openSession(); + commitAndLoadTransaction = commitAndLoadSession.openTransaction(); + + CDOResource resource = commitAndLoadTransaction.createResource("/test1"); + resource.getContents().add(object); + } + + commitAndLoadTransaction.commit(); + commitAndLoadTransaction.close(); + commitAndLoadSession.close(); + + clearCache(getRepository().getRevisionManager()); + + commitAndLoadSession = openSession(); + commitAndLoadTransaction = commitAndLoadSession.openTransaction(); + CDOResource resource = commitAndLoadTransaction.getResource("/test1"); + + @SuppressWarnings("unchecked") + T result = (T)resource.getContents().get(0); + return result; + } } |