Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo')
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/EMFInterceptor.java213
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/EPackageConstructor.java230
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbBaseSessionDataStore.java216
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbConstants.java78
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbContext.java188
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbDataStore.java1866
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbDataStoreFactory.java33
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbEntityDataStore.java737
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbEntityManagerWrapper.java272
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbHelper.java211
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbMapperException.java46
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbSessionDataStore.java274
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbSessionWrapper.java224
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbStoreException.java49
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbUtil.java399
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/LazyCollectionUtils.java307
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/SessionWrapper.java109
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/AnyEObjectType.java472
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/DefaultToStringUserType.java247
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/DynamicENumUserIntegerType.java87
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/DynamicENumUserType.java182
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/EMFInitializeCollectionEventListener.java68
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/ENumUserIntegerType.java89
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/ENumUserType.java196
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/EcoreModelElementType.java166
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/ExternalType.java151
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/HibernatePersistentStoreAdapter.java65
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/QNameUserType.java175
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/SerializableDynamicEObjectImpl.java122
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/XSDDate.java104
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/XSDDateTime.java173
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/XSDDuration.java212
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/DelegatingLateLoadingList.java205
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVBlobValue.java64
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingEMap.java593
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingEcoreEList.java388
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingFeatureMap.java70
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingList.java22
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVExtraMultiContainmentEReferenceValueHolder.java27
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVExtraMultiEAttributeValueHolder.java27
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVExtraMultiNonContainmentEReferenceValueHolder.java27
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVFeatureMapEntryValueHolder.java106
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVFeatureMapValueHolder.java73
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVGenericIDUserType.java128
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVInstantiator.java59
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiContainmentEReferenceValueHolder.java124
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiEAttributeValueHolder.java83
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiNonContainmentEReferenceValueHolder.java86
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiValueHolder.java71
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVObjectTuplizer.java341
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVPropertyHandler.java407
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleContainmentEReferenceValueHolder.java26
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleEAttributeValueHolder.java263
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleEReferenceValueHolder.java140
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleNonContainmentEReferenceValueHolder.java27
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVTextValue.java64
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVTuplizer.java87
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVValueHolder.java283
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVValueInstantiator.java58
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/eav.hbm.xml296
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerAccessor.java68
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerFeatureIDAccessor.java71
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerFeatureIDPropertyHandler.java147
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerFeatureIDUserType.java228
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerPropertyHandler.java148
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerUserType.java549
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/NewEContainerFeatureIDPropertyHandler.java168
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryComponentInstantiator.java47
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryComponentTuplizer.java107
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryInstantiator.java79
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryTuplizer.java119
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HbExtraLazyPersistableEList.java382
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HbExtraLazyPersistableEMap.java193
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernateFeatureMapEntry.java597
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableEList.java622
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableEMap.java233
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableFeatureMap.java244
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/MapHibernatePersistableEMap.java257
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierCacheHandler.java262
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierPropertyHandler.java133
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierUtil.java179
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/internal/TeneoInternalEObject.java14
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/DummyPropertyHandler.java134
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EAttributePropertyHandler.java391
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EListPropertyHandler.java535
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EReferencePropertyHandler.java252
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EcoreAccess.java76
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/FeatureMapEntryFeatureURIPropertyHandler.java138
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/FeatureMapEntryPropertyHandler.java177
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/FeatureMapPropertyHandler.java76
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/SyntheticPropertyHandler.java161
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/VersionPropertyHandler.java124
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/WildCardAttributePropertyHandler.java180
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/WildCardReferencePropertyHandler.java166
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HbResource.java47
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HbResourceImpl.java392
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateResource.java713
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateResourceFactory.java38
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateXMLResource.java138
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateXMLResourceFactory.java38
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/SessionController.java108
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFComponentTuplizer.java162
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFEntityNameResolver.java60
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFInstantiator.java141
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFTuplizer.java367
105 files changed, 21567 insertions, 0 deletions
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/EMFInterceptor.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/EMFInterceptor.java
new file mode 100755
index 000000000..0a523afd9
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/EMFInterceptor.java
@@ -0,0 +1,213 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EMFInterceptor.java,v 1.15 2010/02/04 10:53:08 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.teneo.extension.ExtensionInitializable;
+import org.eclipse.emf.teneo.extension.ExtensionManager;
+import org.eclipse.emf.teneo.extension.ExtensionManagerAware;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierCacheHandler;
+import org.eclipse.emf.teneo.mapping.elist.PersistableDelegateList;
+import org.eclipse.emf.teneo.mapping.strategy.EntityNameStrategy;
+import org.eclipse.emf.teneo.type.PersistentStoreAdapter;
+import org.eclipse.emf.teneo.util.FieldUtil;
+import org.hibernate.EmptyInterceptor;
+import org.hibernate.Transaction;
+import org.hibernate.collection.AbstractPersistentCollection;
+
+/**
+ * Intercepts the getEntityName call to return the EClass name as the entity name.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.15 $
+ */
+
+public class EMFInterceptor extends EmptyInterceptor implements ExtensionPoint, ExtensionManagerAware,
+ ExtensionInitializable {
+
+ // is kept to do dereferencing of collections, see the description in the deReferenceCollections
+ // method
+ // clear all session instances in the persistentcollection to solve
+ // this issue which still occured with Teneo in hibernate 3.2.5
+ // http://forum.hibernate.org/viewtopic.php?t=934961&highlight=two+representations+same+collection
+ // http://opensource.atlassian.com/projects/hibernate/browse/HHH-511
+ // this issue occured when doing the following using a resource:
+ // create a new object with a isMany feature, save the resource,
+ // delete the just saved object, save the resource
+ // undo the delete (possible in the editor) and then
+ // save the resource a 'Found two representations of same collection:'
+ // exception occurs
+ private static ThreadLocal<List<AbstractPersistentCollection>> persistentCollections = new ThreadLocal<List<AbstractPersistentCollection>>();
+ private static ThreadLocal<List<EObject>> deletedEObjects = new ThreadLocal<List<EObject>>();
+
+ // note is also used for non-deleted objects in HbResource
+ public static void registerCollectionsForDereferencing(EObject eObject) {
+ for (EReference eReference : eObject.eClass().getEAllReferences()) {
+ if (eReference.isMany()) {
+ final Object refValue = eObject.eGet(eReference);
+ if (refValue instanceof PersistableDelegateList<?>) {
+ final Object delegate = ((PersistableDelegateList<?>) refValue).getDelegate();
+ if (delegate instanceof AbstractPersistentCollection) {
+ if (persistentCollections.get() == null) {
+ persistentCollections.set(new ArrayList<AbstractPersistentCollection>());
+ }
+ final List<AbstractPersistentCollection> list = persistentCollections.get();
+ list.add((AbstractPersistentCollection) delegate);
+ }
+ }
+ }
+ }
+ if (deletedEObjects.get() == null) {
+ deletedEObjects.set(new ArrayList<EObject>());
+ }
+ deletedEObjects.get().add(eObject);
+ }
+
+ // is used to unset a session in a collection. Note that it would be better to use the
+ // AbstractPersistentCollection.unsetSession/getSession method but these give me a
+ // java.lang.AccessError
+ private static final Field sessionField = FieldUtil.getField(AbstractPersistentCollection.class, "session");
+
+ /**
+ * Generated Serial Version ID
+ */
+ private static final long serialVersionUID = 1680117509182298808L;
+
+ /** The qualify property used to compute the eclassname */
+ private EntityNameStrategy qualifyStrategy;
+
+ private ExtensionManager extensionManager;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.emf.teneo.extension.ExtensionManagerAware#setExtensionManager(org.eclipse.emf.teneo.extension.
+ * ExtensionManager)
+ */
+ public void setExtensionManager(ExtensionManager extensionManager) {
+ this.extensionManager = extensionManager;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.extension.ExtensionInitializable#initializeExtension()
+ */
+ public void initializeExtension() {
+ qualifyStrategy = extensionManager.getExtension(EntityNameStrategy.class);
+ }
+
+ /**
+ * Is overridden to return the eclass uri as the entity name.
+ *
+ * @see org.hibernate.EmptyInterceptor#getEntityName(java.lang.Object)
+ */
+ @Override
+ public String getEntityName(Object object) {
+ if (object instanceof EObject) {
+ // TODO handle featuremap
+ EObject eobj = (EObject) object;
+ return qualifyStrategy.toEntityName(eobj.eClass());
+ }
+
+ return super.getEntityName(object);
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public void postFlush(Iterator entities) {
+ // TODO: consider to move this to after commit
+ final List<AbstractPersistentCollection> list = persistentCollections.get();
+ if (list == null) {
+ return;
+ }
+ try {
+ for (AbstractPersistentCollection apc : list) {
+ try {
+ sessionField.set(apc, null);
+ } catch (Exception e) {
+ throw new HbStoreException(e);
+ }
+ }
+ } finally {
+ persistentCollections.set(null);
+ }
+ }
+
+ @Override
+ public void afterTransactionCompletion(Transaction tx) {
+ if (tx.wasCommitted()) {
+ if (deletedEObjects.get() != null) {
+ try {
+ for (EObject eObject : deletedEObjects.get()) {
+ // remove the PersistentStoreAdapter
+ PersistentStoreAdapter toRemoveAdapter = null;
+ for (Adapter adapter : eObject.eAdapters()) {
+ if (adapter instanceof PersistentStoreAdapter) {
+ toRemoveAdapter = (PersistentStoreAdapter) adapter;
+ }
+ }
+ if (toRemoveAdapter != null) {
+ eObject.eAdapters().remove(toRemoveAdapter);
+ }
+ IdentifierCacheHandler.getInstance().setVersion(eObject, null);
+ IdentifierCacheHandler.getInstance().setID(eObject, null);
+
+ }
+ } finally {
+ deletedEObjects.set(null);
+ }
+ }
+ }
+ super.afterTransactionCompletion(tx);
+ }
+
+ /**
+ * Returns true if the eobject belongs to the newEObject set of a hibernateResource, in all other cases returns
+ * null.
+ */
+ // Disabled this method because an object can be new to a resource but already
+ // exist in the database.
+ // See bugzilla 280355 and the related testcase
+ // @Override
+ // public Boolean isTransient(Object entity) {
+ // if (!(entity instanceof EObject)) {
+ // return null;
+ // }
+ //
+ // final EObject eObject = (EObject) entity;
+ // final Resource res = eObject.eResource();
+ // if (res == null || !(res instanceof StoreResource)) {
+ // return null;
+ // }
+ //
+ // final StoreResource storeResource = (StoreResource) res;
+ // if (storeResource.getNewEObjectSet().contains(entity)) {
+ // return true;
+ // }
+ // // in all other cases let hibernate do it
+ // return null;
+ // }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/EPackageConstructor.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/EPackageConstructor.java
new file mode 100755
index 000000000..518c6083e
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/EPackageConstructor.java
@@ -0,0 +1,230 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EPackageConstructor.java,v 1.5 2010/02/06 18:25:50 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EPackage;
+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.xmi.impl.EcoreResourceFactoryImpl;
+
+/**
+ * Reads epackages from different formats and makes them available to other beans.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EPackageConstructor {
+
+ // The logger
+ private static final Log log = LogFactory.getLog(EPackageConstructor.class);
+
+ // The ecore context in which this app runs
+ // private EcoreContext ecoreContext;
+
+ // The arraylist of epackages, is build in the getEPackages call
+ private List<EPackage> ePackages = null;
+
+ // The classnames of EcoreModelClasses
+ private List<String> ecoreModelClasses = new ArrayList<String>();
+
+ // The array of model class names
+ private List<String> ecoreModelFiles = new ArrayList<String>();
+
+ private boolean initialized = false;
+
+ /**
+ * The list of files with ecore or xsd models.
+ */
+ public void setModelFiles(List<String> ecoreModelFiles) {
+ this.ecoreModelFiles = ecoreModelFiles;
+ }
+
+ /**
+ * Set the list of EcoreModelPackages which are to be read.
+ */
+ public void setModelClasses(List<String> ecoreModelClasses) {
+ this.ecoreModelClasses = ecoreModelClasses;
+ }
+
+ /**
+ * This method will read the models from the modelFiles and the EcoreModelPackages. The EPackages are initialized
+ * and registered in the EPackage registry.
+ *
+ * @return the EPackages which are read from the modelFiles or are defined in EcoreModelPackages.
+ */
+ public List<EPackage> getEPackages() {
+ if (ePackages == null) {
+ initialize();
+ }
+ return ePackages;
+ }
+
+ /** Initialize it all */
+ private void initialize() {
+ if (initialized) {
+ return;
+ }
+ // build the list of EPackages
+ log.debug("Reading EPackages");
+ final ArrayList<EPackage> ePacks = new ArrayList<EPackage>();
+ ePacks.addAll(buildFromModelClasses());
+ ePacks.addAll(buildFromModelFiles());
+
+ for (EPackage epackage : ePacks) {
+ log.info("Registered EPackage: " + epackage.getNsURI());
+ }
+
+ // also add subpackages
+ for (EPackage ePackage : new ArrayList<EPackage>(ePacks)) {
+ addSubPackages(ePacks, ePackage);
+ }
+
+ ePackages = ePacks;
+ initialized = true;
+ }
+
+ private void addSubPackages(List<EPackage> list, EPackage ePackage) {
+ for (EPackage subPackage : ePackage.getESubpackages()) {
+ if (!list.contains(subPackage)) {
+ list.add(subPackage);
+ addSubPackages(list, subPackage);
+ }
+ }
+ }
+
+ /**
+ * Build a list of EPackages from the passed EcoreModelClasses.
+ */
+ private List<EPackage> buildFromModelClasses() {
+ final ArrayList<EPackage> result = new ArrayList<EPackage>();
+ for (String ecoreModelPackageClassName : ecoreModelClasses) {
+ try {
+ final Class<?> cls = this.getClass().getClassLoader().loadClass(ecoreModelPackageClassName);
+ final EPackage emp;
+ // handle the case that this is an EPackage interface
+ if (cls.isInterface()) {
+ final Field f = cls.getField("eINSTANCE");
+ // purposely passing null because it must be static
+ emp = (EPackage) f.get(null);
+ } else {
+ final Method m = cls.getMethod("init");
+ // purposely passing null because it must be static
+ emp = (EPackage) m.invoke(null);
+ }
+
+ // initialise the emp, will also read the epackage
+ result.add(emp);
+ } catch (Exception e) {
+ throw new IllegalStateException(
+ "Excption while trying to retrieve EcoreModelPackage instance from class: "
+ + ecoreModelPackageClassName, e);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Builds a list of epackages from the modelfiles, pre-normalized for duplicates and not registered.
+ */
+ private List<EPackage> buildFromModelFiles() {
+ // separate the files in xsd and ecore files and treat each of them separately
+ final ArrayList<String> ecoreFiles = new ArrayList<String>();
+ final ArrayList<String> xsdFiles = new ArrayList<String>();
+ for (String modelFile : ecoreModelFiles) {
+ if (modelFile.endsWith(".xsd")) {
+ xsdFiles.add(modelFile.trim());
+ } else {
+ if (!modelFile.trim().endsWith(".ecore")) {
+ log.warn("Filename " + modelFile + " passed as modelFile but it does not end on either "
+ + "xsd or ecore, processing it anyway.");
+ }
+ ecoreFiles.add(modelFile.trim());
+ }
+ }
+
+ // now get the ecores and xsd's parse them separately
+ final ArrayList<EPackage> result = new ArrayList<EPackage>();
+ result.addAll(readFromEcore(ecoreFiles));
+ // result.addAll(readFromXmlSchema(xsdFiles));
+
+ return result;
+ }
+
+ // /**
+ // * Builds and registers EPackages from an XML Schema.
+ // *
+ // * @param file
+ // * The XML Schema file.
+ // */
+ // private List<EPackage> readFromXmlSchema(List<String> xsdFiles) {
+ // final ArrayList<EPackage> result = new ArrayList<EPackage>();
+ // for (String xsdFile : xsdFiles) {
+ // log.debug("Building ECore model from XML Schema \"" + xsdFile + "\".");
+ // try {
+ // // final String path = ecoreContext.getQualifiedPath(xsdFile);
+ // final java.net.URI netURI = this.getClass().getResource(xsdFile).toURI();
+ // final URI uri = URI.createURI(netURI.toString());
+ //
+ // // Note: we use an inline SerializableXSDEcoreBuilder to avoid a dependency on
+ // // XSDEcoreBuilder during
+ // // classloading.
+ // for (Object obj : new XSDEcoreBuilder().generate(uri)) {
+ // final EPackage ePackage = (EPackage) obj;
+ // result.add(ePackage);
+ // }
+ // } catch (Exception e) {
+ // throw new StateException("Could not build ECore model from XML Schema, from file " + xsdFile, e);
+ // }
+ // }
+ // return result;
+ // }
+
+ /**
+ * Reads the epackages present in the passed ecore files. Note this method does not register the epackages. It does
+ * not check for duplicates either.
+ */
+ private List<EPackage> readFromEcore(List<String> ecoreFiles) {
+ final ResourceSet resourceSet = new ResourceSetImpl();
+ resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", new EcoreResourceFactoryImpl());
+ final ArrayList<EPackage> epackages = new ArrayList<EPackage>();
+ for (String ecoreFile : ecoreFiles) {
+ log.debug("Reading ecore file: " + ecoreFile);
+ // final String path = ecoreContext.getQualifiedPath(ecoreFile);
+ // log.debug("Using qualified path: " + path);
+ try {
+ final java.net.URI netURI = this.getClass().getResource(ecoreFile).toURI();
+ final Resource res = resourceSet.getResource(URI.createURI(netURI.toString()), true);
+ for (Object obj : res.getContents()) {
+ if (obj instanceof EPackage) {
+ epackages.add((EPackage) obj);
+ }
+ }
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ return epackages;
+ }
+}
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbBaseSessionDataStore.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbBaseSessionDataStore.java
new file mode 100755
index 000000000..954d0a7ef
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbBaseSessionDataStore.java
@@ -0,0 +1,216 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HbBaseSessionDataStore.java,v 1.11 2010/11/11 10:28:18 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.util.Map;
+import java.util.Set;
+
+import javax.naming.NamingException;
+import javax.naming.Reference;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.SessionFactory;
+import org.hibernate.StatelessSession;
+import org.hibernate.classic.Session;
+import org.hibernate.engine.FilterDefinition;
+import org.hibernate.metadata.ClassMetadata;
+import org.hibernate.metadata.CollectionMetadata;
+import org.hibernate.stat.Statistics;
+
+/**
+ * Holds the sessionfactory related methods, makes the HbSessionDataStore better
+ * readable.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.11 $
+ */
+public abstract class HbBaseSessionDataStore extends HbDataStore implements
+ SessionFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ /** The persistency manager factory */
+ private SessionFactory sessionFactory;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbDataStore#close()
+ */
+ @Override
+ public void close() {
+ if (isInitialized()) {
+ closeSessionFactory();
+ // this will call the close method again but because the
+ // datastore
+ // is not initialized anymore it won't get here
+ HbHelper.INSTANCE.deRegisterDataStore(this);
+ }
+ }
+
+ /**
+ * @return the sessionFactory
+ */
+ @Override
+ public SessionFactory getSessionFactory() {
+ if (!isInitialized()) {
+ initialize();
+ }
+ return sessionFactory;
+ }
+
+ // close session factory if set
+ protected void closeSessionFactory() {
+ if (sessionFactory != null && !sessionFactory.isClosed()) {
+ sessionFactory.close();
+ sessionFactory = null;
+ // do set initialized false after closing it
+ setInitialized(false);
+ }
+ }
+
+ /**
+ * @param sessionFactory
+ * the sessionFactory to set
+ */
+ public void setSessionFactory(SessionFactory sessionFactory) {
+ this.sessionFactory = sessionFactory;
+ }
+
+ @SuppressWarnings({ "rawtypes", "deprecation" })
+ public void evict(Class persistentClass, Serializable id)
+ throws HibernateException {
+ getSessionFactory().evict(persistentClass, id);
+ }
+
+ @SuppressWarnings({ "rawtypes", "deprecation" })
+ public void evict(Class persistentClass) throws HibernateException {
+ getSessionFactory().evict(persistentClass);
+ }
+
+ @SuppressWarnings({ "deprecation" })
+ public void evictCollection(String roleName, Serializable id)
+ throws HibernateException {
+ getSessionFactory().evictCollection(roleName, id);
+ }
+
+ @SuppressWarnings({ "deprecation" })
+ public void evictCollection(String roleName) throws HibernateException {
+ getSessionFactory().evictCollection(roleName);
+ }
+
+ @SuppressWarnings({ "deprecation" })
+ public void evictEntity(String entityName, Serializable id)
+ throws HibernateException {
+ getSessionFactory().evictEntity(entityName, id);
+ }
+
+ @SuppressWarnings({ "deprecation" })
+ public void evictEntity(String entityName) throws HibernateException {
+ getSessionFactory().evictEntity(entityName);
+ }
+
+ @SuppressWarnings({ "deprecation" })
+ public void evictQueries() throws HibernateException {
+ getSessionFactory().evictQueries();
+ }
+
+ @SuppressWarnings({ "deprecation" })
+ public void evictQueries(String cacheRegion) throws HibernateException {
+ getSessionFactory().evictQueries(cacheRegion);
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public Map getAllClassMetadata() throws HibernateException {
+ return getSessionFactory().getAllClassMetadata();
+ }
+
+ @SuppressWarnings({ "rawtypes" })
+ public Map getAllCollectionMetadata() throws HibernateException {
+ return getSessionFactory().getAllCollectionMetadata();
+ }
+
+ @SuppressWarnings({ "rawtypes" })
+ public ClassMetadata getClassMetadata(Class persistentClass)
+ throws HibernateException {
+ return getSessionFactory().getClassMetadata(persistentClass);
+ }
+
+ public ClassMetadata getClassMetadata(String entityName)
+ throws HibernateException {
+ return getSessionFactory().getClassMetadata(entityName);
+ }
+
+ public CollectionMetadata getCollectionMetadata(String roleName)
+ throws HibernateException {
+ return getSessionFactory().getCollectionMetadata(roleName);
+ }
+
+ public Session getCurrentSession() throws HibernateException {
+ return getSessionFactory().getCurrentSession();
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Set getDefinedFilterNames() {
+ return getSessionFactory().getDefinedFilterNames();
+ }
+
+ public FilterDefinition getFilterDefinition(String filterName)
+ throws HibernateException {
+ return getSessionFactory().getFilterDefinition(filterName);
+ }
+
+ public Reference getReference() throws NamingException {
+ return getSessionFactory().getReference();
+ }
+
+ public Statistics getStatistics() {
+ return getSessionFactory().getStatistics();
+ }
+
+ public boolean isClosed() {
+ return getSessionFactory().isClosed();
+ }
+
+ public Session openSession() throws HibernateException {
+ return getSessionFactory().openSession();
+ }
+
+ public Session openSession(Connection connection, Interceptor interceptor) {
+ return getSessionFactory().openSession(connection, interceptor);
+ }
+
+ public Session openSession(Connection connection) {
+ return getSessionFactory().openSession(connection);
+ }
+
+ public Session openSession(Interceptor interceptor)
+ throws HibernateException {
+ return getSessionFactory().openSession(interceptor);
+ }
+
+ public StatelessSession openStatelessSession() {
+ return getSessionFactory().openStatelessSession();
+ }
+
+ public StatelessSession openStatelessSession(Connection connection) {
+ return getSessionFactory().openStatelessSession(connection);
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbConstants.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbConstants.java
new file mode 100755
index 000000000..5ed22761e
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbConstants.java
@@ -0,0 +1,78 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HbConstants.java,v 1.9 2010/04/02 15:24:12 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import org.eclipse.emf.teneo.PersistenceOptions;
+
+/**
+ * AnnotationUtil used in the runtime layer as well as the hibernate mapping step.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.9 $
+ */
+public class HbConstants {
+ /**
+ * Column names used to store the econtainer class
+ *
+ * @deprecated use {@link PersistenceOptions#ECONTAINER_CLASS_COLUMN}
+ */
+ public final static String COLUMN_ECONTAINER_CLASS = "econtainer_class";
+
+ /** Property Name of the econtainer property */
+ public final static String PROPERTY_ECONTAINER = "e_container";
+
+ /**
+ * Column names used to store the econtainer hibernate id.
+ *
+ * @deprecated use {@link PersistenceOptions#ECONTAINER_COLUMN}
+ */
+ public final static String COLUMN_ECONTAINER = "e_container";
+
+ /**
+ * Column names used to store the econtainer feature name.
+ *
+ * @deprecated use {@link PersistenceOptions#ECONTAINER_FEATURE_NAME_COLUMN}
+ */
+ public final static String COLUMN_ECONTAINER_FEATURE_NAME = "e_container_feature_name";
+
+ /** Property Name of the econtainer feature id property */
+ public final static String PROPERTY_ECONTAINER_FEATURE_ID = "e_container_featureid";
+
+ /** Property Name of the econtainer feature name property */
+ public final static String PROPERTY_ECONTAINER_FEATURE_NAME = "e_container_featurename";
+
+ /** Column names used to store the econtainer feature id */
+ public final static String COLUMN_ECONTAINER_FEATUREID = "e_container_featureid";
+
+ /** The filename of a hibernate file */
+ public final static String HBM_FILE_NAME = "hibernate.hbm.xml";
+
+ /** The file extension used for ehb files */
+ public final static String EHB_FILE_EXTENSION = "ehb";
+
+ /** The ex/import format from and to xml */
+ public final static int EXCHANGE_FORMAT_XML = 0;
+
+ /** The ex/import format from and to xmi */
+ public final static int EXCHANGE_FORMAT_XMI = 1;
+
+ public final static String EAV_TABLE_PREFIX_PARAMETER_REGEX = "\\{tableprefix\\}";
+
+ public final static String EAV_COLLECTIONLAZY_REGEX = "\\{collectionLazySetting\\}";
+
+ public final static String SYNTHETIC_PROPERTY_INDICATOR = "synthetic-property";
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbContext.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbContext.java
new file mode 100755
index 000000000..5d5d7974a
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbContext.java
@@ -0,0 +1,188 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HbContext.java,v 1.9 2008/02/28 07:08:24 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.teneo.extension.ExtensionManager;
+import org.eclipse.emf.teneo.extension.ExtensionManagerAware;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.mapping.econtainer.EContainerAccessor;
+import org.eclipse.emf.teneo.hibernate.mapping.econtainer.EContainerFeatureIDAccessor;
+import org.eclipse.emf.teneo.hibernate.mapping.elist.FeatureMapEntryTuplizer;
+import org.eclipse.emf.teneo.hibernate.mapping.property.EAttributePropertyHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.property.EListPropertyHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.property.EReferencePropertyHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.property.FeatureMapEntryFeatureURIPropertyHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.property.FeatureMapEntryPropertyHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.property.FeatureMapPropertyHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.property.VersionPropertyHandler;
+import org.eclipse.emf.teneo.hibernate.tuplizer.EMFComponentTuplizer;
+import org.eclipse.emf.teneo.hibernate.tuplizer.EMFTuplizer;
+import org.eclipse.emf.teneo.mapping.strategy.EntityNameStrategy;
+import org.hibernate.Interceptor;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.property.PropertyAccessor;
+
+/**
+ * The HbContext contains factory methods or configuration methods for different objects or other
+ * parameters used by the Hibernate EMF layer. This class can be overridden to instantiate your own
+ * tuplizers, accessors etc.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.9 $
+ */
+public class HbContext implements ExtensionPoint, ExtensionManagerAware {
+
+ private ExtensionManager extensionManager;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbContext#getEMFTuplizerClass(org.hibernate.cfg.Configuration)
+ */
+ public Class<?> getEMFTuplizerClass(Configuration hbConfiguration) {
+ return EMFTuplizer.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbContext#getEMFComponentTuplizerClass(org.hibernate.cfg.Configuration)
+ */
+ public Class<?> getEMFComponentTuplizerClass(Configuration hbConfiguration) {
+ return EMFComponentTuplizer.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbContext#getFeatureMapEntryTuplizer(org.hibernate.cfg.Configuration)
+ */
+ public Class<?> getFeatureMapEntryTuplizer(Configuration hbConfiguration) {
+ return FeatureMapEntryTuplizer.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbContext#createInterceptor(org.hibernate.cfg.Configuration)
+ */
+ public Interceptor createInterceptor(Configuration hbConfiguration, EntityNameStrategy ens) {
+ return extensionManager.getExtension(EMFInterceptor.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbContext#createFeatureMapEntryFeatureURIAccessor()
+ */
+ public PropertyAccessor createFeatureMapEntryFeatureURIAccessor() {
+ return extensionManager.getExtension(FeatureMapEntryFeatureURIPropertyHandler.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbContext#createFeatureMapEntryAccessor(org.eclipse.emf.ecore.EStructuralFeature)
+ */
+ public PropertyAccessor createFeatureMapEntryAccessor(EStructuralFeature feature) {
+ final FeatureMapEntryPropertyHandler handler =
+ extensionManager.getExtension(FeatureMapEntryPropertyHandler.class);
+ handler.initialize(feature);
+ return handler;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbContext#createVersionAccessor()
+ */
+ public PropertyAccessor createVersionAccessor() {
+ return extensionManager.getExtension(VersionPropertyHandler.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbContext#createEContainerAccessor()
+ */
+ public PropertyAccessor createEContainerAccessor() {
+ return extensionManager.getExtension(EContainerAccessor.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbContext#createEContainerFeatureIDAccessor()
+ */
+ public PropertyAccessor createEContainerFeatureIDAccessor() {
+ return extensionManager.getExtension(EContainerFeatureIDAccessor.class);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbContext#createFeatureMapPropertyAccessor(org.eclipse.emf.ecore.EStructuralFeature)
+ */
+ public PropertyAccessor createFeatureMapPropertyAccessor(EStructuralFeature eFeature) {
+ final FeatureMapPropertyHandler fmh = extensionManager.getExtension(FeatureMapPropertyHandler.class);
+ fmh.initialize(eFeature);
+ return fmh;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbContext#createEListAccessor(org.eclipse.emf.ecore.EStructuralFeature)
+ */
+ public PropertyAccessor createEListAccessor(EStructuralFeature eFeature, boolean extraLazy, boolean newEMapMapping) {
+ final EListPropertyHandler handler = extensionManager.getExtension(EListPropertyHandler.class);
+ handler.initialize(eFeature, extraLazy, newEMapMapping);
+ return handler;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbContext#createEReferenceAccessor(org.eclipse.emf.ecore.EReference)
+ */
+ public PropertyAccessor createEReferenceAccessor(EReference eReference) {
+ final EReferencePropertyHandler handler = extensionManager.getExtension(EReferencePropertyHandler.class);
+ handler.initialize(eReference);
+ return handler;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbContext#createEAttributeAccessor(org.eclipse.emf.ecore.EAttribute)
+ */
+ public PropertyAccessor createEAttributeAccessor(EAttribute eAttribute) {
+ return new EAttributePropertyHandler(eAttribute);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.extension.ExtensionManagerAware#setExtensionManager(org.eclipse.emf.teneo.extension.ExtensionManager)
+ */
+ public void setExtensionManager(ExtensionManager extensionManager) {
+ this.extensionManager = extensionManager;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbDataStore.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbDataStore.java
new file mode 100755
index 000000000..5ea9709d7
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbDataStore.java
@@ -0,0 +1,1866 @@
+/**
+ * <copyright> Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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: Martin Taal </copyright> $Id:
+ * HbDataStore.java,v 1.21 2007/04/17 15:49:44 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.FeatureMap.Entry;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;
+import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
+import org.eclipse.emf.teneo.Constants;
+import org.eclipse.emf.teneo.DataStore;
+import org.eclipse.emf.teneo.ERuntime;
+import org.eclipse.emf.teneo.PackageRegistryProvider;
+import org.eclipse.emf.teneo.PersistenceOptions;
+import org.eclipse.emf.teneo.PersistenceOptions.EContainerFeaturePersistenceStrategy;
+import org.eclipse.emf.teneo.TeneoException;
+import org.eclipse.emf.teneo.annotations.mapper.PersistenceMappingBuilder;
+import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEAttribute;
+import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEClass;
+import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEPackage;
+import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEStructuralFeature;
+import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedModel;
+import org.eclipse.emf.teneo.classloader.StoreClassLoadException;
+import org.eclipse.emf.teneo.ecore.EModelResolver;
+import org.eclipse.emf.teneo.extension.ExtensionManager;
+import org.eclipse.emf.teneo.extension.ExtensionManagerFactory;
+import org.eclipse.emf.teneo.hibernate.hbmodel.HbAnnotatedEReference;
+import org.eclipse.emf.teneo.hibernate.mapper.HbMapperConstants;
+import org.eclipse.emf.teneo.hibernate.mapper.HibernateMappingGenerator;
+import org.eclipse.emf.teneo.hibernate.mapper.MappingUtil;
+import org.eclipse.emf.teneo.hibernate.mapping.econtainer.EContainerAccessor;
+import org.eclipse.emf.teneo.hibernate.mapping.econtainer.EContainerFeatureIDAccessor;
+import org.eclipse.emf.teneo.hibernate.mapping.econtainer.EContainerFeatureIDUserType;
+import org.eclipse.emf.teneo.hibernate.mapping.econtainer.EContainerUserType;
+import org.eclipse.emf.teneo.hibernate.mapping.econtainer.NewEContainerFeatureIDPropertyHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.elist.HibernateFeatureMapEntry;
+import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierCacheHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.property.SyntheticPropertyHandler;
+import org.eclipse.emf.teneo.hibernate.resource.HibernateResource;
+import org.eclipse.emf.teneo.hibernate.resource.HibernateResourceFactory;
+import org.eclipse.emf.teneo.hibernate.resource.HibernateXMLResourceFactory;
+import org.eclipse.emf.teneo.hibernate.tuplizer.EMFEntityNameResolver;
+import org.eclipse.emf.teneo.mapping.strategy.EntityNameStrategy;
+import org.eclipse.emf.teneo.util.StoreUtil;
+import org.hibernate.EntityMode;
+import org.hibernate.EntityNameResolver;
+import org.hibernate.FetchMode;
+import org.hibernate.Interceptor;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.cache.HashtableCacheProvider;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.cfg.Mappings;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.IndexedCollection;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.ManyToOne;
+import org.hibernate.mapping.MetaAttribute;
+import org.hibernate.mapping.OneToMany;
+import org.hibernate.mapping.OneToOne;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.Table;
+import org.hibernate.mapping.Value;
+
+/**
+ * Common base class for the standard hb datastore and the entity manager
+ * oriented datastore.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.75 $
+ */
+public abstract class HbDataStore implements DataStore {
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(HbDataStore.class);
+
+ /** Initialize EMF */
+ static {
+ initializeTypes();
+ }
+
+ /** Initializes emf types with jpox */
+ private static synchronized void initializeTypes() {
+ log.debug("Initializing protocol/extension for hibernate");
+ Resource.Factory.Registry.INSTANCE.getProtocolToFactoryMap().put(
+ "hibernate", new HibernateResourceFactory());
+ Resource.Factory.Registry.INSTANCE.getProtocolToFactoryMap().put("ehb",
+ new HibernateResourceFactory());
+ Resource.Factory.Registry.INSTANCE.getProtocolToFactoryMap().put(
+ "hbxml", new HibernateXMLResourceFactory());
+ Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
+ "hibernate", new HibernateResourceFactory());
+ Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
+ "ehb", new HibernateResourceFactory());
+ Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
+ "hbxml", new HibernateXMLResourceFactory());
+ }
+
+ /** HashMap with referers */
+ private HashMap<String, java.util.List<ReferenceTo>> referers;
+
+ /** The array with entities (eclasses) which are not contained */
+ private String[] topEntities;
+
+ /** The list of contained eclasses */
+ private List<EClass> containedEClasses;
+
+ /** The name under which it is registered */
+ private String name;
+
+ /** The list of epackages stored in the datastore */
+ private EPackage[] ePackages;
+
+ private EPackageConstructor ePackageConstructor = null;
+
+ /** Update the schema option */
+ // private boolean updateSchema = true;
+ /** The hb context */
+ private HbContext hbContext = null;
+
+ /** The pannotated model, is set in the mapEPackages method */
+ private PAnnotatedModel paModel = null;
+
+ /** The properties used to create the hibernate configuration object */
+ private PersistenceOptions persistenceOptions;
+
+ /** The properties */
+ private Properties properties = new Properties();
+
+ /** The interceptor */
+ private Interceptor interceptor;
+
+ /**
+ * The used mapping if not passed through a hbm file, can be retrieved for
+ * debugging purposes
+ */
+ private String mappingXML = null;
+
+ /** The extensionManager */
+ private ExtensionManager extensionManager;
+
+ /** the entitynamestrategy is read from the extensionManager */
+ private EntityNameStrategy entityNameStrategy;
+
+ private EMFEntityNameResolver entityNameResolver;
+
+ private Map<EClass, EStructuralFeature> idFeatureByEClass = null;
+
+ private EPackage.Registry packageRegistry = null;
+
+ private boolean resetConfigurationOnInitialization = true;
+
+ public EPackage.Registry getPackageRegistry() {
+ if (packageRegistry == null) {
+ return PackageRegistryProvider.getInstance().getPackageRegistry();
+ }
+ return packageRegistry;
+ }
+
+ public void setPackageRegistry(EPackage.Registry packageRegistry) {
+ this.packageRegistry = packageRegistry;
+ }
+
+ /**
+ * @return the dsName
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return the epackages
+ */
+ public EPackage[] getEPackages() {
+ if (ePackages == null && ePackageConstructor != null) {
+ final java.util.List<EPackage> ePacks = ePackageConstructor
+ .getEPackages();
+ final EPackage[] ePacksArray = new EPackage[ePacks.size()];
+ int i = 0;
+ for (EPackage ePack : ePacks) {
+ ePacksArray[i++] = ePack;
+ }
+ setEPackages(ePacksArray);
+ }
+
+ return ePackages;
+ }
+
+ private List<EClass> computeContainedEClasses() {
+ final List<EClass> result = new ArrayList<EClass>();
+ for (EPackage ePackage : getEPackages()) {
+ for (EClassifier eClassifier : ePackage.getEClassifiers()) {
+ if (eClassifier instanceof EClass) {
+ final EClass eClass = (EClass) eClassifier;
+ for (EReference eReference : eClass.getEAllReferences()) {
+ if (eReference.isContainment()) {
+ if (eReference.getEReferenceType() != EcorePackage.eINSTANCE
+ .getEObject()) {
+ result.add(eReference.getEReferenceType());
+ }
+ }
+ }
+ }
+ }
+ }
+ for (EPackage ePackage : getEPackages()) {
+ for (EClassifier eClassifier : ePackage.getEClassifiers()) {
+ if (eClassifier instanceof EClass) {
+ final EClass eClass = (EClass) eClassifier;
+ if (!result.contains(eClass)
+ && isSuperContained(eClass, result)) {
+ result.add(eClass);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ private boolean isSuperContained(EClass eClass, List<EClass> containedEClass) {
+ for (EClass eSuperClass : eClass.getESuperTypes()) {
+ if (containedEClass.contains(eSuperClass)) {
+ return true;
+ }
+ if (isSuperContained(eSuperClass, containedEClass)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @param epackages
+ * the epackages to set
+ */
+ public void setEPackages(EPackage[] epackages) {
+ // automatically add EPackage
+ final List<EPackage> epacks = new ArrayList<EPackage>();
+ for (EPackage epack : epackages) {
+ resolveSubPackages(epack, epacks);
+ }
+
+ this.ePackages = epacks.toArray(new EPackage[epacks.size()]);
+ }
+
+ private void resolveSubPackages(EPackage epack, List<EPackage> epacks) {
+ if (!epacks.contains(epack)) {
+ epacks.add(epack);
+ }
+
+ for (EPackage subEPackage : epack.getESubpackages()) {
+ resolveSubPackages(subEPackage, epacks);
+ }
+ }
+
+ /**
+ * @param name
+ * the name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ HbHelper.INSTANCE.register(this);
+ }
+
+ /**
+ * The entities (eclasses) which are not contained in another eclass.
+ *
+ * @return the topEntities
+ */
+ public String[] getTopEntities() {
+ return topEntities;
+ }
+
+ /** Initialize the subclass */
+ public abstract void initialize();
+
+ /** Initializes this Data Store */
+ protected void initializeDataStore() {
+ // buildmappings has to be done before setting the tuplizers because
+ // buildMappings will ensure that the element
+ // is set in the List properties.
+ buildMappings();
+
+ setInterceptor();
+
+ log.debug("Determine referers for each class");
+
+ referers = computeReferers();
+
+ topEntities = computeTopEntities();
+
+ containedEClasses = computeContainedEClasses();
+
+ // now add the econtainer mappings to the contained types, only for
+ // unidirectional container relations
+ addContainerMappings();
+ // and add inverse relations for extra lazy
+ addExtraLazyInverseProperties();
+
+ setTuplizer();
+
+ // set the event listeners
+ setEventListeners();
+
+ if (getPersistenceOptions().isUpdateSchema()) {
+ log.warn("The teneo update schema option is not used anymore for hibernate, use the hibernate option: hibernate.hbm2ddl.auto");
+ }
+
+ log.debug("Registering datastore with persistent classes");
+ HbHelper.INSTANCE.registerDataStoreByPC(this);
+ }
+
+ /** Build the mappings in the configuration */
+ protected abstract void buildMappings();
+
+ /**
+ * Closes the data store and its underlying session or entity manager
+ * factory. Calls {@link HbHelper#deRegisterDataStore(String)} to deregister
+ * the data store so that it can not be used anymore.
+ */
+ public abstract void close();
+
+ /** Return the hibernate configuration */
+ public abstract Configuration getHibernateConfiguration();
+
+ /**
+ * Gets the persistence options. The persistence options is a type
+ * representation of the persistence options. If not set through the
+ * setPersistenceProperties method then a properties file is searched If
+ * found it is used to set the persistence options.
+ * <p>
+ * If no properties have been set explicitly, the method will attempt to
+ * load them from the file "/elver-persistence.properties" at the root of
+ * the classpath. (A mechanism similar to "hibernate.properties".)
+ *
+ * @throws HbMapperException
+ * if an error occured reading the properties file.
+ * @return the persistence options as a Properties instance.
+ */
+ public PersistenceOptions getPersistenceOptions() {
+ if (persistenceOptions == null) {
+ final Properties props = new Properties();
+ final InputStream in = this.getClass().getResourceAsStream(
+ PersistenceOptions.DEFAULT_CLASSPATH_FILENAME);
+ if (in != null) {
+ try {
+ props.load(in);
+ } catch (IOException e) {
+ throw new HbMapperException(e);
+ } finally {
+ try {
+ in.close();
+ } catch (IOException e) {
+ throw new HbMapperException(e);
+ }
+ }
+ }
+ persistenceOptions = getExtensionManager().getExtension(
+ PersistenceOptions.class, new Object[] { props });
+ }
+ return persistenceOptions;
+ }
+
+ /**
+ * Sets the persistence options.
+ *
+ * @deprecated use setProperties
+ */
+ @Deprecated
+ public void setPersistenceProperties(Properties persistenceOptions) {
+ this.persistenceOptions = getExtensionManager().getExtension(
+ PersistenceOptions.class, new Object[] { persistenceOptions });
+ }
+
+ /**
+ * @deprecated use getDatastoreProperties
+ */
+ @Deprecated
+ public Properties getHibernateProperties() {
+ return properties;
+ }
+
+ /**
+ * @deprecated use getDatastoreProperties
+ */
+ @Deprecated
+ public Properties getPersistenceProperties() {
+ return persistenceOptions.getProperties();
+ }
+
+ /**
+ * @deprecated use setDatastoreProperties
+ */
+ @Deprecated
+ public void setHibernateProperties(Properties hibernateProperties) {
+ this.properties = hibernateProperties;
+ }
+
+ /**
+ * Sets both the persistence as well as the hibernate properties
+ *
+ * @deprecated use {@link #setDataStoreProperties(Properties)}
+ */
+ public void setProperties(Properties props) {
+ setDataStoreProperties(props);
+ }
+
+ public void setDataStoreProperties(Properties props) {
+ this.persistenceOptions = getExtensionManager().getExtension(
+ PersistenceOptions.class, new Object[] { props });
+ this.properties = props;
+ }
+
+ protected void setDefaultProperties(Properties properties) {
+ if (properties.getProperty("hibernate.cache.provider_class") == null) {
+ log.warn("No hibernate cache provider set, using "
+ + HashtableCacheProvider.class.getName());
+ log.warn("For production use please set the ehcache (or other) provider explicitly and configure it");
+ properties.setProperty("hibernate.cache.provider_class",
+ HashtableCacheProvider.class.getName());
+ }
+ final String hbmUpdate = properties
+ .getProperty(Environment.HBM2DDL_AUTO);
+ if (hbmUpdate == null) {
+ log.info("Hibernate property: " + Environment.HBM2DDL_AUTO
+ + " not set, setting to update");
+ properties.setProperty(Environment.HBM2DDL_AUTO, "update");
+ }
+ log.debug("Setting properties in Hibernate Configuration:");
+ logProperties(properties);
+ }
+
+ /**
+ * Note: was previously called getProperties! Returns the combined hibernate
+ * and persistence properties
+ */
+ public Properties getDataStoreProperties() {
+ final Properties props = new Properties();
+ props.putAll(properties);
+ props.putAll(getPersistenceOptions().getProperties());
+ return props;
+ }
+
+ /** Get the session factory */
+ public abstract SessionFactory getSessionFactory();
+
+ /** Return a new session wrapper */
+ public abstract SessionWrapper createSessionWrapper();
+
+ /** Is the store initialized */
+ private boolean initialized = false;
+
+ /**
+ * @return the hbContext
+ */
+ public HbContext getHbContext() {
+ if (hbContext == null) {
+ hbContext = getExtensionManager().getExtension(HbContext.class);
+ }
+ return hbContext;
+ }
+
+ /**
+ * @param hbContext
+ * the hbContext to set
+ */
+ public void setHbContext(HbContext hbContext) {
+ hbContext.setExtensionManager(getExtensionManager());
+ this.hbContext = hbContext;
+ }
+
+ /** Return the Classmappings as an iterator */
+ public abstract Iterator<?> getClassMappings();
+
+ /**
+ * Returns an array of EObjects and FeatureMapEntries which refer to a
+ * certain EObject, note if the array is of length zero then no refering
+ * EObjects where found. The passed Session is used to create a query. The
+ * transaction handling should be done by the caller.
+ */
+ public Object[] getCrossReferencers(Session session, Object referedTo) {
+ final ArrayList<Object> result = getCrossReferencers(
+ new HbSessionWrapper(this, session), referedTo, false);
+
+ return result.toArray(new Object[result.size()]);
+ }
+
+ /**
+ * Returns an array of EObjects and FeatureMapEntries which refer to a
+ * certain EObject, note if the array is of length zero then no refering
+ * EObjects where found. The passed Session is used to create a query. The
+ * transaction handling should be done by the caller.
+ */
+ public Object[] getCrossReferencers(SessionWrapper sessionWrapper,
+ Object referedTo) {
+ final ArrayList<Object> result = getCrossReferencers(sessionWrapper,
+ referedTo, false);
+ return result.toArray(new Object[result.size()]);
+ }
+
+ /**
+ * Returns an array of EObjects which refer to a certain EObject, note if
+ * the array is of length zero then no refering EObjects where found. The
+ * passed Session is used to create a query. The transaction handling should
+ * be done by the caller. onlyContainers means to only check containment
+ * relations.
+ */
+ private ArrayList<Object> getCrossReferencers(
+ SessionWrapper sessionWrapper, Object referedTo,
+ boolean onlyContainers) {
+ assert (referedTo != null);
+
+ String targetEntityName = null;
+ if (referedTo instanceof EObject) {
+ final EObject eReferedTo = (EObject) referedTo;
+ targetEntityName = getEntityNameStrategy().toEntityName(
+ eReferedTo.eClass());
+ } else if (referedTo instanceof HibernateFeatureMapEntry) {
+ final HibernateFeatureMapEntry fme = (HibernateFeatureMapEntry) referedTo;
+ targetEntityName = fme.getEntityName();
+ } else {
+ throw new IllegalArgumentException("Non eobject not yet supported "
+ + referedTo.getClass().getName());
+ }
+
+ final java.util.List<ReferenceTo> refersList = referers
+ .get(targetEntityName);
+ if (refersList == null || refersList.size() == 0) {
+ return new ArrayList<Object>();
+ }
+ final ArrayList<Object> result = new ArrayList<Object>();
+ for (int i = 0; i < refersList.size(); i++) {
+ final ReferenceTo refersTo = refersList.get(i);
+
+ // if we only check containment relations then skip this
+ if (onlyContainers && !refersTo.isContainer()) {
+ continue;
+ }
+
+ final java.util.List<?> list = sessionWrapper.executeQuery(
+ refersTo.getQueryStr(), "to", referedTo);
+ for (Object obj : list) {
+ if (obj instanceof HibernateFeatureMapEntry) {
+ // search then again with the
+ final ArrayList<Object> fms = getCrossReferencers(
+ sessionWrapper, obj, false);
+ if (fms.size() == 0) {
+ new AssertionError(
+ "The featuremap for featuremap entry "
+ + obj.getClass().getName()
+ + " can not be found");
+ }
+ obj = fms.get(0);
+ }
+
+ // AssertUtil.assertTrue("Getting refersto of " +
+ // referedTo.getClass().getName() +
+ // ", however one of the refersto is not an eobject but a " +
+ // obj.getClass().getName(),
+ // obj instanceof EObject);
+
+ if (!result.contains(obj)) {
+ result.add(obj);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /** Compute the top eclasses */
+ protected String[] computeTopEntities() {
+ final ArrayList<String> result = new ArrayList<String>();
+ for (Iterator<?> pcs = getClassMappings(); pcs.hasNext();) {
+ final PersistentClass pc = (PersistentClass) pcs.next();
+
+ final EClass eclass;
+ if (pc.getEntityName() != null) {
+ eclass = getEntityNameStrategy().toEClass(pc.getEntityName());
+ } else {
+ eclass = EModelResolver.instance().getEClass(
+ pc.getMappedClass());
+ }
+
+ if (eclass == null
+ && !pc.getEntityName().equals(
+ Constants.EAV_EOBJECT_ENTITY_NAME)) {
+ continue;
+ }
+
+ java.util.List<ReferenceTo> refs = referers.get(getMappedName(pc));
+ boolean topEntity = true;
+ if (refs != null) {
+ for (ReferenceTo referenceTo : refs) {
+ ReferenceTo rt = referenceTo;
+ if (rt.isContainer) {
+ topEntity = false;
+ break;
+ }
+ }
+ }
+ try {
+ // see bugzilla 220106
+ if (topEntity && (pc.isAbstract() == null || !pc.isAbstract())) {
+ result.add(getMappedName(pc));
+ }
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ throw new TeneoException(e.getMessage(), e);
+ }
+ }
+ return result.toArray(new String[result.size()]);
+ }
+
+ protected boolean isClassOrSuperClassEAVMapped(PersistentClass pc) {
+ if (pc == null) {
+ return false;
+ }
+ // don't do the EAV mapped ones
+ if (pc.getEntityName().equals(Constants.EAV_EOBJECT_ENTITY_NAME)) {
+ return true;
+ }
+ return isClassOrSuperClassEAVMapped(pc.getSuperclass());
+ }
+
+ /**
+ * Extra lazy mapping for lists needs a real property for the list index and
+ * a real inverse for the other side as well.
+ *
+ * This method iterates over all associations and adds an inverse for the
+ * list and set mappings.
+ */
+ protected void addExtraLazyInverseProperties() {
+ final Map<String, PersistentClass> persistentClasses = new HashMap<String, PersistentClass>();
+ for (Iterator<?> pcs = getClassMappings(); pcs.hasNext();) {
+ final PersistentClass pc = (PersistentClass) pcs.next();
+ if (isClassOrSuperClassEAVMapped(pc)) {
+ continue;
+ }
+ persistentClasses.put(pc.getEntityName(), pc);
+ }
+ for (Iterator<?> pcs = getClassMappings(); pcs.hasNext();) {
+ final PersistentClass pc = (PersistentClass) pcs.next();
+
+ // copy to prevent concurrent modification
+ final Iterator<?> propIt = pc.getPropertyIterator();
+ final List<Property> props = new ArrayList<Property>();
+ while (propIt.hasNext()) {
+ final Property prop = (Property) propIt.next();
+ props.add(prop);
+ }
+
+ for (Property prop : props) {
+ EClass eClass = null;
+ if (pc.getMetaAttribute(HbMapperConstants.FEATUREMAP_META) == null) {
+ if (pc.getEntityName() != null) {
+ eClass = getEntityNameStrategy().toEClass(
+ pc.getEntityName());
+ } else {
+ eClass = EModelResolver.instance().getEClass(
+ pc.getMappedClass());
+ }
+ }
+
+ final EStructuralFeature ef = eClass == null ? null : StoreUtil
+ .getEStructuralFeature(eClass, prop.getName());
+ if (ef != null && ef instanceof EReference
+ && prop.getValue() instanceof Collection) {
+ final Collection collection = (Collection) prop.getValue();
+ final EReference eReference = (EReference) ef;
+
+ // only work for extra lazy
+ if (!collection.isExtraLazy()) {
+ continue;
+ }
+
+ final Value elementValue = collection.getElement();
+ final PersistentClass elementPC;
+ if (elementValue instanceof OneToMany) {
+ final OneToMany oneToMany = (OneToMany) elementValue;
+ elementPC = oneToMany.getAssociatedClass();
+ } else if (elementValue instanceof ManyToOne) {
+ final ManyToOne mto = (ManyToOne) elementValue;
+ elementPC = persistentClasses.get(mto
+ .getReferencedEntityName());
+ } else {
+ continue;
+ }
+
+ if (isClassOrSuperClassEAVMapped(elementPC)) {
+ continue;
+ }
+
+ collection.setInverse(true);
+
+ // and add an eopposite
+ if (eReference.getEOpposite() == null) {
+
+ final Table collectionTable = collection
+ .getCollectionTable();
+
+ if (isClassOrSuperClassEAVMapped(elementPC)) {
+ continue;
+ }
+
+ final Property inverseRefProperty = new Property();
+ inverseRefProperty.setName(StoreUtil
+ .getExtraLazyInversePropertyName(ef));
+ final Map<Object, Object> metas = new HashMap<Object, Object>();
+ final MetaAttribute metaAttribute = new MetaAttribute(
+ HbConstants.SYNTHETIC_PROPERTY_INDICATOR);
+ metaAttribute.addValue("true");
+ metas.put(HbConstants.SYNTHETIC_PROPERTY_INDICATOR,
+ metaAttribute);
+ inverseRefProperty.setMetaAttributes(metas);
+ inverseRefProperty.setNodeName(inverseRefProperty
+ .getName());
+ inverseRefProperty
+ .setPropertyAccessorName(SyntheticPropertyHandler.class
+ .getName());
+ inverseRefProperty.setLazy(false);
+
+ final ManyToOne mto = new ManyToOne(getMappings(),
+ collectionTable);
+ mto.setReferencedEntityName(pc.getEntityName());
+ mto.setLazy(false);
+ mto.setFetchMode(FetchMode.SELECT);
+
+ inverseRefProperty.setValue(mto);
+ final Iterator<?> it = collection.getKey()
+ .getColumnIterator();
+ while (it.hasNext()) {
+ final Column originalColumn = (Column) it.next();
+ // final Column newColumn = new
+ // Column(originalColumn.getName());
+ mto.addColumn(originalColumn);
+ }
+ mto.createForeignKey();
+
+ // now determine if a join should be created
+ if (collectionTable.getName().equalsIgnoreCase(
+ elementPC.getTable().getName())) {
+ elementPC.addProperty(inverseRefProperty);
+ } else {
+ // create a join
+ final Join join = new Join();
+ join.setPersistentClass(elementPC);
+ join.setTable(collectionTable);
+ join.addProperty(inverseRefProperty);
+
+ final ManyToOne keyValue = new ManyToOne(
+ getMappings(), collectionTable);
+ join.setKey(keyValue);
+ @SuppressWarnings("unchecked")
+ final Iterator<Column> keyColumns = collection
+ .getElement().getColumnIterator();
+ while (keyColumns.hasNext()) {
+ keyValue.addColumn(keyColumns.next());
+ }
+ keyValue.setReferencedEntityName(elementPC
+ .getEntityName());
+ keyValue.setTable(collectionTable);
+ keyValue.createForeignKey();
+
+ elementPC.addJoin(join);
+ }
+ }
+
+ // add an opposite index
+ if (collection.isIndexed() && !collection.isMap()) {
+
+ Table collectionTable = collection.getCollectionTable();
+
+ IndexedCollection indexedCollection = (IndexedCollection) collection;
+
+ final Column column = (Column) indexedCollection
+ .getIndex().getColumnIterator().next();
+
+ final Property indexProperty = new Property();
+ indexProperty.setName(StoreUtil
+ .getExtraLazyInverseIndexPropertyName(ef));
+ final Map<Object, Object> metas = new HashMap<Object, Object>();
+ final MetaAttribute metaAttribute = new MetaAttribute(
+ HbConstants.SYNTHETIC_PROPERTY_INDICATOR);
+ metaAttribute.addValue("true");
+ metas.put(HbConstants.SYNTHETIC_PROPERTY_INDICATOR,
+ metaAttribute);
+ indexProperty.setMetaAttributes(metas);
+ indexProperty.setNodeName(indexProperty.getName());
+ indexProperty
+ .setPropertyAccessorName(SyntheticPropertyHandler.class
+ .getName());
+ // always make this nullable, nullability is controlled
+ // by the main property
+ indexProperty.setOptional(true);
+
+ Join join = null;
+ @SuppressWarnings("unchecked")
+ final Iterator<Join> it = (Iterator<Join>) elementPC
+ .getJoinIterator();
+ while (it.hasNext()) {
+ final Join foundJoin = it.next();
+ if (foundJoin
+ .getTable()
+ .getName()
+ .equalsIgnoreCase(collectionTable.getName())) {
+ join = foundJoin;
+ collectionTable = join.getTable();
+ break;
+ }
+ }
+
+ final SimpleValue sv = new SimpleValue(getMappings(),
+ indexedCollection.getIndex().getTable());
+ sv.setTypeName("integer");
+ // final Column svColumn = new Column(column.getName());
+ sv.addColumn(column); // checkColumnExists(collectionTable,
+ // svColumn));
+ indexProperty.setValue(sv);
+ if (join != null) {
+ join.addProperty(indexProperty);
+ } else {
+ elementPC.addProperty(indexProperty);
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ /** Adds a econtainer mapping to the class mapping */
+ protected void addContainerMappings() {
+ if (getPersistenceOptions().isDisableEContainerMapping()) {
+ log.debug("EContainer mapping disabled.");
+ return;
+ }
+ for (Iterator<?> pcs = getClassMappings(); pcs.hasNext();) {
+ final PersistentClass pc = (PersistentClass) pcs.next();
+
+ // if a featuremap then just return
+ if (HbUtil.getEClassNameFromFeatureMapMeta(pc) != null) {
+ continue;
+ }
+
+ // check if container is required is done in the
+ // addContainerMapping call
+ addContainerMapping(pc);
+ }
+ }
+
+ /** Sets the tuplizer */
+ protected void setTuplizer() {
+ for (Iterator<?> pcs = getClassMappings(); pcs.hasNext();) {
+ final PersistentClass pc = (PersistentClass) pcs.next();
+ if (pc.getMetaAttribute(HbMapperConstants.FEATUREMAP_META) != null) { // featuremap
+ // entry
+ pc.addTuplizer(
+ EntityMode.MAP,
+ getHbContext().getFeatureMapEntryTuplizer(
+ getHibernateConfiguration()).getName());
+ } else if (pc.getMetaAttribute(HbMapperConstants.ECLASS_NAME_META) != null) {
+ // only the pc's with this meta should get a tuplizer
+
+ pc.addTuplizer(EntityMode.MAP, getHbContext()
+ .getEMFTuplizerClass(getHibernateConfiguration())
+ .getName());
+ pc.addTuplizer(EntityMode.POJO, getHbContext()
+ .getEMFTuplizerClass(getHibernateConfiguration())
+ .getName());
+ } else if (pc.getMetaAttribute(HbMapperConstants.ECLASS_NAME_META) == null) {
+ // don't change these pc's any further, these are not eclasses
+ continue;
+ }
+
+ // also set the tuplizer for the components, and register for the
+ // component
+
+ // Build a list of all properties.
+ java.util.List<Property> properties = new ArrayList<Property>();
+ final Property identifierProperty = pc.getIdentifierProperty();
+ if (identifierProperty != null) {
+ properties.add(identifierProperty);
+ }
+ for (Iterator<?> it = pc.getPropertyIterator(); it.hasNext();) {
+ properties.add((Property) it.next());
+ }
+
+ // Now set component tuplizers where necessary.
+ for (Object name2 : properties) {
+ Property prop = (Property) name2;
+ if (prop.getName().compareTo("_identifierMapper") == 0) {
+ continue; // ignore this one
+ }
+ final Value value = prop.getValue();
+ if (value instanceof Component) {
+ setComponentTuplizer((Component) value,
+ getHibernateConfiguration());
+ } else if (value instanceof Collection
+ && ((Collection) value).getElement() instanceof Component) {
+ setComponentTuplizer(
+ (Component) ((Collection) value).getElement(),
+ getHibernateConfiguration());
+ }
+ }
+ }
+ }
+
+ /** Set the event listener, can be overridden, in this impl. it does nothing */
+ protected void setEventListeners() {
+ }
+
+ /**
+ * Sets the emf component tuplizer (if it is an eclass) or the hibernate
+ * component tuplizer
+ */
+ protected void setComponentTuplizer(Component component, Configuration cfg) {
+ // check if the eclass exists
+ // todo: change recognizing a component to using metadata!
+ EClass eClass = ERuntime.INSTANCE.getEClass(component
+ .getComponentClass());
+ if (eClass == null) {
+ eClass = getEntityNameStrategy().toEClass(
+ component.getComponentClassName());
+ }
+ if (eClass != null) {
+ log.debug("Found " + eClass.getName() + " as a component");
+ } else {
+ eClass = HbUtil.getEClassFromMeta(component);
+ if (eClass == null) {
+ return;
+ }
+ }
+
+ // is a valid eclass
+ component.addTuplizer(EntityMode.MAP, getHbContext()
+ .getEMFComponentTuplizerClass(cfg).getName());
+ component.addTuplizer(EntityMode.POJO, getHbContext()
+ .getEMFComponentTuplizerClass(cfg).getName());
+ HbHelper.INSTANCE.registerDataStoreByComponent(this, component);
+ }
+
+ /** Returns true if the pc is contained */
+ private boolean isContained(PersistentClass pc) {
+ final EClass eclass;
+ if (pc.getEntityName() != null) {
+ eclass = getEntityNameStrategy().toEClass(pc.getEntityName());
+ } else {
+ eclass = EModelResolver.instance().getEClass(pc.getMappedClass());
+ }
+
+ if (eclass == null
+ && !pc.getEntityName()
+ .equals(Constants.EAV_EOBJECT_ENTITY_NAME)) {
+ return false;
+ }
+
+ if (pc.getEntityName() != null
+ && pc.getEntityName().equals(Constants.EAV_EOBJECT_ENTITY_NAME)) {
+ return true;
+ }
+
+ return containedEClasses.contains(eclass);
+ }
+
+ /** Sets initialized */
+ protected void setInitialized(boolean initialized) {
+ this.initialized = initialized;
+ }
+
+ /**
+ * Gets the initialized state.
+ */
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ /** Sets the interceptor */
+ protected abstract void setInterceptor();
+
+ /** Generate a hibernate mapping xml string from a set of epackages */
+ protected String mapEPackages() {
+ log.debug("Generating mapping file from in-mem ecore");
+ // DCB: Use Hibernate-specific annotation processing mechanism. This
+ // allows use of
+ // Hibernate-specific annotations.
+ final PersistenceOptions po = getPersistenceOptions();
+ setPaModel(getExtensionManager().getExtension(
+ PersistenceMappingBuilder.class).buildMapping(getEPackages(),
+ po, getExtensionManager()));
+ final HibernateMappingGenerator hmg = getExtensionManager()
+ .getExtension(HibernateMappingGenerator.class);
+ hmg.setPersistenceOptions(po);
+ final String hbm = hmg.generateToString(getPaModel());
+
+ log.debug("Computing id types of mapped EClasses");
+ idFeatureByEClass = new HashMap<EClass, EStructuralFeature>();
+ computeIdTypesByEClass(idFeatureByEClass);
+
+ return hbm;
+ }
+
+ /**
+ * @return the type of the id of the passed EClass
+ */
+ public EClassifier getIdType(EClass eClass) {
+ final EStructuralFeature feature = getIdFeature(eClass);
+ if (feature == null) {
+ return XMLTypePackage.eINSTANCE.getLong();
+ }
+ return feature.getEType();
+ }
+
+ /**
+ * Return the ID value of an eObject.
+ *
+ * @param eObject
+ * the object for which to return the id
+ * @return the id, can be null when the object is new.
+ */
+ public Object getId(EObject eObject) {
+ final EStructuralFeature feature = getIdFeature(eObject.eClass());
+ if (feature == null) {
+ return IdentifierCacheHandler.getInstance().getID(eObject);
+ }
+ return eObject.eGet(feature);
+ }
+
+ /**
+ * The {@link EStructuralFeature} representing the id of the passed EClass.
+ *
+ * @param eClass
+ * the id class to check
+ * @return the EStructuralFeature
+ */
+ public EStructuralFeature getIdFeature(EClass eClass) {
+ return idFeatureByEClass.get(eClass);
+ }
+
+ protected void computeIdTypesByEClass(Map<EClass, EStructuralFeature> result) {
+ for (PAnnotatedEPackage aPackage : getPaModel().getPaEPackages()) {
+ for (PAnnotatedEClass aClass : aPackage.getPaEClasses()) {
+ for (PAnnotatedEStructuralFeature aFeature : aClass
+ .getPaEStructuralFeatures()) {
+ if (aFeature instanceof PAnnotatedEAttribute) {
+ final PAnnotatedEAttribute aAttribute = (PAnnotatedEAttribute) aFeature;
+ if (aAttribute.getId() != null) {
+ result.put(aClass.getModelEClass(),
+ aAttribute.getModelEStructuralFeature());
+ break;
+ }
+ }
+ if (aFeature instanceof HbAnnotatedEReference) {
+ final HbAnnotatedEReference aReference = (HbAnnotatedEReference) aFeature;
+ if (aReference.getEmbeddedId() != null) {
+ result.put(aClass.getModelEClass(),
+ aReference.getModelEStructuralFeature());
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /** Recursively check the container prop in the super hierarchy */
+ private boolean hasEContainerProp(PersistentClass pc) {
+ final Iterator<?> it = pc.getPropertyIterator();
+ while (it.hasNext()) {
+ final Property prop = (Property) it.next();
+ if (prop.getName().equals(HbConstants.PROPERTY_ECONTAINER)) {
+ return true;
+ }
+ }
+ if (pc.getSuperclass() == null) {
+ return false;
+ }
+ return hasEContainerProp(pc.getSuperclass());
+ }
+
+ /** Updates the database schema */
+ // this method is removed because it is just as easy to use the hibernate
+ // option
+ // hibernate.hbm2ddl.auto directly
+ // protected void updateDatabaseSchema() {
+ // if (getPersistenceOptions().isUpdateSchema()) {
+ // log.debug("Database schema not updated, option " +
+ // PersistenceOptions.UPDATE_SCHEMA +
+ // " has been set to false");
+ // return;
+ // }
+ // log.debug("Starting update of schema");
+ // new SchemaUpdate(getHibernateConfiguration()).execute(false, true);
+ // log.debug(">>> Update of schema finished");
+ // }
+ /**
+ * Adds a econtainer mapping to the class mapping, is only called for
+ * eclasses which do not have am explicit feature which points to the
+ * container
+ */
+ protected void addContainerMapping(PersistentClass pc) {
+
+ // always first check if the super class should have a container mapping
+ if (pc.getSuperclass() != null) {
+ addContainerMapping(pc.getSuperclass());
+ }
+
+ // always add for the eav object
+ // todo: externalize
+ if (pc.getEntityName().equals(Constants.EAV_EOBJECT_ENTITY_NAME)
+ && !hasEContainerProp(pc)) {
+ addContainerMappingToPC(pc);
+ return;
+ }
+
+ if (!isContained(pc)) {
+ return;
+ }
+ if (hasEContainerProp(pc)) {
+ return;
+ }
+
+ log.debug("Adding container mapping for " + getMappedName(pc));
+ // check if there are not alreadyecontai ner features for the eclass
+
+ final EClass eclass;
+ if (pc.getEntityName() != null) {
+ eclass = getEntityNameStrategy().toEClass(pc.getEntityName());
+ } else {
+ eclass = EModelResolver.instance().getEClass(pc.getMappedClass());
+ }
+
+ // DCB: Provide a way to avoid container mappings for a particular
+ // class. You'd do this if, for example,
+ // you never load the contained objects except through the containers...
+ // or, you don't fit the use case
+ // for which this was put together (i.e., the generated model editing
+ // code tries to eagerly resolve the
+ // container)
+ if (eclass == null
+ || eclass
+ .getEAnnotation("http://facet.elver.org/SkipContainerMappings") != null) {
+ return; // featuremap
+ }
+
+ for (EReference eref : eclass.getEAllReferences()) {
+ if (eref.isContainer()) {
+ log.debug("There are container ereferences present, assuming that no separate econtainer columns are required.");
+ return;
+ }
+ }
+ addContainerMappingToPC(pc);
+ }
+
+ protected void addContainerMappingToPC(PersistentClass pc) {
+ log.debug("Adding eContainer and econtainerfeatureid properties to "
+ + pc.getClassName());
+ final EContainerFeaturePersistenceStrategy featurePersistenceStrategy = getPersistenceOptions()
+ .getEContainerFeaturePersistenceStrategy();
+
+ final Property eContainer = new Property();
+ eContainer.setName(HbConstants.PROPERTY_ECONTAINER);
+ eContainer.setMetaAttributes(new HashMap<Object, Object>());
+ eContainer.setNodeName(eContainer.getName());
+ eContainer.setPropertyAccessorName(EContainerAccessor.class.getName());
+
+ final SimpleValue sv = new SimpleValue(getMappings(), pc.getTable());
+ sv.setTypeName(EContainerUserType.class.getName());
+
+ final Column eccColumn = new Column(getPersistenceOptions()
+ .getSQLColumnNamePrefix()
+ + getPersistenceOptions().getEContainerClassColumn());
+ sv.addColumn(checkColumnExists(pc.getTable(), eccColumn));
+
+ final Column ecColumn = new Column(getPersistenceOptions()
+ .getSQLColumnNamePrefix()
+ + getPersistenceOptions().getEContainerColumn());
+ sv.addColumn(checkColumnExists(pc.getTable(), ecColumn));
+
+ eContainer.setValue(sv);
+ pc.addProperty(eContainer);
+
+ if (featurePersistenceStrategy
+ .equals(EContainerFeaturePersistenceStrategy.FEATUREID)
+ || featurePersistenceStrategy
+ .equals(EContainerFeaturePersistenceStrategy.BOTH)) {
+ final Property ecFID = new Property();
+ ecFID.setName(HbConstants.PROPERTY_ECONTAINER_FEATURE_ID);
+ ecFID.setMetaAttributes(new HashMap<Object, Object>());
+ ecFID.setNodeName(ecFID.getName());
+ ecFID.setPropertyAccessorName(EContainerFeatureIDAccessor.class
+ .getName());
+ final SimpleValue svfid = new SimpleValue(getMappings(),
+ pc.getTable());
+ svfid.setTypeName("integer");
+
+ final Column ecfColumn = new Column(getPersistenceOptions()
+ .getSQLColumnNamePrefix()
+ + HbConstants.COLUMN_ECONTAINER_FEATUREID);
+ svfid.addColumn(checkColumnExists(pc.getTable(), ecfColumn));
+
+ ecFID.setValue(svfid);
+ pc.addProperty(ecFID);
+ }
+ if (featurePersistenceStrategy
+ .equals(EContainerFeaturePersistenceStrategy.FEATURENAME)
+ || featurePersistenceStrategy
+ .equals(EContainerFeaturePersistenceStrategy.BOTH)) {
+ final Property ecFID = new Property();
+ ecFID.setName(HbConstants.PROPERTY_ECONTAINER_FEATURE_NAME);
+ ecFID.setMetaAttributes(new HashMap<Object, Object>());
+ ecFID.setNodeName(ecFID.getName());
+ ecFID.setPropertyAccessorName(NewEContainerFeatureIDPropertyHandler.class
+ .getName());
+ final SimpleValue svfid = new SimpleValue(getMappings(),
+ pc.getTable());
+ svfid.setTypeName(EContainerFeatureIDUserType.class.getName());
+
+ final Column ecfColumn = new Column(getPersistenceOptions()
+ .getSQLColumnNamePrefix()
+ + getPersistenceOptions().getEContainerFeatureNameColumn());
+
+ ecfColumn.setLength(getEContainerFeatureNameColumnLength());
+
+ svfid.addColumn(checkColumnExists(pc.getTable(), ecfColumn));
+
+ ecFID.setValue(svfid);
+ pc.addProperty(ecFID);
+ }
+ }
+
+ // returns the length for string columns used for mapping econtainers
+ protected int getEContainerFeatureNameColumnLength() {
+ return 255;
+ }
+
+ /** Checks if a certain column already exists in a class */
+ private Column checkColumnExists(Table table, Column searchCol) {
+ for (int i = 0; i < table.getColumnSpan(); i++) {
+ final Column column = table.getColumn(i);
+ if (stripQuotes(column.getName()).equalsIgnoreCase(
+ searchCol.getName())) {
+ return column;
+ }
+ }
+ table.addColumn(searchCol);
+ return searchCol;
+ }
+
+ private String stripQuotes(String name) {
+ if (name == null) {
+ return "";
+ }
+ return name.replaceAll("`", "").replaceAll("\"", "");
+ }
+
+ /**
+ * Checks if the passed object is by any change a contained object and if so
+ * returns true
+ */
+ public boolean isContainedObject(Object obj) {
+ // TODO also check containment for superclasses
+ throw new UnsupportedOperationException("Operation is not supported");
+
+ // final ArrayList theReferers = (ArrayList)
+ // referers.get(obj.getClass().getName());
+ // if (theReferers == null || theReferers.size() == 0)
+ // return false;
+ // for (int i = 0; i < theReferers.size(); i++) {
+ // final ReferenceTo refTo = (ReferenceTo) theReferers.get(i);
+ // if (refTo.isContainer())
+ // return true;
+ // }
+ // return false;
+ }
+
+ /**
+ * Import the complete content from an inputstream into the EMF Data Store.
+ * The ExportTarget is the constant defined in the EMFDataStore interface.
+ */
+ public void importDataStore(InputStream is, int importFormat) {
+ final Resource importResource;
+ if (importFormat == HbConstants.EXCHANGE_FORMAT_XML) {
+ importResource = new XMLResourceImpl();
+ } else {
+ importResource = new XMIResourceImpl();
+ }
+
+ final HibernateResource hibResource = new HibernateResource(
+ URI.createFileURI("." + name));
+
+ try {
+ importResource.load(is, Collections.EMPTY_MAP);
+ hibResource.getContents().addAll(importResource.getContents());
+ hibResource.save(Collections.EMPTY_MAP);
+ } catch (IOException e) {
+ throw new HbMapperException("Exception when importing " + name, e);
+ }
+ }
+
+ /**
+ * Export the complete content of the EMF Data Store to an outputstream, the
+ * exportFormat is a HbConstants.EXCHANGE_FORMAT_XML or
+ * HbConstants.EXCHANGE_FORMAT_XMI, the encoding can be null and is used to
+ * set XMLResource.OPTION_ENCODING.
+ */
+ public void exportDataStore(OutputStream os, int exportFormat,
+ String encoding) {
+ final HibernateResource hibResource = new HibernateResource(
+ URI.createFileURI("teneo." + name));
+ hibResource.load(Collections.EMPTY_MAP);
+
+ try {
+ final Resource exportResource;
+ if (exportFormat == HbConstants.EXCHANGE_FORMAT_XML) {
+ exportResource = new XMLResourceImpl();
+ } else {
+ exportResource = new XMIResourceImpl();
+ }
+
+ exportResource.getContents().addAll(hibResource.getContents());
+
+ final HashMap<String, String> options = new HashMap<String, String>();
+ if (encoding != null) {
+ options.put(XMLResource.OPTION_ENCODING, encoding);
+ }
+
+ exportResource.save(os, options);
+
+ hibResource.unload();
+ } catch (IOException e) {
+ throw new HbMapperException("Exception when exporting " + name, e);
+ }
+ }
+
+ /**
+ * Computes the referers, handles the lazy for containment
+ */
+ protected HashMap<String, java.util.List<ReferenceTo>> computeReferers() {
+ final HashMap<String, java.util.List<ReferenceTo>> result = new HashMap<String, java.util.List<ReferenceTo>>();
+
+ final Iterator<?> it = getClassMappings();
+ final ArrayList<String> fmes = new ArrayList<String>();
+ while (it.hasNext()) {
+ final PersistentClass pc = (PersistentClass) it.next();
+
+ // keep track which are the feature map entries
+ if (pc.getMetaAttribute(HbMapperConstants.FEATUREMAP_META) != null) {
+ fmes.add(getMappedName(pc));
+ }
+
+ // everyone should have a list otherwise the copying of referers to
+ // super types to
+ // this type does not work
+ if (result.get(getMappedName(pc)) == null) {
+ result.put(getMappedName(pc), new ArrayList<ReferenceTo>());
+ }
+
+ final Iterator<?> propIt = pc.getPropertyIterator();
+ while (propIt.hasNext()) {
+ // handle few cases
+ // OneToOne or ManyToOne, referenced class can be obtained from
+ // Value and then getReferencedEntityName
+ // List: in this case search for a structural feature and get
+ // the EType from it
+ // if no structural feature then use the type name and hope for
+ // the best.
+
+ final Property prop = (Property) propIt.next();
+ EClass eClass = null;
+ if (pc.getMetaAttribute(HbMapperConstants.FEATUREMAP_META) == null) {
+ if (pc.getEntityName() != null) {
+ eClass = getEntityNameStrategy().toEClass(
+ pc.getEntityName());
+ } else {
+ eClass = EModelResolver.instance().getEClass(
+ pc.getMappedClass());
+ }
+ }
+
+ final EStructuralFeature ef = eClass == null ? null : StoreUtil
+ .getEStructuralFeature(eClass, prop.getName());
+ try {
+ String toEntity = "";
+ boolean isContainer = false;
+ boolean isMany = false;
+
+ if (prop.getValue() instanceof ManyToOne) {
+ final ManyToOne mto = (ManyToOne) prop.getValue();
+ toEntity = mto.getReferencedEntityName();
+ if (ef != null) {
+ isContainer = ef instanceof EReference
+ && ((EReference) ef).isContainment();
+ } else {
+ isContainer = prop.getCascadeStyle()
+ .hasOrphanDelete()
+ || prop.getCascade().compareTo("all") == 0; // ugly
+ // but
+ }
+ // this was
+ // the only
+ // way to
+ // get all
+ // there!
+ } else if (prop.getValue() instanceof OneToOne) {
+ final OneToOne oto = (OneToOne) prop.getValue();
+ toEntity = oto.getReferencedEntityName();
+ if (ef != null) {
+ isContainer = ef instanceof EReference
+ && ((EReference) ef).isContainment();
+ } else {
+ isContainer = prop.getCascadeStyle()
+ .hasOrphanDelete()
+ || prop.getCascadeStyle() == CascadeStyle.ALL;
+ }
+ } else if (prop.getValue() instanceof Collection) {
+ isMany = true;
+ if (ef == null) { // TODO can this happen?
+ isContainer = prop.getCascadeStyle()
+ .hasOrphanDelete()
+ || prop.getCascadeStyle() == CascadeStyle.ALL;
+ if (((Collection) prop.getValue()).getElement() instanceof OneToMany) {
+ final Collection coll = (Collection) prop
+ .getValue();
+ toEntity = ((OneToMany) coll.getElement())
+ .getReferencedEntityName();
+ } else if (((Collection) prop.getValue())
+ .getElement() instanceof ManyToOne) {
+ final Collection coll = (Collection) prop
+ .getValue();
+ toEntity = ((ManyToOne) coll.getElement())
+ .getReferencedEntityName();
+ } else {
+ continue;
+ // throw new HbMapperException("Type "
+ // + ((Collection)
+ // prop.getValue()).getElement().getClass().getName()
+ // + " not supported, property " +
+ // prop.getName());
+ }
+ } else {
+ // in case of featuremap set containment always on
+ // true because only the featuremap entries
+ // themselves know if they are containment
+ if (ef instanceof EAttribute
+ && ((EAttribute) ef).getEType()
+ .getInstanceClass() == Entry.class) {
+ isContainer = true;
+ // composite-elements are not supported.
+ if (!(((Collection) prop.getValue())
+ .getElement() instanceof OneToMany)) {
+ continue;
+ }
+ final OneToMany otm = (OneToMany) ((Collection) prop
+ .getValue()).getElement();
+ toEntity = otm.getReferencedEntityName();
+ } else if (ef instanceof EReference) {
+ final EReference er = (EReference) ef;
+ isContainer = er.isContainment(); // prop.getCascadeStyle().
+ // hasOrphanDelete()
+ // ||
+ // prop.getCascadeStyle()
+ // ==
+ // CascadeStyle.ALL;
+ toEntity = getEntityNameStrategy()
+ .toEntityName(
+ ((EReference) ef)
+ .getEReferenceType());
+ } else if (ef instanceof EAttribute
+ && ef.getEType() instanceof EClass) { // TODO
+ // can
+ // this
+ // ever
+ // happen?
+ isContainer = true; // prop.getCascadeStyle().hasOrphanDelete()
+ // || prop.getCascadeStyle()
+ // == CascadeStyle.ALL;
+ toEntity = getEntityNameStrategy()
+ .toEntityName((EClass) ef.getEType());
+ }
+ // filter out non eobjects
+ else {
+ continue;
+ }
+ }
+ } else {
+ continue;
+ }
+
+ java.util.List<ReferenceTo> list = result.get(toEntity);
+ if (list == null) {
+ list = new ArrayList<ReferenceTo>();
+ result.put(toEntity, list);
+ }
+
+ list.add(new ReferenceTo(getMappedName(pc), prop,
+ isContainer, isMany, toEntity));
+ } catch (StoreClassLoadException e) {
+ throw new HbMapperException(
+ "Class not found using property: " + prop.getName()
+ + " of " + prop, e);
+ }
+ }
+ }
+
+ // at the end for each class all the refersto of superclasses and
+ // interfaces are added also
+ final ArrayList<EClass> classDone = new ArrayList<EClass>();
+ for (String em : result.keySet()) {
+ // only do this if not a fme
+ if (!fmes.contains(em)) {
+ setRefersToOfSupers(em, result, classDone);
+ }
+ }
+ return result;
+ }
+
+ /** Returns either the entityname or the classname, which ever is filled */
+ private String getMappedName(PersistentClass pc) {
+ if (pc.getEntityName() != null) {
+ return pc.getEntityName();
+ }
+ return pc.getClassName();
+ }
+
+ /**
+ * Add the refersto for each superclass/interface to the subclass refersto
+ * list. As a convenience returns the set list
+ */
+ private java.util.List<ReferenceTo> setRefersToOfSupers(String eClassUri,
+ HashMap<String, java.util.List<ReferenceTo>> refersTo,
+ ArrayList<EClass> classDone) {
+ final EntityNameStrategy ens = getEntityNameStrategy();
+ EClass eclass;
+ // eclass = null when the refered to eclass is not mapped
+ // because it is is embeddable
+ eclass = ens.toEClass(eClassUri);
+ if (eclass == null) {
+ return new ArrayList<ReferenceTo>();
+ }
+
+ if (classDone.contains(eclass)) {
+ return refersTo.get(eClassUri);
+ }
+
+ final java.util.List<ReferenceTo> thisList = refersTo.get(ens
+ .toEntityName(eclass));
+ if (thisList == null) {
+ return new ArrayList<ReferenceTo>();
+ }
+ for (EClass class1 : eclass.getESuperTypes()) {
+ String eclassUri = ens.toEntityName(class1);
+ addUnique(thisList,
+ setRefersToOfSupers(eclassUri, refersTo, classDone));
+ }
+ classDone.add(eclass);
+ return thisList;
+ }
+
+ /** Adds list 2 to list 1 without duplicates */
+ private void addUnique(java.util.List<ReferenceTo> l1,
+ java.util.List<ReferenceTo> l2) {
+ if (l2 == null) {
+ return; // this is a valid situation so do nothing
+ }
+
+ final Iterator<ReferenceTo> it = l2.iterator();
+ while (it.hasNext()) {
+ final ReferenceTo obj = it.next();
+ if (!l1.contains(obj)) {
+ l1.add(obj);
+ }
+ }
+ }
+
+ /** Dump properties in the log */
+ protected void logProperties(Properties props) {
+ final Iterator<?> it = props.keySet().iterator();
+ while (it.hasNext()) {
+ final String key = (String) it.next();
+ log.info(key + ": " + props.get(key));
+ }
+ }
+
+ /** Contains the reference to a class which refers to another reference */
+ public static class ReferenceTo {
+
+ /** Is contained */
+ private final boolean isContainer;
+
+ /** The query used to find the occurence */
+ private final String qryStr;
+
+ /** Constructor */
+ public ReferenceTo(String fromEntity, Property prop,
+ boolean isContainer, boolean isMany, String toEntity) {
+ this.isContainer = isContainer;
+ if (isMany) {
+ qryStr = "SELECT ref FROM "
+ + fromEntity
+ + " as ref, "
+ + toEntity
+ + " as refTo WHERE refTo = :to and refTo in elements(ref."
+ + prop.getName() + ")";
+ } else {
+ qryStr = "SELECT ref FROM " + fromEntity
+ + " as ref WHERE :to = ref." + prop.getName();
+ }
+ }
+
+ /**
+ * @return Returns the isContainer.
+ */
+ public boolean isContainer() {
+ return isContainer;
+ }
+
+ /** Returns the query string used used */
+ public String getQueryStr() {
+ return qryStr;
+ }
+ }
+
+ /**
+ * Return the list of mapping files. If the mapping file path property of
+ * persistenceoptions was set then this is returned, otherwise the classpath
+ * is searched for the mapping file.
+ */
+ protected String[] getMappingFileList() {
+ if (getPersistenceOptions().getMappingFilePath() != null) {
+ log.debug("Using specified list of mapping files "
+ + getPersistenceOptions().getMappingFilePath());
+ return getPersistenceOptions().getMappingFilePath().split(",");
+ } else if (getPersistenceOptions().isUseMappingFile()) {
+ // register otherwise the getFileList will not work
+ EModelResolver.instance().register(getEPackages());
+
+ log.debug("Searching hbm files in class paths of epackages");
+ return StoreUtil.getFileList(HbConstants.HBM_FILE_NAME, null);
+ } else {
+ throw new HbStoreException(
+ "This method may only be called if either the useMappingFile property or the MappingFilePath property has been set");
+ }
+ }
+
+ /**
+ * @return the mappingXML
+ */
+ public String getMappingXML() {
+ return mappingXML;
+ }
+
+ /**
+ * @param mappingXML
+ * the mappingXML to set
+ */
+ public void setMappingXML(String mappingXML) {
+ this.mappingXML = mappingXML;
+ }
+
+ /**
+ * @return the interceptor
+ */
+ public Interceptor getInterceptor() {
+ return interceptor;
+ }
+
+ /**
+ * @return the EntityNameResolver
+ * @see org.hibernate.EntityNameResolver
+ */
+ public EntityNameResolver getEntityNameResolver() {
+ if (entityNameResolver == null) {
+ entityNameResolver = getExtensionManager().getExtension(
+ EMFEntityNameResolver.class);
+ entityNameResolver.setQualifyStrategy(getEntityNameStrategy());
+ }
+ return entityNameResolver;
+ }
+
+ /** Returns the persistent class for a certain EObject */
+ public PersistentClass getPersistentClass(String entityName) {
+ final Iterator<?> it = getClassMappings();
+ while (it.hasNext()) {
+ final PersistentClass pc = (PersistentClass) it.next();
+ if (pc.getEntityName() != null
+ && pc.getEntityName().equals(entityName)) {
+ return pc;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @param interceptor
+ * the interceptor to set
+ */
+ public void setInterceptor(Interceptor interceptor) {
+ this.interceptor = interceptor;
+ }
+
+ /**
+ * @return the paModel
+ */
+ public PAnnotatedModel getPaModel() {
+ if (paModel == null) {
+ // happens in case a hbm file is used
+ // just create the pamodel with the default values
+ paModel = getExtensionManager().getExtension(
+ PersistenceMappingBuilder.class).buildMapping(
+ getEPackages(), getPersistenceOptions(),
+ getExtensionManager());
+ }
+ return paModel;
+ }
+
+ /**
+ * @return the referers
+ */
+ public HashMap<String, java.util.List<ReferenceTo>> getReferers() {
+ return referers;
+ }
+
+ /**
+ * If the extensionManager is not yet set then the DefaultExtensionManager
+ * is used.
+ *
+ * @return the extensionManager
+ */
+ public ExtensionManager getExtensionManager() {
+ if (extensionManager == null) {
+ setExtensionManager(ExtensionManagerFactory.getInstance().create());
+ }
+ return extensionManager;
+ }
+
+ /**
+ * @param extensionManager
+ * the extensionManager to set
+ */
+ public void setExtensionManager(ExtensionManager extensionManager) {
+ this.extensionManager = extensionManager;
+ MappingUtil.registerHbExtensions(extensionManager);
+ }
+
+ /**
+ * @return the entityNameStrategy
+ */
+ public EntityNameStrategy getEntityNameStrategy() {
+ if (entityNameStrategy == null) {
+ entityNameStrategy = getExtensionManager().getExtension(
+ EntityNameStrategy.class);
+ entityNameStrategy.setPaModel(getPaModel());
+ }
+ return entityNameStrategy;
+ }
+
+ /**
+ * @param paModel
+ * the paModel to set
+ */
+ public void setPaModel(PAnnotatedModel paModel) {
+ this.paModel = paModel;
+ }
+
+ /**
+ * Facilitates setting ePackages through Spring
+ */
+ public void setEPackageClasses(java.util.List<String> ePackageClasses) {
+ if (ePackageConstructor == null) {
+ ePackageConstructor = new EPackageConstructor();
+ }
+ ePackageConstructor.setModelClasses(ePackageClasses);
+ }
+
+ public void setEPackageFiles(java.util.List<String> ePackageFiles) {
+ if (ePackageConstructor == null) {
+ ePackageConstructor = new EPackageConstructor();
+ }
+ ePackageConstructor.setModelFiles(ePackageFiles);
+ }
+
+ protected String processEAVMapping(InputStream inputStream) {
+ try {
+ final InputStreamReader reader = new InputStreamReader(inputStream,
+ "UTF-8");
+ final char[] chars = new char[500];
+ int readNum = 0;
+ final StringBuilder sb = new StringBuilder();
+ while ((readNum = reader.read(chars, 0, 500)) > 0) {
+ sb.append(chars, 0, readNum);
+ }
+ String eav = sb.toString();
+ eav = eav.replaceAll(HbConstants.EAV_TABLE_PREFIX_PARAMETER_REGEX,
+ getPersistenceOptions().getSQLTableNamePrefix());
+
+ final boolean extraLazy = getPersistenceOptions()
+ .isFetchAssociationExtraLazy();
+ eav = eav.replaceAll(HbConstants.EAV_COLLECTIONLAZY_REGEX,
+ (extraLazy ? "extra" : "false"));
+
+ return eav;
+ } catch (Exception e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ protected Mappings getMappings() {
+ return getHibernateConfiguration().createMappings();
+ }
+
+ /**
+ * If set to true (the default) then when initialize is called the
+ * configuration object is set to null and then recreated.
+ *
+ * @return if the configuration object is reset when initializing
+ */
+ public boolean isResetConfigurationOnInitialization() {
+ return resetConfigurationOnInitialization;
+ }
+
+ /**
+ * @see #isResetConfigurationOnInitialization()
+ * @param resetConfigurationOnInitialization
+ */
+ public void setResetConfigurationOnInitialization(
+ boolean resetConfigurationOnInitialization) {
+ this.resetConfigurationOnInitialization = resetConfigurationOnInitialization;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbDataStoreFactory.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbDataStoreFactory.java
new file mode 100755
index 000000000..51c120270
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbDataStoreFactory.java
@@ -0,0 +1,33 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HbDataStoreFactory.java,v 1.4 2008/02/28 07:08:24 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+/**
+ * Defines the factory interface for creating Hibernate Configuration. By
+ * specifying their own configuration factory the client application can add
+ * their own properties and control the creation of session factories.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.4 $
+ */
+public interface HbDataStoreFactory {
+ /**
+ * The method which gets called to create a EMFDataStore. The default
+ * factory creates a standard EMFDataStore
+ */
+ public HbDataStore createHbDataStore();
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbEntityDataStore.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbEntityDataStore.java
new file mode 100755
index 000000000..ec6d3c53c
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbEntityDataStore.java
@@ -0,0 +1,737 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HbEntityDataStore.java,v 1.37 2011/07/05 05:09:41 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringBufferInputStream;
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.persistence.Cache;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.FlushModeType;
+import javax.persistence.LockModeType;
+import javax.persistence.Parameter;
+import javax.persistence.PersistenceUnitUtil;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.metamodel.Metamodel;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.teneo.PackageRegistryProvider;
+import org.eclipse.emf.teneo.annotations.mapper.PersistenceFileProvider;
+import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEClass;
+import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEPackage;
+import org.eclipse.emf.teneo.hibernate.mapper.MappingUtil;
+import org.eclipse.emf.teneo.hibernate.mapping.EMFInitializeCollectionEventListener;
+import org.eclipse.emf.teneo.hibernate.mapping.eav.EAVGenericIDUserType;
+import org.hibernate.Interceptor;
+import org.hibernate.SessionFactory;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.ejb.Ejb3Configuration;
+import org.hibernate.ejb.EntityManagerFactoryImpl;
+import org.hibernate.ejb.QueryImpl;
+import org.hibernate.engine.query.NamedParameterDescriptor;
+import org.hibernate.event.InitializeCollectionEventListener;
+import org.hibernate.impl.AbstractQueryImpl;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+
+/**
+ * Adds Hibernate Entitymanager behavior to the hbDataStore.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.37 $
+ */
+@SuppressWarnings("deprecation")
+public class HbEntityDataStore extends HbDataStore implements
+ EntityManagerFactory {
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(HbEntityDataStore.class);
+
+ /** The persistency manager factory */
+ private EntityManagerFactory entityManagerFactory;
+
+ /** The used Hibernate configuration */
+ private Ejb3Configuration ejb3Configuration;
+
+ private Field queryParametersField;
+
+ /** Initializes this Data Store */
+ @Override
+ public void initialize() {
+ if (ejb3Configuration != null && isResetConfigurationOnInitialization()) {
+ ejb3Configuration = null;
+ }
+
+ MappingUtil.registerHbExtensions(getExtensionManager());
+
+ try {
+ PackageRegistryProvider.getInstance().setThreadPackageRegistry(
+ getPackageRegistry());
+
+ log.debug("Initializing EJB3 Hb Entity DataStore");
+ // check a few things
+ if (getEPackages() == null) {
+ throw new HbMapperException("EPackages are not set");
+ // if (getName() == null)
+ // throw new HbStoreException("Name is not set");
+ }
+
+ // reset interceptor
+ setInterceptor(null);
+
+ mapModel();
+
+ setPropertiesInConfiguration();
+
+ initializeDataStore();
+
+ // wait for the session factory until the database is (re)created
+ if (entityManagerFactory != null && entityManagerFactory.isOpen()) {
+ entityManagerFactory.close();
+ }
+ entityManagerFactory = buildEntityManagerFactory();
+
+ // register ourselves
+ HbHelper.INSTANCE.register(this);
+
+ setInitialized(true);
+ } finally {
+ PackageRegistryProvider.getInstance()
+ .setThreadPackageRegistry(null);
+ }
+ }
+
+ /** Build the mappings in the configuration */
+ @Override
+ protected void buildMappings() {
+ getConfiguration().buildMappings();
+ }
+
+ /** Set the event listener, can be overridden, in this impl. it does nothing */
+ @Override
+ protected void setEventListeners() {
+ final EMFInitializeCollectionEventListener eventListener = getExtensionManager()
+ .getExtension(EMFInitializeCollectionEventListener.class);
+ getConfiguration()
+ .getEventListeners()
+ .setInitializeCollectionEventListeners(
+ new InitializeCollectionEventListener[] { eventListener });
+ }
+
+ /** Sets the interceptor */
+ @Override
+ protected void setInterceptor() {
+ if (getInterceptor() != null) {
+ return;
+ }
+ final Interceptor interceptor = getHbContext().createInterceptor(
+ getHibernateConfiguration(), getEntityNameStrategy());
+ getConfiguration().setInterceptor(interceptor);
+ setInterceptor(interceptor);
+ }
+
+ /** Returns a new ejb3 configuration object */
+ protected Ejb3Configuration createConfiguration() {
+ return new Ejb3Configuration();
+ }
+
+ /** Sets the properties in the Hibernate Configuration. */
+ protected void setPropertiesInConfiguration() {
+ Properties properties = getDataStoreProperties();
+ if (properties != null) {
+ setDefaultProperties(properties);
+ // set this as this gives errors in the hibernate entity manager
+ // see this bugzilla:
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=330855
+ // Using HbEntityDataStore causes org.hibernate.MappingException:
+ // Unknown entity:...
+ if (!properties.containsKey("hibernate.ejb.metamodel.generation")) {
+ properties.setProperty("hibernate.ejb.metamodel.generation",
+ "disabled");
+ }
+ getConfiguration().addProperties(properties);
+ }
+ }
+
+ /**
+ * Maps an ecore model of one ore more epackages into a hibernate xml String
+ * which is added to the passed configuration
+ */
+ protected void mapModel() {
+ if (getPersistenceOptions().isUseMappingFile()
+ || getPersistenceOptions().getMappingFilePath() != null) {
+ log.debug("Searching hbm files in class paths of epackages");
+ final String[] fileList = getMappingFileList();
+ for (String element : fileList) {
+ log.debug("Adding file " + element
+ + " to Hibernate Configuration");
+ final PersistenceFileProvider pfp = getExtensionManager()
+ .getExtension(PersistenceFileProvider.class);
+ final InputStream is = pfp.getFileContent(this.getClass(),
+ element);
+ if (is == null) {
+ throw new HbStoreException("Path to mapping file: "
+ + element + " does not exist!");
+ }
+ getConfiguration().addInputStream(is);
+ }
+ } else {
+ setMappingXML(mapEPackages());
+
+ boolean hasEAVMapping = false;
+ for (PAnnotatedEPackage aPackage : getPaModel().getPaEPackages()) {
+ for (PAnnotatedEClass aClass : aPackage.getPaEClasses()) {
+ if (aClass.getEavMapping() != null) {
+ hasEAVMapping = true;
+ break;
+ }
+ }
+ }
+ if (hasEAVMapping) {
+ try {
+ if (getPersistenceOptions().getEAVMappingFile() != null) {
+ final PersistenceFileProvider pfp = getExtensionManager()
+ .getExtension(PersistenceFileProvider.class);
+ final InputStream is = pfp.getFileContent(this
+ .getClass(), getPersistenceOptions()
+ .getEAVMappingFile());
+ getConfiguration().addInputStream(processEAV(is));
+ is.close();
+ } else {
+ final PersistenceFileProvider pfp = getExtensionManager()
+ .getExtension(PersistenceFileProvider.class);
+ final InputStream is = pfp.getFileContent(
+ EAVGenericIDUserType.class, "eav.hbm.xml");
+ getConfiguration().addInputStream(processEAV(is));
+ is.close();
+ }
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ // TODO replace this
+ final StringBufferInputStream is = new StringBufferInputStream(
+ getMappingXML());
+ getConfiguration().addInputStream(is);
+ }
+ }
+
+ protected InputStream processEAV(InputStream is) {
+ return new StringBufferInputStream(processEAVMapping(is));
+ }
+
+ /** Build the session factory */
+ protected EntityManagerFactory buildEntityManagerFactory() {
+ final EntityManagerFactory emf = getConfiguration()
+ .buildEntityManagerFactory();
+ return new WrappedEntityManagerFactory(emf);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbDataStore#close()
+ */
+ @Override
+ public void close() {
+ if (isInitialized()) {
+ if (getEntityManagerFactory().isOpen()) {
+ getEntityManagerFactory().close();
+ }
+ entityManagerFactory = null;
+ setInitialized(false);
+ // this will call the close method again but because the
+ // datastore
+ // is not initialized anymore it won't get here
+ HbHelper.INSTANCE.deRegisterDataStore(this);
+ }
+ ejb3Configuration = null;
+ }
+
+ /**
+ * Note: returns an instance of the {@link WrappedEntityManagerFactory}
+ * class.
+ */
+ public EntityManagerFactory getEntityManagerFactory() {
+ if (!isInitialized()) {
+ initialize();
+ }
+ assert (entityManagerFactory != null);
+ return entityManagerFactory;
+ }
+
+ /** Return a new session wrapper */
+ @Override
+ public SessionWrapper createSessionWrapper() {
+ return new HbEntityManagerWrapper(this);
+ }
+
+ /**
+ * @return the ejbConfiguration
+ */
+ public Ejb3Configuration getConfiguration() {
+ if (ejb3Configuration == null) {
+ ejb3Configuration = createConfiguration();
+ }
+ return ejb3Configuration;
+ }
+
+ public void setConfiguration(Ejb3Configuration configuration) {
+ ejb3Configuration = configuration;
+ }
+
+ /**
+ * @return the hbConfiguration
+ */
+ @Override
+ public Configuration getHibernateConfiguration() {
+ return getConfiguration().getHibernateConfiguration();
+ }
+
+ /** Return the Classmappings as an iterator */
+ @Override
+ public Iterator<?> getClassMappings() {
+ return getConfiguration().getClassMappings();
+ }
+
+ /** Is added for interface compliance with HbDataStore, should not be used */
+ @Override
+ public SessionFactory getSessionFactory() {
+ final EntityManagerFactoryImpl entityManagerFactoryImpl;
+ if (getEntityManagerFactory() instanceof WrappedEntityManagerFactory) {
+ entityManagerFactoryImpl = (EntityManagerFactoryImpl) ((WrappedEntityManagerFactory) getEntityManagerFactory())
+ .getDelegate();
+ } else {
+ entityManagerFactoryImpl = (EntityManagerFactoryImpl) getEntityManagerFactory();
+ }
+ return entityManagerFactoryImpl.getSessionFactory();
+ }
+
+ /**
+ * Note: returns the {@link WrappedEntityManager} class.
+ */
+ public EntityManager createEntityManager() {
+ return getEntityManagerFactory().createEntityManager();
+ }
+
+ /**
+ * Note: returns the {@link WrappedEntityManager} class.
+ */
+ @SuppressWarnings("rawtypes")
+ public EntityManager createEntityManager(Map arg0) {
+ return getEntityManagerFactory().createEntityManager(arg0);
+ }
+
+ public boolean isOpen() {
+ return getEntityManagerFactory().isOpen();
+ }
+
+ public Cache getCache() {
+ return getEntityManagerFactory().getCache();
+ }
+
+ public CriteriaBuilder getCriteriaBuilder() {
+ return getEntityManagerFactory().getCriteriaBuilder();
+ }
+
+ public Metamodel getMetamodel() {
+ return getEntityManagerFactory().getMetamodel();
+ }
+
+ public PersistenceUnitUtil getPersistenceUnitUtil() {
+ return getEntityManagerFactory().getPersistenceUnitUtil();
+ }
+
+ public Map<String, Object> getProperties() {
+ return getEntityManagerFactory().getProperties();
+ }
+
+ /**
+ * The HbEntityDataStore uses a wrapped entity manager factory and wrapped
+ * entity manager to work around an issue that the Hibernate entity manager/
+ * query implementation does not resolve query parameters of the EntityType
+ * correctly. It determines a wrong type. See the statement about this in
+ * the javadoc of the Hibernate {@link EntityType#getReturnedClass()}
+ * method.
+ *
+ * To get to the original Hibernate entity manager use the
+ * {@link WrappedEntityManagerFactory#getDelegate()} method.
+ *
+ * @author mtaal
+ */
+ public class WrappedEntityManagerFactory implements EntityManagerFactory {
+ private EntityManagerFactory delegate;
+
+ public WrappedEntityManagerFactory(EntityManagerFactory emf) {
+ delegate = emf;
+ }
+
+ public EntityManagerFactory getDelegate() {
+ return delegate;
+ }
+
+ public void setDelegate(EntityManagerFactory delegate) {
+ this.delegate = delegate;
+ }
+
+ public void close() {
+ delegate.close();
+ }
+
+ public EntityManager createEntityManager() {
+ EntityManager em = delegate.createEntityManager();
+ return new WrappedEntityManager(em);
+ }
+
+ public EntityManager createEntityManager(
+ @SuppressWarnings("rawtypes") Map map) {
+ EntityManager em = delegate.createEntityManager(map);
+ return new WrappedEntityManager(em);
+ }
+
+ public Cache getCache() {
+ return delegate.getCache();
+ }
+
+ public CriteriaBuilder getCriteriaBuilder() {
+ return delegate.getCriteriaBuilder();
+ }
+
+ public Metamodel getMetamodel() {
+ return delegate.getMetamodel();
+ }
+
+ public PersistenceUnitUtil getPersistenceUnitUtil() {
+ return delegate.getPersistenceUnitUtil();
+ }
+
+ public Map<String, Object> getProperties() {
+ return delegate.getProperties();
+ }
+
+ public boolean isOpen() {
+ return delegate.isOpen();
+ }
+ }
+
+ /**
+ * See {@link WrappedEntityManagerFactory} for a description why this class
+ * is needed.
+ *
+ * To get to the original Hibernate entity manager use the
+ * {@link WrappedEntityManager#getDelegateEntityManager()} method.
+ *
+ * @author mtaal
+ *
+ */
+ public class WrappedEntityManager implements EntityManager {
+ private EntityManager delegateEntityManager;
+
+ public WrappedEntityManager(EntityManager em) {
+ delegateEntityManager = em;
+ }
+
+ public void clear() {
+ delegateEntityManager.clear();
+ }
+
+ public void close() {
+ delegateEntityManager.close();
+ }
+
+ public boolean contains(Object arg0) {
+ return delegateEntityManager.contains(arg0);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> TypedQuery<T> createNamedQuery(String arg0, Class<T> arg1) {
+ return (TypedQuery<T>) HbEntityDataStore.this
+ .repairParameterJavaType((QueryImpl<?>) delegateEntityManager
+ .createNamedQuery(arg0, arg1));
+ }
+
+ public Query createNamedQuery(String arg0) {
+ return (Query) HbEntityDataStore.this
+ .repairParameterJavaType((QueryImpl<?>) delegateEntityManager
+ .createNamedQuery(arg0));
+ }
+
+ public Query createNativeQuery(String arg0,
+ @SuppressWarnings("rawtypes") Class arg1) {
+ return (Query) HbEntityDataStore.this
+ .repairParameterJavaType((QueryImpl<?>) delegateEntityManager
+ .createNativeQuery(arg0, arg1));
+ }
+
+ public Query createNativeQuery(String arg0, String arg1) {
+ return (Query) HbEntityDataStore.this
+ .repairParameterJavaType((QueryImpl<?>) delegateEntityManager
+ .createNativeQuery(arg0, arg1));
+ }
+
+ public Query createNativeQuery(String arg0) {
+ return (Query) HbEntityDataStore.this
+ .repairParameterJavaType((QueryImpl<?>) delegateEntityManager
+ .createNativeQuery(arg0));
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> TypedQuery<T> createQuery(CriteriaQuery<T> arg0) {
+ return (TypedQuery<T>) HbEntityDataStore.this
+ .repairParameterJavaType((QueryImpl<?>) delegateEntityManager
+ .createQuery(arg0));
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> TypedQuery<T> createQuery(String arg0, Class<T> arg1) {
+ return (TypedQuery<T>) HbEntityDataStore.this
+ .repairParameterJavaType((QueryImpl<?>) delegateEntityManager
+ .createQuery(arg0, arg1));
+ }
+
+ public Query createQuery(String arg0) {
+ return (Query) HbEntityDataStore.this
+ .repairParameterJavaType((QueryImpl<?>) delegateEntityManager
+ .createQuery(arg0));
+ }
+
+ public void detach(Object arg0) {
+ delegateEntityManager.detach(arg0);
+ }
+
+ public <T> T find(Class<T> arg0, Object arg1, LockModeType arg2,
+ Map<String, Object> arg3) {
+ return delegateEntityManager.find(arg0, arg1, arg2, arg3);
+ }
+
+ public <T> T find(Class<T> arg0, Object arg1, LockModeType arg2) {
+ return delegateEntityManager.find(arg0, arg1, arg2);
+ }
+
+ public <T> T find(Class<T> arg0, Object arg1, Map<String, Object> arg2) {
+ return delegateEntityManager.find(arg0, arg1, arg2);
+ }
+
+ public <T> T find(Class<T> arg0, Object arg1) {
+ return delegateEntityManager.find(arg0, arg1);
+ }
+
+ public void flush() {
+ delegateEntityManager.flush();
+ }
+
+ public CriteriaBuilder getCriteriaBuilder() {
+ return delegateEntityManager.getCriteriaBuilder();
+ }
+
+ public Object getDelegate() {
+ return delegateEntityManager.getDelegate();
+ }
+
+ public EntityManagerFactory getEntityManagerFactory() {
+ return delegateEntityManager.getEntityManagerFactory();
+ }
+
+ public FlushModeType getFlushMode() {
+ return delegateEntityManager.getFlushMode();
+ }
+
+ public LockModeType getLockMode(Object arg0) {
+ return delegateEntityManager.getLockMode(arg0);
+ }
+
+ public Metamodel getMetamodel() {
+ return delegateEntityManager.getMetamodel();
+ }
+
+ public Map<String, Object> getProperties() {
+ return delegateEntityManager.getProperties();
+ }
+
+ public <T> T getReference(Class<T> arg0, Object arg1) {
+ return delegateEntityManager.getReference(arg0, arg1);
+ }
+
+ public EntityTransaction getTransaction() {
+ return delegateEntityManager.getTransaction();
+ }
+
+ public boolean isOpen() {
+ return delegateEntityManager.isOpen();
+ }
+
+ public void joinTransaction() {
+ delegateEntityManager.joinTransaction();
+ }
+
+ public void lock(Object arg0, LockModeType arg1,
+ Map<String, Object> arg2) {
+ delegateEntityManager.lock(arg0, arg1, arg2);
+ }
+
+ public void lock(Object arg0, LockModeType arg1) {
+ delegateEntityManager.lock(arg0, arg1);
+ }
+
+ public <T> T merge(T arg0) {
+ return delegateEntityManager.merge(arg0);
+ }
+
+ public void persist(Object arg0) {
+ delegateEntityManager.persist(arg0);
+ }
+
+ public void refresh(Object arg0, LockModeType arg1,
+ Map<String, Object> arg2) {
+ delegateEntityManager.refresh(arg0, arg1, arg2);
+ }
+
+ public void refresh(Object arg0, LockModeType arg1) {
+ delegateEntityManager.refresh(arg0, arg1);
+ }
+
+ public void refresh(Object arg0, Map<String, Object> arg1) {
+ delegateEntityManager.refresh(arg0, arg1);
+ }
+
+ public void refresh(Object arg0) {
+ delegateEntityManager.refresh(arg0);
+ }
+
+ public void remove(Object arg0) {
+ delegateEntityManager.remove(arg0);
+ }
+
+ public void setFlushMode(FlushModeType arg0) {
+ delegateEntityManager.setFlushMode(arg0);
+ }
+
+ public void setProperty(String arg0, Object arg1) {
+ delegateEntityManager.setProperty(arg0, arg1);
+ }
+
+ public <T> T unwrap(Class<T> arg0) {
+ return delegateEntityManager.unwrap(arg0);
+ }
+
+ public EntityManager getDelegateEntityManager() {
+ return delegateEntityManager;
+ }
+
+ public void setDelegateEntityManager(EntityManager delegateEntityManager) {
+ this.delegateEntityManager = delegateEntityManager;
+ }
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ protected QueryImpl<?> repairParameterJavaType(QueryImpl<?> query) {
+ try {
+ final Set<Parameter<?>> repairedParameters = new HashSet<Parameter<?>>();
+ final Object parametersObject = getQueryParametersField()
+ .get(query);
+ final AbstractQueryImpl queryImpl = AbstractQueryImpl.class
+ .cast(query.getHibernateQuery());
+ for (Parameter<?> parameter : (Collection<Parameter>) parametersObject) {
+ if (Map.class == parameter.getParameterType()) {
+ final Type type;
+ if (parameter.getName() != null) {
+ // repair these ones
+ final NamedParameterDescriptor descriptor = queryImpl
+ .getParameterMetadata()
+ .getNamedParameterDescriptor(
+ parameter.getName());
+ type = descriptor.getExpectedType();
+ } else {
+ type = queryImpl.getParameterMetadata()
+ .getOrdinalParameterExpectedType(
+ parameter.getPosition());
+ }
+ if (type instanceof EntityType) {
+ final Parameter<?> param = new ParameterImpl(
+ parameter.getName(), parameter.getPosition(),
+ Object.class);
+ repairedParameters.add(param);
+ // final EntityType entityType = (EntityType) type;
+ // final String entityName = entityType
+ // .getAssociatedEntityName();
+ // final EClass eClass = HbEntityDataStore.this
+ // .getEntityNameStrategy().toEClass(entityName);
+
+ } else {
+ repairedParameters.add(parameter);
+ }
+ } else {
+ repairedParameters.add(parameter);
+ }
+ }
+ getQueryParametersField().set(query, repairedParameters);
+ return query;
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ protected Field getQueryParametersField() throws Exception {
+ if (queryParametersField != null) {
+ return queryParametersField;
+ }
+ Field field = QueryImpl.class.getDeclaredField("parameters");
+ field.setAccessible(true);
+ return field;
+ }
+
+ @SuppressWarnings("rawtypes")
+ private static class ParameterImpl implements Parameter {
+ private String name;
+ private Integer position;
+ private Class<?> javaClass;
+
+ ParameterImpl(String name, Integer position, Class<?> clz) {
+ this.name = name;
+ this.position = position;
+ this.javaClass = clz;
+ }
+
+ public Class<?> getParameterType() {
+ return javaClass;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Integer getPosition() {
+ return position;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbEntityManagerWrapper.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbEntityManagerWrapper.java
new file mode 100755
index 000000000..382402816
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbEntityManagerWrapper.java
@@ -0,0 +1,272 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * Benjamin Cabe
+ * </copyright>
+ *
+ * $Id: HbEntityManagerWrapper.java,v 1.16 2010/11/12 13:35:37 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+import javax.persistence.FlushModeType;
+import javax.persistence.Query;
+
+import org.eclipse.emf.teneo.annotations.pannotation.InheritanceType;
+import org.hibernate.Session;
+import org.hibernate.engine.ForeignKeys;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.mapping.JoinedSubclass;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.SingleTableSubclass;
+import org.hibernate.mapping.UnionSubclass;
+
+/**
+ * Wraps a hibernate entity manager.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.16 $
+ */
+public class HbEntityManagerWrapper implements SessionWrapper {
+
+ /** The hibernate session */
+ private EntityManager entityManager = null;
+
+ /** The datastore which created me */
+ private final HbEntityDataStore hbEntityDataStore;
+
+ /** The current transaction */
+ private EntityTransaction entityTransaction = null;
+
+ private FlushModeType flushMode = null;
+
+ /** Constructor */
+ public HbEntityManagerWrapper(HbEntityDataStore hbEntityDataStore) {
+ this.hbEntityDataStore = hbEntityDataStore;
+ }
+
+ /** Set the session in the constructor */
+ public HbEntityManagerWrapper(HbEntityDataStore hbEntityDataStore,
+ EntityManager entityManager) {
+ this.hbEntityDataStore = hbEntityDataStore;
+ this.entityManager = entityManager;
+ }
+
+ /**
+ * Return the session or entityManager, return is an object to support both
+ * session as well as entitymanager.
+ */
+ public Object getClassicSession() {
+ if (entityManager == null) {
+ entityManager = hbEntityDataStore.getEntityManagerFactory()
+ .createEntityManager();
+ }
+ return entityManager;
+ }
+
+ /**
+ * Return the session or entityManager, return is an object to support both
+ * session as well as entitymanager.
+ */
+ public Object getSession() {
+ if (entityManager == null) {
+ entityManager = hbEntityDataStore.getEntityManagerFactory()
+ .createEntityManager();
+ }
+ return entityManager;
+ }
+
+ /** Convenience which casts */
+ public EntityManager getEntityManager() {
+ return (EntityManager) getSession();
+ }
+
+ /** Begin a transaction */
+ public void beginTransaction() {
+ assert (entityTransaction == null);
+ entityTransaction = getEntityManager().getTransaction();
+ entityTransaction.begin();
+ }
+
+ /** Commit a transaction */
+ public void commitTransaction() {
+ if (entityTransaction == null) {
+ throw new IllegalStateException(
+ "EntityTransaction is null, call begin before commit!");
+ }
+ entityTransaction.commit();
+ entityTransaction = null;
+ }
+
+ /** Rollback transaction */
+ public void rollbackTransaction() {
+ if (entityTransaction == null) {
+ throw new IllegalStateException(
+ "EntityTransaction is null, call begin before commit!");
+ }
+ entityTransaction.rollback();
+ entityTransaction = null;
+ }
+
+ /** Return an object using the entityname and a serializable id */
+ public Object get(String entityName, Serializable id) {
+ return ((Session) getEntityManager().getDelegate()).get(entityName, id);
+ }
+
+ /** Query */
+ public List<?> executeQuery(String qry) {
+ final Query query = getEntityManager().createQuery(qry);
+ return query.getResultList();
+ }
+
+ /** Query */
+ public List<?> executeQuery(String qry, boolean cacheable) {
+ final Query query = getEntityManager().createQuery(qry);
+ // todo: cacheable in ejb3?
+ // query.setCacheable(cacheable);
+ return query.getResultList();
+ }
+
+ /** Query */
+ public List<?> executeQuery(String qry, String entityParameter,
+ Object entity) {
+ final Query query = getEntityManager().createQuery(qry);
+ query.setParameter(entityParameter, entity);
+ return query.getResultList();
+ }
+
+ /** Query */
+ public List<?> executeQuery(String qry, List<Object> parameters) {
+ final Query query = getEntityManager().createQuery(qry);
+ int pos = 1;
+ for (Object obj : parameters) {
+ query.setParameter(pos++, obj);
+ }
+ return query.getResultList();
+ }
+
+ /** Query with named parameters */
+ public List<?> executeQuery(String qry, Map<String, Object> namedParameters) {
+ final Query query = getEntityManager().createQuery(qry);
+ for (Map.Entry<String, Object> entry : namedParameters.entrySet()) {
+ query.setParameter(entry.getKey(), entry.getValue());
+ }
+ return query.getResultList();
+ }
+
+ /** Does this impl. wrap an entitymanager */
+ public boolean isEJB3EntityManager() {
+ return true;
+ }
+
+ public void restorePreviousFlushMode() {
+ if (flushMode != null) {
+ getEntityManager().setFlushMode(flushMode);
+ flushMode = null;
+ }
+ }
+
+ /** Set the flushmode */
+ public void setFlushModeManual() {
+ flushMode = getEntityManager().getFlushMode();
+ getEntityManager().setFlushMode(FlushModeType.COMMIT);
+ }
+
+ /** Close the underlying session */
+ public void close() {
+ getEntityManager().close();
+ }
+
+ /** Save or update the pass object */
+ public void saveOrUpdate(Object obj) {
+ final Session session = (Session) getEntityManager().getDelegate();
+ final String entityName = hbEntityDataStore.getInterceptor()
+ .getEntityName(obj);
+ if (((SessionImplementor) session).getPersistenceContext().isEntryFor(
+ obj)) {
+ getEntityManager().persist(obj);
+ } else if (ForeignKeys.isNotTransient(entityName, obj, false,
+ (SessionImplementor) session)
+ || !ForeignKeys.isTransient(entityName, obj, false,
+ (SessionImplementor) session)) {
+ // this is a trick because ejb3 does not support saveOrUpdate (why
+ // did they not add
+ // this behavior!)
+ session.saveOrUpdate(obj);
+ } else {
+ getEntityManager().persist(obj);
+ }
+ }
+
+ /** Delete the object */
+ public void delete(Object obj) {
+ getEntityManager().remove(obj);
+ }
+
+ /** Flush the session */
+ public void flush() {
+ getEntityManager().flush();
+ }
+
+ /** Is transaction active */
+ public boolean isTransactionActive() {
+ return entityTransaction != null && entityTransaction.isActive();
+ }
+
+ /** Refresh the object */
+ public void refresh(Object obj) {
+ getEntityManager().refresh(obj);
+ }
+
+ /** Check if a certain class is mapped using a certain inheritance strategy */
+ public boolean isInheritanceStrategy(Class<?> cls, InheritanceType strategy) {
+ final String name = cls.getName();
+ final String realName = name.substring(name.lastIndexOf('.') + 1,
+ name.length() - 4);
+ final PersistentClass cmd = hbEntityDataStore.getConfiguration()
+ .getClassMapping(realName);
+ if (strategy.equals(InheritanceType.SINGLE_TABLE)) {
+ return cmd instanceof SingleTableSubclass;
+ }
+ if (strategy.equals(InheritanceType.JOINED)) {
+ return cmd instanceof JoinedSubclass;
+ }
+ if (strategy.equals(InheritanceType.TABLE_PER_CLASS)) {
+ return cmd instanceof UnionSubclass;
+ }
+ throw new HbStoreException("Strategy: " + strategy.toString()
+ + " not supported ");
+ }
+
+ /** Clear the session */
+ public void clear() {
+ getEntityManager().clear();
+ }
+
+ /** Merge with the datastore */
+ public Object merge(Object obj) {
+ return getEntityManager().merge(obj);
+ }
+
+ public void persist(Object obj) {
+ getEntityManager().persist(obj);
+ }
+
+ public Session getHibernateSession() {
+ return (Session) getEntityManager().getDelegate();
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbHelper.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbHelper.java
new file mode 100755
index 000000000..5b7119ef7
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbHelper.java
@@ -0,0 +1,211 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HbHelper.java,v 1.19 2010/04/02 22:28:53 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.teneo.PersistenceOptions;
+import org.eclipse.emf.teneo.annotations.mapper.PersistenceMappingBuilder;
+import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedModel;
+import org.eclipse.emf.teneo.extension.ExtensionManager;
+import org.eclipse.emf.teneo.extension.ExtensionManagerFactory;
+import org.eclipse.emf.teneo.hibernate.mapper.HibernateMappingGenerator;
+import org.eclipse.emf.teneo.hibernate.mapper.MappingUtil;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.PersistentClass;
+
+/**
+ * Is the main entry point for 'outside' users to create, register and retrieve EMF Data stores.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.19 $
+ */
+public class HbHelper {
+ /** The logger */
+ private static Log log = LogFactory.getLog(HbHelper.class);
+
+ /** The singleton instance of this class */
+ public static final HbHelper INSTANCE = new HbHelper();
+
+ /** The list of EMF Datastores mapped by name */
+ private final Hashtable<String, HbDataStore> emfDataStores = new Hashtable<String, HbDataStore>();
+
+ /** The list of emf datastores mapped by hibernate persistent class */
+ private final Hashtable<Object, HbDataStore> dataStoreByPersistentClass = new Hashtable<Object, HbDataStore>();
+
+ /** The registered emf data store factory */
+ private static HbDataStoreFactory emfDataStoreFactory = new HbDataStoreFactory() {
+ public HbDataStore createHbDataStore() {
+ return new HbSessionDataStore();
+ }
+ };
+
+ /**
+ * @param emfDataStoreFactory
+ * the emfDataStoreFactory to set
+ */
+ public static void setHbDataStoreFactory(HbDataStoreFactory hbDataStoreFactory) {
+ HbHelper.emfDataStoreFactory = hbDataStoreFactory;
+ }
+
+ /** Put a datastore in the dataStoreByPersistentClass */
+ void registerDataStoreByPC(HbDataStore ds) {
+ for (Iterator<?> it = ds.getClassMappings(); it.hasNext();) {
+ final PersistentClass pc = (PersistentClass) it.next();
+ if (dataStoreByPersistentClass.get(pc) != null) {
+ throw new HbMapperException("There is already a datastore registered for this pc: "
+ + pc.getEntityName() + (dataStoreByPersistentClass.get(pc)).getName() + "/" + ds.getName());
+ }
+ log.debug("Datastore: " + ds.getName() + " registered for pc: " + pc.getEntityName());
+ dataStoreByPersistentClass.put(pc, ds);
+ }
+ }
+
+ /** Register the datastore also for the components */
+ void registerDataStoreByComponent(HbDataStore ds, Component component) {
+ log.debug("Datastore: " + ds.getName() + " registered for component: " + component.getComponentClassName());
+ dataStoreByPersistentClass.put(component, ds);
+ }
+
+ /** Return the datastore on the basis of the pc */
+ public HbDataStore getDataStore(PersistentClass pc) {
+ final HbDataStore ds = dataStoreByPersistentClass.get(pc);
+ if (ds == null) {
+ throw new HbMapperException("No datastore for pc " + pc.getEntityName());
+ }
+ return ds;
+ }
+
+ /** Return the datastore on the basis of the component */
+ public HbDataStore getDataStore(Component component) {
+ final HbDataStore ds = dataStoreByPersistentClass.get(component);
+ if (ds == null) {
+ throw new HbMapperException("No datastore for pc " + component.getComponentClassName());
+ }
+ return ds;
+ }
+
+ /** Clears the list of session factories */
+ public synchronized void closeAll() {
+ final List<HbDataStore> dataStores = new ArrayList<HbDataStore>(emfDataStores.values());
+ for (HbDataStore emfds : dataStores) {
+ emfds.close();
+ }
+ emfDataStores.clear();
+ dataStoreByPersistentClass.clear();
+ }
+
+ /** Deregisters a session factory from the registry */
+ public synchronized void deRegisterDataStore(String name) {
+ if (name == null) {
+ throw new HbMapperException("An unique name should be specified when deregistering a session factory");
+ }
+ final HbDataStore emfds = emfDataStores.get(name);
+ if (emfds == null) {
+ return;
+ }
+ deRegisterDataStore(emfds);
+ }
+
+ /** Deregisters a datastore from the registry */
+ public synchronized void deRegisterDataStore(HbDataStore emfds) {
+ // changed for bugzilla 281036
+ final List<Object> toRemove = new ArrayList<Object>();
+ for (Object key : dataStoreByPersistentClass.keySet()) {
+ if (emfds == dataStoreByPersistentClass.get(key)) {
+ toRemove.add(key);
+ }
+ }
+ for (Object key : toRemove) {
+ dataStoreByPersistentClass.remove(key);
+ }
+ if (emfds.getName() != null) {
+ emfDataStores.remove(emfds.getName());
+ }
+ if (emfds.isInitialized()) {
+ emfds.close();
+ }
+ }
+
+ /**
+ * Creates and register a HibernateEMFDataStore, initialization has to be done by the caller
+ */
+ public synchronized HbDataStore createRegisterDataStore(String name) {
+ HbDataStore emfds = emfDataStores.get(name);
+ if (emfds != null) {
+ log.warn("EMF Data Store already registered under name: " + name + ", returning it");
+ return emfds;
+ }
+
+ log.info("Creating emf data store and registering it under name: " + name);
+ emfds = emfDataStoreFactory.createHbDataStore();
+ emfds.setName(name);
+ // next call is done automatically
+ // emfDataStores.put(name, emfds);
+ log.info("Returning created emf data store, initialize this newly created data store!");
+ return emfds;
+ }
+
+ /** Register a datastore */
+ public void register(HbDataStore hbDataStore) {
+ emfDataStores.put(hbDataStore.getName(), hbDataStore);
+ }
+
+ /** Return a emf data store */
+ public HbDataStore getDataStore(String name) {
+ final HbDataStore hds = emfDataStores.get(name);
+ if (hds == null) {
+ log.debug("No datastore found using " + name);
+ }
+ return hds;
+ }
+
+ /**
+ * Separate utility method, generates a hibernate mapping for a set of epackages and options. The hibernate.hbm.xml
+ * is returned as a string. The mapping is not registered or used in any other way by Elver.
+ */
+ public String generateMapping(EPackage[] epackages, Properties props) {
+ return generateMapping(epackages, props, ExtensionManagerFactory.getInstance().create());
+ }
+
+ /**
+ * Separate utility method, generates a hibernate mapping for a set of epackages and options. The hibernate.hbm.xml
+ * is returned as a string. The mapping is not registered or used in any other way by Elver.
+ */
+ public String generateMapping(EPackage[] epackages, Properties props, ExtensionManager extensionManager) {
+ MappingUtil.registerHbExtensions(extensionManager);
+
+ log.debug("Generating mapping file passed epackages");
+ // DCB: Use Hibernate-specific annotation processing mechanism. This
+ // allows use of
+ // Hibernate-specific annotations.
+ final PersistenceOptions po = extensionManager.getExtension(PersistenceOptions.class, new Object[] { props });
+ final PAnnotatedModel paModel = extensionManager.getExtension(PersistenceMappingBuilder.class).buildMapping(
+ epackages, po, extensionManager);
+ final HibernateMappingGenerator hmg = extensionManager.getExtension(HibernateMappingGenerator.class);
+ hmg.setPersistenceOptions(po);
+
+ return hmg.generateToString(paModel);
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbMapperException.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbMapperException.java
new file mode 100755
index 000000000..4e0f02964
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbMapperException.java
@@ -0,0 +1,46 @@
+/**
+ * <copyright> Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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: Martin Taal </copyright> $Id:
+ * HbMapperException.java,v 1.2 2007/02/01 12:35:55 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import org.eclipse.emf.teneo.TeneoException;
+
+/**
+ * Local Runtime Exception which logs.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.1 $
+ */
+
+public class HbMapperException extends TeneoException {
+ /**
+ * Serializable id
+ */
+ private static final long serialVersionUID = 7433341056815136417L;
+
+ /**
+ * The constructor, logs the exception also
+ */
+ public HbMapperException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+
+ /**
+ * The constructor, logs the exception also
+ */
+ public HbMapperException(Throwable cause) {
+ this(cause.getMessage(), cause);
+ }
+
+ /**
+ * The constructor, logs the exception also
+ */
+ public HbMapperException(String msg) {
+ super(msg);
+ }
+}
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbSessionDataStore.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbSessionDataStore.java
new file mode 100755
index 000000000..2a5ce35fa
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbSessionDataStore.java
@@ -0,0 +1,274 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HbSessionDataStore.java,v 1.32 2011/07/05 05:09:41 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.teneo.PackageRegistryProvider;
+import org.eclipse.emf.teneo.annotations.mapper.PersistenceFileProvider;
+import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEClass;
+import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEPackage;
+import org.eclipse.emf.teneo.hibernate.mapper.MappingUtil;
+import org.eclipse.emf.teneo.hibernate.mapping.EMFInitializeCollectionEventListener;
+import org.eclipse.emf.teneo.hibernate.mapping.eav.EAVGenericIDUserType;
+import org.hibernate.Cache;
+import org.hibernate.Interceptor;
+import org.hibernate.TypeHelper;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.event.InitializeCollectionEventListener;
+
+/**
+ * Holds the SessionFactory and performs different initialization related
+ * actions. Initializes the database and offers xml import and export methods.
+ * In addition can be used to retrieve all referers to a certain eobject.
+ * <p>
+ * The behavior can be overridden by overriding the protected methods and
+ * implementing/registering your own HbDataStoreFactory in the HibernateHelper.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.32 $
+ */
+
+@SuppressWarnings("unchecked")
+public class HbSessionDataStore extends HbBaseSessionDataStore {
+
+ private static final long serialVersionUID = 1L;
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(HbSessionDataStore.class);
+
+ /** The used Hibernate configuration */
+ private Configuration hbConfiguration;
+
+ @Override
+ public void close() {
+ super.close();
+ hbConfiguration = null;
+ }
+
+ /** Initializes this Data Store */
+ @Override
+ public void initialize() {
+
+ if (hbConfiguration != null && isResetConfigurationOnInitialization()) {
+ hbConfiguration = null;
+ }
+
+ MappingUtil.registerHbExtensions(getExtensionManager());
+
+ PackageRegistryProvider.getInstance().setThreadPackageRegistry(
+ getPackageRegistry());
+
+ try {
+ log.debug("Initializing Hb Session DataStore");
+
+ // check a few things
+ if (getEPackages() == null) {
+ throw new HbMapperException("EPackages are not set");
+ // if (getName() == null)
+ // throw new HbStoreException("Name is not set");
+ }
+
+ // reset interceptor
+ setInterceptor(null);
+
+ log.debug(">>>>> Creating HB Configuration");
+
+ getConfiguration();
+
+ mapModel();
+
+ setPropertiesInConfiguration();
+
+ initializeDataStore();
+
+ // will close the current sessionfactory if it was set
+ closeSessionFactory();
+
+ buildSessionFactory();
+
+ setInitialized(true);
+ } finally {
+ PackageRegistryProvider.getInstance()
+ .setThreadPackageRegistry(null);
+ }
+ }
+
+ /** Set the event listener, can be overridden */
+ @Override
+ protected void setEventListeners() {
+ final EMFInitializeCollectionEventListener initializeCollectionEventListener = getExtensionManager()
+ .getExtension(EMFInitializeCollectionEventListener.class);
+ getConfiguration()
+ .getEventListeners()
+ .setInitializeCollectionEventListeners(
+ new InitializeCollectionEventListener[] { initializeCollectionEventListener });
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.hibernate.HbContext#createConfiguration()
+ */
+ protected Configuration createConfiguration() {
+ return new Configuration();
+ }
+
+ /** Return the Classmappings as an iterator */
+ @Override
+ public Iterator<?> getClassMappings() {
+ return getConfiguration().getClassMappings();
+ }
+
+ /** Build the mappings in the configuration */
+ @Override
+ protected void buildMappings() {
+ getConfiguration().buildMappings();
+ }
+
+ /** Sets the interceptor */
+ @Override
+ protected void setInterceptor() {
+ if (getInterceptor() != null) { // probably overridden
+ return;
+ }
+ final Interceptor interceptor = getHbContext().createInterceptor(
+ getHibernateConfiguration(), getEntityNameStrategy());
+ getConfiguration().setInterceptor(interceptor);
+ setInterceptor(interceptor);
+ }
+
+ /** Sets the properties in the Hibernate Configuration. */
+ protected void setPropertiesInConfiguration() {
+ Properties properties = getDataStoreProperties();
+ if (properties != null) {
+ setDefaultProperties(properties);
+ getConfiguration().addProperties(properties);
+ }
+ }
+
+ /**
+ * Maps an ecore model of one ore more epackages into a hibernate xml String
+ * which is added to the passed configuration
+ */
+ protected void mapModel() {
+
+ if (getPersistenceOptions().getMappingFilePath() != null
+ || getPersistenceOptions().isUseMappingFile()) {
+ final String[] fileList = getMappingFileList();
+ for (String element : fileList) {
+ log.debug("Adding file " + element
+ + " to Hibernate Configuration");
+ final PersistenceFileProvider pfp = getExtensionManager()
+ .getExtension(PersistenceFileProvider.class);
+ final InputStream is = pfp.getFileContent(this.getClass(),
+ element);
+ if (is == null) {
+ throw new HbStoreException("Path to mapping file: "
+ + element + " does not exist!");
+ }
+ getConfiguration().addInputStream(is);
+ }
+ } else {
+ setMappingXML(mapEPackages());
+
+ boolean hasEAVMapping = false;
+ for (PAnnotatedEPackage aPackage : getPaModel().getPaEPackages()) {
+ for (PAnnotatedEClass aClass : aPackage.getPaEClasses()) {
+ if (aClass.getEavMapping() != null) {
+ hasEAVMapping = true;
+ break;
+ }
+ }
+ }
+ if (hasEAVMapping) {
+ try {
+ if (getPersistenceOptions().getEAVMappingFile() != null) {
+ final PersistenceFileProvider pfp = getExtensionManager()
+ .getExtension(PersistenceFileProvider.class);
+ final InputStream is = pfp.getFileContent(this
+ .getClass(), getPersistenceOptions()
+ .getEAVMappingFile());
+ getConfiguration().addXML(processEAVMapping(is));
+ is.close();
+ } else {
+ final PersistenceFileProvider pfp = getExtensionManager()
+ .getExtension(PersistenceFileProvider.class);
+ final InputStream is = pfp.getFileContent(
+ EAVGenericIDUserType.class, "eav.hbm.xml");
+ getConfiguration().addXML(processEAVMapping(is));
+ is.close();
+ }
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ getConfiguration().addXML(getMappingXML());
+ }
+ }
+
+ /** Build the session factory */
+ protected void buildSessionFactory() {
+ setSessionFactory(getConfiguration().buildSessionFactory());
+ }
+
+ /** Return a new session wrapper */
+ @Override
+ public SessionWrapper createSessionWrapper() {
+ return new HbSessionWrapper(this);
+ }
+
+ /**
+ * @return the hbConfiguration
+ */
+ public Configuration getConfiguration() {
+ if (hbConfiguration == null) {
+ hbConfiguration = createConfiguration();
+ }
+ return hbConfiguration;
+ }
+
+ public void setConfiguration(Configuration configuration) {
+ hbConfiguration = configuration;
+ }
+
+ /**
+ * @return the hbConfiguration
+ */
+ @Override
+ public Configuration getHibernateConfiguration() {
+ return getConfiguration();
+ }
+
+ public boolean containsFetchProfileDefinition(String arg0) {
+ return getSessionFactory().containsFetchProfileDefinition(arg0);
+ }
+
+ public Cache getCache() {
+ return getSessionFactory().getCache();
+ }
+
+ public TypeHelper getTypeHelper() {
+ return getSessionFactory().getTypeHelper();
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbSessionWrapper.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbSessionWrapper.java
new file mode 100755
index 000000000..59373dcb7
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbSessionWrapper.java
@@ -0,0 +1,224 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * Benjamin Cabe
+ * </copyright>
+ *
+ * $Id: HbSessionWrapper.java,v 1.12 2010/11/12 09:33:33 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.teneo.annotations.pannotation.InheritanceType;
+import org.hibernate.FlushMode;
+import org.hibernate.LockOptions;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.impl.SessionImpl;
+import org.hibernate.metadata.ClassMetadata;
+import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
+import org.hibernate.persister.entity.SingleTableEntityPersister;
+import org.hibernate.persister.entity.UnionSubclassEntityPersister;
+
+/**
+ * Wraps a standard hibernate session.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.12 $
+ */
+public class HbSessionWrapper implements SessionWrapper {
+
+ /** The hibernate session */
+ private Session session = null;
+
+ /** The datastore which created me */
+ private final HbDataStore hbDataStore;
+
+ private FlushMode flushMode;
+
+ /** Constructor */
+ public HbSessionWrapper(HbDataStore hbDataStore) {
+ this.hbDataStore = hbDataStore;
+ }
+
+ /** Set the session in the constructor */
+ public HbSessionWrapper(HbDataStore hbDataStore, Session session) {
+ this.hbDataStore = hbDataStore;
+ this.session = session;
+ }
+
+ /**
+ * Return the session, return is an object to support both session as well
+ * as entitymanager.
+ */
+ public Object getSession() {
+ if (session == null) {
+ session = hbDataStore.getSessionFactory().openSession();
+ }
+ return session;
+ }
+
+ /** Convenience which casts */
+ private Session getSessionInternal() {
+ return (Session) getSession();
+ }
+
+ /** Begin a transaction */
+ public void beginTransaction() {
+ getSessionInternal().beginTransaction();
+ }
+
+ /** Commit a transaction */
+ public void commitTransaction() {
+ getSessionInternal().getTransaction().commit();
+ }
+
+ /** Rollback transaction */
+ public void rollbackTransaction() {
+ getSessionInternal().getTransaction().rollback();
+ }
+
+ /** Return an object using the entityname and a serializable id */
+ public Object get(String entityName, Serializable id) {
+ return getSessionInternal().get(entityName, id);
+ }
+
+ /** Query */
+ public List<?> executeQuery(String qry) {
+ final Query query = getSessionInternal().createQuery(qry);
+ return query.list();
+ }
+
+ /** Query */
+ public List<?> executeQuery(String qry, String entityParameter,
+ Object entity) {
+ final Query query = getSessionInternal().createQuery(qry);
+ query.setEntity(entityParameter, entity);
+ return query.list();
+ }
+
+ /** Query */
+ public List<?> executeQuery(String qry, List<Object> parameters) {
+ final Query query = getSessionInternal().createQuery(qry);
+ int pos = 0;
+ for (Object obj : parameters) {
+ query.setParameter(pos++, obj);
+ }
+ return query.list();
+ }
+
+ /** Query */
+ public List<?> executeQuery(String qry, boolean cacheable) {
+ final Query query = getSessionInternal().createQuery(qry);
+ query.setCacheable(cacheable);
+ return query.list();
+ }
+
+ /** Query with named parameters */
+ public List<?> executeQuery(String qry, Map<String, Object> namedParameters) {
+ final Query query = getSessionInternal().createQuery(qry);
+ for (Map.Entry<String, Object> entry : namedParameters.entrySet()) {
+ query.setParameter(entry.getKey(), entry.getValue());
+ }
+ return query.list();
+ }
+
+ /** Does this impl. wrap an entitymanager */
+ public boolean isEJB3EntityManager() {
+ return false;
+ }
+
+ public void restorePreviousFlushMode() {
+ if (flushMode != null) {
+ getSessionInternal().setFlushMode(flushMode);
+ flushMode = null;
+ }
+ }
+
+ /** Set the flushmode */
+ public void setFlushModeManual() {
+ flushMode = getSessionInternal().getFlushMode();
+ getSessionInternal().setFlushMode(FlushMode.MANUAL);
+ }
+
+ /** Close the underlying session */
+ public void close() {
+ getSessionInternal().close();
+ }
+
+ /** Save or update the pass object */
+ public void saveOrUpdate(Object obj) {
+ getSessionInternal().saveOrUpdate(obj);
+ }
+
+ /** Delete the object */
+ public void delete(Object obj) {
+ getSessionInternal().delete(obj);
+ }
+
+ /** Flush the session */
+ public void flush() {
+ getSessionInternal().flush();
+ }
+
+ /** Is transaction active */
+ public boolean isTransactionActive() {
+ return ((SessionImpl) getSessionInternal()).isTransactionInProgress();
+ }
+
+ /** Refresh the object */
+ public void refresh(Object obj) {
+ getSessionInternal().refresh(obj, LockOptions.NONE);
+ }
+
+ /** Check if a certain class is mapped using a certain inheritance strategy */
+ public boolean isInheritanceStrategy(Class<?> cls, InheritanceType strategy) {
+ final String clsName = cls.getName();
+ final String realName = clsName.substring(clsName.lastIndexOf('.') + 1,
+ clsName.length() - 4);
+ final ClassMetadata cmd = hbDataStore.getSessionFactory()
+ .getClassMetadata(realName);
+ if (strategy.equals(InheritanceType.SINGLE_TABLE)) {
+ return cmd instanceof SingleTableEntityPersister;
+ }
+ if (strategy.equals(InheritanceType.JOINED)) {
+ return cmd instanceof JoinedSubclassEntityPersister;
+ }
+ if (strategy.equals(InheritanceType.TABLE_PER_CLASS)) {
+ return cmd instanceof UnionSubclassEntityPersister;
+ }
+ throw new HbStoreException("Strategy: " + strategy.toString()
+ + " not supported ");
+ }
+
+ /** Clear the session */
+ public void clear() {
+ getSessionInternal().clear();
+ }
+
+ /** Merge with the datastore */
+ public Object merge(Object obj) {
+ return getSessionInternal().merge(obj);
+ }
+
+ public void persist(Object obj) {
+ getSessionInternal().save(obj);
+ }
+
+ public Session getHibernateSession() {
+ return getSessionInternal();
+ }
+
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbStoreException.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbStoreException.java
new file mode 100755
index 000000000..2f4d3e62b
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbStoreException.java
@@ -0,0 +1,49 @@
+/**
+ * <copyright> Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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: Martin Taal </copyright> $Id:
+ * HbStoreException.java,v 1.3 2007/02/08 23:11:37 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import org.eclipse.emf.teneo.TeneoException;
+
+/**
+ * Is used to throw runtime emf/jpox integration exceptions. This class offers automatic logging to
+ * commons logging. Note that this class extends RuntimeException, so no forced throws and catch
+ * statements. Although there are very differing views on this topic but it is our experience that
+ * to many checked exceptions only distract the programmer and have no added value.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.5 $
+ */
+
+public class HbStoreException extends TeneoException {
+ /**
+ * Serializable id
+ */
+ private static final long serialVersionUID = 7433341056815136417L;
+
+ /**
+ * The constructor, logs the exception also
+ */
+ public HbStoreException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+
+ /**
+ * The constructor, logs the exception also
+ */
+ public HbStoreException(Throwable cause) {
+ this(cause.getMessage(), cause);
+ }
+
+ /**
+ * The constructor, logs the exception also
+ */
+ public HbStoreException(String msg) {
+ super(msg);
+ }
+}
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbUtil.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbUtil.java
new file mode 100755
index 000000000..b62cf01ec
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/HbUtil.java
@@ -0,0 +1,399 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HbUtil.java,v 1.38 2010/11/12 14:39:12 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+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.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.FeatureMapUtil;
+import org.eclipse.emf.teneo.Constants;
+import org.eclipse.emf.teneo.ERuntime;
+import org.eclipse.emf.teneo.PackageRegistryProvider;
+import org.eclipse.emf.teneo.hibernate.mapper.HbMapperConstants;
+import org.eclipse.emf.teneo.hibernate.mapping.econtainer.NewEContainerFeatureIDPropertyHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierCacheHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierPropertyHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierUtil;
+import org.eclipse.emf.teneo.hibernate.mapping.property.EAttributePropertyHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.property.EReferencePropertyHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.property.SyntheticPropertyHandler;
+import org.eclipse.emf.teneo.util.StoreUtil;
+import org.hibernate.Session;
+import org.hibernate.cfg.Environment;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.MetaAttribute;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.property.EmbeddedPropertyAccessor;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.type.IdentifierType;
+import org.hibernate.type.PrimitiveType;
+import org.hibernate.type.StringType;
+import org.hibernate.type.Type;
+
+/**
+ * Contains some utility methods.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.38 $
+ */
+public class HbUtil {
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(HbUtil.class);
+
+ public static EClass getEClassFromMeta(Component component) {
+ final MetaAttribute ePackageMetaAttribute = component
+ .getMetaAttribute(HbMapperConstants.EPACKAGE_PARAM);
+ if (ePackageMetaAttribute == null) {
+ return null;
+ }
+ final EPackage epackage = PackageRegistryProvider.getInstance()
+ .getPackageRegistry()
+ .getEPackage(ePackageMetaAttribute.getValue());
+ if (epackage == null) {
+ throw new IllegalArgumentException(
+ "Could not find ePackage using nsuri "
+ + ePackageMetaAttribute.getValue());
+ }
+ final MetaAttribute eClassMetaAttribute = component
+ .getMetaAttribute(HbMapperConstants.ECLASS_NAME_META);
+ if (eClassMetaAttribute == null) {
+ return null;
+ }
+ return (EClass) epackage.getEClassifier(eClassMetaAttribute.getValue());
+ }
+
+ /**
+ * A merge method which does not use Session.merge but uses the EMF api to
+ * travers object references and execute merge through the object tree. The
+ * merge will traverse all EReferences. The maximum level it will traverse
+ * is passed in as the maxMergeLevel parameters.
+ *
+ * @param session
+ * the hibernate session
+ * @param eObject
+ * the eObject to merge
+ * @return the object read from the database with Merge support.
+ */
+ public static EObject merge(Session session, EObject eObject,
+ int maxMergeLevel) {
+ SessionImplementor sessionImplementor = (SessionImplementor) session;
+ return merge(sessionImplementor, eObject,
+ new HashMap<EObject, EObject>(), maxMergeLevel, 0);
+ }
+
+ private static EObject merge(SessionImplementor sessionImplementor,
+ EObject eObject, Map<EObject, EObject> copyCache,
+ int maxMergeLevel, int currentMergeLevel) {
+ if (copyCache.containsKey(eObject)) {
+ return copyCache.get(eObject);
+ }
+ final String entityName = sessionImplementor.guessEntityName(eObject);
+ final EntityPersister persister = sessionImplementor
+ .getEntityPersister(entityName, eObject);
+ final Serializable id = persister.getIdentifier(eObject,
+ sessionImplementor);
+ if (id != null) {
+ final EObject source = (EObject) ((Session) sessionImplementor)
+ .get(entityName, id);
+ copyCache.put(eObject, source);
+ if (maxMergeLevel == currentMergeLevel) {
+ return source;
+ }
+ // now copy the features
+ for (EStructuralFeature eFeature : source.eClass()
+ .getEAllStructuralFeatures()) {
+ if (eFeature instanceof EAttribute) {
+ source.eSet(eFeature, eObject.eGet(eFeature));
+ } else if (eFeature.isMany()) {
+ final List<EObject> newValues = new ArrayList<EObject>();
+ @SuppressWarnings("unchecked")
+ final List<EObject> currentValues = (List<EObject>) eObject
+ .eGet(eFeature);
+ for (EObject currentValue : currentValues) {
+ newValues
+ .add(merge(sessionImplementor, currentValue,
+ copyCache, maxMergeLevel,
+ currentMergeLevel + 1));
+ }
+ source.eSet(eFeature, newValues);
+ } else {
+ source.eSet(
+ eFeature,
+ merge(sessionImplementor,
+ (EObject) eObject.eGet(eFeature),
+ copyCache, maxMergeLevel,
+ currentMergeLevel + 1));
+ }
+ }
+ return source;
+ } else {
+ return eObject;
+ }
+ }
+
+ public static boolean isEAVMapped(PersistentClass mappedEntity) {
+ if (mappedEntity.getEntityName() != null
+ && mappedEntity.getEntityName().equals(
+ Constants.EAV_EOBJECT_ENTITY_NAME)) {
+ return true;
+ }
+ if (mappedEntity.getSuperclass() == null) {
+ return false;
+ }
+ return isEAVMapped(mappedEntity.getSuperclass());
+ }
+
+ /** Encode the id of an eobject */
+ @SuppressWarnings("unchecked")
+ public static String idToString(EObject eobj, HbDataStore hd) {
+ final PersistentClass pc = hd.getPersistentClass(hd
+ .getEntityNameStrategy().toEntityName(eobj.eClass()));
+ if (pc == null) { // can happen with map entries
+ return null;
+ }
+ Object id;
+ if (eobj instanceof HibernateProxy) {
+ id = ((HibernateProxy) eobj).getHibernateLazyInitializer()
+ .getIdentifier();
+ } else {
+ id = IdentifierUtil.getID(eobj, hd);
+ }
+ if (id == null) {
+ id = IdentifierCacheHandler.getInstance().getID(eobj);
+ if (id == null) {
+ return null;
+ }
+ }
+ final Type t = pc.getIdentifierProperty().getType();
+ if (t instanceof PrimitiveType) {
+ return ((PrimitiveType<Object>) t).toString(id);
+ } else if (t instanceof StringType) {
+ return (String) id;
+ }
+ return null;
+ }
+
+ /** Encode the id of an eobject */
+ @SuppressWarnings("unchecked")
+ public static Object stringToId(EClass eclass, HbDataStore hd, String id) {
+ try {
+ final PersistentClass pc = hd.getPersistentClass(hd
+ .getEntityNameStrategy().toEntityName(eclass));
+ final Type t = pc.getIdentifierProperty().getType();
+ if (t instanceof IdentifierType) {
+ return ((IdentifierType<Object>) t).stringToObject(id);
+ } else if (t instanceof StringType) {
+ return id;
+ }
+ return null;
+ } catch (Exception e) {
+ throw new HbStoreException("Exception while converting id: " + id
+ + " of eclass " + eclass.getName());
+ }
+ }
+
+ /** Returns the correct accessor on the basis of the type of property */
+ public static PropertyAccessor getPropertyAccessor(Property mappedProperty,
+ HbDataStore ds, String entityName, EClass mappedEClass) {
+ if (mappedProperty
+ .getMetaAttribute(HbConstants.SYNTHETIC_PROPERTY_INDICATOR) != null) { // synthetic
+ return new SyntheticPropertyHandler(mappedProperty.getName());
+ } else if (mappedProperty.getMetaAttribute(HbMapperConstants.ID_META) != null) { // synthetic
+ // ID
+ return new IdentifierPropertyHandler();
+ } else if (mappedProperty
+ .getMetaAttribute(HbMapperConstants.VERSION_META) != null) {
+ return ds.getHbContext().createVersionAccessor();
+ } else if (mappedProperty.getName().compareToIgnoreCase(
+ "_identifierMapper") == 0) { // name
+ // is
+ // used
+ // by
+ // hb
+ return new EmbeddedPropertyAccessor(); // new
+ // DummyPropertyHandler();
+ } else if (mappedProperty.getName().compareToIgnoreCase(
+ HbConstants.PROPERTY_ECONTAINER) == 0) {
+ return ds.getHbContext().createEContainerAccessor();
+ } else if (mappedProperty.getName().compareToIgnoreCase(
+ HbConstants.PROPERTY_ECONTAINER_FEATURE_NAME) == 0) {
+ return ds.getExtensionManager().getExtension(
+ NewEContainerFeatureIDPropertyHandler.class);
+ } else if (mappedProperty.getName().compareToIgnoreCase(
+ HbConstants.PROPERTY_ECONTAINER_FEATURE_ID) == 0) {
+ return ds.getHbContext().createEContainerFeatureIDAccessor();
+ }
+
+ EClass eClass = null;
+ if (mappedEClass != null) {
+ eClass = mappedEClass;
+ } else {
+ eClass = ds.getEntityNameStrategy().toEClass(entityName);
+ if (eClass == null) {
+ // for components this is the case
+ eClass = ERuntime.INSTANCE.getEClass(entityName);
+ }
+ }
+ final EStructuralFeature efeature = StoreUtil.getEStructuralFeature(
+ eClass, mappedProperty.getName());
+
+ if (efeature == null) {
+ throw new HbMapperException(
+ "Feature not found for eclass/entity/property "
+ + eClass.getName() + "/" + entityName + "/"
+ + mappedProperty.getName());
+ }
+
+ log.debug("Creating property accessor for " + mappedProperty.getName()
+ + "/" + entityName + "/" + efeature.getName());
+
+ // check extra lazy
+ final boolean extraLazy = mappedProperty.getValue() instanceof Collection
+ && ((Collection) mappedProperty.getValue()).isExtraLazy();
+
+ if (FeatureMapUtil.isFeatureMap(efeature)) {
+ return ds.getHbContext().createFeatureMapPropertyAccessor(efeature);
+ } else if (efeature instanceof EReference) {
+ final EReference eref = (EReference) efeature;
+ if (eref.isMany()) {
+ return ds.getHbContext().createEListAccessor(efeature,
+ extraLazy,
+ ds.getPersistenceOptions().isMapEMapAsTrueMap());
+ } else {
+ PropertyAccessor erefPropertyHandler = ds.getHbContext()
+ .createEReferenceAccessor(eref);
+ if (erefPropertyHandler instanceof EReferencePropertyHandler) {
+ if (mappedProperty.getPersistentClass() != null) {
+ ((EReferencePropertyHandler) erefPropertyHandler)
+ .setId(mappedProperty == mappedProperty
+ .getPersistentClass()
+ .getIdentifierProperty());
+ }
+ }
+ return erefPropertyHandler;
+ }
+ } else {
+ final EAttribute eattr = (EAttribute) efeature;
+ if (eattr.isMany()) {
+ return ds.getHbContext().createEListAccessor(efeature,
+ extraLazy,
+ ds.getPersistenceOptions().isMapEMapAsTrueMap());
+ } else {
+ // note also array types are going here!
+ final PropertyAccessor pa = ds.getHbContext()
+ .createEAttributeAccessor(eattr);
+ // note this check is necessary because maybe somebody override
+ // HBContext.createEAttributeAccessor
+ // to not return a EAttributePropertyHandler
+ if (pa instanceof EAttributePropertyHandler) {
+ final EAttributePropertyHandler eAttributePropertyHandler = (EAttributePropertyHandler) pa;
+ eAttributePropertyHandler.setPersistenceOptions(ds
+ .getPersistenceOptions());
+ if (mappedProperty.getPersistentClass() != null) {
+ eAttributePropertyHandler
+ .setId(mappedProperty == mappedProperty
+ .getPersistentClass()
+ .getIdentifierProperty());
+ }
+ }
+ return pa;
+ }
+ }
+ }
+
+ /** Returns the meta class uri, if not found then null is returned */
+ public static String getEClassNameFromFeatureMapMeta(PersistentClass pc) {
+ MetaAttribute ma = pc
+ .getMetaAttribute(HbMapperConstants.FEATUREMAP_META);
+ if (ma == null) {
+ return null;
+ }
+ return ma.getValue();
+ }
+
+ /**
+ * Returns the structural feature, handles the case of structural features
+ * which are part of a feature map entry. public static EStructuralFeature
+ * getFeature(PersistentClass pc, String propName, EPackage[] epacks) {
+ * final MetaAttribute ma = pc.getMetaAttribute("eclass"); // TODO:
+ * externalize final String eclassName; if (ma != null) { eclassName =
+ * ma.getValue(); } else { eclassName = pc.getEntityName(); } return
+ * StoreUtil.getEStructuralFeature(eclassName, propName, epacks); }
+ */
+
+ /**
+ * Creates and registers an emf data store using a set of generic store
+ * properties
+ */
+ public static HbDataStore getCreateDataStore(Properties props) {
+ final String name = props.getProperty(Constants.PROP_NAME);
+ HbDataStore eds = HbHelper.INSTANCE.getDataStore(name);
+ if (eds != null) {
+ return eds;
+ }
+
+ final Properties hbProps = new Properties();
+ hbProps.putAll(props);
+ hbProps.put(Environment.USER,
+ doTrim(props.getProperty(Constants.PROP_DB_USER)));
+ hbProps.put(Environment.PASS,
+ doTrim(props.getProperty(Constants.PROP_DB_PWD)));
+ hbProps.put(Environment.DRIVER,
+ doTrim(props.getProperty(Constants.PROP_DB_DRIVER)));
+ hbProps.put(Environment.URL,
+ doTrim(props.getProperty(Constants.PROP_DB_URL)));
+ hbProps.put(Environment.DIALECT,
+ doTrim(props.getProperty(Constants.PROP_DB_DIALECT)));
+
+ EPackage[] epacks = StoreUtil.getEPackages(doTrim(props
+ .getProperty(Constants.PROP_EPACKAGE_NSURI)));
+
+ // create a EMF Data Store, this is retrieved later again
+ eds = HbHelper.INSTANCE.createRegisterDataStore(name);
+ eds.setDataStoreProperties(hbProps);
+ eds.setEPackages(epacks);
+ eds.initialize();
+ return eds;
+ }
+
+ /** Convenience method */
+ private static String doTrim(String totrim) {
+ if (totrim == null) {
+ return null;
+ }
+ return totrim.trim();
+ }
+
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/LazyCollectionUtils.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/LazyCollectionUtils.java
new file mode 100644
index 000000000..ba3f3fbb1
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/LazyCollectionUtils.java
@@ -0,0 +1,307 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: LazyCollectionUtils.java,v 1.9 2010/08/18 11:50:38 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.eclipse.emf.teneo.hibernate.mapping.eav.EAVDelegatingList;
+import org.eclipse.emf.teneo.hibernate.mapping.eav.EAVValueHolder;
+import org.eclipse.emf.teneo.mapping.elist.PersistableDelegateList;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.collection.AbstractPersistentCollection;
+import org.hibernate.engine.CollectionEntry;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.hql.ast.util.SessionFactoryHelper;
+import org.hibernate.persister.collection.AbstractCollectionPersister;
+import org.hibernate.persister.collection.QueryableCollection;
+
+/**
+ * A utility class providing methods related to lazy loading of collections.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.9 $
+ */
+public class LazyCollectionUtils {
+
+ public final static int DEFAULT_PAGE_SIZE = 100;
+
+ /**
+ * Returns an iterator which loads the underlying data from the collection
+ * in pages (controlled by the pageSize parameter). Note if the collection
+ * is not lazy loadable then a normal iterator is returned. This is checked
+ * using the {@link #isLazyLoadableCollection(Collection)} method.
+ *
+ * Note: this method can only handle collections of EObjects so not collections
+ * of primitive typed objects. Paged iteration of these collections is not
+ * supported by Hibernate.
+ *
+ * @param coll
+ * the collection to iterate lazily over
+ * @param pageSize
+ * the pageSize, this determines the pagesize of the page of data
+ * read each time from the database
+ * @return a paging iterator or if not a lazy loadable collection a normal
+ * iterator
+ * @see PagingIterator
+ */
+ public static <E> Iterator<E> getPagedLoadingIterator(Collection<E> coll,
+ int pageSize) {
+ if (!isLazyLoadableCollection(coll)) {
+ return coll.iterator();
+ }
+ final PersistableDelegateList<?> persistableList = (PersistableDelegateList<?>) coll;
+ final AbstractPersistentCollection persistentCollection = (AbstractPersistentCollection) persistableList
+ .getDelegate();
+
+ final SessionImplementor session = persistentCollection.getSession();
+ final PagingIterator<E> pagingIterator = new PagingIterator<E>();
+ pagingIterator.setCollection(persistentCollection);
+ pagingIterator.setPageSize(pageSize);
+ pagingIterator.setSession((Session) session);
+
+ final CollectionEntry entry = session.getPersistenceContext().getCollectionEntry(persistentCollection);
+ final AbstractCollectionPersister persister = (AbstractCollectionPersister)entry.getLoadedPersister();
+ pagingIterator.setEavCollection(coll instanceof EAVDelegatingList);
+ pagingIterator.setIndexColumnNames(persister.getIndexColumnNames());
+ return pagingIterator;
+ }
+
+ /**
+ * Reads the size of a collection in a lazy manner, i.e. will try to not
+ * load the collection from the database. The size is cached in the object,
+ * so subsequent calls to this method will not result in additional database
+ * queries. This until the collection changes then the cache is cleared.
+ *
+ * Note if the collection can not be lazy loaded (see the
+ * {@link #isLazyLoadableCollection(Collection)}) then the size method is
+ * called on the collection. This method call is probably not lazy.
+ *
+ * @param coll
+ * the collection to get the size from
+ * @return the size of the collection
+ */
+ public static int size(Collection<?> coll) {
+ if (!isLazyLoadableCollection(coll)) {
+ return coll.size();
+ }
+ final PersistableDelegateList<?> persistableList = (PersistableDelegateList<?>) coll;
+ final AbstractPersistentCollection persistentCollection = (AbstractPersistentCollection) persistableList
+ .getDelegate();
+ final SessionImplementor session = persistentCollection.getSession();
+ final QueryableCollection persister = new SessionFactoryHelper(session
+ .getFactory()).getCollectionPersister(persistentCollection
+ .getRole());
+ return persister.getSize(persistentCollection.getKey(), session);
+ }
+
+ /**
+ * Determines if a collection can be lazy loaded. A lazy loadable collection
+ * must be a {@link PersistableDelegateList} which has a
+ * {@link AbstractPersistentCollection} as the delegate list which also must
+ * have an open Hibernate session.
+ *
+ * @param coll
+ * the collection for which to determine if it can be lazy loaded
+ * @return false if not lazy loadable, true otherwise
+ */
+ public static <E> boolean isLazyLoadableCollection(Collection<E> coll) {
+ boolean lazyLoadable = coll instanceof PersistableDelegateList<?>;
+ if (!lazyLoadable) {
+ return false;
+ }
+ final PersistableDelegateList<?> persistableList = (PersistableDelegateList<?>) coll;
+ lazyLoadable &= persistableList.getDelegate() instanceof AbstractPersistentCollection;
+ if (!lazyLoadable) {
+ return false;
+ }
+ final AbstractPersistentCollection persistentCollection = (AbstractPersistentCollection) persistableList
+ .getDelegate();
+ final SessionImplementor session = persistentCollection.getSession();
+ // if not a valid session then go away
+ if (session == null
+ || !session.isOpen()
+ || !session.getPersistenceContext().containsCollection(
+ persistentCollection)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * A paging iterator reads the underlying data from the database in pages.
+ * Everytime the iterator reaches the end of a page it reads the next page
+ * from the database.
+ *
+ * @author mtaal
+ */
+ public static class PagingIterator<E> implements Iterator<E> {
+
+ private Session session;
+ private int pageSize;
+ private Boolean hasNext = null;
+ private int currentIteratorIndex = 0;
+ private int nextPageStart = 0;
+ private List<E> content;
+ private Object collection;
+ private String[] indexColumnNames;
+ private String orderBy = "";
+ private boolean eavCollection;
+
+ public boolean hasNext() {
+ if (content == null) {
+ setPageInformation();
+ }
+
+ if (currentIteratorIndex < content.size()) {
+ return true;
+ }
+
+ if (hasNext != null) {
+ return hasNext;
+ }
+
+ if (content.size() < pageSize) {
+ hasNext = false;
+ return hasNext;
+ }
+
+ // load the next page to see if there is any content
+ hasNext = !loadNextPage().isEmpty();
+
+ return hasNext;
+ }
+
+ public E next() {
+ if (currentIteratorIndex < content.size()) {
+ return convert(content.get(currentIteratorIndex++));
+ }
+
+ // load the next page
+ setPageInformation();
+ if (content.isEmpty()) {
+ throw new NoSuchElementException();
+ }
+ return convert(content.get(currentIteratorIndex++));
+ }
+
+ @SuppressWarnings("unchecked")
+ private E convert(E value) {
+ if (value instanceof EAVValueHolder) {
+ return (E) ((EAVValueHolder) value).getValue();
+ }
+ return value;
+ }
+
+ private void setPageInformation() {
+ content = loadNextPage();
+ currentIteratorIndex = 0;
+ hasNext = null;
+ nextPageStart += content.size();
+ }
+
+ @SuppressWarnings("unchecked")
+ private List<E> loadNextPage() {
+ final Query query;
+ if (isEavCollection()) {
+ query = session.createFilter(collection,
+ " order by this.listIndex ");
+ } else {
+ query = session.createFilter(collection, orderBy);
+ }
+ query.setMaxResults(pageSize);
+ query.setFirstResult(nextPageStart);
+ return (List<E>) query.list();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException(
+ "Removal is not supported by the paging iterator");
+ }
+
+ public Session getSession() {
+ return session;
+ }
+
+ public void setSession(Session session) {
+ this.session = session;
+ }
+
+ public int getPageSize() {
+ return pageSize;
+ }
+
+ public void setPageSize(int pageSize) {
+ this.pageSize = pageSize;
+ }
+
+ public Object getCollection() {
+ return collection;
+ }
+
+ public void setCollection(Object collection) {
+ this.collection = collection;
+ }
+
+ public String[] getIndexColumnNames() {
+ return indexColumnNames;
+ }
+
+ public void setIndexColumnNames(String[] indexColumnNames) {
+ this.indexColumnNames = indexColumnNames;
+ final StringBuilder sb = new StringBuilder();
+ if (indexColumnNames != null) {
+ for (String indexColumnName : indexColumnNames) {
+ if (sb.length() == 0) {
+ sb.append(" order by ");
+ } else {
+ sb.append(", ");
+ }
+ sb.append(indexColumnName.replaceAll("`", "").replaceAll(
+ "\"", ""));
+ }
+ }
+ orderBy = sb.toString();
+ }
+
+ public String getOrderBy() {
+ return orderBy;
+ }
+
+ /**
+ * Note the parameter must include the term: order by. Refer to properties of
+ * the collection content using the this keyword.
+ *
+ * @param orderBy the order by clause including the order by keyword, for example: order by this.name
+ */
+ public void setOrderBy(String orderBy) {
+ this.orderBy = orderBy;
+ }
+
+ public boolean isEavCollection() {
+ return eavCollection;
+ }
+
+ public void setEavCollection(boolean eavCollection) {
+ this.eavCollection = eavCollection;
+ }
+
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/SessionWrapper.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/SessionWrapper.java
new file mode 100755
index 000000000..d14b930e8
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/SessionWrapper.java
@@ -0,0 +1,109 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * Benjamin Cabe
+ * </copyright>
+ *
+ * $Id: SessionWrapper.java,v 1.9 2009/05/23 13:57:55 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.teneo.annotations.pannotation.InheritanceType;
+import org.hibernate.Session;
+
+/**
+ * Wraps a session or an entity manager. Is used to support both standard hibernate as well as hibernate entitymanager.
+ * The differences between these two are hidden behind this interface (with different implementations for either case).
+ * The Teneo runtime code uses this interface to start and commit transactions and perform queries.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.9 $
+ */
+public interface SessionWrapper {
+
+ /**
+ * Return the session, return is an object to support both session as well as entitymanager.
+ */
+ Object getSession();
+
+ /** Begin a transaction */
+ void beginTransaction();
+
+ /** Commit a transaction */
+ void commitTransaction();
+
+ /** Rollback transaction */
+ void rollbackTransaction();
+
+ /** Return an object using the entityname and a serializable id */
+ Object get(String entityName, Serializable id);
+
+ /** Query */
+ List<?> executeQuery(String qry);
+
+ /** Query */
+ List<?> executeQuery(String qry, String entityParameter, Object entity);
+
+ /** Query */
+ List<?> executeQuery(String qry, boolean cacheable);
+
+ /** Query */
+ List<?> executeQuery(String qry, List<Object> parameters);
+
+ /** Query with named parameters */
+ List<?> executeQuery(String qry, Map<String, Object> namedParameters);
+
+ /** Does this impl. wrap an entitymanager */
+ boolean isEJB3EntityManager();
+
+ public void restorePreviousFlushMode();
+
+ /** Set the flushmode in the session */
+ void setFlushModeManual();
+
+ /** Close the session/entitymanager */
+ void close();
+
+ /** Save or update the pass object */
+ void saveOrUpdate(Object obj);
+
+ /** Delete the object */
+ void delete(Object obj);
+
+ /** Flush the session */
+ void flush();
+
+ /** Clear the session */
+ void clear();
+
+ /** Is transaction active */
+ boolean isTransactionActive();
+
+ /** Refresh the object */
+ void refresh(Object obj);
+
+ /** Check if a certain class is mapped using a certain inheritance strategy */
+ public boolean isInheritanceStrategy(Class<?> cls, InheritanceType strategy);
+
+ /** Persist a new object */
+ public void persist(Object obj);
+
+ /** Merge with the datastore */
+ public Object merge(Object obj);
+
+ /** Return the underlying session */
+ public Session getHibernateSession();
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/AnyEObjectType.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/AnyEObjectType.java
new file mode 100755
index 000000000..450e422fd
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/AnyEObjectType.java
@@ -0,0 +1,472 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: AnyEObjectType.java,v 1.7 2010/11/12 09:33:33 mtaal Exp $
+ */
+package org.eclipse.emf.teneo.hibernate.mapping;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.dom4j.Node;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.teneo.hibernate.HbStoreException;
+import org.hibernate.EntityMode;
+import org.hibernate.FetchMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.engine.ForeignKeys;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.entity.Joinable;
+import org.hibernate.type.AbstractType;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.CompositeType;
+import org.hibernate.type.ForeignKeyDirection;
+import org.hibernate.type.StandardBasicTypes;
+import org.hibernate.type.Type;
+
+/**
+ * Supports persisting the reference to any persistable EObect, it stores the
+ * entity name, and the id in a string field
+ *
+ * @author <a href="mailto:mkanaley@tibco.com">Mike Kanaley</a>
+ */
+public class AnyEObjectType extends AbstractType implements CompositeType,
+ AssociationType {
+
+ /**
+ * Generated Serial ID
+ */
+ private static final long serialVersionUID = 3857353606004705457L;
+
+ private static final String[] PROPERTY_NAMES = new String[] { "class",
+ "idtype", "idstr" };
+
+ private static final int[] SQL_TYPES = { Types.VARCHAR, Types.VARCHAR,
+ Types.VARCHAR };
+
+ /** Constructor by id */
+ private final HashMap<String, Constructor<?>> constructors = new HashMap<String, Constructor<?>>();
+
+ /**
+ * Return the types of the columns that this UserType will serialize into.
+ *
+ * @return a single column of type VARCHAR.
+ */
+ public int[] sqlTypes() {
+ return SQL_TYPES;
+ }
+
+ /** Just returns the value */
+ public Object deepCopy(Object value, EntityMode entityMode,
+ SessionFactoryImplementor factory) throws HibernateException {
+ return value;
+ }
+
+ /* See superclass */
+ public boolean isMethodOf(Method method) {
+ return false;
+ }
+
+ /** Checks using equals */
+ @Override
+ public boolean isSame(Object x, Object y, EntityMode entityMode)
+ throws HibernateException {
+ if (x != null) {
+ return x.equals(y);
+ }
+ return x == y;
+ }
+
+ /** Compare is not implemented, returning 0 for now */
+ @Override
+ public int compare(Object x, Object y, EntityMode entityMode) {
+ return 0;
+ }
+
+ /** Return the column span */
+ public int getColumnSpan(Mapping session) throws MappingException {
+ return SQL_TYPES.length;
+ }
+
+ /** The name of the type */
+ public String getName() {
+ return "AnyEObject";
+ }
+
+ /** Return false for safety */
+ public boolean isMutable() {
+ return false;
+ }
+
+ /** Returns unsupportedexception */
+ public Object nullSafeGet(ResultSet rs, String name,
+ SessionImplementor session, Object owner)
+ throws HibernateException, SQLException {
+ throw new UnsupportedOperationException("Type is a multicolumn type");
+ }
+
+ /** Returns the object from the resultset */
+ public Object nullSafeGet(ResultSet rs, String[] names,
+ SessionImplementor session, Object owner)
+ throws HibernateException, SQLException {
+ final String entityName = rs.getString(names[0]);
+ if (rs.wasNull()) {
+ return null;
+ }
+ final String idType = rs.getString(names[1]);
+ if (rs.wasNull()) {
+ return null;
+ }
+ final String idStr = rs.getString(names[2]);
+ if (rs.wasNull()) {
+ return null;
+ }
+
+ return session.internalLoad(entityName, getId(idStr, idType), true,
+ false);
+ }
+
+ /** Creates an id object of the correct type */
+ private Serializable getId(String idStr, String idType) {
+ try {
+ Constructor<?> constructor = constructors.get(idType);
+ if (constructor == null) {
+ final Class<?> idClass = this.getClass().getClassLoader()
+ .loadClass(idType);
+ constructor = idClass
+ .getConstructor(new Class[] { String.class });
+ constructors.put(idType, constructor);
+ }
+ return (Serializable) constructor
+ .newInstance(new Object[] { idStr });
+ } catch (Exception e) {
+ throw new HbStoreException("Could not create id type for " + idType
+ + " and id " + idStr, e);
+ }
+ }
+
+ @Override
+ public Object hydrate(ResultSet rs, String[] names,
+ SessionImplementor session, Object owner)
+ throws HibernateException, SQLException {
+ final String entityName = rs.getString(names[0]);
+ if (rs.wasNull()) {
+ return null;
+ }
+ final String idType = rs.getString(names[1]);
+ if (rs.wasNull()) {
+ return null;
+ }
+ final String idStr = rs.getString(names[2]);
+ if (rs.wasNull()) {
+ return null;
+ }
+
+ return new EObjectCacheEntry(entityName, getId(idStr, idType));
+ }
+
+ @Override
+ public Object resolve(Object value, SessionImplementor session, Object owner)
+ throws HibernateException {
+ EObjectCacheEntry entry = (EObjectCacheEntry) value;
+ return session.internalLoad(entry.entityName, entry.id, true, false);
+ }
+
+ /*
+ * public Object semiResolve(Object value, SessionImplementor session,
+ * Object owner) throws HibernateException { throw new
+ * UnsupportedOperationException("Any mappings may not form part of a
+ * property-ref"); }
+ */
+
+ public void nullSafeSet(PreparedStatement st, Object value, int index,
+ SessionImplementor session) throws HibernateException, SQLException {
+ nullSafeSet(st, value, index, null, session);
+ }
+
+ public void nullSafeSet(PreparedStatement st, Object value, int index,
+ boolean[] settable, SessionImplementor session)
+ throws HibernateException, SQLException {
+
+ String entityName = null;
+ String idStr = null;
+ String idType = null;
+ if (value != null) {
+ entityName = session.bestGuessEntityName(value);
+ Serializable id = ForeignKeys.getEntityIdentifierIfNotUnsaved(
+ entityName, value, session);
+ idType = id.getClass().getName();
+ idStr = id.toString();
+ st.setString(index, entityName);
+ st.setString(index + 1, idType);
+ st.setString(index + 2, idStr);
+ } else {
+ st.setNull(index, SQL_TYPES[0]);
+ st.setNull(index, SQL_TYPES[1]);
+ st.setNull(index, SQL_TYPES[2]);
+ }
+ }
+
+ /** Returns EObject */
+ public Class<?> getReturnedClass() {
+ return EObject.class;
+ }
+
+ public int[] sqlTypes(Mapping mapping) throws MappingException {
+ return SQL_TYPES;
+ }
+
+ public void setToXMLNode(Node xml, Object value,
+ SessionFactoryImplementor factory) {
+ throw new UnsupportedOperationException(
+ "Any types cannot be stringified");
+ }
+
+ public String toLoggableString(Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ return value == null ? "null" : value.getClass().getName();
+ }
+
+ public Object fromXMLNode(Node xml, Mapping factory)
+ throws HibernateException {
+ throw new UnsupportedOperationException(); // TODO: is this right??
+ }
+
+ public static final class EObjectCacheEntry implements Serializable {
+ /**
+ * Serial Version ID
+ */
+ private static final long serialVersionUID = 1030890286147221359L;
+
+ /** The cached entityName */
+ String entityName;
+
+ /** And its id */
+ Serializable id;
+
+ EObjectCacheEntry(String entityName, Serializable id) {
+ this.entityName = entityName;
+ this.id = id;
+ }
+ }
+
+ @Override
+ public Object assemble(Serializable cached, SessionImplementor session,
+ Object owner) throws HibernateException {
+ final EObjectCacheEntry entry = (EObjectCacheEntry) cached;
+ return entry == null ? null : session.internalLoad(entry.entityName,
+ entry.id, true, false);
+ }
+
+ @Override
+ public Serializable disassemble(Object value, SessionImplementor session,
+ Object owner) throws HibernateException {
+ if (value == null) {
+ return null;
+ }
+ final String entityName = session.bestGuessEntityName(value);
+ final Serializable id = ForeignKeys.getEntityIdentifierIfNotUnsaved(
+ entityName, value, session);
+ return new EObjectCacheEntry(entityName, id);
+ }
+
+ @Override
+ public boolean isAnyType() {
+ return true;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Object replace(Object original, Object target,
+ SessionImplementor session, Object owner, Map copyCache)
+ throws HibernateException {
+ if (original == null) {
+ return null;
+ } else {
+ final String entityName = session.bestGuessEntityName(original);
+ final Serializable id = ForeignKeys
+ .getEntityIdentifierIfNotUnsaved(entityName, original,
+ session);
+ return session.internalLoad(entityName, id, true, false);
+ }
+ }
+
+ public CascadeStyle getCascadeStyle(int i) {
+ return CascadeStyle.NONE;
+ }
+
+ public FetchMode getFetchMode(int i) {
+ return FetchMode.SELECT;
+ }
+
+ public String[] getPropertyNames() {
+ return PROPERTY_NAMES;
+ }
+
+ public Object getPropertyValue(Object component, int i,
+ SessionImplementor session) throws HibernateException {
+ if (component != null) {
+ final String entityName = session.bestGuessEntityName(component);
+ Serializable id = ForeignKeys.getEntityIdentifierIfNotUnsaved(
+ entityName, component, session);
+ switch (i) {
+ case 0:
+ return session.bestGuessEntityName(component);
+ case 1:
+ return id.getClass().getName();
+ case 2:
+ return id.toString();
+ default:
+ throw new HbStoreException("Index " + i + "not supported");
+ }
+ }
+ return null;
+ }
+
+ public Object[] getPropertyValues(Object component,
+ SessionImplementor session) throws HibernateException {
+ if (component != null) {
+ final String entityName = session.bestGuessEntityName(component);
+ Serializable id = ForeignKeys.getEntityIdentifierIfNotUnsaved(
+ entityName, component, session);
+ return new Object[] { session.bestGuessEntityName(component),
+ id.getClass().getName(), id.toString() };
+ }
+ return null;
+ }
+
+ public Type[] getSubtypes() {
+ return new Type[] { StandardBasicTypes.STRING,
+ StandardBasicTypes.STRING, StandardBasicTypes.STRING };
+ }
+
+ public void setPropertyValues(Object component, Object[] values,
+ EntityMode entityMode) throws HibernateException {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object[] getPropertyValues(Object component, EntityMode entityMode) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isComponentType() {
+ return true;
+ }
+
+ public ForeignKeyDirection getForeignKeyDirection() {
+ return ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT;
+ }
+
+ @Override
+ public boolean isAssociationType() {
+ return true;
+ }
+
+ public boolean useLHSPrimaryKey() {
+ return false;
+ }
+
+ public Joinable getAssociatedJoinable(SessionFactoryImplementor factory) {
+ throw new UnsupportedOperationException(
+ "any types do not have a unique referenced persister");
+ }
+
+ @Override
+ public boolean isModified(Object old, Object current, boolean[] checkable,
+ SessionImplementor session) throws HibernateException {
+ if (current == null) {
+ return old != null;
+ }
+ if (old == null) {
+ return current != null;
+ }
+
+ final EObjectCacheEntry entry = (EObjectCacheEntry) old;
+ final String entityName = session.bestGuessEntityName(current);
+ final Serializable id = ForeignKeys.getEntityIdentifierIfNotUnsaved(
+ entityName, current, session);
+ if (checkable[0] && entry.entityName.compareTo(entityName) != 0) {
+ return true;
+ }
+ if ((checkable[1] || checkable[2]) && !id.equals(entry.id)) {
+ return true;
+ }
+ return false;
+ }
+
+ public String getAssociatedEntityName(SessionFactoryImplementor factory)
+ throws MappingException {
+ throw new UnsupportedOperationException(
+ "any types do not have a unique referenced persister");
+ }
+
+ public boolean[] getPropertyNullability() {
+ return null;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public String getOnCondition(String alias,
+ SessionFactoryImplementor factory, Map enabledFilters)
+ throws MappingException {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isReferenceToPrimaryKey() {
+ return true;
+ }
+
+ public String getRHSUniqueKeyPropertyName() {
+ return null;
+ }
+
+ public String getLHSPropertyName() {
+ return null;
+ }
+
+ public boolean isAlwaysDirtyChecked() {
+ return false;
+ }
+
+ public boolean isEmbeddedInXML() {
+ return false;
+ }
+
+ public boolean[] toColumnNullness(Object value, Mapping mapping) {
+ boolean[] result = new boolean[getColumnSpan(mapping)];
+ if (value != null) {
+ Arrays.fill(result, true);
+ }
+ return result;
+ }
+
+ public boolean isDirty(Object old, Object current, boolean[] checkable,
+ SessionImplementor session) throws HibernateException {
+ return isDirty(old, current, session);
+ }
+
+ public boolean isEmbedded() {
+ return false;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/DefaultToStringUserType.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/DefaultToStringUserType.java
new file mode 100755
index 000000000..dd2272e96
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/DefaultToStringUserType.java
@@ -0,0 +1,247 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Michael Kanaley, TIBCO Software Inc.
+ * </copyright>
+ *
+ * $Id: DefaultToStringUserType.java,v 1.6 2009/10/15 20:35:48 mtaal Exp $
+ */
+package org.eclipse.emf.teneo.hibernate.mapping;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Properties;
+
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EFactory;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.teneo.PackageRegistryProvider;
+import org.eclipse.emf.teneo.hibernate.mapper.HbMapperConstants;
+import org.hibernate.usertype.ParameterizedType;
+import org.hibernate.usertype.UserType;
+
+/**
+ * Provides a Hibernate extension (called a UserType) to support serializing EMF custom datatypes into VARCHAR columns.
+ * The custom DataType mappers provided by this plugin have the job of registering Hibernate typedefs that use this
+ * UserType implementation.
+ *
+ * This class is intended for contribution to Teneo.
+ *
+ * @author <a href="mailto:mkanaley@tibco.com">Mike Kanaley</a>
+ */
+public class DefaultToStringUserType implements UserType, ParameterizedType {
+
+ private static final int[] SQL_TYPES = { Types.VARCHAR };
+ private EFactory eFactory;
+ private EDataType eDataType;
+
+ private EPackage.Registry registry;
+
+ public DefaultToStringUserType() {
+ registry = PackageRegistryProvider.getInstance().getPackageRegistry();
+ }
+
+ /**
+ * Return the types of the columns that this UserType will serialize into.
+ *
+ * @return a single column of type VARCHAR.
+ */
+ public int[] sqlTypes() {
+ return SQL_TYPES;
+ }
+
+ /**
+ * Return the Java class of the object that is serialized for the column.
+ *
+ * @return the Java instance class associated with the EMF DataType.
+ */
+ public Class<?> returnedClass() {
+ return this.eDataType.getInstanceClass();
+ }
+
+ /**
+ * Is this datatype mutable?
+ *
+ * @return Being conservative - false always.
+ */
+ public boolean isMutable() {
+ return false;
+ }
+
+ /**
+ * Provide a copy of the datatypes. Converts to String and then back to datatype again.
+ *
+ * @param value
+ * the value to copy.
+ * @return the value always.
+ */
+ public Object deepCopy(Object value) {
+ String data = this.eFactory.convertToString(this.eDataType, value);
+ return this.eFactory.createFromString(this.eDataType, data);
+ }
+
+ /**
+ * Are the two objects equal?
+ *
+ * @param x
+ * an object to compare.
+ * @param y
+ * an object to compare.
+ * @return a standard equals test between the objects.
+ */
+ public boolean equals(Object x, Object y) {
+ if (x == y)
+ return true;
+ if (x == null || y == null)
+ return false;
+ return x.equals(y);
+ }
+
+ /**
+ * Populate the model object property from the ResultSet.
+ *
+ * @param resultSet
+ * the non-null ResultSet from which the field will be populated.
+ * @param names
+ * the names of the columns.
+ * @param owner
+ * the owning object.
+ * @return null if the column's value is null; otherwise, use the EMF factory to construct a new instance of the
+ * custom EMF data type from the contents of the String value of the column.
+ * @throws SQLException
+ * if the value cannot be retrieved from the ResultSet.
+ */
+ public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws SQLException {
+
+ String data = resultSet.getString(names[0]);
+ if (data == null) {
+ return null;
+ }
+ return this.eFactory.createFromString(this.eDataType, data);
+ }
+
+ /**
+ * Populate the database statement from the model object property.
+ *
+ * @param statement
+ * the non-null Statement to insert the value into.
+ * @param value
+ * the object to convert.
+ * @param index
+ * the index into the statement where to insert the converted value.
+ * @throws SQLException
+ * if the converted value cannot be set in the statement.
+ */
+ public void nullSafeSet(PreparedStatement statement, Object value, int index) throws SQLException {
+ String pvalue = null;
+ if (value != null) {
+ pvalue = this.eFactory.convertToString(this.eDataType, value);
+ }
+ if (pvalue != null) {
+ statement.setString(index, pvalue);
+ } else {
+ statement.setNull(index, Types.VARCHAR);
+ }
+ }
+
+ /**
+ * No-op implementation.
+ *
+ * @param value
+ * the value to dissemble.
+ * @return the value passed in.
+ */
+ public Serializable disassemble(Object value) {
+ return (Serializable) value;
+ }
+
+ /**
+ * No-op implementation.
+ *
+ * @param cachedValue
+ * the value to assemble.
+ * @param owner
+ * the owning object.
+ * @return the cachedValue passed in.
+ */
+ public Object assemble(Serializable cachedValue, Object owner) {
+ return cachedValue;
+ }
+
+ /**
+ * No-op implementation.
+ *
+ * @param original
+ * the value to replace.
+ * @param target
+ * the target object.
+ * @param owner
+ * the owning object.
+ * @return the original value passed in.
+ */
+ public Object replace(Object original, Object target, Object owner) {
+ return original;
+ }
+
+ /**
+ * No-op implementation.
+ *
+ * @param x
+ * the object to get the hashcode for.
+ * @return x's hashcode.
+ */
+ public int hashCode(Object x) {
+ return x.hashCode();
+ }
+
+ /************************************************************************
+ * ParameterizedType implementation
+ ************************************************************************/
+ /**
+ * Read in the type parameters from the Hibernate mapping and determine the EMF factory and custom data type to use.
+ *
+ * @param properties
+ * the properties containing key value pairs for the {@link #PACKAGE_IMPLEMENTATION_CLASS_NAME_PROPERTY}
+ * and {@link #ATTRIBUTE_NAME_PROPERTY} parameters.
+ */
+ public void setParameterValues(Properties properties) {
+ final String ePackageNsUri = properties.getProperty(HbMapperConstants.EPACKAGE_PARAM);
+ if (ePackageNsUri == null || ePackageNsUri.length() == 0) {
+ throw new IllegalArgumentException("Could not find custom UserType property "
+ + HbMapperConstants.EPACKAGE_PARAM);
+ }
+ final EPackage epackage = registry.getEPackage(ePackageNsUri);
+ if (epackage == null) {
+ throw new IllegalArgumentException("Could not find ePackage using nsuri " + ePackageNsUri);
+ }
+ this.eFactory = epackage.getEFactoryInstance();
+ final String edatatypeName = properties.getProperty(HbMapperConstants.EDATATYPE_PARAM);
+ if (edatatypeName == null) {
+ throw new IllegalArgumentException("Could not find custom UserType property "
+ + HbMapperConstants.EDATATYPE_PARAM);
+ }
+ final EClassifier eclassifier = epackage.getEClassifier(edatatypeName);
+ if (eclassifier instanceof EDataType) {
+ this.eDataType = (EDataType) eclassifier;
+ } else {
+ if (eclassifier == null) {
+ throw new IllegalArgumentException("Missing attribute " + edatatypeName + " in package implementation "
+ + epackage.getName());
+ } else {
+ throw new IllegalArgumentException("Found property of type " + eclassifier.getClass().getName()
+ + " when an EDataType was expected.");
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/DynamicENumUserIntegerType.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/DynamicENumUserIntegerType.java
new file mode 100755
index 000000000..599f23df0
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/DynamicENumUserIntegerType.java
@@ -0,0 +1,87 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: DynamicENumUserIntegerType.java,v 1.6 2008/02/28 07:08:24 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.HashMap;
+
+import org.eclipse.emf.common.util.Enumerator;
+import org.hibernate.HibernateException;
+
+/**
+ * Implements the EMF UserType for an Enum in a dynamic model, for an integer field.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.6 $ $Date: 2008/02/28 07:08:24 $
+ */
+
+public class DynamicENumUserIntegerType extends DynamicENumUserType {
+
+ /** The sql types used for enums */
+ private static final int[] SQL_TYPES = new int[] { Types.INTEGER };
+
+ /** Hashmap with string to enum mappings */
+ private final HashMap<Integer, Enumerator> localCache = new HashMap<Integer, Enumerator>();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet, java.lang.String[],
+ * java.lang.Object)
+ */
+ @Override
+ public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+ final int value = rs.getInt(names[0]);
+ if (rs.wasNull()) {
+ return null;
+ }
+
+ Integer objValue = new Integer(value);
+ Enumerator enumValue = localCache.get(objValue);
+ if (enumValue != null) {
+ return enumValue;
+ }
+
+ enumValue = enumInstance.getEEnumLiteral(objValue.intValue());
+ localCache.put(objValue, enumValue);
+ return enumValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement,
+ * java.lang.Object, int)
+ */
+ @Override
+ public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ if (value == null) {
+ st.setNull(index, Types.INTEGER);
+ } else {
+ st.setInt(index, ((Enumerator) value).getValue());
+ }
+ }
+
+ /** An enum is stored in one varchar */
+ @Override
+ public int[] sqlTypes() {
+ return SQL_TYPES;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/DynamicENumUserType.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/DynamicENumUserType.java
new file mode 100755
index 000000000..b2ab68f3e
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/DynamicENumUserType.java
@@ -0,0 +1,182 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: DynamicENumUserType.java,v 1.9 2009/10/15 20:35:48 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.teneo.PackageRegistryProvider;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.mapper.HbMapperConstants;
+import org.hibernate.HibernateException;
+import org.hibernate.usertype.ParameterizedType;
+import org.hibernate.usertype.UserType;
+
+/**
+ * Implements the EMF UserType for an Enum
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.9 $ $Date: 2009/10/15 20:35:48 $
+ */
+
+public class DynamicENumUserType implements UserType, ParameterizedType {
+ /** The sql types used for enums */
+ private static final int[] SQL_TYPES = new int[] { Types.VARCHAR };
+
+ /** The enum type we are handling here */
+ protected EEnum enumInstance;
+
+ /** Hashmap with string to enum mappings */
+ private final HashMap<String, Enumerator> localCache = new HashMap<String, Enumerator>();
+
+ private EPackage.Registry registry;
+
+ public DynamicENumUserType() {
+ registry = PackageRegistryProvider.getInstance().getPackageRegistry();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#assemble(java.io.Serializable, java.lang.Object)
+ */
+ public Object assemble(Serializable cached, Object owner) throws HibernateException {
+ return cached;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object)
+ */
+ public Object deepCopy(Object value) throws HibernateException {
+ return value;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
+ */
+ public Serializable disassemble(Object value) throws HibernateException {
+ return (Serializable) value;
+ }
+
+ /** Compares the int values of the enumerates */
+ public boolean equals(Object x, Object y) throws HibernateException {
+ // todo: check compare on null values
+ if (x == null && y == null) {
+ return true;
+ }
+
+ if (x == null || y == null) {
+ return false;
+ }
+
+ if (x.getClass() != y.getClass()) {
+ return false;
+ }
+ return ((Enumerator) x).getValue() == ((Enumerator) y).getValue();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
+ */
+ public int hashCode(Object x) throws HibernateException {
+ return x.hashCode();
+ }
+
+ /** Not mutable */
+ public boolean isMutable() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet, java.lang.String[], java.lang.Object)
+ */
+ public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+ final String name = rs.getString(names[0]);
+ if (rs.wasNull()) {
+ return null;
+ }
+
+ Enumerator enumValue = localCache.get(name);
+ if (enumValue != null) {
+ return enumValue;
+ }
+
+ enumValue = enumInstance.getEEnumLiteralByLiteral(name.trim());
+ if (enumValue == null) {
+ throw new HbMapperException("The enum value " + name + " is not valid for enumerator: "
+ + enumInstance.getName());
+ }
+ localCache.put(name, enumValue);
+ return enumValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement, java.lang.Object, int)
+ */
+ public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ if (value == null) {
+ st.setNull(index, Types.VARCHAR);
+ } else {
+ st.setString(index, ((Enumerator) value).getName());
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#replace(java.lang.Object, java.lang.Object, java.lang.Object)
+ */
+ public Object replace(Object original, Object target, Object owner) throws HibernateException {
+ return original;
+ }
+
+ /** Returns the parameterizezd enumType */
+ public Class<?> returnedClass() {
+ return enumInstance.getClass();
+ }
+
+ /** An enum is stored in one varchar */
+ public int[] sqlTypes() {
+ return SQL_TYPES;
+ }
+
+ /** Sets the enumclass */
+ public void setParameterValues(Properties parameters) {
+ final String epackUri = parameters.getProperty(HbMapperConstants.EPACKAGE_PARAM);
+ final String eclassifier = parameters.getProperty(HbMapperConstants.ECLASSIFIER_PARAM);
+ final EPackage epack = registry.getEPackage(epackUri);
+ enumInstance = (EEnum) epack.getEClassifier(eclassifier);
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/EMFInitializeCollectionEventListener.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/EMFInitializeCollectionEventListener.java
new file mode 100755
index 000000000..ddda27817
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/EMFInitializeCollectionEventListener.java
@@ -0,0 +1,68 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EMFInitializeCollectionEventListener.java,v 1.3 2008/06/02 07:15:33 mtaal Exp $
+ */
+package org.eclipse.emf.teneo.hibernate.mapping;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.hibernate.HibernateException;
+import org.hibernate.event.InitializeCollectionEvent;
+import org.hibernate.event.def.DefaultInitializeCollectionEventListener;
+
+/**
+ * Sets eDeliver to false for the owner of the collection during the initialization of the
+ * collection.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Mike Kanaley</a>
+ */
+public class EMFInitializeCollectionEventListener extends DefaultInitializeCollectionEventListener implements
+ ExtensionPoint {
+
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.event.def.DefaultInitializeCollectionEventListener#onInitializeCollection(org.hibernate.event.InitializeCollectionEvent)
+ */
+ @Override
+ public void onInitializeCollection(InitializeCollectionEvent event) throws HibernateException {
+ final Object owner = event.getCollection().getOwner();
+ boolean setDeliver = false;
+ boolean eDeliver = false;
+ EObject eobj = null;
+ if (owner instanceof EObject) {
+ eobj = (EObject) owner;
+ eDeliver = eobj.eDeliver();
+ try {
+ // only set to false if it was true
+ if (eDeliver) {
+ eobj.eSetDeliver(false);
+ setDeliver = true;
+ }
+ } catch (UnsupportedOperationException e) {
+ // in this case the eSetDeliver was not overridden from the baseclass
+ // ignore
+ }
+ }
+ try {
+ super.onInitializeCollection(event);
+ } finally {
+ if (setDeliver) {
+ eobj.eSetDeliver(eDeliver);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/ENumUserIntegerType.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/ENumUserIntegerType.java
new file mode 100755
index 000000000..6d3bf5d80
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/ENumUserIntegerType.java
@@ -0,0 +1,89 @@
+package org.eclipse.emf.teneo.hibernate.mapping;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.emf.teneo.classloader.ClassLoaderResolver;
+import org.eclipse.emf.teneo.classloader.StoreClassLoadException;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.mapper.HbMapperConstants;
+import org.hibernate.HibernateException;
+
+/**
+ * Stores a java enum
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.6 $ $Date: 2007/04/17 15:49:44 $
+ */
+
+public class ENumUserIntegerType extends ENumUserType {
+
+ /** The sql types used for enums */
+ private static final int[] SQL_TYPES = new int[] { Types.INTEGER };
+
+ /** Hashmap with string to enum mappings */
+ private final HashMap<Integer, Enumerator> localCache = new HashMap<Integer, Enumerator>();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet, java.lang.String[], java.lang.Object)
+ */
+ public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+ final int value = rs.getInt(names[0]);
+ if (rs.wasNull())
+ return null;
+
+ Integer objValue = new Integer(value);
+ Enumerator enumValue = (Enumerator) localCache.get(objValue);
+ if (enumValue != null)
+ return enumValue;
+
+ // call the getMethod!
+ try {
+ // use non
+ enumValue = (Enumerator) getMethod.invoke(null, new Object[] { objValue });
+ localCache.put(objValue, enumValue);
+ return enumValue;
+ } catch (Exception e) {
+ throw new HbMapperException("Exception when getting enum for class: " + enumType.getName()
+ + " using int value: " + value, e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement, java.lang.Object, int)
+ */
+ public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ if (value == null) {
+ st.setNull(index, Types.INTEGER);
+ } else {
+ st.setInt(index, ((Enumerator) value).getValue());
+ }
+ }
+
+ /** An enum is stored in one varchar */
+ public int[] sqlTypes() {
+ return SQL_TYPES;
+ }
+
+ /** Sets the enumclass */
+ public void setParameterValues(Properties parameters) {
+ final String enumClassName = parameters.getProperty(HbMapperConstants.ENUM_CLASS_PARAM);
+ try {
+ enumType = ClassLoaderResolver.classForName(enumClassName);
+ getMethod = enumType.getMethod("get", new Class[] { int.class });
+ } catch (StoreClassLoadException e) {
+ throw new HbMapperException("Enum class " + enumClassName + " can not be found", e);
+ } catch (NoSuchMethodException e) {
+ throw new HbMapperException("Get method not present in enum class " + enumClassName, e);
+ }
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/ENumUserType.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/ENumUserType.java
new file mode 100755
index 000000000..e877be172
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/ENumUserType.java
@@ -0,0 +1,196 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: ENumUserType.java,v 1.8 2008/02/28 07:08:24 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.emf.teneo.classloader.ClassLoaderResolver;
+import org.eclipse.emf.teneo.classloader.StoreClassLoadException;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.mapper.HbMapperConstants;
+import org.hibernate.HibernateException;
+import org.hibernate.usertype.ParameterizedType;
+import org.hibernate.usertype.UserType;
+
+/**
+ * Implements the EMF UserType for an Enum
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.8 $ $Date: 2008/02/28 07:08:24 $
+ */
+
+public class ENumUserType implements UserType, ParameterizedType {
+
+ /** The sql types used for enums */
+ private static final int[] SQL_TYPES = new int[] { Types.VARCHAR };
+
+ /** The enum type we are handling here */
+ protected Class<?> enumType;
+
+ /** The method which translates a string to an instance of the emf enum */
+ protected Method getMethod;
+
+ /** Hashmap with string to enum mappings */
+ private final HashMap<String, Enumerator> localCache = new HashMap<String, Enumerator>();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#assemble(java.io.Serializable, java.lang.Object)
+ */
+ public Object assemble(Serializable cached, Object owner) throws HibernateException {
+ return cached;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object)
+ */
+ public Object deepCopy(Object value) throws HibernateException {
+ return value;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
+ */
+ public Serializable disassemble(Object value) throws HibernateException {
+ return (Serializable) value;
+ }
+
+ /** Compares the int values of the enumerates */
+ public boolean equals(Object x, Object y) throws HibernateException {
+ // todo: check compare on null values
+ if (x == null && y == null) {
+ return true;
+ }
+
+ if (x == null || y == null) {
+ return false;
+ }
+
+ if (x.getClass() != y.getClass()) {
+ return false;
+ }
+ assert (x instanceof Enumerator);
+ return ((Enumerator) x).getValue() == ((Enumerator) y).getValue();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
+ */
+ public int hashCode(Object x) throws HibernateException {
+ return x.hashCode();
+ }
+
+ /** Not mutable */
+ public boolean isMutable() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet, java.lang.String[],
+ * java.lang.Object)
+ */
+ public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+ final String name = rs.getString(names[0]);
+ if (rs.wasNull()) {
+ return null;
+ }
+
+ Enumerator enumValue = localCache.get(name);
+ if (enumValue != null) {
+ return enumValue;
+ }
+
+ // call the getMethod!
+ try {
+ enumValue = (Enumerator) getMethod.invoke(null, new Object[] { name.trim() });
+ } catch (Exception e) {
+ throw new HbMapperException("Exception when getting enum for class: " + enumType.getName() +
+ " using value: " + name, e);
+ }
+ if (enumValue == null) {
+ throw new HbMapperException("The enum value " + name + " is not valid for enumerator: " +
+ enumType.getName());
+ }
+
+ localCache.put(name, enumValue);
+ return enumValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement,
+ * java.lang.Object, int)
+ */
+ public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ if (value == null) {
+ st.setNull(index, Types.VARCHAR);
+ } else {
+ st.setString(index, ((Enumerator) value).getLiteral());
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#replace(java.lang.Object, java.lang.Object,
+ * java.lang.Object)
+ */
+ public Object replace(Object original, Object target, Object owner) throws HibernateException {
+ return original;
+ }
+
+ /** Returns the parameterizezd enumType */
+ public Class<?> returnedClass() {
+ return enumType;
+ }
+
+ /** An enum is stored in one varchar */
+ public int[] sqlTypes() {
+ return SQL_TYPES;
+ }
+
+ /** Sets the enumclass */
+ public void setParameterValues(Properties parameters) {
+ final String enumClassName = parameters.getProperty(HbMapperConstants.ENUM_CLASS_PARAM);
+ try {
+ enumType = ClassLoaderResolver.classForName(enumClassName);
+ getMethod = enumType.getMethod("get", new Class[] { String.class });
+ } catch (StoreClassLoadException e) {
+ throw new HbMapperException("Enum class " + enumClassName + " can not be found", e);
+ } catch (NoSuchMethodException e) {
+ throw new HbMapperException("Get method not present in enum class " + enumClassName, e);
+ }
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/EcoreModelElementType.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/EcoreModelElementType.java
new file mode 100644
index 000000000..2b3d22593
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/EcoreModelElementType.java
@@ -0,0 +1,166 @@
+package org.eclipse.emf.teneo.hibernate.mapping;
+
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EcoreModelElementType.java,v 1.5 2011/02/27 20:10:36 mtaal Exp $
+ */
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Properties;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.teneo.PackageRegistryProvider;
+import org.hibernate.HibernateException;
+import org.hibernate.usertype.ParameterizedType;
+import org.hibernate.usertype.UserType;
+
+/**
+ * Persists references to EClassifiers and EStructuralFeatures as a varchar
+ * field.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.5 $ $Date: 2011/02/27 20:10:36 $
+ */
+
+public class EcoreModelElementType implements UserType, ParameterizedType {
+
+ private static final int[] SQL_TYPES = new int[] { Types.VARCHAR };
+ private static final String SEPARATOR = "_;_";
+
+ private EPackage.Registry registry;
+
+ public EcoreModelElementType() {
+ registry = PackageRegistryProvider.getInstance().getPackageRegistry();
+ }
+
+ public Object assemble(Serializable cached, Object owner)
+ throws HibernateException {
+ return convertFromString((String) cached);
+ }
+
+ public Object deepCopy(Object value) throws HibernateException {
+ return value;
+ }
+
+ public Serializable disassemble(Object value) throws HibernateException {
+ return convertToString(value);
+ }
+
+ public boolean equals(Object x, Object y) throws HibernateException {
+ if (x == null && y == null) {
+ return true;
+ }
+
+ if (x == null || y == null) {
+ return false;
+ }
+
+ if (x.getClass() != y.getClass()) {
+ return false;
+ }
+ return x.equals(y);
+ }
+
+ public int hashCode(Object x) throws HibernateException {
+ return x.hashCode();
+ }
+
+ public boolean isMutable() {
+ return false;
+ }
+
+ public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
+ throws HibernateException, SQLException {
+ final String value = rs.getString(names[0]);
+ if (rs.wasNull()) {
+ return null;
+ }
+ return convertFromString(value);
+ }
+
+ private Object convertFromString(String value) {
+ final String[] values = value.split(SEPARATOR);
+ final String nsuri = values[0];
+ final EPackage ePackage = registry.getEPackage(nsuri);
+ if (values.length == 1) { // EPackage
+ return ePackage;
+ } else if (values.length == 2) { // EClassifier
+ final String eClassifierName = values[1];
+ final EClassifier eClassifier = ePackage
+ .getEClassifier(eClassifierName);
+ return eClassifier;
+ } else {
+ final String eClassifierName = values[1];
+ final EClassifier eClassifier = ePackage
+ .getEClassifier(eClassifierName);
+ final EClass eClass = (EClass) eClassifier;
+ final String eFeatureName = values[2];
+ return eClass.getEStructuralFeature(eFeatureName);
+ }
+ }
+
+ public void nullSafeSet(PreparedStatement st, Object value, int index)
+ throws HibernateException, SQLException {
+ if (value == null) {
+ st.setNull(index, Types.VARCHAR);
+ } else {
+ st.setString(index, convertToString(value));
+ }
+ }
+
+ private String convertToString(Object value) {
+ if (value instanceof EPackage) {
+ final String uri = ((EPackage) value).getNsURI();
+ return uri;
+
+ } else if (value instanceof EClassifier) {
+ final EClassifier eClassifier = (EClassifier) value;
+ final String uri = eClassifier.getEPackage().getNsURI();
+ final String eClassifierName = eClassifier.getName();
+ return uri + SEPARATOR + eClassifierName;
+
+ } else {
+ final EStructuralFeature feature = (EStructuralFeature) value;
+ final String uri = feature.getEContainingClass().getEPackage()
+ .getNsURI();
+ final String eClassName = feature.getEContainingClass().getName();
+ final String eFeatureName = feature.getName();
+ return uri + SEPARATOR + eClassName + SEPARATOR + eFeatureName;
+ }
+ }
+
+ public Object replace(Object original, Object target, Object owner)
+ throws HibernateException {
+ return original;
+ }
+
+ public Class<?> returnedClass() {
+ return EStructuralFeature.class;
+ }
+
+ public int[] sqlTypes() {
+ return SQL_TYPES;
+ }
+
+ public void setParameterValues(Properties parameters) {
+ // TODO Auto-generated method stub
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/ExternalType.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/ExternalType.java
new file mode 100755
index 000000000..ec0ebcde1
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/ExternalType.java
@@ -0,0 +1,151 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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
+ *
+ * </copyright>
+ *
+ * $Id: ExternalType.java,v 1.4 2009/10/15 20:35:48 mtaal Exp $
+ */
+package org.eclipse.emf.teneo.hibernate.mapping;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Properties;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.teneo.PackageRegistryProvider;
+import org.eclipse.emf.teneo.hibernate.mapper.HbMapperConstants;
+import org.hibernate.usertype.ParameterizedType;
+import org.hibernate.usertype.UserType;
+
+/**
+ * Provides a way to store external references (references to objects not in the same datastore) as a string/uri.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ */
+public class ExternalType implements UserType, ParameterizedType {
+
+ private static final int[] SQL_TYPES = { Types.VARCHAR };
+ private EClass eClass;
+
+ private EPackage.Registry registry;
+
+ public int[] sqlTypes() {
+ return SQL_TYPES;
+ }
+
+ public Class<?> returnedClass() {
+ return eClass.getInstanceClass();
+ }
+
+ public boolean isMutable() {
+ return true;
+ }
+
+ public ExternalType() {
+ registry = PackageRegistryProvider.getInstance().getPackageRegistry();
+ }
+
+ public Object deepCopy(Object value) {
+ return value;
+ }
+
+ public boolean equals(Object x, Object y) {
+ if (x == y) {
+ return true;
+ }
+ if (x == null || y == null) {
+ return false;
+ }
+ return x.equals(y);
+ }
+
+ public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws SQLException {
+
+ final String data = resultSet.getString(names[0]);
+ if (data == null) {
+ return null;
+ }
+
+ // now create a new instance and set its proxyuri
+ final InternalEObject newValue = (InternalEObject) eClass.getEPackage().getEFactoryInstance().create(eClass);
+ final URI uri = URI.createURI(data);
+ newValue.eSetProxyURI(uri);
+ return newValue;
+ }
+
+ public void nullSafeSet(PreparedStatement statement, Object value, int index) throws SQLException {
+ String pvalue = null;
+ if (value != null) {
+ final Resource res = ((InternalEObject) value).eResource();
+ URI uri = res.getURI();
+ final String fragment = res.getURIFragment((EObject) value);
+ uri = uri.appendFragment(fragment);
+ pvalue = uri.toString();
+ }
+ if (pvalue != null) {
+ statement.setString(index, pvalue);
+ } else {
+ statement.setNull(index, Types.VARCHAR);
+ }
+ }
+
+ public Serializable disassemble(Object value) {
+ return (Serializable) value;
+ }
+
+ public Object assemble(Serializable cachedValue, Object owner) {
+ return cachedValue;
+ }
+
+ public Object replace(Object original, Object target, Object owner) {
+ return original;
+ }
+
+ public int hashCode(Object x) {
+ return x.hashCode();
+ }
+
+ public void setParameterValues(Properties properties) {
+ final String ePackageNsUri = properties.getProperty(HbMapperConstants.EPACKAGE_PARAM);
+ if (ePackageNsUri == null || ePackageNsUri.length() == 0) {
+ throw new IllegalArgumentException("Could not find custom UserType property "
+ + HbMapperConstants.EPACKAGE_PARAM);
+ }
+ final EPackage epackage = registry.getEPackage(ePackageNsUri);
+ if (epackage == null) {
+ throw new IllegalArgumentException("Could not find ePackage using nsuri " + ePackageNsUri);
+ }
+ final String eClassName = properties.getProperty(HbMapperConstants.ECLASS_NAME_META);
+ if (eClassName == null) {
+ throw new IllegalArgumentException("Could not find custom UserType property "
+ + HbMapperConstants.ECLASS_NAME_META);
+ }
+ final EClassifier eclassifier = epackage.getEClassifier(eClassName);
+ if (eclassifier instanceof EClass) {
+ eClass = (EClass) eclassifier;
+ } else {
+ if (eclassifier == null) {
+ throw new IllegalArgumentException("Missing eClass " + eClassName + " in package implementation "
+ + epackage.getName());
+ } else {
+ throw new IllegalArgumentException("Found property of type " + eclassifier.getClass().getName()
+ + " when an EClass was expected.");
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/HibernatePersistentStoreAdapter.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/HibernatePersistentStoreAdapter.java
new file mode 100644
index 000000000..b7e9a2c1c
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/HibernatePersistentStoreAdapter.java
@@ -0,0 +1,65 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: HibernatePersistentStoreAdapter.java,v 1.1 2009/03/15 08:09:22 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.teneo.hibernate.mapping.elist.HibernateFeatureMapEntry;
+import org.eclipse.emf.teneo.type.PersistentStoreAdapter;
+
+/**
+ * See superclass.
+ *
+ * This class adds translation of featuremapentries to hibernate feature map
+ * entries.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.1 $
+ */
+
+public class HibernatePersistentStoreAdapter extends PersistentStoreAdapter {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected Object replaceValue(Object value, EStructuralFeature eFeature) {
+ if (value instanceof FeatureMap.Entry) {
+ final FeatureMap.Entry entry = (FeatureMap.Entry) value;
+ final HibernateFeatureMapEntry fme = new HibernateFeatureMapEntry();
+ fme.setFeatureValue(entry.getEStructuralFeature(),
+ entry.getValue(),
+ (FeatureMap.Internal) ((EObject) getTarget())
+ .eGet(eFeature));
+ return fme;
+ }
+ return value;
+ }
+
+ @Override
+ protected List<Object> replaceValues(List<Object> values,
+ EStructuralFeature eFeature) {
+ final List<Object> result = new ArrayList<Object>();
+ for (Object value : values) {
+ result.add(replaceValue(value, eFeature));
+ }
+ return result;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/QNameUserType.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/QNameUserType.java
new file mode 100755
index 000000000..77df05b0d
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/QNameUserType.java
@@ -0,0 +1,175 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: QNameUserType.java,v 1.2 2008/02/28 07:08:24 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import javax.xml.namespace.QName;
+
+import org.eclipse.emf.teneo.hibernate.HbStoreException;
+import org.hibernate.HibernateException;
+import org.hibernate.usertype.UserType;
+
+/**
+ * Implements the Hibernate UserType for the QName. It stores the three parts of the qname in one
+ * varchar.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.2 $ $Date: 2008/02/28 07:08:24 $
+ */
+
+public class QNameUserType implements UserType {
+
+ private static final int[] SQL_TYPES = new int[] { Types.VARCHAR };
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#assemble(java.io.Serializable, java.lang.Object)
+ */
+ public Object assemble(Serializable cached, Object owner) throws HibernateException {
+ return cached;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object)
+ */
+ public Object deepCopy(Object value) throws HibernateException {
+ return value;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
+ */
+ public Serializable disassemble(Object value) throws HibernateException {
+ return (Serializable) value;
+ }
+
+ /** Compares the int values of the enumerates */
+ public boolean equals(Object x, Object y) throws HibernateException {
+ // todo: check compare on null values
+ if (x == null && y == null) {
+ return true;
+ }
+
+ if (x == null || y == null) {
+ return false;
+ }
+
+ if (x.getClass() != y.getClass()) {
+ return false;
+ }
+
+ final QName q1 = (QName) x;
+ final QName q2 = (QName) y;
+
+ return q1.toString().compareTo(q2.toString()) == 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
+ */
+ public int hashCode(Object x) throws HibernateException {
+ return x.toString().hashCode();
+ }
+
+ /** Not mutable */
+ public boolean isMutable() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet, java.lang.String[],
+ * java.lang.Object)
+ */
+ public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+ final String str = rs.getString(names[0]);
+ if (rs.wasNull()) {
+ return null;
+ }
+ return convertFromString(str);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement,
+ * java.lang.Object, int)
+ */
+ public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ if (value == null) {
+ st.setNull(index, Types.VARCHAR);
+ } else {
+ st.setString(index, convertToString((QName) value));
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.UserType#replace(java.lang.Object, java.lang.Object,
+ * java.lang.Object)
+ */
+ public Object replace(Object original, Object target, Object owner) throws HibernateException {
+ return original;
+ }
+
+ /** Returns the parameterizezd enumType */
+ public Class<?> returnedClass() {
+ return QName.class;
+ }
+
+ /** An enum is stored in one varchar */
+ public int[] sqlTypes() {
+ return SQL_TYPES;
+ }
+
+ protected String convertToString(QName qName) {
+ return "{" + qName.getNamespaceURI() + "}" + qName.getPrefix() + ":" + qName.getLocalPart();
+ }
+
+ protected QName convertFromString(String str) {
+ if (str.indexOf("{") == -1) {
+ throw new HbStoreException("String " + str + " can not be converted to a QName, missing starting {");
+ }
+ final int endIndexNS = str.indexOf("}");
+ if (endIndexNS == -1) {
+ throw new HbStoreException("String " + str +
+ " can not be converted to a QName, missing end ns delimiter } ");
+ }
+ final int prefixIndex = str.indexOf(":", endIndexNS);
+ if (prefixIndex == -1) {
+ throw new HbStoreException("String " + str + " can not be converted to a QName, missing prefix delimiter :");
+ }
+ final String ns = str.substring(1, endIndexNS);
+ final String prefix = str.substring(endIndexNS + 1, prefixIndex);
+ final String localPart = str.substring(prefixIndex + 1);
+ return new QName(ns, localPart, prefix);
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/SerializableDynamicEObjectImpl.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/SerializableDynamicEObjectImpl.java
new file mode 100644
index 000000000..4747f4c44
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/SerializableDynamicEObjectImpl.java
@@ -0,0 +1,122 @@
+/**
+ * <copyright> Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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: Martin Taal </copyright> $Id:
+ * DynamicAction.java,v 1.4 2007/03/20 23:33:38 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.impl.DynamicEObjectImpl;
+
+/**
+ * A DynamicEObjectImpl which implements Serializable. This is required by Hibernate.
+ *
+ * TODO: probably serialization code has to be added to actually support serialization of a
+ * DynamicEObjectImpl. Often however Hibernate won't really serialize the object, so it might not be
+ * necessary for most cases.
+ *
+ * Implements Map so that Hibernate can use the MapAccessor to get to the values.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.2 $
+ */
+public class SerializableDynamicEObjectImpl extends DynamicEObjectImpl implements Serializable, Map<String, Object> {
+
+ private static final long serialVersionUID = 1L;
+
+ public SerializableDynamicEObjectImpl(EClass eClass) {
+ super(eClass);
+ }
+
+ public int size() {
+ return eClass().getEAllStructuralFeatures().size();
+ }
+
+ public boolean isEmpty() {
+ // an eobject is never empty
+ return false;
+ }
+
+ public boolean containsKey(Object key) {
+ if (!(key instanceof String)) {
+ return false;
+ }
+ final String keyString = (String)key;
+ final EStructuralFeature eFeature = eClass().getEStructuralFeature(keyString);
+ if (eFeature == null) {
+ return false;
+ }
+ return true;
+ }
+
+ public boolean containsValue(Object value) {
+ if (value == null) {
+ return false;
+ }
+ for (EStructuralFeature eFeature : eClass().getEAllStructuralFeatures()) {
+ final Object featureValue = eGet(eFeature);
+ if (featureValue != null && value.equals(featureValue)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Object get(Object key) {
+ return eGet(eClass().getEStructuralFeature((String)key));
+ }
+
+ public Object put(String key, Object value) {
+ final Object currentValue = eGet(eClass().getEStructuralFeature(key));
+ eSet(eClass().getEStructuralFeature(key), value);
+ return currentValue;
+ }
+
+ public Object remove(Object key) {
+ final Object value = get(key);
+ eSet(eClass().getEStructuralFeature((String)key), null);
+ return value;
+ }
+
+ public void putAll(Map<? extends String, ? extends Object> t) {
+ for (String key : t.keySet()) {
+ put(key, t.get(key));
+ }
+ }
+
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Set<String> keySet() {
+ final HashSet<String> keySet = new HashSet<String>();
+ for (EStructuralFeature eFeature : eClass().getEAllStructuralFeatures()) {
+ keySet.add(eFeature.getName());
+ }
+ return keySet;
+ }
+
+ public Collection<Object> values() {
+ final List<Object> values = new ArrayList<Object>();
+ for (EStructuralFeature eFeature : eClass().getEAllStructuralFeatures()) {
+ values.add(eGet(eFeature));
+ }
+ return values;
+ }
+
+ public Set<java.util.Map.Entry<String, Object>> entrySet() {
+ throw new UnsupportedOperationException();
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/XSDDate.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/XSDDate.java
new file mode 100755
index 000000000..9a506ec8a
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/XSDDate.java
@@ -0,0 +1,104 @@
+/**
+ * <copyright>
+ *
+ * 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:
+ * Brian Vetter
+ * </copyright>
+ *
+ * $Id: XSDDate.java,v 1.2 2007/07/04 19:27:28 mtaal Exp $
+ */
+package org.eclipse.emf.teneo.hibernate.mapping;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Date;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+
+import org.eclipse.emf.teneo.hibernate.HbStoreException;
+import org.eclipse.emf.teneo.util.EcoreDataTypes;
+import org.hibernate.HibernateException;
+
+/**
+ * Implements the hibernate UserType for EMF's XMLGregorianCalendar ("date" type in XSD).
+ *
+ * @author <a href="mailto:bvetter@alterpoint.com">Brian Vetter</a>
+ * @version $Id
+ */
+public class XSDDate extends XSDDateTime {
+
+ static final long serialVersionUID = 1;
+
+ // local copy of the datatype facatory
+ private final DatatypeFactory dataTypeFactory;
+
+ public XSDDate() {
+ try {
+ dataTypeFactory = DatatypeFactory.newInstance();
+ } catch (DatatypeConfigurationException e) {
+ throw new HbStoreException("Exception ", e);
+ }
+ }
+
+ /*
+ * Returns the DATETIME type that maps to the sql TIMESTAMP type
+ *
+ * @see org.hibernate.type.NullableType#sqlType()
+ */
+ @Override
+ public int sqlType() {
+ return Types.DATE;
+ }
+
+ /*
+ * returns a name for the user type
+ *
+ * @see org.hibernate.type.Type#getName()
+ */
+ @Override
+ public String getName() {
+ return "xmldate";
+ }
+
+ /*
+ * Transform the date in the resultSet into a XMLGregorianCalendar instance.
+ *
+ * @see org.hibernate.type.NullableType#get(java.sql.ResultSet, java.lang.String)
+ */
+ @Override
+ public Object get(ResultSet resultSet, String name) throws SQLException {
+ Date date = resultSet.getDate(name);
+ if (date == null) {
+ return null;
+ }
+ return EcoreDataTypes.INSTANCE.getXMLGregorianCalendar(date);
+ }
+
+ /*
+ * Transform the XMLCalendar into a date type to store in the database
+ *
+ * @see org.hibernate.type.NullableType#set(java.sql.PreparedStatement, java.lang.Object, int)
+ */
+ @Override
+ public void set(PreparedStatement statement, Object value, int index) throws SQLException {
+ java.sql.Date d = new java.sql.Date(((XMLGregorianCalendar) value).toGregorianCalendar().getTime().getTime());
+ statement.setDate(index, d);
+ }
+
+ /*
+ * @see org.hibernate.type.NullableType#fromStringValue(java.lang.String)
+ */
+ @Override
+ public Object fromStringValue(String s) throws HibernateException {
+ return dataTypeFactory.newXMLGregorianCalendar(s);
+ }
+}
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/XSDDateTime.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/XSDDateTime.java
new file mode 100755
index 000000000..807e0c085
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/XSDDateTime.java
@@ -0,0 +1,173 @@
+/**
+ * <copyright>
+ *
+ * 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:
+ * Brian Vetter
+ * Martin Taal
+ * Alexandros Karypidis (bugzilla 207799)
+ * </copyright>
+ *
+ * $Id: XSDDateTime.java,v 1.4 2010/11/12 09:33:33 mtaal Exp $
+ */
+package org.eclipse.emf.teneo.hibernate.mapping;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.sql.Types;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+
+import org.eclipse.emf.teneo.hibernate.HbStoreException;
+import org.eclipse.emf.teneo.util.EcoreDataTypes;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.type.MutableType;
+
+/**
+ * Implements the hibernate UserType for EMF's XMLGregorianCalendar ("datetime"
+ * type in XSD).
+ *
+ * @author <a href="mailto:bvetter@alterpoint.com">Brian Vetter</a>
+ * @version $Revision
+ */
+@SuppressWarnings("deprecation")
+public class XSDDateTime extends MutableType {
+
+ static final long serialVersionUID = 1;
+
+ // local copy of the datatype facatory
+ private final DatatypeFactory dataTypeFactory;
+
+ public XSDDateTime() {
+ try {
+ dataTypeFactory = DatatypeFactory.newInstance();
+ } catch (DatatypeConfigurationException e) {
+ throw new HbStoreException("Exception ", e);
+ }
+ }
+
+ /*
+ * Returns the DATETIME type that maps to the sql TIMESTAMP type
+ *
+ * @see org.hibernate.type.NullableType#sqlType()
+ */
+ @Override
+ public int sqlType() {
+ return Types.TIMESTAMP;
+ }
+
+ /*
+ * Copy the XMLGregorianCalendar object
+ *
+ * @see org.hibernate.type.MutableType#deepCopyNotNull(java.lang.Object)
+ */
+ @Override
+ public Object deepCopyNotNull(Object value) {
+ return dataTypeFactory
+ .newXMLGregorianCalendar(((XMLGregorianCalendar) value)
+ .toGregorianCalendar());
+ }
+
+ /*
+ * returns a name for the user type
+ *
+ * @see org.hibernate.type.Type#getName()
+ */
+ public String getName() {
+ return "xmldatetime";
+ }
+
+ /*
+ * This returns an XMLGregorianCalendar.class type
+ *
+ * @see org.hibernate.type.Type#getReturnedClass()
+ */
+ public Class<?> getReturnedClass() {
+ return XMLGregorianCalendar.class;
+ }
+
+ /*
+ * @see org.hibernate.type.NullableType#isEqual(java.lang.Object,
+ * java.lang.Object)
+ */
+ @Override
+ public boolean isEqual(Object x, Object y) throws HibernateException {
+ if (x == y) {
+ return true;
+ }
+ if (x == null || y == null) {
+ return false;
+ }
+ if (x.getClass() != y.getClass()) {
+ return false;
+ }
+ return x.equals(y);
+ }
+
+ /*
+ * @see org.hibernate.type.AbstractType#getHashCode(java.lang.Object,
+ * org.hibernate.EntityMode)
+ */
+ @Override
+ public int getHashCode(Object x, EntityMode entityMode)
+ throws HibernateException {
+ return x.hashCode();
+ }
+
+ /*
+ * Transform the date in the resultSet into a XMLGregorianCalendar instance.
+ *
+ * @see org.hibernate.type.NullableType#get(java.sql.ResultSet,
+ * java.lang.String)
+ */
+ @Override
+ public Object get(ResultSet resultSet, String name) throws SQLException {
+ // MT: changed this to timestamp to get the seconds right
+ Timestamp ts = resultSet.getTimestamp(name);
+ if (ts == null) {
+ return null;
+ }
+ return EcoreDataTypes.INSTANCE.getXMLGregorianCalendarDateTime(ts);
+ }
+
+ /*
+ * Transform the XMLGregorianCalendar into a timestamp type to store in the
+ * database
+ *
+ * @see org.hibernate.type.NullableType#set(java.sql.PreparedStatement,
+ * java.lang.Object, int)
+ */
+ @Override
+ public void set(PreparedStatement statement, Object value, int index)
+ throws SQLException {
+ Timestamp d = new Timestamp(((XMLGregorianCalendar) value)
+ .toGregorianCalendar().getTime().getTime());
+ statement.setTimestamp(index, d);
+ }
+
+ /*
+ * @see org.hibernate.type.NullableType#toString(java.lang.Object)
+ */
+ @Override
+ public String toString(Object val) {
+
+ return ((XMLGregorianCalendar) val).toString();
+ }
+
+ /*
+ * @see org.hibernate.type.NullableType#fromStringValue(java.lang.String)
+ */
+ @Override
+ public Object fromStringValue(String s) throws HibernateException {
+ return dataTypeFactory.newXMLGregorianCalendar(s);
+ }
+}
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/XSDDuration.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/XSDDuration.java
new file mode 100755
index 000000000..4d131ee3c
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/XSDDuration.java
@@ -0,0 +1,212 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: XSDDuration.java,v 1.5 2008/09/04 10:45:17 mtaal Exp $
+ */
+package org.eclipse.emf.teneo.hibernate.mapping;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.Duration;
+
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.hibernate.usertype.UserType;
+
+/**
+ * Provides a Hibernate extension (called a UserType) to support the xml Duration type. The duration
+ * is persisted as a string.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ */
+public class XSDDuration implements UserType {
+
+ private static final int[] SQL_TYPES = { Types.VARCHAR };
+ private final DatatypeFactory factory;
+
+ /**
+ * Construct a new VARCHAR custom data type.
+ */
+ public XSDDuration() {
+ try {
+ factory = DatatypeFactory.newInstance();
+ } catch (Exception e) {
+ throw new HbMapperException("Exception while creating datatypefactory ", e);
+ }
+ }
+
+ /**
+ * Return the types of the columns that this UserType will serialize into.
+ *
+ * @return a single column of type VARCHAR.
+ */
+ public int[] sqlTypes() {
+ return SQL_TYPES;
+ }
+
+ /**
+ * Return the Java class of the object that is serialized for the column.
+ *
+ * @return the Java instance class associated with the EMF DataType.
+ */
+ public Class<?> returnedClass() {
+ return javax.xml.datatype.Duration.class;
+ }
+
+ /**
+ * Is this datatype mutable?
+ *
+ * @return Being conservative - false always.
+ */
+ public boolean isMutable() {
+ return false;
+ }
+
+ /**
+ * Provide a copy of the datatypes. Converts to String and then back to datatype again.
+ *
+ * @param value
+ * the value to copy.
+ * @return the value always.
+ */
+ public Object deepCopy(Object value) {
+ if (value == null) {
+ return null;
+ }
+ return factory.newDuration(((Duration) value).toString());
+ }
+
+ /**
+ * Are the two objects equal?
+ *
+ * @param x
+ * an object to compare.
+ * @param y
+ * an object to compare.
+ * @return a standard equals test between the objects.
+ */
+ public boolean equals(Object x, Object y) {
+ if (x == y) {
+ return true;
+ }
+ if (x == null || y == null) {
+ return false;
+ }
+ return x.equals(y);
+ }
+
+ /**
+ * Populate the model object property from the ResultSet.
+ *
+ * @param resultSet
+ * the non-null ResultSet from which the field will be populated.
+ * @param names
+ * the names of the columns.
+ * @param owner
+ * the owning object.
+ * @return null if the column's value is null; otherwise, use the EMF factory to construct a new
+ * instance of the custom EMF data type from the contents of the String value of the
+ * column.
+ * @throws SQLException
+ * if the value cannot be retrieved from the ResultSet.
+ */
+ public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws SQLException {
+
+ final String data = resultSet.getString(names[0]);
+ if (data == null) {
+ return null;
+ }
+ return factory.newDuration(data);
+ }
+
+ /**
+ * Populate the database statement from the model object property.
+ *
+ * @param statement
+ * the non-null Statement to insert the value into.
+ * @param value
+ * the object to convert.
+ * @param index
+ * the index into the statement where to insert the converted value.
+ * @throws SQLException
+ * if the converted value cannot be set in the statement.
+ */
+ public void nullSafeSet(PreparedStatement statement, Object value, int index) throws SQLException {
+ String pvalue = null;
+ if (value != null) {
+ pvalue = ((Duration) value).toString();
+ }
+ if (pvalue != null) {
+ statement.setString(index, pvalue);
+ } else {
+ statement.setNull(index, Types.VARCHAR);
+ }
+ }
+
+ /**
+ * No-op implementation.
+ *
+ * @param value
+ * the value to dissemble.
+ * @return the value passed in.
+ */
+ public Serializable disassemble(Object value) {
+ if (value == null) {
+ return null;
+ }
+ return ((Duration) value).toString();
+ }
+
+ /**
+ * No-op implementation.
+ *
+ * @param cachedValue
+ * the value to assemble.
+ * @param owner
+ * the owning object.
+ * @return the cachedValue passed in.
+ */
+ public Object assemble(Serializable cachedValue, Object owner) {
+ return cachedValue;
+ }
+
+ /**
+ * No-op implementation.
+ *
+ * @param original
+ * the value to replace.
+ * @param target
+ * the target object.
+ * @param owner
+ * the owning object.
+ * @return the original value passed in.
+ */
+ public Object replace(Object original, Object target, Object owner) {
+ return original;
+ }
+
+ /**
+ * No-op implementation.
+ *
+ * @param x
+ * the object to get the hashcode for.
+ * @return x's hashcode.
+ */
+ public int hashCode(Object x) {
+ return x.hashCode();
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/DelegatingLateLoadingList.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/DelegatingLateLoadingList.java
new file mode 100644
index 000000000..71b345832
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/DelegatingLateLoadingList.java
@@ -0,0 +1,205 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: DelegatingLateLoadingList.java,v 1.1 2009/09/12 05:47:13 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.util.FeatureMap;
+
+/**
+ * A list implementation which initializes its delegate when it is really called and not earlier.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ * @deprecated not used at the moment
+ */
+public class DelegatingLateLoadingList<E extends Object> implements List<E> {
+
+ private List<?> persistentList = null;
+ private List<E> delegateList = null;
+
+ private void initialize() {
+ if (delegateList != null) {
+ return;
+ }
+ delegateList = new ArrayList<E>();
+ for (Object eavValueObj : persistentList) {
+ delegateList.add(getConvertedValue(eavValueObj));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected E getConvertedValue(Object value) {
+ return (E) ((EAVValueHolder) value).getValue();
+ }
+
+ public List<?> getPersistentList() {
+ return persistentList;
+ }
+
+ public void setPersistentList(List<?> persistentList) {
+ this.persistentList = persistentList;
+ }
+
+ public boolean add(E e) {
+ initialize();
+ return delegateList.add(e);
+ }
+
+ public void add(int index, E element) {
+ initialize();
+ delegateList.add(index, element);
+ }
+
+ public boolean addAll(Collection<? extends E> c) {
+ initialize();
+ return delegateList.addAll(c);
+ }
+
+ public boolean addAll(int index, Collection<? extends E> c) {
+ initialize();
+ return delegateList.addAll(index, c);
+ }
+
+ public void clear() {
+ initialize();
+ delegateList.clear();
+ }
+
+ public boolean contains(Object o) {
+ initialize();
+ return delegateList.contains(o);
+ }
+
+ public boolean containsAll(Collection<?> c) {
+ initialize();
+ return delegateList.containsAll(c);
+ }
+
+ public boolean equals(Object o) {
+ initialize();
+ return delegateList.equals(o);
+ }
+
+ public E get(int index) {
+ initialize();
+ return delegateList.get(index);
+ }
+
+ public int hashCode() {
+ initialize();
+ return delegateList.hashCode();
+ }
+
+ public int indexOf(Object o) {
+ initialize();
+ return delegateList.indexOf(o);
+ }
+
+ public boolean isEmpty() {
+ initialize();
+ return delegateList.isEmpty();
+ }
+
+ public Iterator<E> iterator() {
+ initialize();
+ return delegateList.iterator();
+ }
+
+ public int lastIndexOf(Object o) {
+ initialize();
+ return delegateList.lastIndexOf(o);
+ }
+
+ public ListIterator<E> listIterator() {
+ initialize();
+ return delegateList.listIterator();
+ }
+
+ public ListIterator<E> listIterator(int index) {
+ initialize();
+ return delegateList.listIterator(index);
+ }
+
+ public E remove(int index) {
+ initialize();
+ return delegateList.remove(index);
+ }
+
+ public boolean remove(Object o) {
+ initialize();
+ return delegateList.remove(o);
+ }
+
+ public boolean removeAll(Collection<?> c) {
+ initialize();
+ return delegateList.removeAll(c);
+ }
+
+ public boolean retainAll(Collection<?> c) {
+ initialize();
+ return delegateList.retainAll(c);
+ }
+
+ public E set(int index, E element) {
+ initialize();
+ return delegateList.set(index, element);
+ }
+
+ public int size() {
+ initialize();
+ return delegateList.size();
+ }
+
+ public List<E> subList(int fromIndex, int toIndex) {
+ initialize();
+ return delegateList.subList(fromIndex, toIndex);
+ }
+
+ public Object[] toArray() {
+ initialize();
+ return delegateList.toArray();
+ }
+
+ public <T> T[] toArray(T[] a) {
+ initialize();
+ return delegateList.toArray(a);
+ }
+
+ public static class FeatureMapList extends DelegatingLateLoadingList<FeatureMap.Entry> {
+
+ private InternalEObject owner;
+
+ protected FeatureMap.Entry getConvertedValue(Object value) {
+ return (FeatureMap.Entry) ((EAVValueHolder) value).get(owner);
+ }
+
+ public InternalEObject getOwner() {
+ return owner;
+ }
+
+ public void setOwner(InternalEObject owner) {
+ this.owner = owner;
+ }
+
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVBlobValue.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVBlobValue.java
new file mode 100644
index 000000000..61f5c1fcb
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVBlobValue.java
@@ -0,0 +1,64 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVBlobValue.java,v 1.1 2009/09/11 22:52:36 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+/**
+ * Holds a blob value.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EAVBlobValue {
+
+ private long id;
+ private int version;
+
+ private byte[] blobValue;
+ private EAVSingleEAttributeValueHolder valueHolder;
+
+ public EAVSingleEAttributeValueHolder getValueHolder() {
+ return valueHolder;
+ }
+
+ public void setValueHolder(EAVSingleEAttributeValueHolder valueHolder) {
+ this.valueHolder = valueHolder;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ public void setVersion(int version) {
+ this.version = version;
+ }
+
+ public byte[] getBlobValue() {
+ return blobValue;
+ }
+
+ public void setBlobValue(byte[] blobValue) {
+ this.blobValue = blobValue;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingEMap.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingEMap.java
new file mode 100644
index 000000000..2224b5ab9
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingEMap.java
@@ -0,0 +1,593 @@
+/**
+ * Copyright (c) 2009 Martin Taal 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:
+ * Martin Taal - initial api
+ */
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import org.eclipse.emf.common.notify.NotificationChain;
+import org.eclipse.emf.common.util.BasicEMap;
+import org.eclipse.emf.common.util.EMap;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EFactory;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.util.EcoreEMap;
+import org.eclipse.emf.ecore.util.InternalEList;
+import org.eclipse.emf.teneo.hibernate.LazyCollectionUtils;
+import org.eclipse.emf.teneo.mapping.elist.PersistableDelegateList;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.collection.AbstractPersistentCollection;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.collection.PersistentList;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * The emap which initializes itself from the persistent collection when first
+ * accessed.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EAVDelegatingEMap<K, V> implements EMap<K, V>, EAVDelegatingList,
+ InternalEList.Unsettable<Map.Entry<K, V>>, EStructuralFeature.Setting,
+ PersistableDelegateList<Map.Entry<K, V>> {
+
+ private static final long serialVersionUID = 1L;
+ private List<EAVValueHolder> persistentList;
+ private EcoreEMap<K, V> delegatingEMap;
+ private EClass entryEClass;
+ private Class<?> entryClass;
+ private InternalEObject owner;
+ private int featureID;
+ private EStructuralFeature eStructuralFeature;
+ private EAVMultiValueHolder valueHolderOwner;
+
+ public EAVDelegatingEMap(EClass entryEClass, Class<?> entryClass,
+ InternalEObject owner, int featureID) {
+ this.entryClass = entryClass;
+ this.entryEClass = entryEClass;
+ this.owner = owner;
+ this.featureID = featureID;
+ }
+
+ public boolean isDelegateInitialized() {
+ return delegatingEMap != null;
+ }
+
+ @SuppressWarnings("unchecked")
+ private void initialize() {
+ if (delegatingEMap != null) {
+ return;
+ }
+ delegatingEMap = new EcoreEMap<K, V>(entryEClass, entryClass, owner,
+ featureID);
+
+ int index = 0;
+ for (Object obj : persistentList) {
+ EAVSingleContainmentEReferenceValueHolder valueHolder = (EAVSingleContainmentEReferenceValueHolder) obj;
+ valueHolder.setListIndex(index++);
+ valueHolder.setValueOwner(getValueHolderOwner());
+ delegatingEMap.basicAdd((BasicEMap.Entry<K, V>) valueHolder
+ .getReferenceValue(), null);
+ }
+ // force the map to be computed, this sets the internal entrydata/size
+ // member
+ delegatingEMap.get(null);
+ }
+
+ public boolean add(Entry<K, V> object) {
+ initialize();
+ return delegatingEMap.add(object);
+ }
+
+ public void add(int index, Entry<K, V> object) {
+ initialize();
+ delegatingEMap.add(index, object);
+ }
+
+ public boolean addAll(Collection<? extends Entry<K, V>> collection) {
+ initialize();
+ return delegatingEMap.addAll(collection);
+ }
+
+ public boolean addAll(int index,
+ Collection<? extends Entry<K, V>> collection) {
+ initialize();
+ return delegatingEMap.addAll(index, collection);
+ }
+
+ public boolean addAllUnique(Collection<? extends Entry<K, V>> collection) {
+ initialize();
+ return delegatingEMap.addAllUnique(collection);
+ }
+
+ public boolean addAllUnique(int index,
+ Collection<? extends Entry<K, V>> collection) {
+ initialize();
+ return delegatingEMap.addAllUnique(index, collection);
+ }
+
+ public void addUnique(Entry<K, V> object) {
+ initialize();
+ delegatingEMap.addUnique(object);
+ }
+
+ public void addUnique(int index, Entry<K, V> object) {
+ initialize();
+ delegatingEMap.addUnique(index, object);
+ }
+
+ public NotificationChain basicAdd(Entry<K, V> object,
+ NotificationChain notifications) {
+ initialize();
+ return delegatingEMap.basicAdd(object, notifications);
+ }
+
+ public boolean basicContains(Object object) {
+ initialize();
+ return delegatingEMap.basicContains(object);
+ }
+
+ public boolean basicContainsAll(Collection<?> collection) {
+ initialize();
+ return delegatingEMap.basicContainsAll(collection);
+ }
+
+ public org.eclipse.emf.common.util.BasicEMap.Entry<K, V> basicGet(int index) {
+ initialize();
+ return delegatingEMap.basicGet(index);
+ }
+
+ public int basicIndexOf(Object object) {
+ initialize();
+ return delegatingEMap.basicIndexOf(object);
+ }
+
+ public Iterator<Entry<K, V>> basicIterator() {
+ initialize();
+ return delegatingEMap.basicIterator();
+ }
+
+ public int basicLastIndexOf(Object object) {
+ initialize();
+ return delegatingEMap.basicLastIndexOf(object);
+ }
+
+ public List<Entry<K, V>> basicList() {
+ initialize();
+ return delegatingEMap.basicList();
+ }
+
+ public ListIterator<Entry<K, V>> basicListIterator() {
+ initialize();
+ return delegatingEMap.basicListIterator();
+ }
+
+ public ListIterator<Entry<K, V>> basicListIterator(int index) {
+ initialize();
+ return delegatingEMap.basicListIterator(index);
+ }
+
+ public NotificationChain basicRemove(Object object,
+ NotificationChain notifications) {
+ initialize();
+ return delegatingEMap.basicRemove(object, notifications);
+ }
+
+ public Object[] basicToArray() {
+ initialize();
+ return delegatingEMap.basicToArray();
+ }
+
+ public <T> T[] basicToArray(T[] array) {
+ initialize();
+ return delegatingEMap.basicToArray(array);
+ }
+
+ public void clear() {
+ initialize();
+ delegatingEMap.clear();
+ }
+
+ public Object clone() {
+ initialize();
+ return delegatingEMap.clone();
+ }
+
+ public boolean contains(Object object) {
+ initialize();
+ return delegatingEMap.contains(object);
+ }
+
+ public boolean containsAll(Collection<?> collection) {
+ initialize();
+ return delegatingEMap.containsAll(collection);
+ }
+
+ public boolean containsKey(Object key) {
+ initialize();
+ return delegatingEMap.containsKey(key);
+ }
+
+ public boolean containsValue(Object value) {
+ initialize();
+ return delegatingEMap.containsValue(value);
+ }
+
+ public Set<Entry<K, V>> entrySet() {
+ initialize();
+ return delegatingEMap.entrySet();
+ }
+
+ public boolean equals(Object object) {
+ initialize();
+ return delegatingEMap.equals(object);
+ }
+
+ public Object get(boolean resolve) {
+ initialize();
+ return delegatingEMap.get(resolve);
+ }
+
+ public org.eclipse.emf.common.util.BasicEMap.Entry<K, V> get(int index) {
+ initialize();
+ return delegatingEMap.get(index);
+ }
+
+ @SuppressWarnings("unchecked")
+ public V get(Object key) {
+ if (isExtraLazyAndNotInitialized()) {
+ final AbstractPersistentCollection persistentCollection = (AbstractPersistentCollection) getDelegate();
+ final SessionImplementor sessionImplementor = ((AbstractPersistentCollection) persistentCollection)
+ .getSession();
+ final Session session = (Session)sessionImplementor;
+ session.flush();
+
+ // create a query
+ // the owner is a EAVMultiValueHolder which has a list of referenceValues
+ // each referenceValue is an EAV_Object which has a values containing
+ // the key and value values. The key can be a primitive or a
+
+ final StringBuilder qryStr = new StringBuilder();
+ if (((EReference)getEStructuralFeature()).isContainment()) {
+ qryStr.append("select singleValue from EAVSingleContainmentEReferenceValueHolder singleValue left join fetch singleValue.eavObjectReference");
+ } else {
+ qryStr.append("select singleValue.referenceValue from EAVSingleNonContainmentEReferenceValueHolder singleValue left join fetch singleValue.eavObjectReference");
+ }
+ final EStructuralFeature keyFeature = entryEClass.getEStructuralFeature("key");
+ final Object keyParameter;
+ if (keyFeature instanceof EReference) {
+ final EReference eReference = (EReference)keyFeature;
+ if (eReference.isContainment()) {
+ qryStr.append(", EAVSingleContainmentEReferenceValueHolder keyValue where");
+ } else {
+ qryStr.append(", EAVSingleNonContainmentEReferenceValueHolder keyValue where");
+ }
+
+ // a reference
+ qryStr.append(" keyValue.referenceValue=:keyParameter ");
+ keyParameter = key;
+ } else {
+ qryStr.append(", EAVSingleEAttributeValueHolder keyValue where");
+ qryStr.append(" keyValue.typeNeutralValue=:keyParameter");
+ final EAttribute eAttribute = (EAttribute)keyFeature;
+ final EFactory eFactory = eAttribute.getEAttributeType().getEPackage().getEFactoryInstance();
+ keyParameter = eFactory.convertToString(eAttribute.getEAttributeType(), key);
+ }
+ qryStr.append( " and keyValue.feature=:feature and singleValue.eavObjectReference=keyValue.owner and singleValue.valueOwner=:owner");
+
+ final Query qry = session.createQuery(qryStr.toString());
+ qry.setParameter("keyParameter", keyParameter);
+ qry.setParameter("feature", keyFeature);
+ qry.setParameter("owner", persistentCollection.getOwner());
+ for (Object o : qry.list()) {
+ final EAVSingleEReferenceValueHolder valueHolder = (EAVSingleEReferenceValueHolder)o;
+ final Object result = valueHolder.getReferenceValue();
+ if (!(result instanceof EObject)) {
+ continue;
+ }
+
+ final EObject eContainer = ((EObject)result).eContainer();
+ final EObject owner = getEObject();
+ if (result instanceof Map.Entry<?, ?> && eContainer == owner) {
+ final Map.Entry<K, V> entry = (Map.Entry<K, V>)result;
+ return entry.getValue();
+ }
+ }
+ return null;
+ }
+ initialize();
+ return delegatingEMap.get(key);
+ }
+
+ public EObject getEObject() {
+ return owner;
+ }
+
+ public EStructuralFeature getEStructuralFeature() {
+ return eStructuralFeature;
+ }
+
+ public int hashCode() {
+ initialize();
+ return delegatingEMap.hashCode();
+ }
+
+ public int indexOf(Object object) {
+ initialize();
+ return delegatingEMap.indexOf(object);
+ }
+
+ public int indexOfKey(Object key) {
+ initialize();
+ return delegatingEMap.indexOfKey(key);
+ }
+
+ public boolean isEmpty() {
+ return size() == 0;
+ }
+
+ public boolean isSet() {
+ return !isEmpty();
+ }
+
+ public Iterator<Entry<K, V>> iterator() {
+ if (isExtraLazyAndNotInitialized()) {
+ // return a paging iterator
+ return LazyCollectionUtils.getPagedLoadingIterator(this,
+ LazyCollectionUtils.DEFAULT_PAGE_SIZE);
+ }
+ initialize();
+ return delegatingEMap.iterator();
+ }
+
+ public Set<K> keySet() {
+ initialize();
+ return delegatingEMap.keySet();
+ }
+
+ public int lastIndexOf(Object object) {
+ initialize();
+ return delegatingEMap.lastIndexOf(object);
+ }
+
+ public ListIterator<Entry<K, V>> listIterator() {
+ initialize();
+ return delegatingEMap.listIterator();
+ }
+
+ public ListIterator<Entry<K, V>> listIterator(int index) {
+ initialize();
+ return delegatingEMap.listIterator(index);
+ }
+
+ public Map<K, V> map() {
+ initialize();
+ return delegatingEMap.map();
+ }
+
+ public void move(int index, Entry<K, V> object) {
+ initialize();
+ delegatingEMap.move(index, object);
+ }
+
+ public Entry<K, V> move(int targetIndex, int sourceIndex) {
+ initialize();
+ return delegatingEMap.move(targetIndex, sourceIndex);
+ }
+
+ @SuppressWarnings("unchecked")
+ public V put(K key, V value) {
+ if (isExtraLazyAndNotInitialized()) {
+ final Map.Entry<K, V> entry = (Map.Entry<K, V>) get(key);
+ if (entry != null
+ && entry instanceof org.eclipse.emf.common.util.BasicEMap.Entry<?, ?>) {
+ final V result = entry.getValue();
+ entry.setValue(value);
+ return result;
+ } else {
+ final EAVValueHolder valueHolder = (EAVValueHolder) getValueHolderOwner()
+ .getElement(newEntry(key, value));
+ valueHolder.setListIndex(getPersistentList().size());
+ getPersistentList().add(valueHolder);
+ return null;
+ }
+ } else {
+ initialize();
+ return delegatingEMap.put(key, value);
+ }
+ }
+
+ public void putAll(EMap<? extends K, ? extends V> map) {
+ for (Map.Entry<? extends K, ? extends V> entry : map) {
+ put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ public void putAll(Map<? extends K, ? extends V> map) {
+ for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
+ put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ public Entry<K, V> remove(int index) {
+ initialize();
+ return delegatingEMap.remove(index);
+ }
+
+ public boolean remove(Object object) {
+ initialize();
+ return delegatingEMap.remove(object);
+ }
+
+ public boolean removeAll(Collection<?> collection) {
+ initialize();
+ return delegatingEMap.removeAll(collection);
+ }
+
+ public V removeKey(Object key) {
+ initialize();
+ return delegatingEMap.removeKey(key);
+ }
+
+ public boolean retainAll(Collection<?> collection) {
+ initialize();
+ return delegatingEMap.retainAll(collection);
+ }
+
+ public Entry<K, V> set(int index, Entry<K, V> object) {
+ initialize();
+ return delegatingEMap.set(index, object);
+ }
+
+ public void set(Object value) {
+ initialize();
+ delegatingEMap.set(value);
+ }
+
+ public Entry<K, V> setUnique(int index, Entry<K, V> object) {
+ initialize();
+ return delegatingEMap.setUnique(index, object);
+ }
+
+ public int size() {
+ if (isInitialized()) {
+ return delegatingEMap.size();
+ }
+ return persistentList.size();
+ }
+
+ public List<Entry<K, V>> subList(int start, int end) {
+ initialize();
+ return delegatingEMap.subList(start, end);
+ }
+
+ public Object[] toArray() {
+ initialize();
+ return delegatingEMap.toArray();
+ }
+
+ public <T> T[] toArray(T[] array) {
+ initialize();
+ return delegatingEMap.toArray(array);
+ }
+
+ public String toString() {
+ initialize();
+ return delegatingEMap.toString();
+ }
+
+ public void unset() {
+ initialize();
+ delegatingEMap.unset();
+ }
+
+ public Collection<V> values() {
+ initialize();
+ return delegatingEMap.values();
+ }
+
+ public List<EAVValueHolder> getPersistentList() {
+ return persistentList;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void setPersistentList(List<?> persistentList) {
+ this.persistentList = (List<EAVValueHolder>) persistentList;
+ if (isHibernateListPresent() && getHibernatePersistentList().wasInitialized()) {
+ initialize();
+ } if (persistentList instanceof ArrayList<?>) {
+ // newly persisted
+ initialize();
+ }
+ }
+
+ public Object getDelegate() {
+ return persistentList;
+ }
+
+ public boolean isInitialized() {
+ return delegatingEMap != null;
+ }
+
+ public boolean isLoaded() {
+ return delegatingEMap != null;
+ }
+
+ public void setEStructuralFeature(EStructuralFeature eStructuralFeature) {
+ this.eStructuralFeature = eStructuralFeature;
+ }
+
+ private boolean isHibernateListPresent() {
+ return (persistentList instanceof AbstractPersistentCollection);
+ }
+
+ private EAVMultiValueHolder getValueHolderOwner() {
+ return valueHolderOwner;
+ }
+
+ private PersistentList getHibernatePersistentList() {
+ return (PersistentList) persistentList;
+ }
+
+ protected final boolean isConnectedToSession() {
+ if (!(getDelegate() instanceof AbstractPersistentCollection)) {
+ return false;
+ }
+ final AbstractPersistentCollection persistentCollection = (AbstractPersistentCollection) getDelegate();
+ final SessionImplementor session = ((AbstractPersistentCollection) persistentCollection)
+ .getSession();
+ return isConnectedToSession(session);
+ }
+
+ private final boolean isConnectedToSession(SessionImplementor session) {
+ final PersistentCollection persistentCollection = (PersistentCollection) getDelegate();
+ return session != null
+ && session.isOpen()
+ && session.getPersistenceContext().containsCollection(
+ persistentCollection);
+ }
+
+ private boolean isExtraLazyAndNotInitialized() {
+ if (!isInitialized() && isHibernateListPresent()
+ && isConnectedToSession()) {
+ boolean extraLazyLoaded = getValueHolderOwner() instanceof EAVExtraMultiContainmentEReferenceValueHolder;
+ extraLazyLoaded |= getValueHolderOwner() instanceof EAVExtraMultiNonContainmentEReferenceValueHolder;
+ extraLazyLoaded |= getValueHolderOwner() instanceof EAVExtraMultiEAttributeValueHolder;
+ return extraLazyLoaded;
+ }
+ return false;
+ }
+
+ protected org.eclipse.emf.common.util.BasicEMap.Entry<K, V> newEntry(K key, V value) {
+ @SuppressWarnings("unchecked")
+ org.eclipse.emf.common.util.BasicEMap.Entry<K, V> entry = (org.eclipse.emf.common.util.BasicEMap.Entry<K, V>) entryEClass.getEPackage()
+ .getEFactoryInstance().create(entryEClass);
+ entry.setHash(key.hashCode());
+ entry.setKey(key);
+ entry.setValue(value);
+ return entry;
+ }
+
+ public void setValueHolderOwner(EAVMultiValueHolder valueHolderOwner) {
+ this.valueHolderOwner = valueHolderOwner;
+ }
+}
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingEcoreEList.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingEcoreEList.java
new file mode 100644
index 000000000..9772195c9
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingEcoreEList.java
@@ -0,0 +1,388 @@
+/**
+ * Copyright (c) 2009 Martin Taal 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:
+ * Martin Taal - initial api
+ */
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.util.DelegatingEcoreEList;
+import org.eclipse.emf.teneo.hibernate.LazyCollectionUtils;
+import org.eclipse.emf.teneo.mapping.elist.PersistableDelegateList;
+import org.hibernate.collection.AbstractPersistentCollection;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.collection.PersistentList;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * The list used in instances mapped using the EAV schema. The persistentList is
+ * the Hibernate list present as the referenceValues in the
+ * EAVMulti*ContainmentEReferenceValueHolder.
+ */
+public class EAVDelegatingEcoreEList<E> extends DelegatingEcoreEList<E>
+ implements EAVDelegatingList, PersistableDelegateList<E> {
+
+ private static final long serialVersionUID = 1L;
+ private EStructuralFeature eStructuralFeature;
+ private List<E> delegate;
+ private List<EAVValueHolder> persistentList;
+ private EAVMultiValueHolder valueHolderOwner;
+
+ public EAVDelegatingEcoreEList(InternalEObject owner) {
+ super(owner);
+ }
+
+ protected void initialize() {
+ if (isDelegateInitialized()) {
+ return;
+ }
+ doInitialize();
+ }
+
+ public boolean isDelegateInitialized() {
+ return delegate != null;
+ }
+
+ protected void doInitialize() {
+ delegate = new ArrayList<E>();
+ int index = 0;
+ for (Object eavValueObj : persistentList) {
+ final EAVValueHolder eavValueHolder = (EAVValueHolder) eavValueObj;
+ eavValueHolder.setListIndex(index++);
+ eavValueHolder.setValueOwner(getValueHolderOwner());
+ delegate.add(getConvertedValue(eavValueObj));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected E getConvertedValue(Object value) {
+ return (E) ((EAVValueHolder) value).getValue();
+ }
+
+ @Override
+ protected List<E> delegateList() {
+ initialize();
+ return delegate;
+ }
+
+ public List<?> getDelegate() {
+ return persistentList;
+ }
+
+ public void setDelegate(List<E> delegate) {
+ this.delegate = delegate;
+ }
+
+ public EStructuralFeature getEStructuralFeature() {
+ return eStructuralFeature;
+ }
+
+ public void setEStructuralFeature(EStructuralFeature eStructuralFeature) {
+ this.eStructuralFeature = eStructuralFeature;
+ }
+
+ public List<EAVValueHolder> getPersistentList() {
+ return persistentList;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void setPersistentList(List<?> persistentList) {
+ this.persistentList = (List<EAVValueHolder>) persistentList;
+ if (isHibernateListPresent()
+ && getHibernatePersistentList().wasInitialized()) {
+ doInitialize();
+ } else if (persistentList instanceof ArrayList<?>) {
+ // newly persisted
+ doInitialize();
+ }
+ }
+
+ public boolean isInitialized() {
+ return isDelegateInitialized();
+ }
+
+ public boolean isLoaded() {
+ return isDelegateInitialized();
+ }
+
+ @Override
+ /**
+ * Will always return false, means that the unique check is not performed
+ * for the eav list. This is a small price to pay for increased performance.
+ */
+ public boolean isUnique() {
+ return false;
+ }
+
+ private boolean isHibernateListPresent() {
+ return (persistentList instanceof AbstractPersistentCollection);
+ }
+
+ private PersistentList getHibernatePersistentList() {
+ return (PersistentList) persistentList;
+ }
+
+ protected final boolean isConnectedToSession() {
+ if (!(getDelegate() instanceof AbstractPersistentCollection)) {
+ return false;
+ }
+ final AbstractPersistentCollection persistentCollection = (AbstractPersistentCollection) getDelegate();
+ final SessionImplementor session = ((AbstractPersistentCollection) persistentCollection)
+ .getSession();
+ return isConnectedToSession(session);
+ }
+
+ private final boolean isConnectedToSession(SessionImplementor session) {
+ final PersistentCollection persistentCollection = (PersistentCollection) getDelegate();
+ return session != null
+ && session.isOpen()
+ && session.getPersistenceContext().containsCollection(
+ persistentCollection);
+ }
+
+ @Override
+ protected void delegateAdd(E object) {
+ final EAVValueHolder valueHolder = (EAVValueHolder) getValueHolderOwner()
+ .getElement(object);
+ valueHolder.setListIndex(getHibernatePersistentList().size());
+ persistentList.add(valueHolder);
+
+ if (isDelegateInitialized()) {
+ super.delegateAdd(object);
+ }
+ }
+
+ @Override
+ protected void delegateAdd(int index, E object) {
+ if (index == size() && !isDelegateInitialized()) {
+ delegateAdd(object);
+ // stop here as the delegate is not yet set
+ return;
+ }
+
+ // insert in the middle, load the whole list
+ delegateList();
+
+ final EAVValueHolder valueHolder = (EAVValueHolder) getValueHolderOwner()
+ .getElement(object);
+
+ persistentList.add(index, valueHolder);
+
+ int newIndex = index;
+ // note, can not use the size() call, must do persistentList.size()
+ for (EAVValueHolder element : persistentList.subList(index,
+ persistentList.size())) {
+ element.setListIndex(newIndex++);
+ }
+
+ super.delegateAdd(index, object);
+ }
+
+ @Override
+ protected List<E> delegateBasicList() {
+ return super.delegateBasicList();
+ }
+
+ @Override
+ protected void delegateClear() {
+ for (EAVValueHolder valueHolder : persistentList) {
+ valueHolder.setOwner(null);
+ valueHolder.setValueOwner(null);
+ }
+
+ super.delegateClear();
+ }
+
+ @Override
+ protected boolean delegateContains(Object object) {
+ // TODO: consider building a query to support lazy contains
+ return super.delegateContains(object);
+ }
+
+ @Override
+ protected boolean delegateContainsAll(Collection<?> collection) {
+ // will read the persistent list anyway
+ return super.delegateContainsAll(collection);
+ }
+
+ @Override
+ protected boolean delegateEquals(Object object) {
+ // will read the persistent list anyway
+ return super.delegateEquals(object);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected E delegateGet(int index) {
+ final EAVValueHolder valueHolder = persistentList.get(index);
+ return (E) valueHolder.getValue();
+ }
+
+ @Override
+ protected int delegateHashCode() {
+ // hashcode will read the persistentlist always anyway
+ return super.delegateHashCode();
+ }
+
+ @Override
+ protected int delegateIndexOf(Object object) {
+ // indexof will read the persistentlist always anyway
+ return super.delegateIndexOf(object);
+ }
+
+ @Override
+ protected boolean delegateIsEmpty() {
+ return delegateSize() == 0;
+ }
+
+ @Override
+ public Iterator<E> delegateIterator() {
+ return iterator();
+ }
+
+ @Override
+ public Iterator<E> iterator() {
+ if (!isDelegateInitialized() && isHibernateListPresent()
+ && isConnectedToSession()) {
+ boolean extraLazyLoaded = getValueHolderOwner() instanceof EAVExtraMultiContainmentEReferenceValueHolder;
+ extraLazyLoaded |= getValueHolderOwner() instanceof EAVExtraMultiNonContainmentEReferenceValueHolder;
+ extraLazyLoaded |= getValueHolderOwner() instanceof EAVExtraMultiEAttributeValueHolder;
+ if (extraLazyLoaded) {
+ // return a paging iterator
+ return LazyCollectionUtils.getPagedLoadingIterator(this,
+ LazyCollectionUtils.DEFAULT_PAGE_SIZE);
+ }
+ }
+ return super.iterator();
+ }
+
+ @Override
+ protected int delegateLastIndexOf(Object object) {
+ // will read the persistentlist always anyway
+ return super.delegateLastIndexOf(object);
+ }
+
+ @Override
+ protected ListIterator<E> delegateListIterator() {
+ // will read the persistentlist always anyway
+ return super.delegateListIterator();
+ }
+
+ @Override
+ protected E delegateMove(int targetIndex, int sourceIndex) {
+ final EAVValueHolder result = persistentList.remove(sourceIndex);
+
+ int newIndex = sourceIndex;
+ for (EAVValueHolder element : persistentList.subList(sourceIndex,
+ size())) {
+ element.setListIndex(newIndex++);
+ }
+
+ persistentList.add(targetIndex, result);
+
+ newIndex = targetIndex;
+ for (EAVValueHolder element : persistentList.subList(sourceIndex,
+ size())) {
+ element.setListIndex(newIndex++);
+ }
+ return super.delegateMove(targetIndex, sourceIndex);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected E delegateRemove(int index) {
+ final boolean reallyLazy = index == (size() - 1)
+ && !isDelegateInitialized();
+ if (!reallyLazy) {
+ // force a load before removing
+ delegateList();
+ }
+ final EAVValueHolder result = persistentList.remove(index);
+ result.setOwner(null);
+ result.setValueOwner(null);
+
+ if (reallyLazy) {
+ // no need to update other things
+ return (E) result.getValue();
+ }
+
+ int newIndex = index;
+ // must use persistentList.size() as the delegate size has not yet been
+ // updated!
+ for (EAVValueHolder element : persistentList.subList(index,
+ persistentList.size())) {
+ element.setListIndex(newIndex++);
+ }
+ return super.delegateRemove(index);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected E delegateSet(int index, E object) {
+ final EAVValueHolder newValueHolder = (EAVValueHolder) getValueHolderOwner()
+ .getElement(object);
+ newValueHolder.setListIndex(index);
+ final EAVValueHolder oldValueHolder = persistentList.set(index,
+ newValueHolder);
+
+ // clear old object
+ if (oldValueHolder != null) {
+ oldValueHolder.setOwner(null);
+ oldValueHolder.setValueOwner(null);
+ }
+ if (isDelegateInitialized()) {
+ return super.delegateSet(index, object);
+ }
+ if (oldValueHolder != null) {
+ return (E) oldValueHolder.getValue();
+ }
+ return null;
+ }
+
+ @Override
+ protected int delegateSize() {
+ if (!isDelegateInitialized()) {
+ return persistentList.size();
+ }
+ return delegate.size();
+ }
+
+ @Override
+ protected Object[] delegateToArray() {
+ // will load list anyway
+ return super.delegateToArray();
+ }
+
+ @Override
+ protected <T> T[] delegateToArray(T[] array) {
+ // will load list anyway
+ return super.delegateToArray(array);
+ }
+
+ @Override
+ protected String delegateToString() {
+ // will load list anyway
+ return super.delegateToString();
+ }
+
+ public void setValueHolderOwner(EAVMultiValueHolder valueHolderOwner) {
+ this.valueHolderOwner = valueHolderOwner;
+ }
+
+ private EAVMultiValueHolder getValueHolderOwner() {
+ return valueHolderOwner;
+ }
+
+}
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingFeatureMap.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingFeatureMap.java
new file mode 100644
index 000000000..3a3332e83
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingFeatureMap.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2009 Martin Taal 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:
+ * Martin Taal - initial api
+ */
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.util.DelegatingFeatureMap;
+import org.eclipse.emf.ecore.util.FeatureMap;
+
+/**
+ * The list used in instances mapped using the EAV schema.
+ */
+public class EAVDelegatingFeatureMap extends DelegatingFeatureMap implements EAVDelegatingList {
+
+ private static final long serialVersionUID = 1L;
+ private List<FeatureMap.Entry> delegate;
+ private List<?> persistentList;
+
+ public EAVDelegatingFeatureMap(InternalEObject owner, EStructuralFeature eFeature) {
+ super(owner, eFeature);
+ }
+
+ private void initialize() {
+ if (delegate != null) {
+ return;
+ }
+ delegate = new ArrayList<FeatureMap.Entry>();
+ for (Object eavValueObj : persistentList) {
+ delegate.add((FeatureMap.Entry) ((EAVValueHolder) eavValueObj).get(owner));
+ }
+ }
+
+ public boolean isDelegateInitialized() {
+ return delegate != null;
+ }
+
+ @Override
+ protected List<FeatureMap.Entry> delegateList() {
+ initialize();
+ return delegate;
+ }
+
+ public List<FeatureMap.Entry> getDelegate() {
+ initialize();
+ return delegate;
+ }
+
+ public void setDelegate(List<FeatureMap.Entry> delegate) {
+ this.delegate = delegate;
+ }
+
+ public List<?> getPersistentList() {
+ return persistentList;
+ }
+
+ public void setPersistentList(List<?> persistentList) {
+ this.persistentList = persistentList;
+ }
+}
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingList.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingList.java
new file mode 100644
index 000000000..0056a98d4
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingList.java
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2009 Martin Taal 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:
+ * Martin Taal - initial api
+ */
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.util.List;
+
+/**
+ * Tags EAV list and featuremap.
+ */
+public interface EAVDelegatingList {
+ boolean isDelegateInitialized();
+
+ void setPersistentList(List<?> persistentList);
+}
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVExtraMultiContainmentEReferenceValueHolder.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVExtraMultiContainmentEReferenceValueHolder.java
new file mode 100644
index 000000000..4cd260c69
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVExtraMultiContainmentEReferenceValueHolder.java
@@ -0,0 +1,27 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVExtraMultiContainmentEReferenceValueHolder.java,v 1.1 2010/04/02 15:24:11 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+
+/**
+ * Variant of super class which loads all lists extra-lazily.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EAVExtraMultiContainmentEReferenceValueHolder extends EAVMultiContainmentEReferenceValueHolder {
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVExtraMultiEAttributeValueHolder.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVExtraMultiEAttributeValueHolder.java
new file mode 100644
index 000000000..7f397cc7b
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVExtraMultiEAttributeValueHolder.java
@@ -0,0 +1,27 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVExtraMultiEAttributeValueHolder.java,v 1.1 2010/04/02 15:24:12 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+
+/**
+ * Variant of super class which loads all lists extra-lazily.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EAVExtraMultiEAttributeValueHolder extends EAVMultiEAttributeValueHolder {
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVExtraMultiNonContainmentEReferenceValueHolder.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVExtraMultiNonContainmentEReferenceValueHolder.java
new file mode 100644
index 000000000..f9c55d73e
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVExtraMultiNonContainmentEReferenceValueHolder.java
@@ -0,0 +1,27 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVExtraMultiNonContainmentEReferenceValueHolder.java,v 1.1 2010/04/02 15:24:11 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+
+/**
+ * Variant of super class which loads all lists extra-lazily.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EAVExtraMultiNonContainmentEReferenceValueHolder extends EAVMultiNonContainmentEReferenceValueHolder {
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVFeatureMapEntryValueHolder.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVFeatureMapEntryValueHolder.java
new file mode 100644
index 000000000..599a9588c
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVFeatureMapEntryValueHolder.java
@@ -0,0 +1,106 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVFeatureMapEntryValueHolder.java,v 1.3 2009/08/22 00:09:57 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.impl.EStructuralFeatureImpl;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.ecore.util.FeatureMapUtil;
+
+/**
+ * This class holds a feature map entry which can have a primitive value or an eReference .*
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EAVFeatureMapEntryValueHolder extends EAVSingleEAttributeValueHolder {
+
+ private EObject referenceValue;
+ private EObject containedReferenceValue;
+ private boolean isEReference;
+ private boolean isContainment;
+
+ private FeatureMap.Entry featureMapEntry;
+
+ public void set(Object value) {
+
+ setMandatoryValue(null);
+
+ ;
+ final FeatureMap.Entry entry = (FeatureMap.Entry) value;
+ featureMapEntry = entry;
+ if (entry.getValue() != null) {
+ setMandatoryValue(NOT_NULL_VALUE);
+ }
+ setEStructuralFeature(entry.getEStructuralFeature());
+ if (isEReference) {
+ referenceValue = (EObject) entry.getValue();
+ if (isContainment) {
+ containedReferenceValue = (EObject) entry.getValue();
+ }
+ } else {
+ super.set(entry.getValue());
+ }
+ }
+
+ public FeatureMap.Entry get(InternalEObject owner) {
+ if (featureMapEntry != null) {
+ return featureMapEntry;
+ }
+
+ featureMapEntry = ((EStructuralFeatureImpl) getEStructuralFeature()).getFeatureMapEntryPrototype();
+ if (isEReference) {
+ featureMapEntry = FeatureMapUtil.createEntry(getEStructuralFeature(), referenceValue);
+ } else {
+ featureMapEntry = FeatureMapUtil.createEntry(getEStructuralFeature(), super.get(owner));
+ }
+ return featureMapEntry;
+ }
+
+ public void setValueInOwner(InternalEObject owner) {
+ throw new UnsupportedOperationException("This method should not be called");
+ }
+
+ public EObject getReferenceValue() {
+ return referenceValue;
+ }
+
+ public void setReferenceValue(EObject referenceValue) {
+ this.referenceValue = referenceValue;
+ }
+
+ @Override
+ public void setEStructuralFeature(EStructuralFeature eStructuralFeature) {
+ super.setEStructuralFeature(eStructuralFeature);
+ isEReference = eStructuralFeature instanceof EReference;
+ if (isEReference) {
+ isContainment = ((EReference) eStructuralFeature).isContainment();
+ }
+ }
+
+ public EObject getContainedReferenceValue() {
+ return containedReferenceValue;
+ }
+
+ public void setContainedReferenceValue(EObject containedReferenceValue) {
+ this.containedReferenceValue = containedReferenceValue;
+ }
+
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVFeatureMapValueHolder.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVFeatureMapValueHolder.java
new file mode 100755
index 000000000..60eb6aee4
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVFeatureMapValueHolder.java
@@ -0,0 +1,73 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVFeatureMapValueHolder.java,v 1.5 2010/04/02 15:24:11 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.InternalEObject;
+
+/**
+ * This class holds a multi (ismany) EAttribute value.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EAVFeatureMapValueHolder extends EAVMultiValueHolder {
+
+ private List<EAVFeatureMapEntryValueHolder> values;
+
+ public void set(Object value) {
+ setMandatoryValue(null);
+ final List<?> listValues = (List<?>) value;
+ values = new ArrayList<EAVFeatureMapEntryValueHolder>();
+ for (Object o : listValues) {
+ values.add((EAVFeatureMapEntryValueHolder) getElement(o));
+ setMandatoryValue(NOT_NULL_VALUE);
+ }
+ }
+
+ public Object getValue() {
+ return getValues();
+ }
+
+ public Object getElement(Object value) {
+ final EAVFeatureMapEntryValueHolder valueHolder = new EAVFeatureMapEntryValueHolder();
+ valueHolder.setOwner(getOwner());
+ valueHolder.setHbDataStore(getHbDataStore());
+ valueHolder.set(value);
+ return valueHolder;
+ }
+
+ public Object get(InternalEObject owner) {
+ final EAVDelegatingFeatureMap featureMap = new EAVDelegatingFeatureMap((InternalEObject) owner,
+ getEStructuralFeature());
+ // final DelegatingLateLoadingList.FeatureMapList objValues = new DelegatingLateLoadingList.FeatureMapList();
+ // objValues.setOwner(owner);
+ // objValues.setPersistentList(values);
+ featureMap.setPersistentList(values);
+ return featureMap;
+ }
+
+ public List<EAVFeatureMapEntryValueHolder> getValues() {
+ return values;
+ }
+
+ public void setValues(List<EAVFeatureMapEntryValueHolder> values) {
+ this.values = values;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVGenericIDUserType.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVGenericIDUserType.java
new file mode 100644
index 000000000..461c291a7
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVGenericIDUserType.java
@@ -0,0 +1,128 @@
+/**
+ * Copyright (c) 2004 - 2009 Martin Taal 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:
+ * Martin Taal - initial api
+ * Eike Stepper - maintenance
+ */
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.HashMap;
+
+import org.hibernate.type.StandardBasicTypes;
+import org.hibernate.usertype.UserType;
+
+/**
+ * Is used in a many-to-any to support any type of id.
+ */
+public class EAVGenericIDUserType implements UserType {
+ private static final int[] SQL_TYPES = { Types.VARCHAR };
+
+ private static final String SEPARATOR = "__;__";
+
+ /** Constructor by id */
+ private final HashMap<String, Constructor<?>> constructors = new HashMap<String, Constructor<?>>();
+
+ public EAVGenericIDUserType() {
+ }
+
+ public int[] sqlTypes() {
+ return SQL_TYPES;
+ }
+
+ public Class<?> returnedClass() {
+ return Object.class;
+ }
+
+ public boolean isMutable() {
+ return false;
+ }
+
+ public Object deepCopy(Object value) {
+ return value;
+ }
+
+ public boolean equals(Object x, Object y) {
+ if (x == y) {
+ return true;
+ }
+
+ if (x == null || y == null) {
+ return false;
+ }
+
+ return x.equals(y);
+ }
+
+ public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
+ throws SQLException {
+ final String value = (String) StandardBasicTypes.STRING.nullSafeGet(rs,
+ names[0]);
+ if (rs.wasNull()) {
+ return null;
+ }
+
+ final int end1 = value.indexOf(SEPARATOR);
+ final int start2 = end1 + SEPARATOR.length();
+
+ final String idStr = value.substring(0, end1);
+ final String idClassName = value.substring(start2);
+ final Serializable id = getId(idStr, idClassName);
+ return id;
+ }
+
+ public void nullSafeSet(PreparedStatement statement, Object value, int index)
+ throws SQLException {
+ if (value == null) {
+ statement.setNull(index, Types.VARCHAR);
+ } else {
+ statement.setString(index, value.toString() + SEPARATOR
+ + value.getClass().getName());
+ }
+ }
+
+ public Serializable disassemble(Object value) {
+ return (Serializable) value;
+ }
+
+ public Object assemble(Serializable cachedValue, Object owner) {
+ return cachedValue;
+ }
+
+ public Object replace(Object original, Object target, Object owner) {
+ return original;
+ }
+
+ public int hashCode(Object x) {
+ return x.hashCode();
+ }
+
+ /** Creates an id object of the correct type */
+ private Serializable getId(String idStr, String idType) {
+ try {
+ Constructor<?> constructor = constructors.get(idType);
+ if (constructor == null) {
+ Class<?> idClass = this.getClass().getClassLoader()
+ .loadClass(idType);
+ constructor = idClass
+ .getConstructor(new Class[] { String.class });
+ constructors.put(idType, constructor);
+ }
+
+ return (Serializable) constructor
+ .newInstance(new Object[] { idStr });
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+}
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVInstantiator.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVInstantiator.java
new file mode 100755
index 000000000..bcc7e8728
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVInstantiator.java
@@ -0,0 +1,59 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EAVInstantiator.java,v 1.1 2009/08/21 10:16:36 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.io.Serializable;
+
+import org.eclipse.emf.ecore.EObject;
+import org.hibernate.tuple.Instantiator;
+
+/**
+ * Instantiator for the EAV_EObject root.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.1 $
+ */
+
+public class EAVInstantiator implements Instantiator {
+
+ /**
+ * Generated Serial Version ID
+ */
+ private static final long serialVersionUID = 6946442685247491904L;
+
+ /** Constructor */
+ public EAVInstantiator() {
+ }
+
+ /** Instantiates using EcoreUtil.create() */
+ public Object instantiate() {
+ throw new UnsupportedOperationException();
+ }
+
+ /** Instantiates using EcoreUtil.create() */
+ public Object instantiate(Serializable id) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** Checks using the mapped class or the proxy interface */
+ public boolean isInstance(Object object) {
+ if (object instanceof EObject) {
+ return true;
+ }
+ return false;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiContainmentEReferenceValueHolder.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiContainmentEReferenceValueHolder.java
new file mode 100644
index 000000000..e4b598adc
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiContainmentEReferenceValueHolder.java
@@ -0,0 +1,124 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVMultiContainmentEReferenceValueHolder.java,v 1.11 2010/04/05 05:33:31 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.common.util.BasicEMap;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.teneo.util.StoreUtil;
+
+/**
+ * Stores a multi containment EReference value.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EAVMultiContainmentEReferenceValueHolder extends
+ EAVMultiValueHolder {
+
+ private List<EAVSingleContainmentEReferenceValueHolder> referenceValues;
+ private EAVDelegatingList ecoreObjectList = null;
+
+ @SuppressWarnings("unchecked")
+ public void set(Object value) {
+ // set to null first, if there is at least one value then it is set to a
+ // value
+ setMandatoryValue(null);
+ final List<?> values = (List<Object>) value;
+ referenceValues = new ArrayList<EAVSingleContainmentEReferenceValueHolder>();
+ int index = 0;
+ for (Object o : values) {
+ final EAVSingleContainmentEReferenceValueHolder eavValue = (EAVSingleContainmentEReferenceValueHolder) getElement(o);
+ eavValue.setVirtualListIndex(index++);
+ referenceValues.add(eavValue);
+ setMandatoryValue(NOT_NULL_VALUE);
+ }
+ }
+
+ public Object getElement(Object value) {
+ EAVSingleContainmentEReferenceValueHolder valueHolder = new EAVSingleContainmentEReferenceValueHolder();
+ valueHolder.setEStructuralFeature(getEStructuralFeature());
+ valueHolder.setHbDataStore(getHbDataStore());
+ valueHolder.setOwner(getOwner());
+ valueHolder.setValueOwner(this);
+ valueHolder.set(value);
+ return valueHolder;
+ }
+
+ public Object get(InternalEObject owner) {
+ if (ecoreObjectList != null) {
+ return ecoreObjectList;
+ }
+ setEcoreObjectList();
+ return ecoreObjectList;
+ }
+
+ private void setEcoreObjectList() {
+ if (StoreUtil.isMap(getEStructuralFeature())) {
+ final EClass entryEClass = (EClass) getEStructuralFeature()
+ .getEType();
+ Class<?> entryClass = entryEClass.getInstanceClass();
+ // prevents a failing assertion in the EcoreEMap
+ if (entryClass == null
+ || !BasicEMap.Entry.class.isAssignableFrom(entryClass)) {
+ entryClass = BasicEMap.Entry.class;
+ }
+
+ final int featureID = getOwner().eClass().getFeatureID(
+ getEStructuralFeature());
+ final EAVDelegatingEMap<Object, Object> eMap = new EAVDelegatingEMap<Object, Object>(
+ entryEClass, entryClass, (InternalEObject) getOwner(),
+ featureID);
+ eMap.setValueHolderOwner(this);
+ ecoreObjectList = eMap;
+ eMap.setEStructuralFeature(getEStructuralFeature());
+ eMap.setPersistentList(referenceValues);
+ } else {
+ // final DelegatingLateLoadingList<Object> lateLoadingList = new
+ // DelegatingLateLoadingList<Object>();
+ // lateLoadingList.setPersistentList((List<?>) referenceValues);
+ final EAVDelegatingEcoreEList<Object> ecoreList = new EAVDelegatingEcoreEList<Object>(
+ (InternalEObject) getOwner());
+ ecoreList.setValueHolderOwner(this);
+ ecoreList.setEStructuralFeature(getEStructuralFeature());
+ ecoreList.setPersistentList(referenceValues);
+ ecoreObjectList = ecoreList;
+ }
+
+ }
+
+ public Object getValue() {
+ return referenceValues;
+ }
+
+ public List<EAVSingleContainmentEReferenceValueHolder> getReferenceValues() {
+ return referenceValues;
+ }
+
+ public void setReferenceValues(
+ List<EAVSingleContainmentEReferenceValueHolder> referenceValues) {
+ this.referenceValues = referenceValues;
+ if (ecoreObjectList == null) {
+ setEcoreObjectList();
+ } else {
+ ecoreObjectList.setPersistentList(referenceValues);
+ }
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiEAttributeValueHolder.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiEAttributeValueHolder.java
new file mode 100644
index 000000000..6073060a0
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiEAttributeValueHolder.java
@@ -0,0 +1,83 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVMultiEAttributeValueHolder.java,v 1.5 2010/04/05 05:33:32 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.InternalEObject;
+
+/**
+ * This class holds a multi (ismany) EAttribute value.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EAVMultiEAttributeValueHolder extends EAVMultiValueHolder {
+
+ private List<EAVSingleEAttributeValueHolder> values;
+ private EAVDelegatingList ecoreObjectList = null;
+
+ public void set(Object value) {
+ // set to null first, if there is at least one value then it is set to a value
+ setMandatoryValue(null);
+ final List<?> listValues = (List<?>) value;
+ values = new ArrayList<EAVSingleEAttributeValueHolder>();
+ int index = 0;
+ for (Object o : listValues) {
+ final EAVSingleEAttributeValueHolder eavValue = (EAVSingleEAttributeValueHolder) getElement(o);
+ eavValue.setListIndex(index++);
+ values.add(eavValue);
+ setMandatoryValue(NOT_NULL_VALUE);
+ }
+ }
+
+ public Object getValue() {
+ return values;
+ }
+
+ public Object getElement(Object value) {
+ final EAVSingleEAttributeValueHolder valueHolder = new EAVSingleEAttributeValueHolder();
+ valueHolder.setEStructuralFeature(getEStructuralFeature());
+ valueHolder.setHbDataStore(getHbDataStore());
+ valueHolder.setOwner(getOwner());
+ valueHolder.setValueOwner(this);
+ valueHolder.set(value);
+ return valueHolder;
+ }
+
+ public Object get(InternalEObject owner) {
+ if (ecoreObjectList != null) {
+ return ecoreObjectList;
+ }
+ final EAVDelegatingEcoreEList<Object> ecoreList = new EAVDelegatingEcoreEList<Object>((InternalEObject) owner);
+ ecoreList.setValueHolderOwner(this);
+ ecoreList.setEStructuralFeature(getEStructuralFeature());
+ ecoreList.setPersistentList(values);
+ ecoreObjectList = ecoreList;
+ return ecoreList;
+ }
+
+ public List<EAVSingleEAttributeValueHolder> getValues() {
+ return values;
+ }
+
+ public void setValues(List<EAVSingleEAttributeValueHolder> values) {
+ this.values = values;
+ ((EAVDelegatingList)get((InternalEObject)getOwner())).setPersistentList(values);
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiNonContainmentEReferenceValueHolder.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiNonContainmentEReferenceValueHolder.java
new file mode 100644
index 000000000..ffa818f57
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiNonContainmentEReferenceValueHolder.java
@@ -0,0 +1,86 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVMultiNonContainmentEReferenceValueHolder.java,v 1.7 2010/04/05 05:33:30 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.InternalEObject;
+
+/**
+ * Stores a multi containment EReference value.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EAVMultiNonContainmentEReferenceValueHolder extends EAVMultiValueHolder {
+
+ private List<EAVSingleNonContainmentEReferenceValueHolder> referenceValues;
+ private EAVDelegatingList ecoreObjectList = null;
+
+ @SuppressWarnings("unchecked")
+ public void set(Object value) {
+ // set to null first, if there is at least one value then it is set to a value
+ setMandatoryValue(null);
+ final List<?> values = (List<Object>) value;
+ referenceValues = new ArrayList<EAVSingleNonContainmentEReferenceValueHolder>();
+ int index = 0;
+ for (Object o : values) {
+ final EAVSingleNonContainmentEReferenceValueHolder eavValue = (EAVSingleNonContainmentEReferenceValueHolder) getElement(o);
+ eavValue.setListIndex(index++);
+ referenceValues.add(eavValue);
+ setMandatoryValue(NOT_NULL_VALUE);
+ }
+ }
+
+ public Object getElement(Object value) {
+ EAVSingleNonContainmentEReferenceValueHolder valueHolder = new EAVSingleNonContainmentEReferenceValueHolder();
+ valueHolder.setEStructuralFeature(getEStructuralFeature());
+ valueHolder.setOwner(getOwner());
+ valueHolder.setValueOwner(this);
+ valueHolder.setHbDataStore(getHbDataStore());
+ valueHolder.set(value);
+ return valueHolder;
+ }
+
+ public Object get(InternalEObject owner) {
+ if (ecoreObjectList != null) {
+ return ecoreObjectList;
+ }
+ // final DelegatingLateLoadingList<Object> lateLoadingList = new DelegatingLateLoadingList<Object>();
+ // lateLoadingList.setPersistentList(referenceValues);
+ final EAVDelegatingEcoreEList<Object> ecoreList = new EAVDelegatingEcoreEList<Object>((InternalEObject) owner);
+ ecoreList.setValueHolderOwner(this);
+ ecoreList.setEStructuralFeature(getEStructuralFeature());
+ ecoreList.setPersistentList(referenceValues);
+ ecoreObjectList = ecoreList;
+ return ecoreList;
+ }
+
+ public Object getValue() {
+ return referenceValues;
+ }
+
+ public List<EAVSingleNonContainmentEReferenceValueHolder> getReferenceValues() {
+ return referenceValues;
+ }
+
+ public void setReferenceValues(List<EAVSingleNonContainmentEReferenceValueHolder> referenceValues) {
+ this.referenceValues = referenceValues;
+ ((EAVDelegatingList)get((InternalEObject)getOwner())).setPersistentList(referenceValues);
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiValueHolder.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiValueHolder.java
new file mode 100644
index 000000000..dd1278686
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVMultiValueHolder.java
@@ -0,0 +1,71 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVMultiValueHolder.java,v 1.4 2010/04/02 15:24:11 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.lang.reflect.Field;
+
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.InternalEObject.EStore;
+import org.eclipse.emf.ecore.impl.BasicEObjectImpl;
+import org.eclipse.emf.teneo.hibernate.mapping.property.EcoreAccess;
+import org.eclipse.emf.teneo.util.FieldUtil;
+import org.eclipse.emf.teneo.util.StoreUtil;
+
+/**
+ * This class holds a multi (ismany) EStructuralFeature value.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public abstract class EAVMultiValueHolder extends EAVValueHolder {
+
+ public abstract Object getElement(Object value);
+
+ public void setValueInOwner(InternalEObject owner) {
+
+ if (!EcoreAccess.isStaticFeature(getEStructuralFeature(), (BasicEObjectImpl) owner)) {
+ Object currentValue = EcoreAccess.getManyEFeatureValue(getEStructuralFeature(), (BasicEObjectImpl) owner);
+
+ if (StoreUtil.isEStoreList(currentValue)) {
+ final EStore eStore = owner.eStore();
+ if (eStore.size(owner, getEStructuralFeature()) != -1) {
+ currentValue = eStore.get((InternalEObject) owner, getEStructuralFeature(), EStore.NO_INDEX);
+ }
+ }
+
+ if (currentValue instanceof EAVDelegatingEcoreEList<?>) {
+ return;
+ }
+
+ final Object newValue = get(owner);
+ EcoreAccess.setManyEFeatureValue(getEStructuralFeature(), newValue, (BasicEObjectImpl) owner);
+ } else {
+ final Field javaField = FieldUtil.getField(owner.getClass(), getEStructuralFeature().getName());
+
+ try {
+ final Object currentValue = javaField.get(owner);
+ if (currentValue instanceof EAVDelegatingEcoreEList<?>) {
+ return;
+ }
+ final Object newValue = get(owner);
+ javaField.set(owner, newValue);
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVObjectTuplizer.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVObjectTuplizer.java
new file mode 100755
index 000000000..6090ac250
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVObjectTuplizer.java
@@ -0,0 +1,341 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EAVObjectTuplizer.java,v 1.4 2010/11/12 09:33:33 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+import org.eclipse.emf.teneo.Constants;
+import org.eclipse.emf.teneo.hibernate.HbDataStore;
+import org.eclipse.emf.teneo.hibernate.HbHelper;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.HbStoreException;
+import org.eclipse.emf.teneo.hibernate.HbUtil;
+import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierCacheHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.internal.TeneoInternalEObject;
+import org.eclipse.emf.teneo.hibernate.tuplizer.EMFInstantiator;
+import org.hibernate.EntityMode;
+import org.hibernate.EntityNameResolver;
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.Subclass;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.ProxyFactory;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.tuple.entity.AbstractEntityTuplizer;
+import org.hibernate.tuple.entity.EntityMetamodel;
+import org.hibernate.type.CompositeType;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * The Tuplizer for objects mapped according to the EAV Schema.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.4 $
+ */
+
+public class EAVObjectTuplizer extends AbstractEntityTuplizer {
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(EAVObjectTuplizer.class);
+
+ /**
+ * The mapped class, defaults to EObject for entities and to the real impl
+ * class for mapped classes
+ */
+ private Class<?> mappedClass;
+
+ private PersistentClass persistentClass;
+
+ /** The entitymetamodel for which this is all done */
+ // private final EntityMetamodel theEntityMetamodel;
+ /** Constructor */
+ public EAVObjectTuplizer(EntityMetamodel entityMetamodel,
+ PersistentClass mappedEntity) {
+ super(entityMetamodel, mappedEntity);
+ // theEntityMetamodel = entityMetamodel;
+ if (mappedEntity.getMappedClass() != null) {
+ mappedClass = mappedEntity.getMappedClass();
+ } else {
+ mappedClass = EObject.class;
+ }
+ persistentClass = mappedEntity;
+ }
+
+ /**
+ * First checks the id cache and if not found uses the superclass.
+ */
+ @Override
+ public Serializable getIdentifier(Object object) throws HibernateException {
+ Serializable id = (Serializable) IdentifierCacheHandler.getInstance()
+ .getID(object);
+ if (id != null) {
+ return id;
+ }
+ return super.getIdentifier(object);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.hibernate.tuple.entity.EntityTuplizer#determineConcreteSubclassEntityName
+ * (java.lang.Object, org.hibernate.engine.SessionFactoryImplementor)
+ */
+ public String determineConcreteSubclassEntityName(Object entityInstance,
+ SessionFactoryImplementor factory) {
+ final Class<?> concreteEntityClass = entityInstance.getClass();
+ if (concreteEntityClass == getMappedClass()) {
+ return getEntityName();
+ } else {
+ String entityName = getEntityMetamodel()
+ .findEntityNameByEntityClass(concreteEntityClass);
+ if (entityName == null) {
+ throw new HibernateException(
+ "Unable to resolve entity name from Class ["
+ + concreteEntityClass.getName() + "]"
+ + " expected instance/subclass of ["
+ + getEntityName() + "]");
+ }
+ return entityName;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.entity.EntityTuplizer#getEntityNameResolvers()
+ */
+ public EntityNameResolver[] getEntityNameResolvers() {
+ final HbDataStore ds = HbHelper.INSTANCE.getDataStore(persistentClass);
+ return new EntityNameResolver[] { ds.getEntityNameResolver() };
+ }
+
+ /**
+ * Uses the identifiercache to get the version.
+ */
+ @Override
+ public Object getVersion(Object object) throws HibernateException {
+ final Object version = super.getVersion(object);
+ if (version != null) {
+ return version;
+ }
+
+ return IdentifierCacheHandler.getInstance().getVersion(object);
+ }
+
+ /**
+ * Sets the identifier in the cache.
+ */
+ @Override
+ public void setIdentifier(Object object, Serializable id)
+ throws HibernateException {
+ IdentifierCacheHandler.getInstance().setID(object, id);
+ super.setIdentifier(object, id);
+ }
+
+ /** Creates an EMF Instantiator */
+ @Override
+ protected Instantiator buildInstantiator(PersistentClass persistentClass) {
+ if (persistentClass.getEntityName().equals(
+ Constants.EAV_EOBJECT_ENTITY_NAME)) {
+ return null;
+ }
+ final HbDataStore ds = HbHelper.INSTANCE.getDataStore(persistentClass);
+ final EClass eclass = ds.getEntityNameStrategy().toEClass(
+ persistentClass.getEntityName());
+ if (eclass == null) {
+ throw new HbMapperException("No eclass found for entityname: "
+ + persistentClass.getEntityName());
+ }
+ return new EMFInstantiator(eclass, persistentClass);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.hibernate.tuple.AbstractEntityTuplizer#buildPropertyGetter(org.hibernate
+ * .mapping.Property , org.hibernate.mapping.PersistentClass)
+ */
+ @Override
+ protected Getter buildPropertyGetter(Property mappedProperty,
+ PersistentClass mappedEntity) {
+ if (mappedProperty.getName().equals("values")) {
+ return mappedProperty.getGetter(EObjectImpl.class);
+ }
+ return getPropertyAccessor(mappedProperty, mappedEntity).getGetter(
+ null, mappedProperty.getName());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.hibernate.tuple.AbstractEntityTuplizer#buildPropertySetter(org.hibernate
+ * .mapping.Property , org.hibernate.mapping.PersistentClass)
+ */
+ @Override
+ protected Setter buildPropertySetter(Property mappedProperty,
+ PersistentClass mappedEntity) {
+ if (mappedProperty.getName().equals("values")) {
+ return mappedProperty.getSetter(EObjectImpl.class);
+ }
+ return getPropertyAccessor(mappedProperty, mappedEntity).getSetter(
+ null, mappedProperty.getName());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.hibernate.tuple.AbstractEntityTuplizer#buildProxyFactory(org.
+ * hibernate.mapping. PersistentClass, org.hibernate.property.Getter,
+ * org.hibernate.property.Setter)
+ */
+ @Override
+ protected ProxyFactory buildProxyFactory(PersistentClass persistentClass,
+ Getter idGetter, Setter idSetter) {
+ if (persistentClass.getClassName() == null) { // an entity, no proxy
+ return null;
+ }
+
+ final HbDataStore ds = HbHelper.INSTANCE.getDataStore(persistentClass);
+ final EClass eclass = ds.getEntityNameStrategy().toEClass(
+ persistentClass.getEntityName());
+ if (eclass == null) {
+ throw new HbMapperException("No eclass found for entityname: "
+ + persistentClass.getEntityName());
+ }
+
+ // get all the interfaces from the main class, add the real interface
+ // first
+ final Set<Class<?>> proxyInterfaces = new LinkedHashSet<Class<?>>();
+ final Class<?> pInterface = persistentClass.getProxyInterface();
+ if (pInterface != null) {
+ proxyInterfaces.add(pInterface);
+ }
+ final Class<?> mappedClass = persistentClass.getMappedClass();
+ if (mappedClass.isInterface()) {
+ proxyInterfaces.add(mappedClass);
+ }
+ proxyInterfaces.add(HibernateProxy.class);
+ proxyInterfaces.add(TeneoInternalEObject.class);
+
+ for (Class<?> interfaces : mappedClass.getInterfaces()) {
+ proxyInterfaces.add(interfaces);
+ }
+
+ // iterate over all subclasses and add them also
+ final Iterator<?> iter = persistentClass.getSubclassIterator();
+ while (iter.hasNext()) {
+ final Subclass subclass = (Subclass) iter.next();
+ final Class<?> subclassProxy = subclass.getProxyInterface();
+ final Class<?> subclassClass = subclass.getMappedClass();
+ if (subclassProxy != null && !subclassClass.equals(subclassProxy)) {
+ proxyInterfaces.add(subclassProxy);
+ }
+ }
+
+ // get the idgettters/setters
+ final Method theIdGetterMethod = idGetter == null ? null : idGetter
+ .getMethod();
+ final Method theIdSetterMethod = idSetter == null ? null : idSetter
+ .getMethod();
+
+ final Method proxyGetIdentifierMethod = theIdGetterMethod == null
+ || pInterface == null ? null : ReflectHelper.getMethod(
+ pInterface, theIdGetterMethod);
+ final Method proxySetIdentifierMethod = theIdSetterMethod == null
+ || pInterface == null ? null : ReflectHelper.getMethod(
+ pInterface, theIdSetterMethod);
+
+ ProxyFactory pf = Environment.getBytecodeProvider()
+ .getProxyFactoryFactory().buildProxyFactory();
+ try {
+ pf.postInstantiate(
+ getEntityName(),
+ mappedClass,
+ proxyInterfaces,
+ proxyGetIdentifierMethod,
+ proxySetIdentifierMethod,
+ persistentClass.hasEmbeddedIdentifier() ? (CompositeType) persistentClass
+ .getIdentifier().getType() : null);
+ } catch (HbStoreException e) {
+ log.warn("could not create proxy factory for:" + getEntityName(), e);
+ pf = null;
+ }
+ return pf;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.AbstractEntityTuplizer#getEntityMode()
+ */
+ public EntityMode getEntityMode() {
+ return EntityMode.POJO;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.EntityTuplizer#getConcreteProxyClass()
+ */
+ public Class<?> getConcreteProxyClass() {
+ return EObject.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.EntityTuplizer#isInstrumented()
+ */
+ public boolean isInstrumented() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.Tuplizer#getMappedClass()
+ */
+ public Class<?> getMappedClass() {
+ return mappedClass;
+ }
+
+ /** Returns the correct accessor on the basis of the type of property */
+ protected PropertyAccessor getPropertyAccessor(Property mappedProperty,
+ PersistentClass pc) {
+ final HbDataStore ds = HbHelper.INSTANCE.getDataStore(pc);
+ return HbUtil.getPropertyAccessor(mappedProperty, ds,
+ pc.getEntityName(), null);
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVPropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVPropertyHandler.java
new file mode 100755
index 000000000..42851217b
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVPropertyHandler.java
@@ -0,0 +1,407 @@
+/**
+ * <copyright> Copyright (c) 2009 Springsite BV (The Netherlands) 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: Martin Taal </copyright> $Id:
+ * EReferencePropertyHandler.java,v 1.4 2007/04/07 12:43:51 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.HbDataStore;
+import org.eclipse.emf.teneo.util.StoreUtil;
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+
+/**
+ * The property handler which takes care of setting/getting the
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.11 $
+ */
+@SuppressWarnings("unchecked")
+public class EAVPropertyHandler implements Getter, Setter, PropertyAccessor,
+ ExtensionPoint {
+
+ private static final long serialVersionUID = -3712366809398761331L;
+
+ private HbDataStore hbDataStore = null;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getGetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Getter getGetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getSetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Setter getSetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#get(java.lang.Object)
+ */
+ public Object get(Object owner) throws HibernateException {
+
+ final EObject eOwner = (EObject) owner;
+ for (Adapter adapter : eOwner.eAdapters()) {
+ if (adapter instanceof EAVObjectAdapter) {
+ final EAVObjectAdapter eavAdapter = (EAVObjectAdapter) adapter;
+ return eavAdapter.getValueList();
+ }
+ }
+
+ final EAVObjectAdapter eavAdapter = new EAVObjectAdapter();
+ eavAdapter.setTarget(eOwner);
+ final List<EAVValueHolder> valueList = createValueList(eOwner);
+ // note this will replace the values in the eobject
+ // i.e. list instances
+ fillTargetObject((EObject) eOwner, valueList);
+ eavAdapter.setValueList(valueList);
+ eOwner.eAdapters().add(eavAdapter);
+ return valueList;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getForInsert(java.lang.Object,
+ * java.util.Map, org.hibernate.engine.SessionImplementor)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getForInsert(Object owner, Map mergeMap,
+ SessionImplementor session) throws HibernateException {
+ return get(owner);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Setter#set(java.lang.Object,
+ * java.lang.Object, org.hibernate.engine.SessionFactoryImplementor)
+ */
+ public void set(Object target, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ final EObject eOwner = (EObject) target;
+ for (Adapter adapter : eOwner.eAdapters()) {
+ if (adapter instanceof EAVObjectAdapter) {
+ final EAVObjectAdapter eavAdapter = (EAVObjectAdapter) adapter;
+ // todo: is the value every different, I don't think so..)
+ eavAdapter.setValueList((List<EAVValueHolder>) value);
+ return;
+ }
+ }
+ fillTargetObject((EObject) target, (List<EAVValueHolder>) value);
+ final EAVObjectAdapter eavAdapter = new EAVObjectAdapter();
+ eavAdapter.setTarget(eOwner);
+ eavAdapter.setValueList((List<EAVValueHolder>) value);
+ eOwner.eAdapters().add(eavAdapter);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethod()
+ */
+ public Method getMethod() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMember()
+ */
+ public Member getMember() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethodName()
+ */
+ public String getMethodName() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getReturnType()
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getReturnType() {
+ return InternalEObject.class;
+ }
+
+ private List<EAVValueHolder> createValueList(EObject target) {
+ final List<EAVValueHolder> valueHolders = new ArrayList<EAVValueHolder>();
+ for (EStructuralFeature eFeature : target.eClass()
+ .getEAllStructuralFeatures()) {
+ if (eFeature.isDerived() || eFeature.isTransient()
+ || eFeature.isVolatile()) {
+ continue;
+ }
+ final EAVValueHolder valueHolder = EAVValueHolder.create(target,
+ eFeature, hbDataStore);
+ valueHolder.set(target.eGet(eFeature));
+ if (eFeature.isUnsettable()) {
+ valueHolder.setValueIsSet(target.eIsSet(eFeature));
+ }
+ valueHolders.add(valueHolder);
+ }
+ return valueHolders;
+ }
+
+ private void fillTargetObject(EObject target, List<EAVValueHolder> valueList) {
+ for (EAVValueHolder valueHolder : valueList) {
+ valueHolder.setValueInOwner((InternalEObject) target);
+ }
+ }
+
+ private static class EAVObjectAdapter implements Adapter {
+
+ private Notifier target;
+
+ private List<EAVValueHolder> valueList;
+
+ public Notifier getTarget() {
+ return target;
+ }
+
+ public void setTarget(Notifier newTarget) {
+ target = newTarget;
+ }
+
+ public List<EAVValueHolder> getValueList() {
+ return valueList;
+ }
+
+ public void setValueList(List<EAVValueHolder> valueList) {
+ this.valueList = valueList;
+ }
+
+ public boolean isAdapterForType(Object type) {
+ return false;
+ }
+
+ private EAVValueHolder getValueHolder(EStructuralFeature eFeature) {
+ for (EAVValueHolder valueHolder : valueList) {
+ if (valueHolder.getEStructuralFeature() == eFeature) {
+ return valueHolder;
+ }
+ }
+ // can happen when adding
+ return null;
+ }
+
+ public void notifyChanged(Notification notification) {
+ final EStructuralFeature eFeature = (EStructuralFeature) notification
+ .getFeature();
+
+ final EAVValueHolder valueHolder = getValueHolder(eFeature);
+ EAVMultiValueHolder multiValueHolder = null;
+
+ List<Object> list = null;
+ if (valueHolder instanceof EAVMultiValueHolder) {
+ list = (List<Object>) valueHolder.getValue();
+ multiValueHolder = (EAVMultiValueHolder) valueHolder;
+ }
+
+ // this can happen in case of a featuremap
+ if (valueHolder == null) {
+ return;
+ }
+
+ final Object currentEMFValue = valueHolder.getOwner()
+ .eGet(eFeature);
+ if (currentEMFValue instanceof EAVDelegatingEcoreEList<?>) {
+ // this type of list manages the changes directly
+ return;
+ }
+
+ // note for list features we can only get here for new objects which
+ // have not been
+ // read from the db but which have been persisted. Objects read from
+ // the database
+ // will always have a EAVDelegatingEcoreEList.
+ // The code below is also executed in case of changes to an EAV EMap
+
+ int repairFromIndex = -1;
+
+ switch (notification.getEventType()) {
+ case Notification.ADD: {
+ if (notification.getPosition() != Notification.NO_INDEX) {
+ repairFromIndex = notification.getPosition();
+ list.add(notification.getPosition(), multiValueHolder
+ .getElement(notification.getNewValue()));
+ } else {
+ repairFromIndex = list.size();
+ list.add(multiValueHolder.getElement(notification
+ .getNewValue()));
+ }
+ }
+ break;
+ case Notification.ADD_MANY: {
+ final List<Object> values = new ArrayList<Object>();
+ for (Object o : (List<Object>) notification.getNewValue()) {
+ values.add(multiValueHolder.getElement(o));
+ }
+ if (notification.getPosition() != Notification.NO_INDEX) {
+ repairFromIndex = notification.getPosition();
+ list.addAll(notification.getPosition(), values);
+ } else {
+ repairFromIndex = list.size();
+ list.addAll(values);
+ }
+ }
+ break;
+ case Notification.REMOVE: {
+ int removeIndex = notification.getPosition();
+ if (removeIndex == Notification.NO_INDEX) {
+ final Object oldValue = notification.getOldValue();
+ for (Object o : list) {
+ final EAVValueHolder elemValue = (EAVValueHolder) o;
+ if (elemValue.getValue() != null && oldValue != null
+ && elemValue.getValue().equals(oldValue)) {
+ removeIndex = list.indexOf(o);
+ break;
+ } else if (elemValue.getValue() == oldValue) {
+ removeIndex = list.indexOf(o);
+ break;
+ }
+ }
+ }
+
+ if (removeIndex != Notification.NO_INDEX) {
+ repairFromIndex = removeIndex;
+ list.remove(removeIndex);
+ }
+ }
+ break;
+ case Notification.REMOVE_MANY:
+ final List<?> oldValues = (List<?>) notification.getOldValue();
+ for (Object oldValue : oldValues) {
+ int removeIndex = notification.getPosition();
+ if (removeIndex == Notification.NO_INDEX) {
+ for (Object o : list) {
+ final EAVValueHolder elemValue = (EAVValueHolder) o;
+ if (elemValue.getValue() != null
+ && oldValue != null
+ && elemValue.getValue().equals(oldValue)) {
+ removeIndex = list.indexOf(o);
+ break;
+ } else if (elemValue.getValue() == oldValue) {
+ removeIndex = list.indexOf(o);
+ break;
+ }
+ elemValue.setListIndex(-1);
+ elemValue.setValueOwner(null);
+ elemValue.setOwner(null);
+ }
+
+ if (removeIndex != Notification.NO_INDEX) {
+ repairFromIndex = 0;
+ list.remove(removeIndex);
+ }
+ }
+ }
+ break;
+ case Notification.MOVE:
+ if (list != null) {
+ final int oldPosition = (Integer) notification
+ .getOldValue();
+ final int newPosition = notification.getPosition();
+ final Object o = list.remove(oldPosition);
+ list.add(newPosition, o);
+ if (newPosition < oldPosition) {
+ repairFromIndex = newPosition;
+ } else {
+ repairFromIndex = oldPosition;
+ }
+ }
+ break;
+ case Notification.SET:
+ if (eFeature.isMany()) {
+ final int position = notification.getPosition();
+ final EAVValueHolder elementValueHolder = (EAVValueHolder) list
+ .set(position, multiValueHolder
+ .getElement(notification.getNewValue()));
+ repairFromIndex = notification.getPosition();
+ if (elementValueHolder != null) {
+ elementValueHolder.setListIndex(0);
+ elementValueHolder.setValueOwner(null);
+ elementValueHolder.setOwner(null);
+ }
+ } else {
+ valueHolder.set(notification.getNewValue());
+ }
+ break;
+ case Notification.UNSET:
+ if (!eFeature.isMany()) {
+ valueHolder.set(notification.getNewValue());
+ }
+ break;
+ }
+ if (repairFromIndex != -1) {
+ int index = repairFromIndex;
+ for (Object o : list.subList(repairFromIndex, list.size())) {
+
+ if (o instanceof EObject) {
+ StoreUtil.setSyntheticListIndex(eFeature, o, index++);
+ StoreUtil.setSyntheticListOwner(eFeature, o,
+ notification.getNotifier());
+ }
+ if (o instanceof EAVValueHolder) {
+ final EAVValueHolder eavValueHolder = (EAVValueHolder) o;
+ eavValueHolder.setListIndex(index++);
+ eavValueHolder
+ .setValueOwner((EAVMultiValueHolder) valueHolder);
+ }
+ }
+ }
+ }
+ }
+
+ public HbDataStore getHbDataStore() {
+ return hbDataStore;
+ }
+
+ public void setHbDataStore(HbDataStore hbDataStore) {
+ this.hbDataStore = hbDataStore;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleContainmentEReferenceValueHolder.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleContainmentEReferenceValueHolder.java
new file mode 100644
index 000000000..0210d8ebb
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleContainmentEReferenceValueHolder.java
@@ -0,0 +1,26 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVSingleContainmentEReferenceValueHolder.java,v 1.1 2009/08/20 15:59:38 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+/**
+ * Stores a single EReference value when the EReference is containment.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EAVSingleContainmentEReferenceValueHolder extends EAVSingleEReferenceValueHolder {
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleEAttributeValueHolder.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleEAttributeValueHolder.java
new file mode 100644
index 000000000..af87962d3
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleEAttributeValueHolder.java
@@ -0,0 +1,263 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVSingleEAttributeValueHolder.java,v 1.11 2010/10/31 21:50:36 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.MathContext;
+import java.util.Date;
+
+import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EFactory;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEAttribute;
+import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEDataType;
+import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEStructuralFeature;
+import org.eclipse.emf.teneo.annotations.pannotation.FetchType;
+import org.eclipse.emf.teneo.hibernate.HbDataStore;
+
+/**
+ * This class holds a single EAttribute value.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EAVSingleEAttributeValueHolder extends EAVValueHolder {
+
+ private static final int MAX_PRECISION = 38;
+
+ private String type;
+ private String typeNeutralValue;
+ private String stringValue;
+ private Date dateValue;
+ private BigDecimal numericValue;
+ private double doubleValue;
+ private long longValue;
+ private Object objectValue;
+ private EAVBlobValue blobValue;
+ private EAVTextValue textValue;
+
+ public void set(Object value) {
+
+ // nullify old data
+ stringValue = null;
+ dateValue = null;
+ numericValue = null;
+ longValue = 0;
+ setValueIsSet(false);
+ setMandatoryValue(null);
+
+ objectValue = value;
+
+ // stop here as everything has been nullified anyway
+ if (value == null) {
+ return;
+ }
+
+ // value is not null, set the mandatory trigger
+ setMandatoryValue(NOT_NULL_VALUE);
+
+ // do type specific handling
+ final boolean isBlob = value instanceof byte[]
+ || (value instanceof String && isClob(getEStructuralFeature()));
+ final EDataType eDataType = (EDataType) getEStructuralFeature()
+ .getEType();
+ final EFactory eFactory = eDataType.getEPackage().getEFactoryInstance();
+ if (!isBlob) {
+ typeNeutralValue = eFactory.convertToString(eDataType, value);
+ }
+ type = value.getClass().getName();
+
+ if (value instanceof byte[]) {
+ blobValue = new EAVBlobValue();
+ blobValue.setBlobValue((byte[]) value);
+ blobValue.setValueHolder(this);
+ } else if (value instanceof Enumerator) {
+ stringValue = ((Enumerator) value).getName();
+ } else if (value instanceof String && isBlob) {
+ textValue = new EAVTextValue();
+ textValue.setTextValue((String) value);
+ textValue.setValueHolder(this);
+ } else if (value instanceof String) {
+ stringValue = (String) value;
+ } else if (value instanceof Date) {
+ dateValue = (Date) value;
+ } else if (value instanceof Number) {
+ if (value instanceof BigDecimal) {
+ final BigDecimal bdValue = (BigDecimal) value;
+ if (bdValue.precision() > MAX_PRECISION) {
+ final MathContext mathContext = new MathContext(
+ MAX_PRECISION);
+ numericValue = bdValue.round(mathContext);
+ } else {
+ numericValue = bdValue;
+ }
+ } else if (value instanceof BigInteger) {
+ longValue = ((BigInteger) value).longValue();
+ } else if (value instanceof Double || value instanceof Float) {
+ doubleValue = ((Number) value).doubleValue();
+ } else if (value instanceof Integer || value instanceof Long
+ || value instanceof Short || value instanceof Byte) {
+ longValue = ((Number) value).longValue();
+ } else {
+ throw new UnsupportedOperationException("Primitive type "
+ + value.getClass() + " not supported here.");
+ }
+ }
+ }
+
+ public Object get(InternalEObject owner) {
+ if (objectValue == null && blobValue != null) {
+ objectValue = blobValue.getBlobValue();
+ } else if (objectValue == null && textValue != null) {
+ objectValue = textValue.getTextValue();
+ } else if (objectValue == null && typeNeutralValue != null) {
+ final EDataType eDataType = (EDataType) getEStructuralFeature()
+ .getEType();
+ final EFactory eFactory = eDataType.getEPackage()
+ .getEFactoryInstance();
+ objectValue = eFactory
+ .createFromString(eDataType, typeNeutralValue);
+ }
+
+ return objectValue;
+ }
+
+ public Object getValue() {
+ return get(null);
+ }
+
+ public void setValueInOwner(InternalEObject owner) {
+ if (getEStructuralFeature().isUnsettable() && !isValueIsSet()) {
+ owner.eUnset(getEStructuralFeature());
+ } else {
+ owner.eSet(getEStructuralFeature(), get(owner));
+ }
+ }
+
+ public String getStringValue() {
+ return stringValue;
+ }
+
+ public void setStringValue(String stringValue) {
+ this.stringValue = stringValue;
+ }
+
+ public Date getDateValue() {
+ return dateValue;
+ }
+
+ public void setDateValue(Date dateValue) {
+ this.dateValue = dateValue;
+ }
+
+ public BigDecimal getNumericValue() {
+ return numericValue;
+ }
+
+ public void setNumericValue(BigDecimal numericValue) {
+ this.numericValue = numericValue;
+ }
+
+ public long getLongValue() {
+ return longValue;
+ }
+
+ public void setLongValue(long longValue) {
+ this.longValue = longValue;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getTypeNeutralValue() {
+ return typeNeutralValue;
+ }
+
+ public void setTypeNeutralValue(String typeNeutralValue) {
+ this.typeNeutralValue = typeNeutralValue;
+ }
+
+ public EAVBlobValue getBlobValue() {
+ return blobValue;
+ }
+
+ public void setBlobValue(EAVBlobValue blobValue) {
+ this.blobValue = blobValue;
+ }
+
+ public EAVTextValue getTextValue() {
+ return textValue;
+ }
+
+ public void setTextValue(EAVTextValue textValue) {
+ this.textValue = textValue;
+ }
+
+ private boolean isClob(EStructuralFeature eFeature) {
+ final EAttribute eAttribute = (EAttribute) eFeature;
+ try {
+ final PAnnotatedEAttribute paEAttribute = getHbDataStore()
+ .getPaModel().getPAnnotated(eAttribute);
+ if (paEAttribute == null) {
+ return false;
+ }
+ if (paEAttribute.getLob() != null) {
+ return true;
+ }
+ final PAnnotatedEDataType paDataType = getHbDataStore()
+ .getPaModel().getPAnnotated(eAttribute.getEAttributeType());
+ if (paDataType == null) {
+ return false;
+ }
+ return paDataType.getLob() != null;
+ } catch (IllegalArgumentException e) {
+ // no problem, happens in some cases with featuremaps
+ return false;
+ }
+ }
+
+ protected static boolean isFeatureExtraLazy(HbDataStore hbDataStore,
+ EStructuralFeature eFeature) {
+ if (hbDataStore.getPersistenceOptions().isFetchAssociationExtraLazy()) {
+ return true;
+ }
+ final PAnnotatedEStructuralFeature paFeature = hbDataStore.getPaModel()
+ .getPAnnotated(eFeature);
+ if (paFeature.getOneToMany() != null
+ && paFeature.getOneToMany().getFetch().equals(FetchType.EXTRA)) {
+ return Boolean.TRUE;
+ }
+ return false;
+ }
+
+ public double getDoubleValue() {
+ return doubleValue;
+ }
+
+ public void setDoubleValue(double doubleValue) {
+ this.doubleValue = doubleValue;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleEReferenceValueHolder.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleEReferenceValueHolder.java
new file mode 100644
index 000000000..162d98d77
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleEReferenceValueHolder.java
@@ -0,0 +1,140 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVSingleEReferenceValueHolder.java,v 1.5 2010/04/04 12:10:51 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import org.eclipse.emf.common.notify.NotificationChain;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.impl.DynamicEObjectImpl;
+import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEClass;
+import org.eclipse.emf.teneo.hibernate.HbUtil;
+import org.hibernate.mapping.PersistentClass;
+
+/**
+ * Stores a single EReference value when the EReference is containment.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EAVSingleEReferenceValueHolder extends EAVValueHolder {
+
+ private EObject referenceValue;
+
+ private EObject eavObjectReference;
+
+ private EReference getEReference() {
+ return (EReference) getEStructuralFeature();
+ }
+
+ public void setValueInOwner(InternalEObject owner) {
+ final Object curValue = owner.eGet(getEStructuralFeature());
+ final int featureId = owner.eClass().getFeatureID(
+ getEStructuralFeature());
+ if (curValue == referenceValue) {
+ // note that == works fine if the
+ // curValue and value have been read in the same jvm.
+ return; // do nothing in this case
+ }
+
+ if (getEReference().getEOpposite() != null
+ || (owner instanceof DynamicEObjectImpl && getEReference()
+ .isContainment())) {
+ // these are handled a bit differently because
+ if (referenceValue == null) { // remove
+ // Note that the eInverseRemove is called on the target itself
+ // and the value is passed
+ // therefore the eReference featureid is passed and not the
+ // opposite
+ final NotificationChain nots = ((InternalEObject) owner)
+ .eInverseRemove((InternalEObject) curValue, featureId,
+ getEReference().getEType().getInstanceClass(),
+ null);
+ if (nots != null) {
+ nots.dispatch();
+ }
+ } else {
+ final NotificationChain nots = ((InternalEObject) owner)
+ .eInverseAdd((InternalEObject) referenceValue,
+ featureId, getEReference().getEType()
+ .getInstanceClass(), null);
+ if (nots != null) {
+ nots.dispatch();
+ }
+ }
+ } else {
+ owner.eSet(getEReference(), referenceValue);
+ }
+ }
+
+ public void set(Object value) {
+ setMandatoryValue(null);
+ referenceValue = (EObject) value;
+ if (referenceValue != null) {
+ setMandatoryValue(NOT_NULL_VALUE);
+ if (isEAVMapped(referenceValue.eClass())) {
+ setEavObjectReference(referenceValue);
+ }
+ } else {
+ setEavObjectReference(null);
+ }
+
+ }
+
+ public Object getValue() {
+ return getReferenceValue();
+ }
+
+ public Object get(InternalEObject owner) {
+ return referenceValue;
+ }
+
+ public EObject getReferenceValue() {
+ return referenceValue;
+ }
+
+ public void setReferenceValue(EObject referenceValue) {
+ this.referenceValue = referenceValue;
+ }
+
+ public EObject getEavObjectReference() {
+ return eavObjectReference;
+ }
+
+ public void setEavObjectReference(EObject eavObjectReference) {
+ this.eavObjectReference = eavObjectReference;
+ }
+
+ private boolean isEAVMapped(EClass eClass) {
+ try {
+ final PAnnotatedEClass paClass = getHbDataStore().getPaModel()
+ .getPAnnotated(eClass);
+ if (paClass.getEntity() == null) {
+ return false;
+ }
+ final String entityName = paClass.getEntity().getName();
+ final PersistentClass pc = getHbDataStore().getPersistentClass(
+ entityName);
+ return HbUtil.isEAVMapped(pc);
+ } catch (IllegalArgumentException e) {
+ // not mapped
+ return false;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleNonContainmentEReferenceValueHolder.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleNonContainmentEReferenceValueHolder.java
new file mode 100644
index 000000000..143a61dc7
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVSingleNonContainmentEReferenceValueHolder.java
@@ -0,0 +1,27 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVSingleNonContainmentEReferenceValueHolder.java,v 1.1 2009/08/20 15:59:38 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+
+/**
+ * Stores a single EReference value when the EReference is non containment.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EAVSingleNonContainmentEReferenceValueHolder extends EAVSingleEReferenceValueHolder {
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVTextValue.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVTextValue.java
new file mode 100644
index 000000000..a26122d14
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVTextValue.java
@@ -0,0 +1,64 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVTextValue.java,v 1.1 2009/09/11 22:52:36 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+/**
+ * Holds a text value.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+public class EAVTextValue {
+
+ private long id;
+ private int version;
+
+ private String textValue;
+ private EAVSingleEAttributeValueHolder valueHolder;
+
+ public EAVSingleEAttributeValueHolder getValueHolder() {
+ return valueHolder;
+ }
+
+ public void setValueHolder(EAVSingleEAttributeValueHolder valueHolder) {
+ this.valueHolder = valueHolder;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ public void setVersion(int version) {
+ this.version = version;
+ }
+
+ public String getTextValue() {
+ return textValue;
+ }
+
+ public void setTextValue(String textValue) {
+ this.textValue = textValue;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVTuplizer.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVTuplizer.java
new file mode 100644
index 000000000..43ac9286a
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVTuplizer.java
@@ -0,0 +1,87 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVTuplizer.java,v 1.3 2010/04/02 22:10:11 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.util.Iterator;
+
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentList;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.intercept.LazyPropertyInitializer;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.tuple.entity.EntityMetamodel;
+import org.hibernate.tuple.entity.PojoEntityTuplizer;
+
+/**
+ * Tuplizer created to work around this issue: http://opensource.atlassian.com/projects/hibernate/browse/HHH-4078
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+
+public class EAVTuplizer extends PojoEntityTuplizer {
+
+ private PersistentClass persistentClass;
+
+ public EAVTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
+ super(entityMetamodel, mappedEntity);
+ persistentClass = mappedEntity;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) {
+ final Class<?> concreteEntityClass = entityInstance.getClass();
+ if (concreteEntityClass == getMappedClass()) {
+ return getEntityName();
+ } else {
+ final Iterator<?> iter = persistentClass.getSubclassIterator();
+ while (iter.hasNext()) {
+ final PersistentClass pc = (PersistentClass) iter.next();
+ if (pc.getMappedClass() == concreteEntityClass) {
+ return pc.getEntityName();
+ }
+ }
+ throw new HibernateException("Unable to resolve entity name from Class [" + concreteEntityClass.getName()
+ + "]" + " expected instance/subclass of [" + getEntityName() + "]");
+ }
+ }
+
+ // overridden to make sure that the owner is set earlier
+ public void setPropertyValues(Object entity, Object[] values) throws HibernateException {
+ boolean setAll = !getEntityMetamodel().hasLazyProperties();
+
+ for ( int j = 0; j < getEntityMetamodel().getPropertySpan(); j++ ) {
+ if ( setAll || values[j] != LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
+ if (values[j] instanceof PersistentList) {
+ final PersistentList persistentList = (PersistentList)values[j];
+ if (persistentList.getOwner() == null) {
+ persistentList.setOwner(entity);
+ }
+ }
+ setters[j].set( entity, values[j], getFactory() );
+ }
+ }
+ }
+
+ @Override
+ protected Instantiator buildInstantiator(PersistentClass persistentClass) {
+ return new EAVValueInstantiator( persistentClass, null );
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVValueHolder.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVValueHolder.java
new file mode 100755
index 000000000..e30314920
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVValueHolder.java
@@ -0,0 +1,283 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial API and implementation
+ *
+ * </copyright>
+ *
+ * $Id: EAVValueHolder.java,v 1.7 2010/10/29 09:35:28 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.util.FeatureMapUtil;
+import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEStructuralFeature;
+import org.eclipse.emf.teneo.annotations.pannotation.FetchType;
+import org.eclipse.emf.teneo.hibernate.HbDataStore;
+
+/**
+ * The base class of the value stored in an EAV schema. The value in an EAV
+ * schema is both the type (the EStructuralFeature) and its value. The following
+ * different types of values can be identified:
+ * <ul>
+ * <li>EAttribute: a single primitive value</li>
+ * <li>EReference: a single reference to another object, containment or
+ * non-containment</li>
+ * <li>MultiEAttribute: a multi-occurrence EAttribute</li>
+ * <li>MultiEReference: a multi-occurrence EReference</li>
+ * </ul>
+ * In addition there is the FeatureMap and Map support which needs to be
+ * handled. In EMF both are lists with EAttributes.
+ *
+ * The above structure is reflected in the EAVValueHolder class hierarchy.
+ *
+ * @author <a href="mtaal@elver.org">Martin Taal</a>
+ */
+
+// NOTES:
+// the container reference is stored in the eobject itself!
+
+public abstract class EAVValueHolder {
+
+ protected static Integer NOT_NULL_VALUE = new Integer(1);
+
+ public static EAVValueHolder create(EObject owner,
+ EStructuralFeature eFeature, HbDataStore hbDataStore) {
+ final EAVValueHolder valueHolder;
+ if (eFeature instanceof EReference) {
+ final EReference eReference = (EReference) eFeature;
+ if (eReference.isMany()) {
+ if (eReference.isContainment()) {
+ if (isFeatureExtraLazy(hbDataStore, eFeature)) {
+ valueHolder = new EAVExtraMultiContainmentEReferenceValueHolder();
+ } else {
+ valueHolder = new EAVMultiContainmentEReferenceValueHolder();
+ }
+ } else {
+ if (isFeatureExtraLazy(hbDataStore, eFeature)) {
+ valueHolder = new EAVExtraMultiNonContainmentEReferenceValueHolder();
+ } else {
+ valueHolder = new EAVMultiNonContainmentEReferenceValueHolder();
+ }
+ }
+ } else {
+ if (eReference.isContainment()) {
+ valueHolder = new EAVSingleContainmentEReferenceValueHolder();
+ } else {
+ valueHolder = new EAVSingleNonContainmentEReferenceValueHolder();
+ }
+ }
+ } else {
+ if (FeatureMapUtil.isFeatureMap(eFeature)) {
+ valueHolder = new EAVFeatureMapValueHolder();
+ } else if (eFeature.isMany()) {
+ if (isFeatureExtraLazy(hbDataStore, eFeature)) {
+ valueHolder = new EAVExtraMultiEAttributeValueHolder();
+ } else {
+ valueHolder = new EAVMultiEAttributeValueHolder();
+ }
+ } else {
+ valueHolder = new EAVSingleEAttributeValueHolder();
+ }
+ }
+ valueHolder.setEStructuralFeature(eFeature);
+ valueHolder.setOwner(owner);
+ valueHolder.setHbDataStore(hbDataStore);
+ return valueHolder;
+ }
+
+ protected static boolean isFeatureExtraLazy(HbDataStore hbDataStore,
+ EStructuralFeature eFeature) {
+ if (hbDataStore.getPersistenceOptions().isFetchAssociationExtraLazy()) {
+ return true;
+ }
+ try {
+ final PAnnotatedEStructuralFeature paFeature = hbDataStore
+ .getPaModel().getPAnnotated(eFeature);
+ if (paFeature.getOneToMany() != null
+ && paFeature.getOneToMany().getFetch().equals(
+ FetchType.EXTRA)) {
+ return Boolean.TRUE;
+ }
+ return false;
+ } catch (IllegalArgumentException e) {
+ // be robust about model elements not annotated
+ return false;
+ }
+
+ }
+
+ private HbDataStore hbDataStore;
+ private long id;
+ private int version;
+ private EStructuralFeature eStructuralFeature;
+ private boolean valueIsSet;
+ private EObject owner;
+
+ private EAVMultiValueHolder valueOwner;
+
+ // is used when a value is held in a list
+ private int listIndex;
+
+ // the mandatoryValue is used as follows.
+ // it is defined as mandatory in the hibernate mapping
+ // if !eStructuralFeature.isRequired then it is always set to the
+ // NOT_NULL_VALUE
+ // if eStructuralFeature.isRequired then it is set if the value of the
+ // EStructuralFeature
+ // is set.
+ // in this way the mandatory value check is executed by hibernate on the
+ // basis
+ // of eStructuralFeature.isRequired
+ private Integer mandatoryValue = null;
+
+ public abstract void set(Object value);
+
+ public abstract Object get(InternalEObject owner);
+
+ public abstract void setValueInOwner(InternalEObject owner);
+
+ public abstract Object getValue();
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ public void setVersion(int version) {
+ this.version = version;
+ }
+
+ public EStructuralFeature getEStructuralFeature() {
+ return eStructuralFeature;
+ }
+
+ public void setEStructuralFeature(EStructuralFeature eStructuralFeature) {
+ this.eStructuralFeature = eStructuralFeature;
+ }
+
+ // extra getter and setter because hibernate gets confused with the other
+ // getter/setter and the uppercase 2 characters
+ public EStructuralFeature getFeature() {
+ return eStructuralFeature;
+ }
+
+ public void setFeature(EStructuralFeature eStructuralFeature) {
+ // setEStructuralFeature is overridden by subclasses
+ setEStructuralFeature(eStructuralFeature);
+ }
+
+ public boolean isValueIsSet() {
+ return valueIsSet;
+ }
+
+ public void setValueIsSet(boolean valueIsSet) {
+ this.valueIsSet = valueIsSet;
+ }
+
+ public Integer getMandatoryValue() {
+ // in case of merging the estructuralfeature is not yet set
+ if (getEStructuralFeature() == null) {
+ return NOT_NULL_VALUE;
+ }
+ // if not required then the not-value is set always
+ if (!getEStructuralFeature().isRequired()
+ || getEStructuralFeature().isUnsettable()) {
+ return NOT_NULL_VALUE;
+ }
+ return mandatoryValue;
+ }
+
+ public void setMandatoryValue(Integer mandatoryValue) {
+ this.mandatoryValue = mandatoryValue;
+ }
+
+ public EObject getOwner() {
+ return owner;
+ }
+
+ public void setOwner(EObject owner) {
+ this.owner = owner;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof EAVValueHolder)) {
+ return false;
+ }
+ final EAVValueHolder eavHolder = (EAVValueHolder) obj;
+ if (eavHolder.getEStructuralFeature() != getEStructuralFeature()) {
+ return false;
+ }
+ // handles null
+ if (getValue() == eavHolder.getValue()) {
+ return true;
+ }
+ if (getValue() == null) {
+ return false;
+ }
+ if (eavHolder.getValue() == null) {
+ return false;
+ }
+ return getValue().equals(eavHolder.getValue());
+ }
+
+ @Override
+ public int hashCode() {
+ if (getValue() == null) {
+ return getEStructuralFeature().hashCode();
+ }
+ return getEStructuralFeature().hashCode() ^ getValue().hashCode();
+ }
+
+ public int getListIndex() {
+ return listIndex;
+ }
+
+ public void setListIndex(int listIndex) {
+ this.listIndex = listIndex;
+ }
+
+ public int getVirtualListIndex() {
+ return listIndex;
+ }
+
+ public void setVirtualListIndex(int listIndex) {
+ this.listIndex = listIndex;
+ }
+
+ public EAVMultiValueHolder getValueOwner() {
+ return valueOwner;
+ }
+
+ public void setValueOwner(EAVMultiValueHolder valueOwner) {
+ this.valueOwner = valueOwner;
+ }
+
+ public HbDataStore getHbDataStore() {
+ return hbDataStore;
+ }
+
+ public void setHbDataStore(HbDataStore hbDataStore) {
+ this.hbDataStore = hbDataStore;
+ }
+
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVValueInstantiator.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVValueInstantiator.java
new file mode 100644
index 000000000..ecd872a73
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVValueInstantiator.java
@@ -0,0 +1,58 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EAVValueInstantiator.java,v 1.1 2010/04/02 15:24:11 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import org.eclipse.emf.teneo.hibernate.HbDataStore;
+import org.eclipse.emf.teneo.hibernate.HbHelper;
+import org.hibernate.bytecode.ReflectionOptimizer;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.tuple.PojoInstantiator;
+
+/**
+ * Instantiator for the EAV value objects, sets the datastore in the object.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.1 $
+ */
+
+public class EAVValueInstantiator extends PojoInstantiator {
+
+ private static final long serialVersionUID = 6946442685247491904L;
+
+ private HbDataStore hbDataStore;
+
+ public EAVValueInstantiator(Component component, ReflectionOptimizer.InstantiationOptimizer optimizer) {
+ super(component, optimizer);
+ hbDataStore = HbHelper.INSTANCE.getDataStore(component);
+ }
+
+ public EAVValueInstantiator(PersistentClass persistentClass, ReflectionOptimizer.InstantiationOptimizer optimizer) {
+ super(persistentClass, optimizer);
+ hbDataStore = HbHelper.INSTANCE.getDataStore(persistentClass);
+ }
+
+ public Object instantiate() {
+ final Object object = super.instantiate();
+ if (object instanceof EAVValueHolder) {
+ final EAVValueHolder valueHolder = (EAVValueHolder)object;
+ valueHolder.setHbDataStore(hbDataStore);
+ }
+ return object;
+ }
+
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/eav.hbm.xml b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/eav.hbm.xml
new file mode 100755
index 000000000..347ac43be
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/eav.hbm.xml
@@ -0,0 +1,296 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping auto-import="false">
+ <class name="org.eclipse.emf.ecore.impl.EObjectImpl" entity-name="EAV_EObject"
+ abstract="true" lazy="true" discriminator-value="eav_eobject"
+ table="`{tableprefix}eaveobject`" proxy="org.eclipse.emf.ecore.EObject">
+
+ <tuplizer entity-mode="pojo"
+ class="org.eclipse.emf.teneo.hibernate.tuplizer.EMFTuplizer" />
+ <tuplizer entity-mode="dynamic-map"
+ class="org.eclipse.emf.teneo.hibernate.tuplizer.EMFTuplizer" />
+
+ <id type="long" name="id" column="`eid`"
+ access="org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierPropertyHandler">
+ <meta attribute="syntheticId">true</meta>
+ <generator class="native" />
+ </id>
+ <discriminator column="`dtype`" type="string" />
+ <version name="e_version" column="`eversion`"
+ access="org.eclipse.emf.teneo.hibernate.mapping.property.VersionPropertyHandler">
+ <meta attribute="syntheticVersion">true</meta>
+ </version>
+
+ <list name="values" lazy="true" cascade="all,delete-orphan"
+ access="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVPropertyHandler">
+ <key column="`listkey`"/>
+ <list-index column="`idx`" />
+ <one-to-many entity-name="EAV_Value" />
+ </list>
+ </class>
+ <class name="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVValueHolder"
+ entity-name="EAV_Value" abstract="true" lazy="false" table="`{tableprefix}eavvalue`">
+
+ <tuplizer entity-mode="pojo"
+ class="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVTuplizer" />
+
+ <id type="long" name="id" column="`eavid`">
+ <generator class="native" />
+ </id>
+ <discriminator column="`discriminator`" />
+ <version name="version" column="`eavversion`" />
+ <property name="feature"
+ type="org.eclipse.emf.teneo.hibernate.mapping.EcoreModelElementType"
+ not-null="true" />
+ <property name="valueIsSet" />
+ <property name="mandatoryValue" not-null="true" />
+ <property name="listIndex" column="`listindex`" />
+ <many-to-one name="owner" entity-name="EAV_EObject" column="`owner`" />
+ <many-to-one name="valueOwner" entity-name="EAV_Value"
+ not-null="false" column="`valueowner`" />
+ </class>
+ <subclass
+ name="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVSingleEAttributeValueHolder"
+ entity-name="EAVSingleEAttributeValueHolder" abstract="false" lazy="false"
+ extends="EAV_Value" discriminator-value="EAVSingleEAttributeValueHolder">
+
+ <tuplizer entity-mode="pojo"
+ class="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVTuplizer" />
+
+ <property name="typeNeutralValue" />
+ <property name="type" />
+ <property name="stringValue" />
+ <property name="dateValue" />
+ <property name="doubleValue" />
+ <property name="numericValue" precision="31" scale="19" />
+ <property name="longValue" />
+ <one-to-one name="blobValue" property-ref="valueHolder"
+ entity-name="EAV_Blob" cascade="all" />
+ <one-to-one name="textValue" property-ref="valueHolder"
+ entity-name="EAV_Text" cascade="all" />
+ </subclass>
+ <subclass
+ name="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVMultiEAttributeValueHolder"
+ entity-name="EAVMultiEAttributeValueHolder" abstract="false" lazy="false"
+ extends="EAV_Value" discriminator-value="EAVMultiEAttributeValueHolder">
+
+ <tuplizer entity-mode="pojo"
+ class="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVTuplizer" />
+
+ <list name="values" lazy="true" cascade="all,delete-orphan"
+ inverse="true">
+ <key update="true">
+ <column name="`valueowner`" not-null="false" unique="false" />
+ </key>
+ <list-index column="`listindex`" />
+ <one-to-many entity-name="EAVSingleEAttributeValueHolder" />
+ </list>
+ </subclass>
+ <subclass
+ name="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVExtraMultiEAttributeValueHolder"
+ entity-name="EAVExtraMultiEAttributeValueHolder" abstract="false" lazy="false"
+ extends="EAV_Value" discriminator-value="EAVExtraMultiEAttributeValueHolder">
+
+ <tuplizer entity-mode="pojo"
+ class="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVTuplizer" />
+
+ <list name="values" lazy="extra" cascade="all,delete-orphan"
+ inverse="true">
+ <key update="true">
+ <column name="`valueowner`" not-null="false" unique="false" />
+ </key>
+ <list-index column="`listindex`" />
+ <one-to-many entity-name="EAVSingleEAttributeValueHolder" />
+ </list>
+ </subclass>
+ <subclass
+ name="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVFeatureMapValueHolder"
+ entity-name="EAVFeatureMapValueHolder" abstract="false" lazy="false"
+ extends="EAV_Value" discriminator-value="EAVFeatureMapValueHolder">
+
+ <tuplizer entity-mode="pojo"
+ class="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVTuplizer" />
+
+ <list name="values" lazy="false" cascade="all,delete-orphan">
+ <key update="true">
+ <column name="`valuesholderid`" not-null="false" unique="false" />
+ </key>
+ <list-index column="`valuesholderidx`" />
+ <one-to-many entity-name="EAVFeatureMapEntryValueHolder" />
+ </list>
+ </subclass>
+ <subclass
+ name="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVFeatureMapEntryValueHolder"
+ entity-name="EAVFeatureMapEntryValueHolder" abstract="false" lazy="false"
+ extends="EAVSingleEAttributeValueHolder" discriminator-value="EAVFeatureMapEntryValueHolder">
+
+ <tuplizer entity-mode="pojo"
+ class="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVTuplizer" />
+
+ <any name="referenceValue" cascade="persist, save-update, merge, evict, replicate, refresh"
+ id-type="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVGenericIDUserType"
+ meta-type="string">
+ <column not-null="false" unique="false" name="`reftype`" />
+ <column not-null="false" unique="false" name="`refid`" />
+ </any>
+
+ <any name="containedReferenceValue"
+ cascade="persist, save-update, merge, delete, evict, replicate, refresh"
+ id-type="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVGenericIDUserType"
+ meta-type="string">
+ <column not-null="false" unique="false" name="`conreftype`" />
+ <column not-null="false" unique="false" name="`conrefid`" />
+ </any>
+ </subclass>
+ <subclass
+ name="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVSingleNonContainmentEReferenceValueHolder"
+ entity-name="EAVSingleNonContainmentEReferenceValueHolder" abstract="false"
+ lazy="false" extends="EAV_Value" discriminator-value="EAVSingleNonContainmentEReferenceValueHolder">
+
+ <tuplizer entity-mode="pojo"
+ class="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVTuplizer" />
+
+ <any name="referenceValue" cascade="persist, save-update, merge, evict, replicate, refresh"
+ id-type="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVGenericIDUserType"
+ meta-type="string">
+ <column not-null="false" unique="false" name="`reftype`" />
+ <column not-null="false" unique="false" name="`refid`" />
+ </any>
+
+ <!--
+ this many-to-one is added to support efficient querying in case an object is an eav object
+ foreign key to none prevents a foreign key, hibernate does not do cascade delete in the correct order sometimes
+ the foreign key to none is save as the value is the same as for the referencevalue
+ NOTE: this many-to-one must be declared after the referencevalue tag above to hint to Hibernate
+ what the correct proxy is to use. If the order is turned around hibernate will add all proxy interfaces (of all classes to the
+ hibernate proxy
+ -->
+ <many-to-one name="eavObjectReference" entity-name="EAV_EObject" cascade="persist, save-update, merge, evict, replicate, refresh" foreign-key="none"/>
+
+ </subclass>
+ <subclass
+ name="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVSingleContainmentEReferenceValueHolder"
+ entity-name="EAVSingleContainmentEReferenceValueHolder" abstract="false"
+ lazy="false" extends="EAV_Value" discriminator-value="EAVSingleContainmentEReferenceValueHolder">
+
+ <tuplizer entity-mode="pojo"
+ class="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVTuplizer" />
+
+ <any name="referenceValue"
+ cascade="persist, merge, save-update, evict, delete, replicate, refresh"
+ id-type="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVGenericIDUserType"
+ meta-type="string">
+ <column not-null="false" unique="false" name="`conreftype`" />
+ <column not-null="false" unique="false" name="`conrefid`" />
+ </any>
+
+ <!--
+ this many-to-one is added to support efficient querying in case an object is an eav object
+ foreign key to none prevents a foreign key, hibernate does not do cascade delete in the correct order sometimes
+ the foreign key to none is save as the value is the same as for the referencevalue
+ NOTE: this many-to-one must be declared after the referencevalue tag above to hint to Hibernate
+ what the correct proxy is to use. If the order is turned around hibernate will add all proxy interfaces (of all classes to the
+ hibernate proxy
+ -->
+ <many-to-one name="eavObjectReference" entity-name="EAV_EObject" cascade="all" foreign-key="none"/>
+
+ </subclass>
+ <subclass
+ name="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVMultiContainmentEReferenceValueHolder"
+ entity-name="EAVMultiContainmentEReferenceValueHolder" abstract="false"
+ lazy="false" extends="EAV_Value" discriminator-value="EAVMultiContainmentEReferenceValueHolder">
+
+ <tuplizer entity-mode="pojo"
+ class="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVTuplizer" />
+
+ <list name="referenceValues" lazy="true"
+ cascade="all,delete-orphan" inverse="true">
+ <key update="true">
+ <column name="`valueowner`" not-null="false" unique="false" />
+ </key>
+ <list-index column="`listindex`" />
+ <one-to-many entity-name="EAVSingleContainmentEReferenceValueHolder" />
+ </list>
+ </subclass>
+ <subclass
+ name="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVExtraMultiContainmentEReferenceValueHolder"
+ entity-name="EAVExtraMultiContainmentEReferenceValueHolder" abstract="false"
+ lazy="false" extends="EAV_Value" discriminator-value="EAVExtraMultiContainmentEReferenceValueHolder">
+
+ <tuplizer entity-mode="pojo"
+ class="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVTuplizer" />
+
+ <list name="referenceValues" lazy="extra"
+ cascade="all,delete-orphan" inverse="true">
+ <key update="true">
+ <column name="`valueowner`" not-null="false" unique="false" />
+ </key>
+ <list-index column="`listindex`" />
+ <one-to-many entity-name="EAVSingleContainmentEReferenceValueHolder" />
+ </list>
+ </subclass>
+ <subclass
+ name="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVMultiNonContainmentEReferenceValueHolder"
+ entity-name="EAVMultiNonContainmentEReferenceValueHolder" abstract="false"
+ lazy="false" extends="EAV_Value" discriminator-value="EAVMultiNonContainmentEReferenceValueHolder">
+
+ <tuplizer entity-mode="pojo"
+ class="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVTuplizer" />
+
+ <list name="referenceValues" lazy="true"
+ cascade="all,delete-orphan" inverse="true">
+ <key update="true">
+ <column name="`valueowner`" not-null="false" unique="false" />
+ </key>
+ <list-index column="`listindex`" />
+ <one-to-many entity-name="EAVSingleNonContainmentEReferenceValueHolder" />
+ </list>
+ </subclass>
+ <subclass
+ name="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVExtraMultiNonContainmentEReferenceValueHolder"
+ entity-name="EAVExtraMultiNonContainmentEReferenceValueHolder" abstract="false"
+ lazy="false" extends="EAV_Value" discriminator-value="EAVExtraMultiNonContainmentEReferenceValueHolder">
+
+ <tuplizer entity-mode="pojo"
+ class="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVTuplizer" />
+
+ <list name="referenceValues" lazy="extra"
+ cascade="all,delete-orphan" inverse="true">
+ <key update="true">
+ <column name="`valueowner`" not-null="false" unique="false" />
+ </key>
+ <list-index column="`listindex`" />
+ <one-to-many entity-name="EAVSingleNonContainmentEReferenceValueHolder" />
+ </list>
+ </subclass>
+ <class name="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVBlobValue"
+ entity-name="EAV_Blob" abstract="true" lazy="false" table="`{tableprefix}eavblob`">
+
+ <id type="long" name="id" column="`eavid`">
+ <generator class="native" />
+ </id>
+ <version name="version" column="`eavversion`" />
+ <property name="blobValue" type="binary" column="`blobvalue`"
+ length="10000" />
+
+ <many-to-one name="valueHolder" entity-name="EAVSingleEAttributeValueHolder"
+ column="`valueholder`" unique="true" not-null="true" />
+
+ </class>
+ <class name="org.eclipse.emf.teneo.hibernate.mapping.eav.EAVTextValue"
+ entity-name="EAV_Text" abstract="true" lazy="false" table="`{tableprefix}eavtext`">
+
+ <id type="long" name="id" column="`eavid`">
+ <generator class="native" />
+ </id>
+ <version name="version" column="`eavversion`" />
+ <property name="textValue" type="text" column="`textvalue`"
+ length="10000" />
+
+ <many-to-one name="valueHolder" entity-name="EAVSingleEAttributeValueHolder"
+ column="`valueholder`" unique="true" not-null="true" />
+
+ </class>
+
+</hibernate-mapping> \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerAccessor.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerAccessor.java
new file mode 100755
index 000000000..65da5f6c9
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerAccessor.java
@@ -0,0 +1,68 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EContainerAccessor.java,v 1.6 2010/02/04 10:53:07 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.econtainer;
+
+import org.eclipse.emf.teneo.extension.ExtensionManager;
+import org.eclipse.emf.teneo.extension.ExtensionManagerAware;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+
+/**
+ * Creates the getter and setter for eContainer members.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.6 $
+ */
+public class EContainerAccessor implements PropertyAccessor, ExtensionPoint, ExtensionManagerAware {
+
+ private ExtensionManager extensionManager;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getGetter(java.lang.Class, java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException {
+ final EContainerPropertyHandler handler = extensionManager.getExtension(EContainerPropertyHandler.class);
+ handler.initialize(propertyName);
+ return handler;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getSetter(java.lang.Class, java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException {
+ final EContainerPropertyHandler handler = extensionManager.getExtension(EContainerPropertyHandler.class);
+ handler.initialize(propertyName);
+ return handler;
+ }
+
+ /**
+ * @param extensionManager
+ * the extensionManager to set
+ */
+ public void setExtensionManager(ExtensionManager extensionManager) {
+ this.extensionManager = extensionManager;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerFeatureIDAccessor.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerFeatureIDAccessor.java
new file mode 100755
index 000000000..fbc6a7a31
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerFeatureIDAccessor.java
@@ -0,0 +1,71 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EContainerFeatureIDAccessor.java,v 1.6 2010/02/04 10:53:07 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.econtainer;
+
+import org.eclipse.emf.teneo.extension.ExtensionManager;
+import org.eclipse.emf.teneo.extension.ExtensionManagerAware;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+
+/**
+ * Creates the getter and setter for eContainerFeatureID members.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.6 $
+ */
+public class EContainerFeatureIDAccessor implements PropertyAccessor, ExtensionPoint, ExtensionManagerAware {
+
+ private ExtensionManager extensionManager;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getGetter(java.lang.Class, java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException {
+ final EContainerFeatureIDPropertyHandler handler =
+ extensionManager.getExtension(EContainerFeatureIDPropertyHandler.class);
+ handler.initialize(propertyName);
+ return handler;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getSetter(java.lang.Class, java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException {
+ final EContainerFeatureIDPropertyHandler handler =
+ extensionManager.getExtension(EContainerFeatureIDPropertyHandler.class);
+ handler.initialize(propertyName);
+ return handler;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.teneo.extension.ExtensionManagerAware#setExtensionManager(org.eclipse.emf.teneo.extension.ExtensionManager)
+ */
+ public void setExtensionManager(ExtensionManager extensionManager) {
+ this.extensionManager = extensionManager;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerFeatureIDPropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerFeatureIDPropertyHandler.java
new file mode 100755
index 000000000..2f813c7d0
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerFeatureIDPropertyHandler.java
@@ -0,0 +1,147 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EContainerFeatureIDPropertyHandler.java,v 1.10 2010/11/11 10:28:18 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.econtainer;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.ecore.impl.BasicEObjectImpl;
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.util.FieldUtil;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.Setter;
+
+/**
+ * Implements the setter for the eContainerFeatureID member of an EObject.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.10 $
+ */
+public class EContainerFeatureIDPropertyHandler implements Getter, Setter,
+ ExtensionPoint {
+ /**
+ * Generated Serial ID
+ */
+ private static final long serialVersionUID = -7360171596936226424L;
+
+ /** The logger */
+ private static Log log = LogFactory
+ .getLog(EContainerFeatureIDPropertyHandler.class);
+
+ /** The javafield of the eContainer */
+ private Field ecField;
+
+ /** Constructor */
+ public void initialize(String field) {
+ ecField = FieldUtil.getField(EObjectImpl.class, "eContainerFeatureID");
+ log.debug("Created eContainerFeatureID handler");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Setter#getMethod()
+ */
+ public Method getMethod() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMember()
+ */
+ public Member getMember() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Setter#getMethodName()
+ */
+ public String getMethodName() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Setter#set(java.lang.Object,
+ * java.lang.Object, org.hibernate.engine.SessionFactoryImplementor)
+ */
+ public void set(Object target, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ if (target instanceof MinimalEObjectImpl) {
+ // TODO: externalize this
+ FieldUtil.callMethod(target, "eBasicSetContainerFeatureID",
+ new Object[] { value });
+ } else {
+ assert (target instanceof EObjectImpl);
+ assert (value instanceof Integer);
+ try {
+ ecField.set(target, value);
+ } catch (Exception e) {
+ throw new HbMapperException(
+ "Exception when setting eContainerFeatureID for: "
+ + target.getClass().getName() + " to value: "
+ + value, e);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#get(java.lang.Object)
+ */
+ public Object get(Object owner) throws HibernateException {
+ return new Integer(((BasicEObjectImpl) owner).eContainerFeatureID());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getForInsert(java.lang.Object,
+ * java.util.Map, org.hibernate.engine.SessionImplementor)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getForInsert(Object owner, Map mergeMap,
+ SessionImplementor session) throws HibernateException {
+ return new Integer(((BasicEObjectImpl) owner).eContainerFeatureID());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getReturnType()
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getReturnType() {
+ return Integer.class;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerFeatureIDUserType.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerFeatureIDUserType.java
new file mode 100644
index 000000000..ef7074c0c
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerFeatureIDUserType.java
@@ -0,0 +1,228 @@
+package org.eclipse.emf.teneo.hibernate.mapping.econtainer;
+
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal - Initial api and implementation
+ * Jan Haesli - solution for equals test on feature holder
+ * </copyright>
+ *
+ * $Id: EContainerFeatureIDUserType.java,v 1.5 2010/05/02 14:24:11 mtaal Exp $
+ */
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.teneo.PackageRegistryProvider;
+import org.hibernate.HibernateException;
+import org.hibernate.usertype.UserType;
+
+/**
+ * Persists an EContainerFeatureID as a varchar which contains both the EClass of the container as the complete
+ * reference to the EFeature.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.5 $ $Date: 2010/05/02 14:24:11 $
+ */
+
+public class EContainerFeatureIDUserType implements UserType {
+
+ private static final int[] SQL_TYPES = new int[] { Types.VARCHAR };
+ private static final String SEPARATOR = "_;_";
+
+ public static String convertEContainerRelationToString(EClass eClass, EStructuralFeature eFeature) {
+ StringBuilder result = new StringBuilder();
+ {
+ final String uri = eClass.getEPackage().getNsURI();
+ final String eClassifierName = eClass.getName();
+ result.append(uri + SEPARATOR + eClassifierName);
+ }
+
+ {
+ final String uri = eFeature.getEContainingClass().getEPackage().getNsURI();
+ final String eClassName = eFeature.getEContainingClass().getName();
+ final String eFeatureName = eFeature.getName();
+ result.append(SEPARATOR + uri + SEPARATOR + eClassName + SEPARATOR + eFeatureName);
+ }
+ return result.toString();
+ }
+
+ private EPackage.Registry registry;
+
+ public EContainerFeatureIDUserType() {
+ registry = PackageRegistryProvider.getInstance().getPackageRegistry();
+ }
+
+ public Object assemble(Serializable cached, Object owner) throws HibernateException {
+ final EContainerFeatureIDHolder holder = new EContainerFeatureIDHolder();
+ holder.convertFromString((String) cached, registry);
+ return holder;
+ }
+
+ public Object deepCopy(Object value) throws HibernateException {
+ return value;
+ }
+
+ public Serializable disassemble(Object value) throws HibernateException {
+ if (value == null) {
+ return null;
+ }
+ return ((EContainerFeatureIDHolder) value).convertToString();
+ }
+
+ public boolean equals(Object x, Object y) throws HibernateException {
+ if (x == null && y == null) {
+ return true;
+ }
+
+ if (x == null || y == null) {
+ return false;
+ }
+
+ if (x.getClass() != y.getClass()) {
+ return false;
+ }
+ return x.equals(y);
+ }
+
+ public int hashCode(Object x) throws HibernateException {
+ return x.hashCode();
+ }
+
+ public boolean isMutable() {
+ return false;
+ }
+
+ public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
+ final String value = rs.getString(names[0]);
+ if (rs.wasNull()) {
+ return null;
+ }
+ final EContainerFeatureIDHolder holder = new EContainerFeatureIDHolder();
+ holder.convertFromString(value, registry);
+ return holder;
+ }
+
+ public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+ if (value == null) {
+ st.setNull(index, Types.VARCHAR);
+ } else {
+ st.setString(index, ((EContainerFeatureIDHolder) value).convertToString());
+ }
+ }
+
+ public Object replace(Object original, Object target, Object owner) throws HibernateException {
+ return original;
+ }
+
+ public Class<?> returnedClass() {
+ return EStructuralFeature.class;
+ }
+
+ public int[] sqlTypes() {
+ return SQL_TYPES;
+ }
+
+ public static class EContainerFeatureIDHolder {
+ private EClass eClass;
+ private EStructuralFeature eFeature;
+
+ /**
+ * @return the eFeature
+ */
+ public EStructuralFeature getEFeature() {
+ return eFeature;
+ }
+
+ /**
+ * @param feature
+ * the eFeature to set
+ */
+ public void setEFeature(EStructuralFeature feature) {
+ eFeature = feature;
+ }
+
+ public void convertFromString(String value, EPackage.Registry theRegistry) {
+ final String[] values = value.split(SEPARATOR);
+ final String nsuri = values[0];
+ final EPackage eContainerPackage = theRegistry.getEPackage(nsuri);
+ final String eContainerEClassName = values[1];
+ eClass = (EClass) eContainerPackage.getEClassifier(eContainerEClassName);
+
+ final EPackage eFeaturePackage = theRegistry.getEPackage(values[2]);
+
+ final String eClassifierName = values[3];
+ final EClassifier eClassifier = eFeaturePackage.getEClassifier(eClassifierName);
+ final EClass eClass = (EClass) eClassifier;
+ final String eFeatureName = values[4];
+ eFeature = eClass.getEStructuralFeature(eFeatureName);
+ }
+
+ public String convertToString() {
+ return convertEContainerRelationToString(eClass, eFeature);
+ }
+
+ /**
+ * @return the eClass
+ */
+ public EClass getEClass() {
+ return eClass;
+ }
+
+ /**
+ * @param class1
+ * the eClass to set
+ */
+ public void setEClass(EClass class1) {
+ eClass = class1;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((eClass == null) ? 0 : eClass.hashCode());
+ result = prime * result + ((eFeature == null) ? 0 : eFeature.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ EContainerFeatureIDHolder other = (EContainerFeatureIDHolder) obj;
+ if (eClass == null && other.eClass != null) {
+ return false;
+ } else if (!eClass.equals(other.eClass)) {
+ return false;
+ }
+ if (eFeature == null && other.eFeature != null) {
+ return false;
+ } else if (!eFeature.equals(other.eFeature)) {
+ return false;
+ }
+ return true;
+ }
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerPropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerPropertyHandler.java
new file mode 100755
index 000000000..6de96cad7
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerPropertyHandler.java
@@ -0,0 +1,148 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EContainerPropertyHandler.java,v 1.10 2010/11/11 10:28:18 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.econtainer;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.util.AssertUtil;
+import org.eclipse.emf.teneo.util.FieldUtil;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.Setter;
+
+/**
+ * Implements the accessor for eContainer member
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.10 $
+ */
+
+public class EContainerPropertyHandler implements Getter, Setter,
+ ExtensionPoint {
+ /**
+ * Generated Serial Version UID
+ */
+ private static final long serialVersionUID = -414024662032391298L;
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(EContainerPropertyHandler.class);
+
+ /** The javafield of the eContainer */
+ private Field ecField;
+
+ /** Constructor */
+ public void initialize(String field) {
+ log.debug("Created eContainer property handler");
+ ecField = FieldUtil.getField(EObjectImpl.class, "eContainer");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMember()
+ */
+ public Member getMember() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#get(java.lang.Object)
+ */
+ public Object get(Object owner) throws HibernateException {
+ return ((EObject) owner).eContainer();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getForInsert(java.lang.Object,
+ * java.util.Map, org.hibernate.engine.SessionImplementor)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getForInsert(Object owner, Map mergeMap,
+ SessionImplementor session) throws HibernateException {
+ return ((EObject) owner).eContainer();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Setter#set(java.lang.Object,
+ * java.lang.Object, org.hibernate.engine.SessionFactoryImplementor)
+ */
+ public void set(Object target, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ if (target instanceof MinimalEObjectImpl) {
+ // TODO: externalize this
+ FieldUtil.callMethod(target, "eBasicSetContainer",
+ new Object[] { value });
+ } else {
+ AssertUtil.assertInstanceOfNotNull(target, InternalEObject.class);
+ AssertUtil.assertInstanceOf(value, EObject.class);
+ try {
+ ecField.set(target, value);
+ } catch (Exception e) {
+ throw new HbMapperException(
+ "Exception when setting econtainer for: "
+ + target.getClass().getName() + " to value: "
+ + value, e);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethod()
+ */
+ public Method getMethod() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethodName()
+ */
+ public String getMethodName() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getReturnType()
+ */
+ public Class<?> getReturnType() {
+ return EObject.class;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerUserType.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerUserType.java
new file mode 100755
index 000000000..700f86cdb
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/EContainerUserType.java
@@ -0,0 +1,549 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EContainerUserType.java,v 1.13 2010/11/12 09:33:33 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.econtainer;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.dom4j.Node;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.teneo.classloader.ClassLoaderResolver;
+import org.eclipse.emf.teneo.classloader.StoreClassLoadException;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierCacheHandler;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.TransientObjectException;
+import org.hibernate.engine.ForeignKeys;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.impl.SessionImpl;
+import org.hibernate.persister.entity.Joinable;
+import org.hibernate.type.AbstractStandardBasicType;
+import org.hibernate.type.AbstractType;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.ForeignKeyDirection;
+import org.hibernate.type.StandardBasicTypes;
+import org.hibernate.type.Type;
+import org.hibernate.usertype.CompositeUserType;
+
+/**
+ * Implements the EMF UserType for an Enum
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.13 $ $Date: 2010/11/12 09:33:33 $
+ */
+
+public class EContainerUserType extends AbstractType implements
+ CompositeUserType, AssociationType {
+ /**
+ * Serial version id
+ */
+ private static final long serialVersionUID = 6385066726834417274L;
+
+ /** Separator used in encoding the class name and value */
+ private static final String ENCODING_SEPARATOR = ";";
+
+ /** The property names */
+ private static final String[] propertyNames = new String[] {
+ "containerclass", "containerid" };
+
+ /** The property types (two strings) */
+ private static final Type[] propertyTypes = new Type[] {
+ StandardBasicTypes.STRING, StandardBasicTypes.STRING };
+
+ /** The sql types */
+ private static final int[] sqlTypes = new int[] { Types.VARCHAR,
+ Types.VARCHAR };
+
+ /** HashTable with cached constructors */
+ private final Hashtable<String, Constructor<?>> constructorCache = new Hashtable<String, Constructor<?>>();
+
+ /** HashTable with identifier types hashed by entityname */
+ private final Hashtable<String, Type> identifierTypeCache = new Hashtable<String, Type>();
+
+ /**
+ * Abstract method from super class, currently does not really print
+ * anything meaningfull
+ */
+ public String toLoggableString(Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ return (value != null ? "EContainer: " + value.getClass().getName()
+ : "EContainer null value");
+ }
+
+ /** The generic class returned (nl. Object) */
+ public Class<?> getReturnedClass() {
+ return Object.class;
+ }
+
+ /** Just returns passed value */
+ public Object deepCopy(Object value, EntityMode entityMode,
+ SessionFactoryImplementor factory) throws HibernateException {
+ return value;
+ }
+
+ /** Not supported */
+ public Object fromXMLNode(Node xml, Mapping factory)
+ throws HibernateException {
+ throw new UnsupportedOperationException("not supported for econtainer");
+ }
+
+ /** Two columns */
+ public int getColumnSpan(Mapping mapping) throws MappingException {
+ return 2;
+ }
+
+ /** A name */
+ public String getName() {
+ return "econtainer";
+ }
+
+ /** Does nothing */
+ public boolean isDirty(Object old, Object current, boolean[] checkable,
+ SessionImplementor session) throws HibernateException {
+ return isDirty(old, current, session);
+ }
+
+ /** Not supported */
+ public Object nullSafeGet(ResultSet rs, String name,
+ SessionImplementor session, Object owner)
+ throws HibernateException, SQLException {
+ throw new UnsupportedOperationException("not supported for econtainer");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.type.Type#nullSafeSet(java.sql.PreparedStatement,
+ * java.lang.Object, int, boolean[],
+ * org.hibernate.engine.SessionImplementor)
+ */
+ public void nullSafeSet(PreparedStatement st, Object value, int index,
+ boolean[] settable, SessionImplementor session)
+ throws HibernateException, SQLException {
+ // TODO Auto-generated method stub
+ if (settable == null || settable[0]) {
+ nullSafeSet(st, value, index, session);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.type.Type#replace(java.lang.Object, java.lang.Object,
+ * org.hibernate.engine.SessionImplementor, java.lang.Object, java.util.Map)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object replace(Object original, Object target,
+ SessionImplementor session, Object owner, Map copyCache)
+ throws HibernateException {
+ return replace(original, target, session, owner);
+ }
+
+ /** Not supported */
+ public void setToXMLNode(Node node, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ throw new UnsupportedOperationException("not supported for econtainer");
+ }
+
+ /** Two varchars */
+ public int[] sqlTypes(Mapping mapping) throws MappingException {
+ return sqlTypes;
+ }
+
+ /**
+ * Returns array of boolean denoting which columns are null when the value
+ * is null
+ */
+ public boolean[] toColumnNullness(Object value, Mapping mapping) {
+ boolean[] result = new boolean[getColumnSpan(mapping)];
+ if (value != null) {
+ for (int i = 0; i < result.length; i++) {
+ result[i] = true;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * True as this is very similar to anytype, needed to return true because
+ * otherwise Hibernate would not recognize that the container object should
+ * be saved before this object and saving transient instance was called.
+ */
+ @Override
+ public boolean isAnyType() {
+ return true;
+ }
+
+ /**
+ * Methods from
+ *
+ * /** Reference to other object so true
+ */
+ @Override
+ public boolean isAssociationType() {
+ return true;
+ }
+
+ /** And consists of multiple other objects */
+ @Override
+ public boolean isComponentType() {
+ return false;
+ }
+
+ /** Not supported */
+ public String getAssociatedEntityName(SessionFactoryImplementor factory)
+ throws MappingException {
+ throw new UnsupportedOperationException(
+ "Econtainer type is a generic type, no specific associated entity");
+ }
+
+ /** Not supported */
+ public Joinable getAssociatedJoinable(SessionFactoryImplementor factory)
+ throws MappingException {
+ throw new UnsupportedOperationException(
+ "Econtainer type is a generic type, no specific associated entity");
+ }
+
+ /** From parent */
+ public ForeignKeyDirection getForeignKeyDirection() {
+ return ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT;
+ }
+
+ /** Returns null */
+ public String getLHSPropertyName() {
+ return null;
+ }
+
+ /** Not supported */
+ @SuppressWarnings("rawtypes")
+ public String getOnCondition(String alias,
+ SessionFactoryImplementor factory, Map enabledFilters)
+ throws MappingException {
+ throw new UnsupportedOperationException("not supported for econtainer");
+ }
+
+ /** Returns null */
+ public String getRHSUniqueKeyPropertyName() {
+ return null;
+ }
+
+ /** False */
+ public boolean isAlwaysDirtyChecked() {
+ return false;
+ }
+
+ /** False */
+ public boolean isEmbeddedInXML() {
+ return false;
+ }
+
+ /** False */
+ public boolean useLHSPrimaryKey() {
+ return false;
+ }
+
+ /** Does nothing */
+ public Object deepCopy(Object value) throws HibernateException {
+ return value;
+ }
+
+ /** Is equal, does object equality? */
+ public boolean equals(Object x, Object y) throws HibernateException {
+ return x == y;
+ }
+
+ /** Just returns the hashcode of the passed object */
+ public int hashCode(Object x) throws HibernateException {
+ return x.hashCode();
+ }
+
+ /** Not mutable */
+ public boolean isMutable() {
+ return false;
+ }
+
+ /** Can be any object */
+ public Class<?> returnedClass() {
+ return Object.class;
+ }
+
+ /**
+ * Translates the serialized cached object to a real object
+ */
+ @Override
+ public Object assemble(Serializable cached, SessionImplementor session,
+ Object owner) throws HibernateException {
+
+ // palash: fix for ALL our teneo/ehcache woes!!
+ // if cache is null, just return null, without guessing; hibernate is
+ // smart enough to fetch it from the db
+ if (cached == null) {
+ return null;
+ }
+
+ // already correct
+ if (!(cached instanceof ContainerPointer)) {
+ final String entityName = session.bestGuessEntityName(cached);
+ final Serializable idObject = getID(entityName, cached, session);
+ return session.internalLoad(entityName, idObject, false, false);
+ } else {
+ final ContainerPointer cp = (ContainerPointer) cached;
+ return cp.getObject(session);
+ }
+ }
+
+ /** Create a containerpointer */
+ public Serializable disassemble(Object value, SessionImplementor session)
+ throws HibernateException {
+ if (value == null) {
+ return null;
+ }
+ try {
+ final String entityName = session.bestGuessEntityName(value);
+ final Object idObject = getID(entityName, value, session);
+ return new ContainerPointer(getIdentifierType(entityName, session),
+ entityName, idObject.toString());
+ } catch (TransientObjectException toe) {
+ return null;
+ }
+ }
+
+ @Override
+ public Serializable disassemble(Object value, SessionImplementor session,
+ Object owner) throws HibernateException {
+ return disassemble(value, session);
+ }
+
+ /** Propertynames: containerclass, containerid */
+ public String[] getPropertyNames() {
+ return propertyNames;
+ }
+
+ /** The propertyTypes */
+ public Type[] getPropertyTypes() {
+ return propertyTypes;
+ }
+
+ /** Not supported */
+ public Object getPropertyValue(Object component, int property)
+ throws HibernateException {
+ final Object container = ((InternalEObject) component).eContainer();
+ if (container == null) {
+ return null;
+ }
+
+ if (property == 0) {
+ return container.getClass().getName();
+ }
+ if (property == 1) {
+ return IdentifierCacheHandler.getInstance().getID(container);
+ }
+
+ throw new HbMapperException("Property: " + property
+ + " not supported in " + component.getClass().getName());
+ }
+
+ /** Load the object on the basis of the data in the resultset */
+ public Object nullSafeGet(ResultSet rs, String[] names,
+ SessionImplementor session, Object owner)
+ throws HibernateException, SQLException {
+ final String cc = rs.getString(names[0]); // container class
+ if (cc == null) {
+ return null;
+ }
+ final String idStr = rs.getString(names[1]);
+ if (idStr == null) {
+ return null;
+ }
+
+ final Object obj = session.internalLoad(cc,
+ extractID(getIdentifierType(cc, session), idStr), false, false);
+ return obj;
+ }
+
+ /** Set the data in the resultset */
+ public void nullSafeSet(PreparedStatement st, Object value, int index,
+ SessionImplementor session) throws HibernateException, SQLException {
+ if (value == null) {
+ st.setNull(index, Types.VARCHAR);
+ st.setNull(index + 1, Types.VARCHAR);
+ } else {
+ // EObject eobj = (EObject) value;
+ final String ename = session.bestGuessEntityName(value);
+ st.setString(index, ename);
+ st.setString(
+ index + 1,
+ createIDString(getIdentifierType(ename, session),
+ getID(ename, value, session)));
+ }
+ }
+
+ /**
+ * Returns the identifiertype on the basis of the class of the passed object
+ */
+ private Type getIdentifierType(String entityName, SessionImplementor session) {
+ Type type = identifierTypeCache.get(entityName);
+ if (type != null) {
+ return type;
+ }
+
+ final Type identifierType = ((SessionImpl) session).getFactory()
+ .getClassMetadata(entityName).getIdentifierType();
+ identifierTypeCache.put(entityName, identifierType);
+ return identifierType;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.CompositeUserType#replace(java.lang.Object,
+ * java.lang.Object, org.hibernate.engine.SessionImplementor,
+ * java.lang.Object)
+ */
+ public Object replace(Object original, Object target,
+ SessionImplementor session, Object owner) throws HibernateException {
+ if (original == null) {
+ return null;
+ }
+ final String ename = session.bestGuessEntityName(original);
+ final Serializable id = getID(ename, original, session);
+ return session.internalLoad(ename, id, false, false);
+ }
+
+ /** Returns the id of the passed object */
+ private Serializable getID(String entityName, Object value,
+ SessionImplementor session) {
+ Serializable result = ForeignKeys.getEntityIdentifierIfNotUnsaved(
+ entityName, value, session);
+
+ if (result != null) {
+ return result;
+ }
+ return (Serializable) IdentifierCacheHandler.getInstance().getID(value);
+ }
+
+ /**
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.usertype.CompositeUserType#setPropertyValue(java.lang.Object,
+ * int, java.lang.Object)
+ */
+ public void setPropertyValue(Object component, int property, Object value)
+ throws HibernateException {
+ // do nothing and hope for the best
+ }
+
+ /** Creates the serializable id object from a string */
+ private Serializable extractID(Type type, String idString) {
+ // first handle the most common case
+ if (type instanceof AbstractStandardBasicType) {
+ final AbstractStandardBasicType<?> ntype = (AbstractStandardBasicType<?>) type;
+ return (Serializable) ntype.fromStringValue(idString);
+ }
+
+ // for all other cases the classname is encoded into the field
+ final String className = idString.substring(0,
+ idString.indexOf(ENCODING_SEPARATOR));
+ final String strValue = idString.substring(1 + idString
+ .indexOf(ENCODING_SEPARATOR));
+
+ Constructor<?> constructor = constructorCache.get(className);
+ if (constructor == null) {
+ try {
+ final Class<?> clazz = ClassLoaderResolver
+ .classForName(className);
+ constructor = clazz
+ .getConstructor(new Class[] { String.class });
+ } catch (StoreClassLoadException e) {
+ throw new HbMapperException("Class " + className + " not found");
+ } catch (NoSuchMethodException e) {
+ throw new HbMapperException(
+ "Class "
+ + className
+ + " does not have a constructor with a String parameter!");
+ }
+ }
+ if (constructor == null) {
+ throw new HbMapperException("Class " + className
+ + " does not have a constructor with a String parameter!");
+ }
+
+ try {
+ return (Serializable) constructor
+ .newInstance(new Object[] { strValue });
+ } catch (InvocationTargetException e) {
+ throw new HbMapperException("Can not instantiate: " + className
+ + " using value " + strValue);
+ } catch (InstantiationException e) {
+ throw new HbMapperException("Can not instantiate: " + className
+ + " using value " + strValue);
+ } catch (IllegalAccessException e) {
+ throw new HbMapperException("Can not instantiate: " + className
+ + " using value " + strValue);
+ }
+ }
+
+ /** Creates an id string from a serializable object */
+ private String createIDString(Type type, Serializable id) {
+ if (type instanceof AbstractStandardBasicType) {
+ @SuppressWarnings("unchecked")
+ final AbstractStandardBasicType<Object> ntype = (AbstractStandardBasicType<Object>) type;
+ return ntype.toString(id);
+ }
+
+ return id.getClass().getName() + ENCODING_SEPARATOR + id.toString();
+ }
+
+ /**
+ * Creates a type of proxy object which keeps the container class and
+ * container id
+ */
+ private class ContainerPointer implements Serializable {
+ /**
+ * Serial version id
+ */
+ private static final long serialVersionUID = -2777938032663239346L;
+
+ /** The container class */
+ private final String container;
+
+ /** The id object */
+ private final Serializable id;
+
+ /** Constructor */
+ ContainerPointer(Type type, String theContainer, String theIDStr) {
+ container = theContainer;
+ id = extractID(type, theIDStr);
+ }
+
+ /** Returns the container object pointed to */
+ private Object getObject(SessionImplementor session) {
+ return session.internalLoad(container, id, false, false);
+ }
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/NewEContainerFeatureIDPropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/NewEContainerFeatureIDPropertyHandler.java
new file mode 100644
index 000000000..ea403a2ed
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/econtainer/NewEContainerFeatureIDPropertyHandler.java
@@ -0,0 +1,168 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: NewEContainerFeatureIDPropertyHandler.java,v 1.4 2010/11/11 10:28:18 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.econtainer;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.mapping.econtainer.EContainerFeatureIDUserType.EContainerFeatureIDHolder;
+import org.eclipse.emf.teneo.util.AssertUtil;
+import org.eclipse.emf.teneo.util.FieldUtil;
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+
+/**
+ * Handles the eContainerFeatureId field of an EObjectImpl.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.4 $
+ */
+
+public class NewEContainerFeatureIDPropertyHandler implements PropertyAccessor,
+ Getter, Setter, ExtensionPoint {
+ /**
+ * Generated Serial Version UID
+ */
+ private static final long serialVersionUID = -414024662032391298L;
+
+ private static Log log = LogFactory
+ .getLog(NewEContainerFeatureIDPropertyHandler.class);
+
+ private Field ecField;
+
+ public NewEContainerFeatureIDPropertyHandler() {
+ log.debug("Created eContainer property handler");
+ ecField = FieldUtil.getField(EObjectImpl.class, "eContainerFeatureID");
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Getter getGetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMember()
+ */
+ public Member getMember() {
+ return null;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Setter getSetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ public Object get(Object owner) throws HibernateException {
+ final InternalEObject eObject = (InternalEObject) owner;
+ if (eObject.eContainer() == null) {
+ return null;
+ }
+ final EContainerFeatureIDHolder holder = new EContainerFeatureIDHolder();
+ holder.setEClass(eObject.eContainer().eClass());
+ holder.setEFeature(eObject.eContainingFeature());
+ return holder;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Object getForInsert(Object owner, Map mergeMap,
+ SessionImplementor session) throws HibernateException {
+ return get(owner);
+ }
+
+ public void set(Object target, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ AssertUtil.assertInstanceOfNotNull(target, InternalEObject.class);
+ AssertUtil.assertInstanceOf(value, EContainerFeatureIDHolder.class);
+
+ if (value != null) {
+ EContainerFeatureIDHolder holder = (EContainerFeatureIDHolder) value;
+ if (target instanceof MinimalEObjectImpl) {
+ // TODO: externalize this
+ FieldUtil.callMethod(
+ target,
+ "eBasicSetContainerFeatureID",
+ new Object[] { getContainerFeatureId(
+ holder.getEClass(), (EObject) target,
+ holder.getEFeature()) });
+ } else {
+ try {
+ ecField.set(
+ target,
+ getContainerFeatureId(holder.getEClass(),
+ (EObject) target, holder.getEFeature()));
+ } catch (Exception e) {
+ throw new HbMapperException(
+ "Exception when setting econtainer for: "
+ + target.getClass().getName()
+ + " to value: " + value, e);
+ }
+ }
+ }
+ }
+
+ public int getContainerFeatureId(EClass containingEClass,
+ EObject contained, EStructuralFeature eFeature) {
+ if (eFeature instanceof EAttribute) {
+ return InternalEObject.EOPPOSITE_FEATURE_BASE
+ - containingEClass.getFeatureID(eFeature);
+
+ }
+ final EReference eReference = (EReference) eFeature;
+ if (eReference.getEOpposite() != null) {
+ final EReference containerEReference = eReference.getEOpposite();
+ return contained.eClass().getFeatureID(containerEReference);
+ } else {
+ return InternalEObject.EOPPOSITE_FEATURE_BASE
+ - containingEClass.getFeatureID(eReference);
+ }
+ }
+
+ public Method getMethod() {
+ return null;
+ }
+
+ public String getMethodName() {
+ return null;
+ }
+
+ public Class<?> getReturnType() {
+ return EStructuralFeature.class;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryComponentInstantiator.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryComponentInstantiator.java
new file mode 100644
index 000000000..7bf17783b
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryComponentInstantiator.java
@@ -0,0 +1,47 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008, 2009 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.elist;
+
+import java.io.Serializable;
+
+import org.hibernate.mapping.Component;
+import org.hibernate.tuple.Instantiator;
+
+/**
+ * Instantiates feature map entries which are mapped as components.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.2 $
+ */
+
+public class FeatureMapEntryComponentInstantiator implements Instantiator {
+ private static final long serialVersionUID = -1219767393020090471L;
+
+ public FeatureMapEntryComponentInstantiator(Component component) {
+ }
+
+ public Object instantiate() {
+ final HibernateFeatureMapEntry fme = new HibernateFeatureMapEntry();
+ return fme;
+ }
+
+ public Object instantiate(Serializable id) {
+ return instantiate();
+ }
+
+ public boolean isInstance(Object object) {
+ return HibernateFeatureMapEntry.class.isInstance(object);
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryComponentTuplizer.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryComponentTuplizer.java
new file mode 100644
index 000000000..59f3c6b13
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryComponentTuplizer.java
@@ -0,0 +1,107 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: FeatureMapEntryComponentTuplizer.java,v 1.3 2010/02/04 10:53:08 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.elist;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.teneo.Constants;
+import org.eclipse.emf.teneo.hibernate.HbDataStore;
+import org.eclipse.emf.teneo.hibernate.HbHelper;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.mapper.HbMapperConstants;
+import org.eclipse.emf.teneo.hibernate.mapping.property.WildCardAttributePropertyHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.property.WildCardReferencePropertyHandler;
+import org.eclipse.emf.teneo.util.StoreUtil;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.MetaAttribute;
+import org.hibernate.mapping.Property;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.tuple.component.AbstractComponentTuplizer;
+
+/**
+ * Tuplizer for feature map entries. These types are mapped using the dynamic capabilities of Hibernate.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.3 $
+ */
+
+public class FeatureMapEntryComponentTuplizer extends AbstractComponentTuplizer {
+
+ private static final long serialVersionUID = 1L;
+ private static Log log = LogFactory.getLog(FeatureMapEntryComponentTuplizer.class);
+
+ public FeatureMapEntryComponentTuplizer(Component component) {
+ super(component);
+ }
+
+ protected Instantiator buildInstantiator(Component component) {
+ return new FeatureMapEntryComponentInstantiator(component);
+ }
+
+ protected Getter buildGetter(Component component, Property prop) {
+ return getPropertyAccessor(prop, component).getGetter(component.getComponentClass(), prop.getName());
+ }
+
+ protected Setter buildSetter(Component component, Property prop) {
+ return getPropertyAccessor(prop, component).getSetter(component.getComponentClass(), prop.getName());
+ }
+
+ protected PropertyAccessor getPropertyAccessor(Property mappedProperty, Component component) {
+ final HbDataStore hds = HbHelper.INSTANCE.getDataStore(component.getOwner());
+ if (mappedProperty.getMetaAttribute(HbMapperConstants.VERSION_META) != null) {
+ return hds.getHbContext().createVersionAccessor();
+ } else if (mappedProperty.getName().compareToIgnoreCase(HbMapperConstants.PROPERTY_FEATURE) == 0) {
+ return hds.getHbContext().createFeatureMapEntryFeatureURIAccessor();
+ } else if (mappedProperty.getName().compareToIgnoreCase(HbMapperConstants.PROPERTY_MIXED_CDATA) == 0) {
+ return hds.getHbContext().createFeatureMapEntryAccessor(Constants.CDATA);
+ } else if (mappedProperty.getName().compareToIgnoreCase(HbMapperConstants.PROPERTY_MIXED_COMMENT) == 0) {
+ return hds.getHbContext().createFeatureMapEntryAccessor(Constants.COMMENT);
+ } else if (mappedProperty.getName().compareToIgnoreCase(HbMapperConstants.PROPERTY_MIXED_TEXT) == 0) {
+ return hds.getHbContext().createFeatureMapEntryAccessor(Constants.TEXT);
+ } else if (mappedProperty.getName().endsWith(HbMapperConstants.PROPERTY_ANY_PRIMITIVE)) {
+ return hds.getExtensionManager().getExtension(WildCardAttributePropertyHandler.class);
+ } else if (mappedProperty.getName().endsWith(HbMapperConstants.PROPERTY_ANY_REFERENCE)) {
+ return hds.getExtensionManager().getExtension(WildCardReferencePropertyHandler.class);
+ }
+
+ final MetaAttribute ma = component.getMetaAttribute(HbMapperConstants.FEATUREMAP_META);
+ final String eclassUri = ma.getValue();
+ final EClass eClass = hds.getEntityNameStrategy().toEClass(eclassUri);
+ final EStructuralFeature efeature = StoreUtil.getEStructuralFeature(eClass, mappedProperty.getName());
+
+ if (efeature == null) {
+ throw new HbMapperException("Feature not found for property " + mappedProperty.getName());
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Creating property accessor for " + mappedProperty.getName() + "/" + eclassUri + "/"
+ + efeature.getName());
+ }
+
+ return hds.getHbContext().createFeatureMapEntryAccessor(efeature);
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Class getMappedClass() {
+ return HibernateFeatureMapEntry.class;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryInstantiator.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryInstantiator.java
new file mode 100755
index 000000000..6c4e56d23
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryInstantiator.java
@@ -0,0 +1,79 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: FeatureMapEntryInstantiator.java,v 1.5 2008/02/28 07:08:24 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.elist;
+
+import java.io.Serializable;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.teneo.hibernate.mapper.HbMapperConstants;
+import org.eclipse.emf.teneo.util.AssertUtil;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.tuple.Instantiator;
+
+/**
+ * Instantiates feature map entries.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.5 $
+ */
+
+public class FeatureMapEntryInstantiator implements Instantiator {
+
+ /**
+ * Serial Version ID
+ */
+ private static final long serialVersionUID = -1219767393020090471L;
+
+ /** The logger */
+ private static Log log = LogFactory
+ .getLog(FeatureMapEntryInstantiator.class);
+
+ /** The persistentclass for which we do all this */
+ private final PersistentClass persistentClass;
+
+ /** The proxy interface if used */
+ private final Class<?> proxyInterface;
+
+ /** Constructor */
+ public FeatureMapEntryInstantiator(PersistentClass pc) {
+ AssertUtil.assertTrue(pc.getEntityName()
+ + " does not have a meta attribute", pc
+ .getMetaAttribute(HbMapperConstants.FEATUREMAP_META) != null);
+ log.debug("Creating fme instantiator for " + pc.getEntityName());
+ proxyInterface = pc.getProxyInterface();
+ persistentClass = pc;
+ }
+
+ /** Instantiates using the EFactory */
+ public Object instantiate() {
+ final HibernateFeatureMapEntry fme = new HibernateFeatureMapEntry();
+ fme.setEntityName(persistentClass.getEntityName());
+ return fme;
+ }
+
+ /** Instantiates using the EFactory */
+ public Object instantiate(Serializable id) {
+ return instantiate();
+ }
+
+ /** Checks using the mapped class or the proxy interface */
+ public boolean isInstance(Object object) {
+ return HibernateFeatureMapEntry.class.isInstance(object)
+ || (proxyInterface != null && proxyInterface.isInstance(object));
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryTuplizer.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryTuplizer.java
new file mode 100755
index 000000000..39ffca94e
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/FeatureMapEntryTuplizer.java
@@ -0,0 +1,119 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: FeatureMapEntryTuplizer.java,v 1.15 2009/06/28 02:04:54 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.elist;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.teneo.Constants;
+import org.eclipse.emf.teneo.hibernate.HbDataStore;
+import org.eclipse.emf.teneo.hibernate.HbHelper;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.HbUtil;
+import org.eclipse.emf.teneo.hibernate.mapper.HbMapperConstants;
+import org.eclipse.emf.teneo.hibernate.mapping.property.WildCardAttributePropertyHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.property.WildCardReferencePropertyHandler;
+import org.eclipse.emf.teneo.hibernate.tuplizer.EMFTuplizer;
+import org.eclipse.emf.teneo.util.StoreUtil;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.tuple.entity.EntityMetamodel;
+
+/**
+ * Tuplizer for feature map entries. These types are mapped using the dynamic capabilities of Hibernate.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.15 $
+ */
+
+public class FeatureMapEntryTuplizer extends EMFTuplizer {
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(FeatureMapEntryTuplizer.class);
+
+ /** Constructor */
+ public FeatureMapEntryTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
+ super(entityMetamodel, mappedEntity);
+ }
+
+ /** Creates an EMF Instantiator */
+ @Override
+ protected Instantiator buildInstantiator(PersistentClass persistentClass) {
+ return new FeatureMapEntryInstantiator(persistentClass);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.EntityTuplizer#getConcreteProxyClass()
+ */
+ @Override
+ public Class<?> getConcreteProxyClass() {
+ return EObject.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.Tuplizer#getMappedClass()
+ */
+ @Override
+ public Class<?> getMappedClass() {
+ return EObject.class;
+ }
+
+ /** Returns the correct accessor on the basis of the type of property */
+ @Override
+ protected PropertyAccessor getPropertyAccessor(Property mappedProperty, PersistentClass pc) {
+ final HbDataStore hds = HbHelper.INSTANCE.getDataStore(pc);
+ if (mappedProperty.getMetaAttribute(HbMapperConstants.VERSION_META) != null) {
+ return hds.getHbContext().createVersionAccessor();
+ } else if (mappedProperty.getName().compareToIgnoreCase(HbMapperConstants.PROPERTY_FEATURE) == 0) {
+ return hds.getHbContext().createFeatureMapEntryFeatureURIAccessor();
+ } else if (mappedProperty.getName().compareToIgnoreCase(HbMapperConstants.PROPERTY_MIXED_CDATA) == 0) {
+ return hds.getHbContext().createFeatureMapEntryAccessor(Constants.CDATA);
+ } else if (mappedProperty.getName().compareToIgnoreCase(HbMapperConstants.PROPERTY_MIXED_COMMENT) == 0) {
+ return hds.getHbContext().createFeatureMapEntryAccessor(Constants.COMMENT);
+ } else if (mappedProperty.getName().compareToIgnoreCase(HbMapperConstants.PROPERTY_MIXED_TEXT) == 0) {
+ return hds.getHbContext().createFeatureMapEntryAccessor(Constants.TEXT);
+ } else if (mappedProperty.getName().endsWith(HbMapperConstants.PROPERTY_ANY_PRIMITIVE)) {
+ return hds.getExtensionManager().getExtension(WildCardAttributePropertyHandler.class);
+ } else if (mappedProperty.getName().endsWith(HbMapperConstants.PROPERTY_ANY_REFERENCE)) {
+ return hds.getExtensionManager().getExtension(WildCardReferencePropertyHandler.class);
+ }
+
+ final String eclassUri = HbUtil.getEClassNameFromFeatureMapMeta(pc);
+ final EClass eClass = hds.getEntityNameStrategy().toEClass(eclassUri);
+ final EStructuralFeature efeature = StoreUtil.getEStructuralFeature(eClass, mappedProperty.getName());
+
+ if (efeature == null) {
+ throw new HbMapperException("Feature not found for entity/property " + pc.getEntityName() + "/"
+ + mappedProperty.getName());
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Creating property accessor for " + mappedProperty.getName() + "/" + pc.getEntityName() + "/"
+ + eclassUri + "/" + efeature.getName());
+ }
+
+ return hds.getHbContext().createFeatureMapEntryAccessor(efeature);
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HbExtraLazyPersistableEList.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HbExtraLazyPersistableEList.java
new file mode 100755
index 000000000..305b687d6
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HbExtraLazyPersistableEList.java
@@ -0,0 +1,382 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HbExtraLazyPersistableEList.java,v 1.18 2010/04/04 12:10:51 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.elist;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.teneo.EContainerRepairControl;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.LazyCollectionUtils;
+import org.eclipse.emf.teneo.hibernate.SessionWrapper;
+import org.eclipse.emf.teneo.hibernate.resource.HbResource;
+import org.eclipse.emf.teneo.resource.StoreResource;
+import org.eclipse.emf.teneo.util.StoreUtil;
+import org.hibernate.Session;
+import org.hibernate.collection.AbstractPersistentCollection;
+import org.hibernate.collection.PersistentBag;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.collection.PersistentIdentifierBag;
+import org.hibernate.collection.PersistentList;
+
+/**
+ * Implements the hibernate persistable elist with extra lazy behavior, most
+ * operations should not load the complete list. This is targeted at very large
+ * lists. Note that this list can not work in a detached mode.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.18 $
+ */
+
+public class HbExtraLazyPersistableEList<E> extends
+ HibernatePersistableEList<E> implements ExtensionPoint {
+
+ /** The logger */
+ // private static Log log =
+ // LogFactory.getLog(HbExtraLazyPersistableEList.class);
+ /**
+ * Serial version id
+ */
+ private static final long serialVersionUID = 5479222310361594394L;
+
+ private boolean previousDeliverSetting = false;
+
+ /** Constructor */
+ public HbExtraLazyPersistableEList(InternalEObject owner,
+ EStructuralFeature feature, List<E> list) {
+ super(owner, feature, list);
+ }
+
+ @Override
+ /**
+ * Always returns false because this prevents full loading of the list.
+ * Prevents checks on uniqueness. This is a small price to pay for better performance.
+ */
+ public boolean isUnique() {
+ return false;
+ }
+
+ // done in superclass:
+ // - delegateSize and delegateIsEmpty: super implementation is already extra
+ // lazy
+ // - delegateBasicList: will result in a full load
+ // - delegateContains and delegateContainsAll: will result in a full load
+ // - delegateEquals and delegatehashCode: will result in a full load
+ // - delegateIndexOf and delegateLastIndexOf: will result in a full load
+ // - delegateToArray: will result in a full load
+ // - delegateIterator and delegateListIterator: will result in a full load
+ // - delegateToString: will result in a full load
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.common.util.DelegatingEList#delegateAdd(int,
+ * java.lang.Object)
+ */
+ @Override
+ protected void delegateAdd(int index, E object) {
+ if (index == size()) {
+ delegateAdd(object);
+ return;
+ }
+
+ // force a load
+ delegateList().iterator();
+
+ delegateList().add(index, object);
+
+ int newIndex = index;
+ for (Object element : delegateList().subList(index, size())) {
+ // for the new one set the owner
+ if (newIndex == index) {
+ StoreUtil.setSyntheticListOwner(getEStructuralFeature(),
+ element, getOwner());
+ }
+ StoreUtil.setSyntheticListIndex(getEStructuralFeature(), element,
+ newIndex++);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.emf.common.util.DelegatingEList#delegateAdd(java.lang.Object)
+ */
+ @Override
+ protected void delegateAdd(E object) {
+ int newIndex = delegateList().size();
+ delegateList().add(object);
+ StoreUtil.setSyntheticListIndex(getEStructuralFeature(), object,
+ newIndex);
+ StoreUtil.setSyntheticListOwner(getEStructuralFeature(), object,
+ getOwner());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.common.util.DelegatingEList#delegateClear()
+ */
+ @Override
+ protected void delegateClear() {
+ for (Object element : delegateList()) {
+ StoreUtil.resetSyntheticListInfo(getEStructuralFeature(), element);
+ }
+ delegateList().clear();
+ }
+
+ @Override
+ public Iterator<E> delegateIterator() {
+ return iterator();
+ }
+
+ @Override
+ public Iterator<E> iterator() {
+ // return a paging iterator
+ return LazyCollectionUtils.getPagedLoadingIterator(this, LazyCollectionUtils.DEFAULT_PAGE_SIZE);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.emf.common.util.DelegatingEList#delegateContains(java.lang
+ * .Object)
+ */
+ @Override
+ protected boolean delegateContains(Object object) {
+ return delegateList().contains(object);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.emf.common.util.DelegatingEList#delegateContainsAll(java.
+ * util.Collection)
+ */
+ @Override
+ protected boolean delegateContainsAll(Collection<?> collection) {
+ return delegateList().containsAll(collection);
+ }
+
+ /** Returns the underlying elist */
+ @Override
+ protected List<E> delegateList() {
+ return getDelegate();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.common.util.DelegatingEList#delegateGet(int)
+ */
+ @Override
+ protected E delegateGet(int index) {
+ boolean callAfterLoadInstance = false;
+ if (!isLoaded()) {
+ beforeLoadInstance();
+ callAfterLoadInstance = true;
+ }
+ final E object = delegateList().get(index);
+ if (callAfterLoadInstance && object instanceof EObject) {
+ final EObject eObject = (EObject) object;
+ afterLoadInstance(eObject);
+ }
+ return object;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.common.util.DelegatingEList#delegateRemove(int)
+ */
+ @Override
+ protected E delegateRemove(int index) {
+ if (index == (size() - 1) && !isInitialized() && isConnectedToSession()) {
+ // removing the last one
+ final E result = delegateList().remove(index);
+ StoreUtil.resetSyntheticListInfo(getEStructuralFeature(), result);
+ if (getEStructuralFeature() instanceof EReference
+ && ((EReference) getEStructuralFeature()).isContainment()) {
+ // remove the removed object
+ // if the list is not initialized then cascade deletes won't
+ // work
+ final Session session = (Session) ((PersistentList) getDelegate())
+ .getSession();
+ session.delete(result);
+ }
+ return result;
+ }
+
+ // force a full load
+ delegateList().iterator();
+
+ final E result = delegateList().remove(index);
+ StoreUtil.resetSyntheticListInfo(getEStructuralFeature(), result);
+
+ int newIndex = index;
+ for (Object element : delegateList().subList(index, size())) {
+ StoreUtil.setSyntheticListIndex(getEStructuralFeature(), element,
+ newIndex++);
+ }
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.common.util.DelegatingEList#delegateSet(int,
+ * java.lang.Object)
+ */
+ @Override
+ protected E delegateSet(int index, E object) {
+ final E oldObject = delegateList().set(index, object);
+
+ // clear old object
+ if (oldObject != null) {
+ StoreUtil
+ .resetSyntheticListInfo(getEStructuralFeature(), oldObject);
+ }
+
+ // set new object
+ StoreUtil.setSyntheticListIndex(getEStructuralFeature(), object, index);
+ StoreUtil.setSyntheticListOwner(getEStructuralFeature(), object,
+ getOwner());
+ return oldObject;
+ }
+
+ /**
+ * Implements the actions which need to be done before getting/loading an
+ * instance.
+ */
+ protected synchronized void beforeLoadInstance() {
+ final Resource res = owner.eResource();
+ if (res != null && res instanceof HbResource) {
+ final SessionWrapper sessionWrapper = ((HbResource) res)
+ .getSessionWrapper();
+ if (res.isLoaded()) // resource is loaded reopen transaction
+ {
+ // if the delegate is already loaded then no transaction is
+ // required
+ final boolean isDelegateLoaded = delegate instanceof AbstractPersistentCollection
+ && ((AbstractPersistentCollection) delegate)
+ .wasInitialized();
+ if (!isDelegateLoaded && !sessionWrapper.isTransactionActive()) {
+ sessionWrapper.setFlushModeManual();
+ }
+ ((StoreResource) res).setIsLoading(true);
+ }
+ }
+ previousDeliverSetting = owner.eDeliver();
+ try {
+ // only set to false if it was true
+ if (previousDeliverSetting) {
+ owner.eSetDeliver(false);
+ }
+ } catch (UnsupportedOperationException e) {
+ // in this case the eSetDeliver was not overridden from the
+ // baseclass
+ // ignore
+ }
+ }
+
+ protected void afterLoadInstance(EObject eObject) {
+
+ // disabled for now as containers are persisted by hibernate
+ // anyway
+ if (isContainment() && eObject.eContainer() == null) {
+ EContainerRepairControl.setContainer(owner,
+ (InternalEObject) eObject, getEStructuralFeature());
+ }
+ final Resource res = owner.eResource();
+ if (res != null && res instanceof HbResource) {
+ // attach the new contained objects so that they are adapted
+ // when required
+ ((StoreResource) res).addToContentOrAttach(
+ (InternalEObject) eObject,
+ (EReference) getEStructuralFeature());
+ ((StoreResource) res).setIsLoading(false);
+ }
+
+ try {
+ // only set to false if it was true
+ if (previousDeliverSetting) {
+ owner.eSetDeliver(true);
+ }
+ } catch (UnsupportedOperationException e) {
+ // in this case the eSetDeliver was not overridden from the
+ // baseclass
+ // ignore
+ }
+ }
+
+ /** If the delegate has been initialized */
+ public boolean isInitialized() {
+ return ((PersistentCollection) delegate).wasInitialized();
+ }
+
+ /** Overridden because general list type is not supported as a replacement */
+ @Override
+ public void replaceDelegate(List<E> newDelegate) {
+ if (newDelegate instanceof PersistentList) {
+ // disabled this assertion because in case of a session refresh it
+ // is possible
+ // that the list is replaced by a persistent list
+ // AssertUtil.assertTrue("This elist " + logString + " contains a
+ // different list than the " +
+ // " passed list",
+ // ((PersistentList)newDelegate).isWrapper(delegate));
+ super.replaceDelegate(newDelegate);
+ } else if (newDelegate instanceof PersistentBag) {
+ // disabled this assertion because in case of a session refresh it
+ // is possible
+ // that the list is replaced by a persistent list
+ // AssertUtil.assertTrue("This elist " + logString + " contains a
+ // different list than the " +
+ // " passed list",
+ // ((PersistentBag)newDelegate).isWrapper(delegate));
+ super.replaceDelegate(newDelegate);
+ } else if (newDelegate instanceof PersistentIdentifierBag) {
+ // Added to support <idbag>
+ super.replaceDelegate(newDelegate);
+ } else if (newDelegate == delegate) // this can occur and is okay, do
+ // nothing in this case
+ {
+
+ } else {
+ throw new HbMapperException("Type "
+ + newDelegate.getClass().getName() + " can not be "
+ + " used as a replacement for elist " + logString);
+ }
+ }
+
+ /** Returns true if the wrapped list is a persistency layer specific list */
+ @Override
+ public boolean isPersistencyWrapped() {
+ return delegate instanceof PersistentCollection;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HbExtraLazyPersistableEMap.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HbExtraLazyPersistableEMap.java
new file mode 100644
index 000000000..c7ebccd08
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HbExtraLazyPersistableEMap.java
@@ -0,0 +1,193 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HbExtraLazyPersistableEMap.java,v 1.3 2010/08/18 11:50:38 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.elist;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.common.util.BasicEMap;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.teneo.hibernate.LazyCollectionUtils;
+import org.eclipse.emf.teneo.mapping.elist.PersistableEList;
+import org.eclipse.emf.teneo.util.StoreUtil;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.collection.AbstractPersistentCollection;
+import org.hibernate.collection.PersistentList;
+import org.hibernate.engine.CollectionEntry;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.AbstractCollectionPersister;
+import org.hibernate.type.EntityType;
+
+/**
+ * Extends the default hibernate persistable emap with extra lazy behavior.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.3 $
+ */
+
+public class HbExtraLazyPersistableEMap<K, V> extends HibernatePersistableEMap<K, V> {
+
+ private static final long serialVersionUID = 1L;
+
+ /** Constructor */
+ public HbExtraLazyPersistableEMap(InternalEObject owner, EReference eref, List<Entry<K, V>> list) {
+ super(owner, eref, list);
+ }
+
+ @Override
+ public Iterator<java.util.Map.Entry<K, V>> iterator() {
+ return LazyCollectionUtils.getPagedLoadingIterator(this, LazyCollectionUtils.DEFAULT_PAGE_SIZE);
+ }
+
+ @Override
+ public int size() {
+ // if we are not loaded yet, we return the size of the buffered lazy
+ // load delegate
+
+ if (!isLoaded() && isHibernateListPresent()) {
+ try {
+ size = ((PersistentList)((PersistableEList<?>) delegateEList).getDelegate()).size();
+ return size;
+ } catch (Throwable t) {
+ // ignore on purpose, let the call to super handle it
+ }
+ }
+
+ // didnt work, so we simply call the parent version
+ return super.size();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public V get(Object key) {
+ // do a lazy get
+ if (key != null && !isLoaded() && isHibernateListPresent()) {
+ final Session session = getSession();
+
+ session.flush();
+
+ // create a query
+ final AbstractPersistentCollection collection = (AbstractPersistentCollection)getDelegate();
+ final CollectionEntry collectionEntry = ((SessionImplementor)session).getPersistenceContext().getCollectionEntry(collection);
+ final AbstractCollectionPersister persister = (AbstractCollectionPersister)collectionEntry.getLoadedPersister();
+ final String entityName = ((EntityType)persister.getCollectionMetadata().getElementType()).getAssociatedEntityName();
+ final Query qry = session.createQuery("select e from " + entityName + " as e where e.key=:key and e." + StoreUtil.getExtraLazyInversePropertyName(getEStructuralFeature()) + "=:owner");
+ qry.setParameter("key", key);
+ qry.setParameter("owner", getOwner());
+ final Object result = qry.uniqueResult();
+ if (result instanceof Map.Entry<?, ?>) {
+ final Map.Entry<K, V> entry = (Map.Entry<K, V>)result;
+ return entry.getValue();
+ }
+ return null;
+ }
+ // TODO Auto-generated method stub
+ return super.get(key);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public V put(K key, V value) {
+ if (!isLoaded() && isHibernateListPresent()) {
+ final Map.Entry<K, V> entry = (Map.Entry<K, V>)get(key);
+ if (entry != null && entry instanceof org.eclipse.emf.common.util.BasicEMap.Entry<?, ?>) {
+ V result = putEntry((org.eclipse.emf.common.util.BasicEMap.Entry<K, V>)entry, value);
+ didModify((org.eclipse.emf.common.util.BasicEMap.Entry<K, V>)entry, result);
+ return result;
+ } else {
+ // we get here, create a new one and add it to the persistablelist...
+ org.eclipse.emf.common.util.BasicEMap.Entry<K, V> newEntry = newEntry(hashOf(key), key, value);
+ delegateEList.add(newEntry);
+ return null;
+ }
+ }
+ return super.put(key, value);
+ }
+
+
+ /** Needs to be implemented by concrete subclass */
+ @Override
+ protected EList<BasicEMap.Entry<K, V>> createDelegateEList(InternalEObject owner, EStructuralFeature feature,
+ List<BasicEMap.Entry<K, V>> delegateORMList) {
+ return new HbExtraLazyPersistableEList<Entry<K, V>>(owner, feature, delegateORMList) {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void didAdd(int index, Entry<K, V> newObject) {
+ doPut(newObject);
+ }
+
+ @Override
+ protected void didSet(int index, Entry<K, V> newObject, Entry<K, V> oldObject) {
+ didRemove(index, oldObject);
+ didAdd(index, newObject);
+ }
+
+ @Override
+ protected void didRemove(int index, Entry<K, V> oldObject) {
+ HbExtraLazyPersistableEMap.this.doRemove(oldObject);
+ }
+
+ @Override
+ protected void didClear(int size, Object[] oldObjects) {
+ doClear();
+ }
+
+ @Override
+ protected void didMove(int index, Entry<K, V> movedObject, int oldIndex) {
+ HbExtraLazyPersistableEMap.this.doMove(movedObject);
+ }
+ };
+ }
+
+
+ @Override
+ public boolean remove(Object object) {
+ // TODO Auto-generated method stub
+ return super.remove(object);
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> collection) {
+ // TODO Auto-generated method stub
+ return super.removeAll(collection);
+ }
+
+ @Override
+ public V removeKey(Object key) {
+ // TODO Auto-generated method stub
+ return super.removeKey(key);
+ }
+
+ private boolean isHibernateListPresent() {
+ return getDelegate() instanceof AbstractPersistentCollection;
+ }
+
+ private Session getSession() {
+ final AbstractPersistentCollection persistentCollection = (AbstractPersistentCollection) getDelegate();
+ final SessionImplementor session = ((AbstractPersistentCollection) persistentCollection)
+ .getSession();
+ return (Session)session;
+ }
+
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernateFeatureMapEntry.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernateFeatureMapEntry.java
new file mode 100755
index 000000000..04d59a25c
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernateFeatureMapEntry.java
@@ -0,0 +1,597 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HibernateFeatureMapEntry.java,v 1.11 2010/02/04 10:53:08 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.elist;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.eclipse.emf.common.notify.NotificationChain;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.util.ExtendedMetaData;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.teneo.EContainerRepairControl;
+import org.eclipse.emf.teneo.util.AssertUtil;
+import org.eclipse.emf.teneo.util.StoreUtil;
+
+/**
+ * Is used to replace the EMF feature map entry with an entry which can be handled by the or layer.
+ *
+ * The special feature of this entry is that all allowed features can be set, internally it keeps a list of feature
+ * value pairs. Only one of these pairs is the valid one, which one is determined by the value of the eStructuralFeature
+ * member.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.11 $
+ */
+
+public class HibernateFeatureMapEntry implements FeatureMap.Entry.Internal, Serializable {
+
+ /**
+ * Generated serial ID
+ */
+ private static final long serialVersionUID = 3946138277481892125L;
+
+ /**
+ * Gets an 'normal' FeatureMap.Entry and if it is not a FeatureMapEntry replaces it with a specific implementation.
+ */
+ public static HibernateFeatureMapEntry replaceEntry(Object obj, FeatureMap.Internal owningMap) {
+ // do special check, in case the featuremap entry does not need to be
+ // changed
+ if (obj instanceof HibernateFeatureMapEntry) {
+ final HibernateFeatureMapEntry fmEntry = (HibernateFeatureMapEntry) obj;
+
+ // return the entry if it is not yet set, in this case it does not
+ // yet belong to a
+ // featuremap and can be used. This happens with a featuremap which
+ // has already been
+ // replaced.
+ if (!fmEntry.isFeatureMapSet() || fmEntry.belongsToFeatureMap(owningMap)) {
+ return fmEntry;
+ }
+ }
+ HibernateFeatureMapEntry entry = new HibernateFeatureMapEntry();
+ entry.setEntry((FeatureMap.Entry) obj, owningMap);
+ return entry;
+ }
+
+ /**
+ * Replaces standard FeatureMap.Entry with a FeatureMapEntry for a collection
+ */
+ public static Collection<HibernateFeatureMapEntry> replaceEntryAll(Collection<FeatureMap.Entry> c,
+ Class<?> replaceByType, FeatureMap.Internal owningMap) {
+ final ArrayList<HibernateFeatureMapEntry> newEntries = new ArrayList<HibernateFeatureMapEntry>();
+ final Iterator<FeatureMap.Entry> it = c.iterator();
+ while (it.hasNext()) {
+ newEntries.add(replaceEntry(it.next(), owningMap));
+ }
+ return newEntries;
+ }
+
+ /** Creates an entry with the correct type */
+ public static FeatureMap.Entry createEntry(EStructuralFeature feature, Object value, FeatureMap.Internal owningMap) {
+ HibernateFeatureMapEntry entry = new HibernateFeatureMapEntry();
+ entry.setFeatureValue(feature, value, owningMap);
+ return entry;
+ }
+
+ /**
+ * Method which creates a list of entries based on one feature and multiple values
+ */
+ public static Collection<FeatureMap.Entry> createEntryAll(EStructuralFeature feature, Collection<?> values,
+ FeatureMap.Internal owningMap) {
+ final ArrayList<FeatureMap.Entry> entries = new ArrayList<FeatureMap.Entry>();
+ final Iterator<?> it = values.iterator();
+ while (it.hasNext()) {
+ entries.add(createEntry(feature, it.next(), owningMap));
+ }
+ return entries;
+ }
+
+ /** The structural feature which defines which element this is */
+ private EStructuralFeature eStructuralFeature;
+
+ /** To store the efeature during serialization */
+ private String eFeaturePath;
+
+ /**
+ * The featuremap to which we are connected. Is used to determine if entries have been added to another featuremap.
+ * This happens in copy actions.
+ */
+ private FeatureMap.Internal owningMap;
+
+ /** The feature value map */
+ private ArrayList<FeatureValue> featureValues = new ArrayList<FeatureValue>();
+
+ // is used to hold a value temporarily until a feature is set.
+ private Object tempValue;
+
+ /**
+ * The entity name of this entry, is filled when the object is read from the db
+ */
+ private String entityName = null;
+
+ /**
+ * Constructor called by the storage layer, fields need to be set by calls to subclass
+ */
+ public HibernateFeatureMapEntry() {
+ }
+
+ /** Sets the featuremap, is done when an entry is added to the featuremap */
+ public void setFeatureMap(FeatureMap.Internal featureMap) {
+ owningMap = featureMap;
+ if (featureMap != null) {
+ entityName = StoreUtil.getEntityName(featureMap.getEStructuralFeature());
+ }
+ }
+
+ /** Unsets the featuremap, is done when an entry is removed */
+ public void unsetFeatureMap() {
+ owningMap = null;
+ }
+
+ /** Is true if this featureMap already belongs to a Map */
+ public boolean isFeatureMapSet() {
+ return owningMap != null;
+ }
+
+ /** Is true if this featureMap already belongs to the passed map */
+ public boolean belongsToFeatureMap(FeatureMap.Internal fm) {
+ return owningMap == fm; // object equality!
+ }
+
+ /** Takes care of serializing the efeature */
+ private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+ eFeaturePath = StoreUtil.structuralFeatureToString(eStructuralFeature);
+ eStructuralFeature = null;
+ out.defaultWriteObject();
+ }
+
+ /** Takes care of deserializing the efeature */
+ private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ eStructuralFeature = StoreUtil.stringToStructureFeature(eFeaturePath);
+ }
+
+ /** Set the value from a previous entry */
+ public void setEntry(FeatureMap.Entry entry, FeatureMap.Internal owningMap) {
+ eStructuralFeature = entry.getEStructuralFeature();
+ featureValues.add(createFeatureValue(eStructuralFeature, entry.getValue()));
+ setFeatureMap(owningMap);
+ }
+
+ /** Returns structural feature */
+ public EStructuralFeature getEStructuralFeature() {
+ return eStructuralFeature;
+ }
+
+ /**
+ * @param structuralFeature
+ * the eStructuralFeature to set
+ */
+ private void setEStructuralFeature(EStructuralFeature structuralFeature) {
+ eStructuralFeature = structuralFeature;
+ if (tempValue != null) {
+ // is a string needs to be translated
+ final Object value = doPossibleConversion(tempValue);
+ addFeatureValue(eStructuralFeature, value);
+ tempValue = null;
+ }
+ }
+
+ /** Return the string repr. of the feature */
+ public String getFeatureURI() {
+ return StoreUtil.structuralFeatureToString(getEStructuralFeature());
+ }
+
+ /** Set the feature on the basis of the string */
+ public void setEStructuralFeature(String featureURI) {
+ setEStructuralFeature(StoreUtil.stringToStructureFeature(featureURI));
+ }
+
+ /** Returns the value */
+ public Object getValue() {
+ return getValue(getEStructuralFeature());
+ }
+
+ /**
+ * Add a feature value combination to the entry, only one of these values is the valid one but the other nullable
+ * values are stored in the db
+ */
+ public void addFeatureValue(EStructuralFeature feature, Object value) {
+ // final FeatureValue fv = getFeatureValue(feature);
+ // if (fv != null) {
+ // featureValues.add(createFeatureValue(feature, value));
+ // } else {
+ featureValues.add(createFeatureValue(feature, value));
+ // }
+ }
+
+ /**
+ * Sets a value in this feature map entry, if no eStructuralFeature is set then it is set in the tempValue until an
+ * estructural feature is set. This is done because it is not certain in which order hibernate calls the property
+ * handlers.
+ */
+ public void setValue(Object value) {
+ if (getEStructuralFeature() != null) {
+ // is a string needs to be translated
+ addFeatureValue(getEStructuralFeature(), doPossibleConversion(value));
+ } else {
+ tempValue = value;
+ }
+ }
+
+ private Object doPossibleConversion(Object value) {
+ // is a string needs to be translated
+ if (getEStructuralFeature() instanceof EAttribute) {
+ final EAttribute eAttribute = (EAttribute) getEStructuralFeature();
+ final EDataType eDataType = eAttribute.getEAttributeType();
+
+ final Object realValue = eDataType.getEPackage().getEFactoryInstance().createFromString(eDataType,
+ (String) value);
+ return realValue;
+ }
+ return value;
+ }
+
+ /** Sets the exact feature value for this entry */
+ public void setFeatureValue(EStructuralFeature feature, Object value, FeatureMap.Internal owningMap) {
+ featureValues.add(createFeatureValue(feature, value));
+ setEStructuralFeature(feature);
+ setFeatureMap(owningMap);
+ }
+
+ /** Returns the value for a specific feature */
+ public Object getValue(EStructuralFeature feature) {
+ for (FeatureValue fv : featureValues) {
+ if (fv.matchesFeature(feature)) {
+ return fv.getValue();
+ }
+ }
+ return null; // TODO: maybe throw error?
+ }
+
+ /** get the real feature value */
+ private FeatureValue getFeatureValue() {
+ final EStructuralFeature feature = getEStructuralFeature();
+
+ AssertUtil.assertTrue("Feature is not set", feature != null);
+
+ for (FeatureValue fv : featureValues) {
+ if (fv.matchesFeature(feature)) {
+ return fv;
+ }
+ }
+
+ // can not get here, see assertion above
+ return null;
+ }
+
+ /**
+ * Sets the container property of the value if the value is an EObject and the feature is a containment feature.
+ */
+ public void setContainer(InternalEObject owner) {
+ final Object value = getValue();
+ if (value != null && value instanceof InternalEObject && eStructuralFeature instanceof EReference
+ && ((EReference) eStructuralFeature).isContainment()) {
+ EContainerRepairControl.setContainer(owner, (InternalEObject) value, eStructuralFeature);
+ }
+ }
+
+ /** Code copied from FeatureMapUtil.EntryImpl */
+ @Override
+ public boolean equals(Object that) {
+ if (this == that) {
+ return true;
+ } else if (!(that instanceof FeatureMap.Entry)) {
+ return false;
+ } else {
+ final FeatureMap.Entry entry = (FeatureMap.Entry) that;
+ final Object value = getValue();
+ return entry.getEStructuralFeature() == eStructuralFeature
+ && (value == null ? entry.getValue() == null : value.equals(entry.getValue()));
+ }
+ }
+
+ /** Code copied from FeatureMapUtil.EntryImpl */
+ @Override
+ public int hashCode() {
+ /*
+ * Used to create a hashcode which maps all instances of one class to the same hashcode Is required because the
+ * normal hashcode method (see hashcode impl in emf EntryImpl) resulted in null-pointer exceptions in hibernate
+ * because the content of the entry was used for determining the hashcode while the object was not initialized
+ * from the db
+ */
+ return this.getClass().hashCode();
+ }
+
+ /** Code copied from FeatureMapUtil.EntryImpl */
+ @Override
+ public String toString() {
+ String prefix = eStructuralFeature.getEContainingClass().getEPackage().getNsPrefix();
+ eStructuralFeature.getName();
+ return (prefix != null && prefix.length() != 0 ? prefix + ":" + eStructuralFeature.getName()
+ : eStructuralFeature.getName())
+ + "=" + getValue();
+ }
+
+ /**
+ * @return the entityName
+ */
+ public String getEntityName() {
+ return entityName;
+ }
+
+ /**
+ * @param entityName
+ * the entityName to set
+ */
+ public void setEntityName(String entityName) {
+ this.entityName = entityName;
+ }
+
+ /** Create the correct feature value type */
+ private FeatureValue createFeatureValue(EStructuralFeature feature, Object value) {
+ if (feature instanceof EReference && ((EReference) feature).getEOpposite() != null) {
+ return new InverseFeatureValue(feature, value);
+ } else if (feature instanceof EReference && ((EReference) feature).isContainment()) {
+ return new ContainmentFeatureValue(feature, value);
+ } else {
+ return new FeatureValue(feature, value);
+ }
+ }
+
+ /** Create a copy of this entry with a different value */
+ public Internal createEntry(InternalEObject value) {
+ HibernateFeatureMapEntry hfm = new HibernateFeatureMapEntry();
+ hfm.setFeatureValue(getEStructuralFeature(), value, owningMap);
+ return hfm;
+ }
+
+ /**
+ * Create a copy of this entry with a different value, calls createEntry(InternalEObject value)
+ */
+ public Internal createEntry(Object value) {
+ return createEntry((InternalEObject) value);
+ }
+
+ /** Does inverse action on other end */
+ public final NotificationChain inverseAdd(InternalEObject owner, int featureID, NotificationChain notifications) {
+ return getFeatureValue().inverseAdd(owner, getValue(), featureID, notifications);
+ }
+
+ /** Does inverse action on other end */
+ public final NotificationChain inverseRemove(InternalEObject owner, int featureID, NotificationChain notifications) {
+ return getFeatureValue().inverseRemove(owner, getValue(), featureID, notifications);
+ }
+
+ /** Does inverse action on other end */
+ public final NotificationChain inverseAdd(InternalEObject owner, Object otherEnd, int featureID,
+ NotificationChain notifications) {
+ return getFeatureValue().inverseAdd(owner, getValue(), featureID, notifications);
+ }
+
+ /** Does inverse action on other end */
+ public NotificationChain inverseRemove(InternalEObject owner, Object otherEnd, int featureID,
+ NotificationChain notifications) {
+ return getFeatureValue().inverseRemove(owner, otherEnd, featureID, notifications);
+ }
+
+ /** validate the type of the value with the type expected by the efeature */
+ public void validate(Object value) {
+ getFeatureValue().validate(value);
+ }
+
+ /** Class to store feature value pairs together with their validator */
+ private class FeatureValue implements Serializable {
+
+ /**
+ * Generated Serial Version ID
+ */
+ private static final long serialVersionUID = 3665363921316852811L;
+
+ /** The feature */
+ protected EStructuralFeature feature;
+
+ /** The featurepath, is used during serialization */
+ private String featurePath;
+
+ /** Its value (can be null) */
+ protected Object value;
+
+ /** Constructor */
+ private FeatureValue(EStructuralFeature feature, Object value) {
+ this.feature = feature;
+ this.value = value;
+ }
+
+ /** Takes care of serializing the efeature */
+ private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+ featurePath = StoreUtil.structuralFeatureToString(feature);
+ feature = null;
+ out.defaultWriteObject();
+ }
+
+ /** Takes care of deserializing the efeature */
+ private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ feature = StoreUtil.stringToStructureFeature(featurePath);
+ }
+
+ /**
+ * Returns true if this feature value corresponds to the passed feature (taking into account substitution groups
+ */
+ private boolean matchesFeature(EStructuralFeature eFeature) {
+ if (feature.equals(eFeature)) {
+ return true;
+ }
+
+ // an entry which is the value of another entry
+ if (owningMap == null) {
+ return false;
+ }
+
+ // compare on the basis of the affiliates (substitutiongroup)
+ final EStructuralFeature aff1 = ExtendedMetaData.INSTANCE.getAffiliation(owningMap.getEObject().eClass(),
+ feature);
+ final EStructuralFeature aff2 = ExtendedMetaData.INSTANCE.getAffiliation(owningMap.getEObject().eClass(),
+ eFeature);
+ if (aff1 != null && aff2 != null && aff1 == aff2) {
+ return true;
+ }
+ return false;
+ }
+
+ /** Returns the value */
+ private Object getValue() {
+ return value;
+ }
+
+ /** Handles inverse action, differs on the basis of the feature type */
+ public NotificationChain inverseAdd(InternalEObject owner, Object otherEnd, int featureID,
+ NotificationChain notifications) {
+ return notifications;
+ }
+
+ /** Handles inverse action, differs on the basis of the feature type */
+ public NotificationChain inverseRemove(InternalEObject owner, Object otherEnd, int featureID,
+ NotificationChain notifications) {
+ return notifications;
+ }
+
+ /**
+ * validate the type of the value with the type expected by the efeature
+ */
+ public void validate(Object value) {
+ if (value != null && !eStructuralFeature.getEType().isInstance(value)) {
+ String valueClass = value instanceof EObject ? ((EObject) value).eClass().getName() : value.getClass()
+ .getName();
+ throw new ClassCastException("The feature '" + eStructuralFeature.getName() + "'s type '"
+ + eStructuralFeature.getEType().getName() + "' does not permit a value of type '" + valueClass
+ + "'");
+ }
+ }
+ }
+
+ /** Containment feature value */
+ private class ContainmentFeatureValue extends FeatureValue {
+
+ /**
+ * Generated serial id
+ */
+ private static final long serialVersionUID = -5915172909939056481L;
+
+ /** Constructor */
+ private ContainmentFeatureValue(EStructuralFeature feature, Object value) {
+ super(feature, value);
+ }
+
+ /** Handles inverse action, differs on the basis of the feature type */
+ @Override
+ public NotificationChain inverseAdd(InternalEObject owner, Object otherEnd, int featureID,
+ NotificationChain notifications) {
+ return inverseAdd(owner, (InternalEObject) value, featureID, notifications);
+ }
+
+ /** Handles inverse action, differs on the basis of the feature type */
+ @Override
+ public NotificationChain inverseRemove(InternalEObject owner, Object otherEnd, int featureID,
+ NotificationChain notifications) {
+ return inverseRemove(owner, (InternalEObject) value, featureID, notifications);
+ }
+
+ /** Does inverse action on other end */
+ private NotificationChain inverseAdd(InternalEObject owner, InternalEObject otherEnd, int featureID,
+ NotificationChain notifications) {
+ if (otherEnd != null) {
+ int containmentFeatureID = owner.eClass().getFeatureID(eStructuralFeature);
+ notifications = otherEnd.eInverseAdd(owner, InternalEObject.EOPPOSITE_FEATURE_BASE
+ - (containmentFeatureID == -1 ? featureID : containmentFeatureID), null, notifications);
+ }
+
+ return notifications;
+ }
+
+ /** Does inverse action on other end */
+ private NotificationChain inverseRemove(InternalEObject owner, InternalEObject otherEnd, int featureID,
+ NotificationChain notifications) {
+ if (otherEnd != null) {
+ int containmentFeatureID = owner.eClass().getFeatureID(eStructuralFeature);
+ notifications = otherEnd.eInverseRemove(owner, InternalEObject.EOPPOSITE_FEATURE_BASE
+ - (containmentFeatureID == -1 ? featureID : containmentFeatureID), null, notifications);
+ }
+
+ return notifications;
+ }
+ }
+
+ /** Bidirectional feature value */
+ private class InverseFeatureValue extends FeatureValue {
+
+ /**
+ * Generated Serial Version ID
+ */
+ private static final long serialVersionUID = 7207038502480577523L;
+
+ /** Constructor */
+ private InverseFeatureValue(EStructuralFeature feature, Object value) {
+ super(feature, value);
+ }
+
+ /** Handles inverse action, differs on the basis of the feature type */
+ @Override
+ public NotificationChain inverseAdd(InternalEObject owner, Object otherEnd, int featureID,
+ NotificationChain notifications) {
+ return inverseAdd(owner, (InternalEObject) value, featureID, notifications);
+ }
+
+ /** Handles inverse action, differs on the basis of the feature type */
+ @Override
+ public NotificationChain inverseRemove(InternalEObject owner, Object otherEnd, int featureID,
+ NotificationChain notifications) {
+ return inverseRemove(owner, (InternalEObject) value, featureID, notifications);
+ }
+
+ /** Does inverse action on other end */
+ private final NotificationChain inverseAdd(InternalEObject owner, InternalEObject otherEnd, int featureID,
+ NotificationChain notifications) {
+ if (otherEnd != null) {
+ notifications = otherEnd.eInverseAdd(owner, otherEnd.eClass().getFeatureID(
+ ((EReference) eStructuralFeature).getEOpposite()), null, notifications);
+ }
+
+ return notifications;
+ }
+
+ /** Does inverse action on other end */
+ private final NotificationChain inverseRemove(InternalEObject owner, InternalEObject otherEnd, int featureID,
+ NotificationChain notifications) {
+ if (otherEnd != null) {
+ notifications = otherEnd.eInverseRemove(owner, otherEnd.eClass().getFeatureID(
+ ((EReference) eStructuralFeature).getEOpposite()), null, notifications);
+ }
+ return notifications;
+ }
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableEList.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableEList.java
new file mode 100755
index 000000000..a43c7ec37
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableEList.java
@@ -0,0 +1,622 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HibernatePersistableEList.java,v 1.35 2010/03/25 01:05:53 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.elist;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.teneo.EContainerRepairControl;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.SessionWrapper;
+import org.eclipse.emf.teneo.hibernate.resource.HbResource;
+import org.eclipse.emf.teneo.mapping.elist.PersistableEList;
+import org.eclipse.emf.teneo.resource.StoreResource;
+import org.eclipse.emf.teneo.util.AssertUtil;
+import org.hibernate.HibernateException;
+import org.hibernate.collection.AbstractPersistentCollection;
+import org.hibernate.collection.PersistentBag;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.collection.PersistentIdentifierBag;
+import org.hibernate.collection.PersistentList;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.loader.CollectionAliases;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.Type;
+
+/**
+ * Implements the hibernate persistable elist.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.35 $
+ */
+
+public class HibernatePersistableEList<E> extends PersistableEList<E> implements
+ ExtensionPoint, PersistentCollection {
+ /**
+ * Serial Version ID
+ */
+ private static final long serialVersionUID = -4553160393592497834L;
+ /** The logger */
+ private static Log log = LogFactory.getLog(HibernatePersistableEList.class);
+
+ /** Constructor */
+ public HibernatePersistableEList(InternalEObject owner,
+ EStructuralFeature feature, List<E> list) {
+ super(owner, feature, list);
+ }
+
+ /** If the delegate has been initialized */
+ public boolean isInitialized() {
+ return ((PersistentCollection) delegate).wasInitialized();
+ }
+
+ /**
+ * Override isLoaded to check if the delegate lists was not already loaded
+ * by hibernate behind the scenes, this happens with eagerly loaded lists.
+ */
+ @Override
+ public boolean isLoaded() {
+ // if the delegated list was loaded under the hood and this
+ // HibernatePersistableEList did
+ // not yet notice it then do the local load behavior.
+ // delegate is loaded in case of subselect or eager loading
+ final boolean isDelegateLoaded = delegate instanceof AbstractPersistentCollection
+ && ((AbstractPersistentCollection) delegate).wasInitialized();
+ if (!super.isLoaded() && !isLoading() && isDelegateLoaded) {
+ if (log.isDebugEnabled()) {
+ log
+ .debug("Persistentlist already initialized, probably eagerly loaded: "
+ + getLogString());
+ }
+ try {
+ setIsLoading(true);
+ // do load to load the resource
+ doLoad();
+ setIsLoaded(true);
+ } finally {
+ setIsLoading(false);
+ }
+ }
+ return super.isLoaded();
+ }
+
+ /** Do the actual load can be overridden */
+ @Override
+ protected synchronized void doLoad() {
+ // TODO, read the following link and reconsider transaction usage
+ // http://community.jboss.org/wiki/Non-transactionaldataaccessandtheauto-commitmode
+
+ AssertUtil.assertTrue("EList " + logString, !isLoaded());
+
+ log.debug("Started loading elist " + logString);
+
+ SessionWrapper sessionWrapper = null;
+ boolean controlsTransaction = false;
+ boolean err = true;
+ Resource res = null;
+ try {
+ res = owner.eResource();
+ if (res != null && res instanceof HbResource) {
+ sessionWrapper = ((HbResource) res).getSessionWrapper();
+ if (res.isLoaded()) // resource is loaded reopen transaction
+ {
+ // if the delegate is already loaded then no transaction is
+ // required
+ final boolean isDelegateLoaded = delegate instanceof AbstractPersistentCollection
+ && ((AbstractPersistentCollection) delegate)
+ .wasInitialized();
+ if (!isDelegateLoaded
+ && !sessionWrapper.isTransactionActive()) {
+ log
+ .debug("Reconnecting session to read a lazy collection, elist: "
+ + logString);
+ controlsTransaction = true;
+ sessionWrapper.beginTransaction();
+ sessionWrapper.setFlushModeManual();
+ } else {
+ log
+ .debug("Delegate loaded or resource session is still active, using it");
+ }
+ } else {
+ log.debug("Elist uses session from resource, " + logString);
+ }
+ } else {
+ log.debug("EList is not loaded in session context");
+ }
+
+ if (controlsTransaction) {
+ assert (res instanceof HbResource);
+ ((StoreResource) res).setIsLoading(true);
+ }
+
+ try {
+ Object[] objs = delegate.toArray(); // this forces the load
+
+ // disabled for now as containers are persisted by hibernate
+ // anyway
+ if (isContainment()) {
+ for (Object element : objs) {
+ if (element instanceof InternalEObject) {
+ EContainerRepairControl.setContainer(owner,
+ (InternalEObject) element,
+ getEStructuralFeature());
+ }
+ }
+ }
+
+ // add the new objects to the resource so they are tracked
+ if (res != null && res instanceof StoreResource) {
+ // attach the new contained objects so that they are adapted
+ // when required
+ for (Object element : objs) {
+ if (element instanceof EObject) {
+ ((StoreResource) res).addToContentOrAttach(
+ (InternalEObject) element,
+ (EReference) getEStructuralFeature());
+ }
+ }
+ }
+
+ log.debug("Loaded " + objs.length + " from backend store for "
+ + logString);
+ } finally {
+ if (controlsTransaction) {
+ ((StoreResource) res).setIsLoading(false);
+ }
+ }
+ err = false;
+ } finally {
+ if (controlsTransaction) {
+ if (err) {
+ sessionWrapper.rollbackTransaction();
+ sessionWrapper.restorePreviousFlushMode();
+ } else {
+ // a bit rough but delete from the persitence context
+ // otherwise
+ // hibernate will think that this collection is not attached
+ // to anything and
+ // will delete me
+ // getSession().getPersistenceContext().getCollectionEntries().remove(this);
+ sessionWrapper.commitTransaction();
+ sessionWrapper.restorePreviousFlushMode();
+ }
+ }
+ if (sessionWrapper != null) {
+ ((HbResource) res).returnSessionWrapper(sessionWrapper);
+ }
+ }
+ log.debug("Finished loading elist " + logString);
+ }
+
+ /** Overridden because general list type is not supported as a replacement */
+ @Override
+ public void replaceDelegate(List<E> newDelegate) {
+ if (newDelegate instanceof PersistentList) {
+ // disabled this assertion because in case of a session refresh it
+ // is possible
+ // that the list is replaced by a persistent list
+ // AssertUtil.assertTrue("This elist " + logString + " contains a
+ // different list than the " +
+ // " passed list",
+ // ((PersistentList)newDelegate).isWrapper(delegate));
+ super.replaceDelegate(newDelegate);
+ } else if (newDelegate instanceof PersistentBag) {
+ // disabled this assertion because in case of a session refresh it
+ // is possible
+ // that the list is replaced by a persistent list
+ // AssertUtil.assertTrue("This elist " + logString + " contains a
+ // different list than the " +
+ // " passed list",
+ // ((PersistentBag)newDelegate).isWrapper(delegate));
+ super.replaceDelegate(newDelegate);
+ } else if (newDelegate instanceof PersistentIdentifierBag) {
+ // Added to support <idbag>
+ super.replaceDelegate(newDelegate);
+ } else if (newDelegate == delegate) // this can occur and is okay, do
+ // nothing in this case
+ {
+
+ } else {
+ throw new HbMapperException("Type "
+ + newDelegate.getClass().getName() + " can not be "
+ + " used as a replacement for elist " + logString);
+ }
+ }
+
+ /** Returns true if the wrapped list is a persistency layer specific list */
+ public boolean isPersistencyWrapped() {
+ return delegate instanceof PersistentCollection;
+ }
+
+ public boolean afterInitialize() {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).afterInitialize();
+ }
+ return false;
+ }
+
+ public void afterRowInsert(CollectionPersister persister, Object entry,
+ int i) throws HibernateException {
+ if (isPersistencyWrapped()) {
+ ((PersistentCollection) delegate).afterRowInsert(persister, entry,
+ i);
+ }
+ }
+
+ public void beforeInitialize(CollectionPersister persister,
+ int anticipatedSize) {
+ if (isPersistencyWrapped()) {
+ ((PersistentCollection) delegate).beforeInitialize(persister,
+ anticipatedSize);
+ }
+ }
+
+ public void beginRead() {
+ if (isPersistencyWrapped()) {
+ ((PersistentCollection) delegate).beginRead();
+ }
+ }
+
+ public void clearDirty() {
+ if (isPersistencyWrapped()) {
+ ((PersistentCollection) delegate).clearDirty();
+ }
+ }
+
+ public void dirty() {
+ if (isPersistencyWrapped()) {
+ ((PersistentCollection) delegate).dirty();
+ }
+ }
+
+ public Serializable disassemble(CollectionPersister persister)
+ throws HibernateException {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).disassemble(persister);
+ }
+ return null;
+ }
+
+ public boolean empty() {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).empty();
+ }
+ return false;
+ }
+
+ public boolean endRead() {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).endRead();
+ }
+ return false;
+ }
+
+ public Iterator<?> entries(CollectionPersister persister) {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).entries(persister);
+ }
+ return null;
+ }
+
+ public boolean entryExists(Object entry, int i) {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).entryExists(entry, i);
+ }
+ return false;
+ }
+
+ public boolean equalsSnapshot(CollectionPersister persister)
+ throws HibernateException {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).equalsSnapshot(persister);
+ }
+ return false;
+ }
+
+ public void forceInitialization() throws HibernateException {
+ if (isPersistencyWrapped()) {
+ ((PersistentCollection) delegate).forceInitialization();
+ }
+ }
+
+ public Iterator<?> getDeletes(CollectionPersister persister,
+ boolean indexIsFormula) throws HibernateException {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).getDeletes(persister,
+ indexIsFormula);
+ }
+ return null;
+ }
+
+ public Object getElement(Object entry) {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).getElement(entry);
+ }
+ return null;
+ }
+
+ public Object getIdentifier(Object entry, int i) {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).getIdentifier(entry, i);
+ }
+ return null;
+ }
+
+ public Object getIndex(Object entry, int i, CollectionPersister persister) {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).getIndex(entry, i,
+ persister);
+ }
+ return null;
+ }
+
+ public Serializable getKey() {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).getKey();
+ }
+ return null;
+ }
+
+ public Collection<?> getOrphans(Serializable snapshot, String entityName)
+ throws HibernateException {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).getOrphans(snapshot,
+ entityName);
+ }
+ return null;
+ }
+
+ public Object getOwner() {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).getOwner();
+ }
+ return getEObject();
+ }
+
+ public Collection<?> getQueuedOrphans(String entityName) {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate)
+ .getQueuedOrphans(entityName);
+ }
+ return null;
+ }
+
+ public String getRole() {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).getRole();
+ }
+ return null;
+ }
+
+ public Serializable getSnapshot(CollectionPersister persister)
+ throws HibernateException {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).getSnapshot(persister);
+ }
+ return null;
+ }
+
+ public Object getSnapshotElement(Object entry, int i) {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).getSnapshotElement(entry,
+ i);
+ }
+ return null;
+ }
+
+ public Serializable getStoredSnapshot() {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).getStoredSnapshot();
+ }
+ return null;
+ }
+
+ public Object getValue() {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).getValue();
+ }
+ return null;
+ }
+
+ public boolean hasQueuedOperations() {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).hasQueuedOperations();
+ }
+ return false;
+ }
+
+ public void initializeFromCache(CollectionPersister persister,
+ Serializable disassembled, Object owner) throws HibernateException {
+ if (isPersistencyWrapped()) {
+ ((PersistentCollection) delegate).initializeFromCache(persister,
+ disassembled, owner);
+ }
+ }
+
+ public boolean isDirectlyAccessible() {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).isDirectlyAccessible();
+ }
+ return false;
+ }
+
+ public boolean isDirty() {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).isDirty();
+ }
+ return false;
+ }
+
+ public boolean isRowUpdatePossible() {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).isRowUpdatePossible();
+ }
+ return false;
+ }
+
+ public boolean isSnapshotEmpty(Serializable snapshot) {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).isSnapshotEmpty(snapshot);
+ }
+ return false;
+ }
+
+ public boolean isUnreferenced() {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).isUnreferenced();
+ }
+ return false;
+ }
+
+ public boolean isWrapper(Object collection) {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).isWrapper(collection);
+ }
+ return false;
+ }
+
+ public boolean needsInserting(Object entry, int i, Type elemType)
+ throws HibernateException {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).needsInserting(entry, i,
+ elemType);
+ }
+ return false;
+ }
+
+ public boolean needsRecreate(CollectionPersister persister) {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).needsRecreate(persister);
+ }
+ return false;
+ }
+
+ public boolean needsUpdating(Object entry, int i, Type elemType)
+ throws HibernateException {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).needsUpdating(entry, i,
+ elemType);
+ }
+ return false;
+ }
+
+ public void postAction() {
+ if (isPersistencyWrapped()) {
+ ((PersistentCollection) delegate).postAction();
+ }
+ }
+
+ @Override
+ protected int delegateSize() {
+ return delegateList().size();
+ }
+
+ protected final boolean isConnectedToSession() {
+ if (!(getDelegate() instanceof AbstractPersistentCollection)) {
+ return false;
+ }
+ final AbstractPersistentCollection persistentCollection = (AbstractPersistentCollection) getDelegate();
+ final SessionImplementor session = ((AbstractPersistentCollection) persistentCollection)
+ .getSession();
+ return isConnectedToSession(session);
+ }
+
+ private final boolean isConnectedToSession(SessionImplementor session) {
+ final PersistentCollection persistentCollection = (PersistentCollection) getDelegate();
+ return session != null
+ && session.isOpen()
+ && session.getPersistenceContext().containsCollection(
+ persistentCollection);
+ }
+
+ @Override
+ protected boolean delegateIsEmpty() {
+ return delegateSize() == 0;
+ }
+
+ public void preInsert(CollectionPersister persister)
+ throws HibernateException {
+ if (isPersistencyWrapped()) {
+ ((PersistentCollection) delegate).preInsert(persister);
+ }
+ }
+
+ public Iterator<?> queuedAdditionIterator() {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).queuedAdditionIterator();
+ }
+ return null;
+ }
+
+ public Object readFrom(ResultSet rs, CollectionPersister role,
+ CollectionAliases descriptor, Object owner)
+ throws HibernateException, SQLException {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).readFrom(rs, role,
+ descriptor, owner);
+ }
+ return null;
+ }
+
+ public boolean setCurrentSession(SessionImplementor session)
+ throws HibernateException {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).setCurrentSession(session);
+ }
+ return false;
+ }
+
+ public void setOwner(Object entity) {
+ if (isPersistencyWrapped()) {
+ ((PersistentCollection) delegate).setOwner(entity);
+ }
+ }
+
+ public void setSnapshot(Serializable key, String role, Serializable snapshot) {
+ if (isPersistencyWrapped()) {
+ ((PersistentCollection) delegate).setSnapshot(key, role, snapshot);
+ }
+ }
+
+ public boolean unsetSession(SessionImplementor currentSession) {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate)
+ .unsetSession(currentSession);
+ }
+ return false;
+ }
+
+ public boolean wasInitialized() {
+ if (isPersistencyWrapped()) {
+ return ((PersistentCollection) delegate).wasInitialized();
+ }
+ return false;
+ }
+
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableEMap.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableEMap.java
new file mode 100755
index 000000000..399636725
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableEMap.java
@@ -0,0 +1,233 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HibernatePersistableEMap.java,v 1.13 2010/11/12 09:33:33 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.elist;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.common.util.BasicEMap;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.SessionWrapper;
+import org.eclipse.emf.teneo.hibernate.resource.HbResource;
+import org.eclipse.emf.teneo.mapping.elist.PersistableDelegateList;
+import org.eclipse.emf.teneo.mapping.elist.PersistableEList;
+import org.eclipse.emf.teneo.mapping.elist.PersistableEMap;
+import org.eclipse.emf.teneo.resource.StoreResource;
+import org.hibernate.Session;
+import org.hibernate.collection.AbstractPersistentCollection;
+import org.hibernate.collection.PersistentCollection;
+
+/**
+ * Implements the hibernate persistable emap. Note an emap is not loaded lazily!
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.13 $
+ */
+
+public class HibernatePersistableEMap<K, V> extends PersistableEMap<K, V>
+ implements ExtensionPoint {
+ /**
+ * Serial Version ID
+ */
+ private static final long serialVersionUID = -4553160393592497834L;
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(HibernatePersistableEMap.class);
+
+ /** Constructor */
+ public HibernatePersistableEMap(InternalEObject owner, EReference eref,
+ List<Entry<K, V>> list) {
+ super(eref.getEReferenceType(), owner, eref, list);
+ }
+
+ /** Do the actual load can be overridden */
+ @Override
+ protected void doLoad() {
+ SessionWrapper sessionWrapper = null;
+ boolean controlsTransaction = false;
+ boolean err = true;
+ Resource res = null;
+ final List<?> delegate = ((HibernatePersistableEList<?>) delegateEList)
+ .getDelegate();
+ try {
+ res = getEObject().eResource();
+ if (res != null && res instanceof HbResource) {
+ sessionWrapper = ((HbResource) res).getSessionWrapper();
+ if (res.isLoaded()) // resource is loaded reopen transaction
+ {
+ // if the delegate is already loaded then no transaction is
+ // required
+ final boolean isDelegateLoaded = delegate instanceof AbstractPersistentCollection
+ && ((AbstractPersistentCollection) delegate)
+ .wasInitialized();
+ if (!isDelegateLoaded
+ && !sessionWrapper.isTransactionActive()) {
+ log.debug("Reconnecting session to read a lazy collection, elist: "
+ + logString);
+ controlsTransaction = true;
+ sessionWrapper.beginTransaction();
+ sessionWrapper.setFlushModeManual();
+ } else {
+ log.debug("Delegate loaded or resource session is still active, using it");
+ }
+ } else {
+ log.debug("EMap uses session from resource, " + logString);
+ }
+ } else {
+ log.debug("EMap is not loaded in session context");
+ }
+
+ if (controlsTransaction) {
+ assert (res instanceof HbResource);
+ ((StoreResource) res).setIsLoading(true);
+ }
+
+ try {
+ Object[] objs = delegate.toArray(); // this forces the load
+
+ // add the new objects to the resource so they are tracked
+ if (res != null && res instanceof StoreResource) {
+ // attach the new contained objects so that they are adapted
+ // when required
+ for (Object element : objs) {
+ if (element instanceof EObject) {
+ ((StoreResource) res).addToContentOrAttach(
+ (InternalEObject) element,
+ (EReference) getEStructuralFeature());
+ }
+ }
+ }
+ log.debug("Loaded " + objs.length + " from backend store for "
+ + logString);
+ } finally {
+ if (controlsTransaction) {
+ ((StoreResource) res).setIsLoading(false);
+ }
+ }
+ err = false;
+ } finally {
+ if (controlsTransaction) {
+ if (err) {
+ sessionWrapper.rollbackTransaction();
+ sessionWrapper.restorePreviousFlushMode();
+ } else {
+ // a bit rough but delete from the persitence context
+ // otherwise
+ // hibernate will think that this collection is not attached
+ // to anything and
+ // will delete me
+ // getSession().getPersistenceContext().getCollectionEntries().remove(this);
+ sessionWrapper.commitTransaction();
+ sessionWrapper.restorePreviousFlushMode();
+ }
+ ((HbResource) res).returnSessionWrapper(sessionWrapper);
+ }
+ }
+ log.debug("Finished loading elist " + logString);
+ }
+
+ /**
+ * Overridden because of access to size attribute. This version will try to
+ * read the collection size without lading it if it is lazy loaded
+ */
+ @Override
+ public int size() {
+ // if we are not loaded yet, we return the size of the buffered lazy
+ // load delegate
+
+ if (!isLoaded()
+ && delegateEList instanceof PersistableEList<?>
+ && ((PersistableEList<?>) delegateEList).getDelegate() instanceof AbstractPersistentCollection) {
+ try {
+ final Session s = (Session) ((AbstractPersistentCollection) ((PersistableEList<?>) delegateEList)
+ .getDelegate()).getSession();
+
+ // now that we have the session, we can query the size of
+ // the list without loading it
+ s.flush();
+ size = ((Long) s
+ .createFilter(
+ ((PersistableEList<?>) delegateEList)
+ .getDelegate(),
+ "select count(*)").list().get(0)).intValue();
+ return size;
+ } catch (Throwable t) {
+ // ignore on purpose, let the call to super handle it
+ }
+ }
+
+ // didnt work, so we simply call the parent version
+ return super.size();
+ }
+
+ /** Needs to be implemented by concrete subclass */
+ @Override
+ protected EList<BasicEMap.Entry<K, V>> createDelegateEList(
+ InternalEObject owner, EStructuralFeature feature,
+ List<BasicEMap.Entry<K, V>> delegateORMList) {
+ return new HibernatePersistableEList<Entry<K, V>>(owner, feature,
+ delegateORMList) {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void didAdd(int index, Entry<K, V> newObject) {
+ doPut(newObject);
+ }
+
+ @Override
+ protected void didSet(int index, Entry<K, V> newObject,
+ Entry<K, V> oldObject) {
+ didRemove(index, oldObject);
+ didAdd(index, newObject);
+ }
+
+ @Override
+ protected void didRemove(int index, Entry<K, V> oldObject) {
+ HibernatePersistableEMap.this.doRemove(oldObject);
+ }
+
+ @Override
+ protected void didClear(int size, Object[] oldObjects) {
+ doClear();
+ }
+
+ @Override
+ protected void didMove(int index, Entry<K, V> movedObject,
+ int oldIndex) {
+ HibernatePersistableEMap.this.doMove(movedObject);
+ }
+ };
+ }
+
+ /** If the delegate has been initialized */
+ public boolean isInitialized() {
+ return ((PersistentCollection) getDelegate()).wasInitialized();
+ }
+
+ /** Return the orm backing list */
+ @Override
+ public Object getDelegate() {
+ return ((PersistableDelegateList<?>) delegateEList).getDelegate();
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableFeatureMap.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableFeatureMap.java
new file mode 100755
index 000000000..a1292e511
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableFeatureMap.java
@@ -0,0 +1,244 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HibernatePersistableFeatureMap.java,v 1.15 2009/11/02 10:24:50 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.elist;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.teneo.EContainerRepairControl;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.SessionWrapper;
+import org.eclipse.emf.teneo.hibernate.resource.HibernateResource;
+import org.eclipse.emf.teneo.mapping.elist.PersistableFeatureMap;
+import org.eclipse.emf.teneo.resource.StoreResource;
+import org.eclipse.emf.teneo.util.AssertUtil;
+import org.hibernate.Session;
+import org.hibernate.collection.AbstractPersistentCollection;
+import org.hibernate.collection.PersistentBag;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.collection.PersistentList;
+
+/**
+ * Implements the hibernate persistable elist.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.15 $
+ */
+
+public class HibernatePersistableFeatureMap extends PersistableFeatureMap implements ExtensionPoint {
+ /**
+ * Serial Version ID
+ */
+ private static final long serialVersionUID = -1916994464446630140L;
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(HibernatePersistableFeatureMap.class);
+
+ /** Constructor */
+ public HibernatePersistableFeatureMap(InternalEObject owner, EStructuralFeature feature, List<FeatureMap.Entry> list) {
+ super(owner, feature, list);
+
+ if (isLoaded()) {
+ for (Entry entry : getDelegate()) {
+ final HibernateFeatureMapEntry fme = (HibernateFeatureMapEntry) entry;
+ if (!fme.belongsToFeatureMap(this)) {
+ fme.setFeatureMap(this);
+ }
+ }
+ }
+ }
+
+ /** Returns the element type to be used */
+ @Override
+ protected Class<? extends FeatureMap.Entry> determineElementType() {
+ return HibernateFeatureMapEntry.class;
+ }
+
+ /** OVerridden to create the correct featuremap entry */
+ @Override
+ protected FeatureMap.Entry createEntry(EStructuralFeature eStructuralFeature, Object value) {
+ final HibernateFeatureMapEntry entry = new HibernateFeatureMapEntry();
+ entry.setFeatureValue(eStructuralFeature, value, this);
+ return entry;
+ }
+
+ /** Shortcut to replace entries */
+ protected FeatureMap.Entry replaceEntry(Object entry) {
+ if (entry instanceof HibernateFeatureMapEntry && ((HibernateFeatureMapEntry) entry).belongsToFeatureMap(this)) {
+ return (HibernateFeatureMapEntry) entry;
+ }
+
+ final FeatureMap.Entry emfEntry = (FeatureMap.Entry) entry;
+ final HibernateFeatureMapEntry fme = new HibernateFeatureMapEntry();
+ fme.setFeatureValue(emfEntry.getEStructuralFeature(), emfEntry.getValue(), this);
+ return fme;
+ }
+
+ /** If the delegate has been initialized */
+ public boolean isInitialized() {
+ return ((PersistentCollection) delegate).wasInitialized();
+ }
+
+ /**
+ * Override isLoaded to check if the delegate lists was not already loaded by hibernate behind the scenes, this
+ * happens with eagerly loaded lists.
+ */
+ @Override
+ public boolean isLoaded() {
+ if (delegate instanceof AbstractPersistentCollection) {
+ if (((AbstractPersistentCollection) delegate).wasInitialized()) {
+ // delegate is loaded in case of subselect or eager loading
+ if (isLoading()) {
+ // probably are we doing this already return
+ return false;
+ }
+ log.debug("Persistentlist already initialized, probably eagerly loaded: " + getLogString());
+ try {
+ setIsLoading(true);
+ // do load to load the resource
+ doLoad();
+ setIsLoaded(true);
+ } finally {
+ setIsLoading(false);
+ }
+ }
+ }
+ return super.isLoaded();
+ }
+
+ /** Do the actual load can be overridden, called from the subclass */
+ @Override
+ protected synchronized void doLoad() {
+ AssertUtil.assertTrue("EList " + logString, !isLoaded());
+
+ SessionWrapper sessionWrapper = null;
+ boolean controlsSession = false;
+ boolean err = true;
+ try {
+ final Resource res = owner.eResource();
+
+ if (res != null && res instanceof HibernateResource) {
+ sessionWrapper = ((HibernateResource) res).getSessionWrapper();
+ if (res.isLoaded()) { // resource is loaded reopen transaction
+ if (!sessionWrapper.isTransactionActive()) {
+ log.debug("Reconnecting session to read a lazy collection, Featuremap: " + logString);
+ controlsSession = true;
+ sessionWrapper.beginTransaction();
+ sessionWrapper.setFlushModeManual();
+ } else {
+ log.debug("Resource session is still active, using it");
+ }
+ } else {
+ log.debug("Featuremap uses session from resource, " + logString);
+ }
+ } else {
+ log.debug("EList is not loaded in session context");
+ }
+
+ Object[] objs = delegate.toArray(); // this forces the load
+
+ // set the owner of the feature map entries
+ // set the econtainer
+ for (Object element : objs) {
+ final HibernateFeatureMapEntry fme = (HibernateFeatureMapEntry) element;
+ fme.setFeatureMap(this);
+
+ if (fme.getEStructuralFeature() instanceof EReference
+ && ((EReference) fme.getEStructuralFeature()).isContainment()) {
+ final InternalEObject eobj = (InternalEObject) fme.getValue();
+ if (eobj != null) {
+ EContainerRepairControl.setContainer(owner, eobj, fme.getEStructuralFeature());
+ if (res != null && res instanceof StoreResource
+ && fme.getEStructuralFeature() instanceof EReference) {
+ ((StoreResource) res).addToContentOrAttach((InternalEObject) fme.getValue(),
+ (EReference) fme.getEStructuralFeature());
+ }
+ }
+ }
+ }
+
+ err = false;
+ log.debug("Loaded " + objs.length + " from backend store for " + logString);
+ } finally {
+ if (controlsSession) {
+ if (err) {
+ sessionWrapper.rollbackTransaction();
+ sessionWrapper.restorePreviousFlushMode();
+ } else {
+ // a bit rough but delete from the persitence context
+ // otherwise
+ // hibernate will think that this collection is not attached
+ // to anything and
+ // will delete me
+ // getSession().getPersistenceContext().getCollectionEntries().remove(this);
+ sessionWrapper.commitTransaction();
+ sessionWrapper.restorePreviousFlushMode();
+ }
+ }
+ }
+ }
+
+ /** Overridden because general list type is not supported as a replacement */
+ @Override
+ public void replaceDelegate(List<FeatureMap.Entry> newDelegate) {
+ if (newDelegate instanceof PersistentList) {
+ AssertUtil.assertTrue("This elist " + logString + " contains a different list than the " + " passed list",
+ ((PersistentList) newDelegate).isWrapper(delegate));
+ super.replaceDelegate(newDelegate);
+ } else if (newDelegate instanceof PersistentBag) {
+ AssertUtil.assertTrue("This elist " + logString + " contains a different list than the " + " passed list",
+ ((PersistentBag) newDelegate).isWrapper(delegate));
+ super.replaceDelegate(newDelegate);
+ } else {
+ throw new HbMapperException("Type " + newDelegate.getClass().getName() + " can not be "
+ + " used as a replacement for elist " + logString);
+ }
+ }
+
+ /** Returns true if the wrapped list is a persistency layer specific list */
+ @Override
+ public boolean isPersistencyWrapped() {
+ return delegate instanceof PersistentCollection;
+ }
+
+ @Override
+ protected Entry delegateRemove(int index) {
+ final Entry old = super.delegateRemove(index);
+
+ if (old.getEStructuralFeature() instanceof EReference && getDelegate() instanceof PersistentList) {
+ final PersistentList pl = (PersistentList) getDelegate();
+ final EReference eref = (EReference) old.getEStructuralFeature();
+ if (eref.isContainment()) {
+ ((Session) pl.getSession()).delete(old.getValue());
+ }
+ }
+ return old;
+ }
+
+ @Override
+ protected Object clone() throws CloneNotSupportedException {
+ // TODO Auto-generated method stub
+ return super.clone();
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/MapHibernatePersistableEMap.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/MapHibernatePersistableEMap.java
new file mode 100755
index 000000000..02ba29cfd
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/MapHibernatePersistableEMap.java
@@ -0,0 +1,257 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: MapHibernatePersistableEMap.java,v 1.9 2010/02/04 10:53:08 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.elist;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.common.util.BasicEMap;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.SessionWrapper;
+import org.eclipse.emf.teneo.hibernate.resource.HbResource;
+import org.eclipse.emf.teneo.mapping.elist.MapPersistableEMap;
+import org.eclipse.emf.teneo.resource.StoreResource;
+import org.hibernate.Session;
+import org.hibernate.collection.AbstractPersistentCollection;
+import org.hibernate.collection.PersistentMap;
+
+/**
+ * Implements the hibernate persistable emap using a real map mapping (instead of the previous list
+ * mapping).
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @author <a href="mailto:jdboudreault@gmail.com">Jean-Denis Boudreault</a>
+ * @version $Revision: 1.9 $
+ */
+
+public class MapHibernatePersistableEMap<K, V> extends MapPersistableEMap<K, V> implements ExtensionPoint {
+ /**
+ * Serial Version ID
+ */
+ private static final long serialVersionUID = -4553160393592497834L;
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(MapHibernatePersistableEMap.class);
+
+ /**
+ * Constructor: this version will take a natural map as input (probided by hibernate) and
+ * transform the entries into the EMF keyToValue format
+ *
+ *
+ */
+ public MapHibernatePersistableEMap(InternalEObject owner, EReference eref, Map<K, V> map) {
+ super(eref.getEReferenceType(), owner, eref, map);
+ }
+
+ /**
+ * This constructor is usually called when the list is created and filled by the user first.
+ * when called by a hibernate load, the other overload with a map input is used instead.
+ *
+ */
+ public MapHibernatePersistableEMap(InternalEObject owner, EReference eref, List<BasicEMap.Entry<K, V>> list) {
+ super(eref.getEReferenceType(), owner, eref, list);
+ }
+
+ /** If the delegate has been initialized */
+ public boolean isInitialized() {
+ return isORMMapDelegateLoaded();
+ }
+
+ /**
+ * Override isLoaded to check if the delegate lists was not already loaded by hibernate behind
+ * the scenes, this happens with eagerly loaded lists.
+ */
+ @Override
+ public boolean isLoaded() {
+ // if the lazyload delegate is null, then this map is already loaded
+ if (ormMapDelegate == null) {
+ return true;
+ }
+
+ // if the delegated map was loaded under the hood and this
+ // HibernatePersistableEMap did
+ // not yet notice it then do the local load behavior.
+ // delegate is loaded in case of subselect or eager loading
+ if (!super.isLoaded() && !isLoading() && isORMMapDelegateLoaded()) {
+ log.debug("Persistentlist already initialized, probably eagerly loaded: " + getLogString());
+ try {
+ this.setLoading(true);
+ // do load to load the resource
+ doLoad();
+ this.setLoading(true);
+ } finally {
+ this.setLoading(false);
+ }
+ }
+ return super.isLoaded();
+ }
+
+ /**
+ * Overridden because of access to size attribute. This version will try to read the collection
+ * size without lading it if it is lazy loaded
+ */
+ @Override
+ public int size() {
+ if (size != 0) {
+ return size;
+ }
+
+ // if we are not loaded yet, we return the size of the buffered lazy
+ // load delegate
+ if (!isMapValueIsEAttribute() && this.getORMMapDelegate() != null) {
+ if (!this.isORMMapDelegateLoaded() && (this.getORMMapDelegate() instanceof AbstractPersistentCollection)) {
+ try {
+ // here is a neat trick. we use reflection to get the
+ // session of the persistanMap.
+ Field field = AbstractPersistentCollection.class.getDeclaredField("session");
+ field.setAccessible(true);
+ Session s = (Session) field.get(this.getORMMapDelegate());
+
+ // now that we have the session, we can query the size of
+ // the list without loading it
+ size =
+ ((Long) s.createFilter(this.getORMMapDelegate(), "select count(*)").list().get(0))
+ .intValue();
+ return size;
+ } catch (Throwable t) {
+ // ignore on purpose, let the call to super handle it
+ }
+ }
+ }
+
+ // didnt work, so we simply call the parent version
+ return super.size();
+ }
+
+ /**
+ * this method is used to determine if the underlying hibernate map collection has been eagerly
+ * loaded
+ *
+ * @return true if is laoded, false if not
+ */
+ @Override
+ protected boolean isORMMapDelegateLoaded() {
+ if (this.getORMMapDelegate() == null) {
+ return false;
+ }
+
+ return ((this.ormMapDelegate instanceof PersistentMap) && (((PersistentMap) ormMapDelegate).wasInitialized()));
+ }
+
+ /**
+ * Do the actual load and wrapping. can be overridden
+ */
+ @Override
+ @SuppressWarnings({"rawtypes","unchecked"})
+ protected void doLoad() {
+ SessionWrapper sessionWrapper = null;
+ boolean controlsTransaction = false;
+ boolean err = true;
+ Resource res = null;
+ final Map<K, V> delegate = getORMMapDelegate();
+
+ try {
+ res = getEObject().eResource();
+ if (res != null && res instanceof HbResource) {
+ sessionWrapper = ((HbResource) res).getSessionWrapper();
+ if (res.isLoaded()) // resource is loaded reopen transaction
+ {
+ // if the delegate is already loaded then no transaction is
+ // required
+ final boolean isDelegateLoaded =
+ delegate instanceof AbstractPersistentCollection &&
+ ((AbstractPersistentCollection) delegate).wasInitialized();
+ if (!isDelegateLoaded && !sessionWrapper.isTransactionActive()) {
+ log.debug("Reconnecting session to read a lazy collection, elist: " + logString);
+ controlsTransaction = true;
+ sessionWrapper.beginTransaction();
+ sessionWrapper.setFlushModeManual();
+ } else {
+ log.debug("Delegate loaded or resource session is still active, using it");
+ }
+ } else {
+ log.debug("EMap uses session from resource, " + logString);
+ }
+ } else {
+ log.debug("EMap is not loaded in session context");
+ }
+
+ if (controlsTransaction) {
+ assert (res instanceof HbResource);
+ ((StoreResource) res).setIsLoading(true);
+ }
+
+ try {
+ // set all entries in ourselves by wrapping the hibernate map.
+ // this also forces the load
+ for (Object o : this.getORMMapDelegate().entrySet()) {
+ final Map.Entry entry = (Map.Entry) o;
+ put((K) entry.getKey(), (V) entry.getValue());
+ }
+
+ // add the new objects to the resource so they are tracked
+ if (res != null && res instanceof StoreResource) {
+ // attach the new contained objects so that they are adapted
+ // when required
+ for (Object o : entrySet()) {
+ if (o instanceof EObject) {
+ ((StoreResource) res).addToContentOrAttach((InternalEObject) o,
+ (EReference) getEStructuralFeature());
+ }
+ }
+ }
+ log.debug("Loaded " + delegate.size() + " from backend store for " + logString);
+ } finally {
+ if (controlsTransaction) {
+ ((StoreResource) res).setIsLoading(false);
+ }
+ }
+ err = false;
+ } finally {
+ if (controlsTransaction) {
+ if (err) {
+ sessionWrapper.rollbackTransaction();
+ sessionWrapper.restorePreviousFlushMode();
+ } else {
+ // a bit rough but delete from the persitence context
+ // otherwise
+ // hibernate will think that this collection is not attached
+ // to anything and
+ // will delete me
+ // getSession().getPersistenceContext().getCollectionEntries().remove(this);
+ sessionWrapper.commitTransaction();
+ sessionWrapper.restorePreviousFlushMode();
+ }
+ ((HbResource) res).returnSessionWrapper(sessionWrapper);
+ }
+ }
+ log.debug("Finished loading emap " + logString);
+ }
+
+ /** Return the hibernate map */
+ @Override
+ public Object getDelegate() {
+ return getORMMapDelegate();
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierCacheHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierCacheHandler.java
new file mode 100755
index 000000000..f1ad7b7bc
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierCacheHandler.java
@@ -0,0 +1,262 @@
+/**
+ * <copyright> Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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: Martin Taal </copyright> $Id:
+ * IdentifierCacheHandler.getInstance().java,v 1.5 2007/02/08 23:11:37 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.identifier;
+
+import java.lang.ref.WeakReference;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Implements two maps for caching identifier and version information.
+ * Internally uses weakreferences and periodic purge actions to clean the maps.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.21 $
+ */
+
+public class IdentifierCacheHandler {
+ /** The logger */
+ private static Log log = LogFactory.getLog(IdentifierCacheHandler.class);
+
+ /** At this count the maps will be purged for stale entries */
+ public static final int PURGE_TRESHOLD = 100;
+
+ private static IdentifierCacheHandler instance = new IdentifierCacheHandler();
+
+ public static IdentifierCacheHandler getInstance() {
+ return instance;
+ }
+
+ public static void setInstance(IdentifierCacheHandler identifierCacheHandler) {
+ instance = identifierCacheHandler;
+ }
+
+ private Map<Key, Object> idMap = new ConcurrentHashMap<Key, Object>();
+ private int idModCount = 0;
+
+ private Map<Key, Object> versionMap = new ConcurrentHashMap<Key, Object>();
+ private int versionModCount = 0;
+
+ /** Clear the identifier cache */
+ public void clear() {
+ idMap.clear();
+ idModCount = 0;
+ versionMap.clear();
+ versionModCount = 0;
+ }
+
+ public Map<Key, Object> getIdMap() {
+ return idMap;
+ }
+
+ public Map<Key, Object> getVersionMap() {
+ return versionMap;
+ }
+
+ public void purgeMaps() {
+ purgeIDMap();
+ purgeVersionMap();
+ }
+
+ /** Get an identifier from the cache */
+ public Object getID(Object obj) {
+ final Object id = idMap.get(new Key(obj));
+ if (id == null) {
+ log.debug("ID for object " + obj.getClass().getName()
+ + " not found in id cache");
+ return null;
+ }
+ if (id instanceof WeakReference<?>) {
+ return ((WeakReference<?>) id).get();
+ }
+ return id;
+ }
+
+ /** Set an identifier in the cache */
+ public void setID(Object obj, Object id) {
+ if (log.isDebugEnabled()) {
+ log.debug("Setting id: " + id + " for object "
+ + obj.getClass().getName() + " in idcache ");
+ }
+
+ if (id == null) { // actually a remove of the id
+ idMap.remove(new Key(obj));
+ } else if (useWeakReference(id)) {
+ idMap.put(new Key(obj), new WeakReference<Object>(id));
+ } else {
+ idMap.put(new Key(obj), id);
+ }
+
+ // also set the id in the resource
+ // disabled for now
+ // if (false && obj instanceof EObject) {
+ // final EObject eobj = (EObject) obj;
+ // final Resource res = eobj.eResource();
+ // if (res != null && res instanceof XMLResource) {
+ // if (log.isDebugEnabled()) {
+ // log.debug("Setting id " + id.toString() + " in resource " +
+ // res.getClass().getName());
+ // }
+ // ((XMLResource) res).setID(eobj, id.toString());
+ // }
+ // }
+
+ idModCount++;
+ if (idModCount > getPurgeTreshold()) {
+ purgeIDMap();
+ }
+ }
+
+ /** Gets a version from the cache */
+ public Object getVersion(Object obj) {
+ final Object version = versionMap.get(new Key(obj));
+ if (version == null) {
+ return version;
+ }
+ return version;
+ }
+
+ private boolean useWeakReference(Object id) {
+ if (Number.class.isAssignableFrom(id.getClass())) {
+ return false;
+ }
+ if (String.class.isAssignableFrom(id.getClass())) {
+ return false;
+ }
+ return true;
+ }
+
+ protected int getPurgeTreshold() {
+ return PURGE_TRESHOLD;
+ }
+
+ /** Sets a version in the cache */
+ public void setVersion(Object obj, Object version) {
+ if (log.isDebugEnabled()) {
+ log.debug("Setting version: " + version + " for object "
+ + obj.getClass().getName() + " in idcache ");
+ }
+ if (version == null) {
+ versionMap.remove(new Key(obj));
+ } else {
+ versionMap.put(new Key(obj), version);
+ }
+ versionModCount++;
+ if (versionModCount > getPurgeTreshold()) {
+ purgeVersionMap();
+ }
+ }
+
+ /** Purge the versionmap for stale entries */
+ private void purgeIDMap() {
+ purgeMap(idMap);
+ idModCount = 0;
+ }
+
+ /** Purge the versionmap for stale entries */
+ protected void purgeVersionMap() {
+ purgeMap(versionMap);
+ versionModCount = 0;
+ }
+
+ /** Purges the passed map for stale entries */
+ protected void purgeMap(Map<Key, Object> map) {
+ final Iterator<Key> it = map.keySet().iterator();
+ while (it.hasNext()) {
+ final Key key = it.next();
+ if (!key.isValid()) {
+ it.remove();
+ }
+ }
+ }
+
+ /** Dumps the idmap */
+ public void dumpID() {
+ dumpContents(idMap);
+ }
+
+ /** Dumps the content of the passed map */
+ private void dumpContents(Map<Key, Object> map) {
+ Iterator<Key> it = map.keySet().iterator();
+ while (it.hasNext()) {
+ Key key = it.next();
+ key.weakRef.get();
+ }
+ }
+
+ /**
+ * Own implementation of the key in the hashmap to override the equals
+ * method. Equality for this cache is real memory location equality
+ */
+
+ protected static class Key {
+ /** The real object as a weakreference */
+ private final WeakReference<Object> weakRef;
+
+ /** The hashcode of the stored object */
+ private final int hashcode;
+
+ /** Constructor */
+ Key(Object keyObject) {
+ weakRef = new WeakReference<Object>(keyObject);
+ hashcode = keyObject.hashCode();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object arg0) {
+ assert (arg0 != null);
+ assert (arg0 instanceof Key);
+
+ final Key key0 = (Key) arg0;
+ final Object obj0 = key0.weakRef.get();
+ final Object obj1 = weakRef.get();
+
+ // weakreference already gone compare on keys itself
+ if (obj0 == null || obj1 == null) {
+ return this == key0;
+ }
+
+ // still present compare on values
+ // equals call should maybe also be done but goes wrong for
+ // featuremap entries
+ // which are equal if their values and featuremap are equal
+ // identifier and version caching are only usefull in case of object
+ // equality
+ // because it uses weak references and the first level cache of hb
+ // should
+ // ensure that only one instance of a certain object is present.
+ // There should always be one instance anyway in one session
+ // otherwise
+ // references between objects can be set wrong (or at least there is
+ // a great
+ // change that they go wrong).
+ return obj0 == obj1;
+ }
+
+ /** The hashcode of the enclosed object is returned */
+ @Override
+ public int hashCode() {
+ return hashcode;
+ }
+
+ /** Returns true if the weakReference is not yet gc'ed */
+ public boolean isValid() {
+ return weakRef.get() != null;
+ }
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierPropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierPropertyHandler.java
new file mode 100755
index 000000000..d13bdba9c
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierPropertyHandler.java
@@ -0,0 +1,133 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: IdentifierPropertyHandler.java,v 1.7 2010/11/11 10:28:18 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.identifier;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+
+/**
+ * Handles getting and setting of id's in the identifiercache handler, is only
+ * used for synthetic id's.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.7 $
+ */
+public class IdentifierPropertyHandler implements Getter, Setter,
+ PropertyAccessor {
+ /**
+ * Serial Version ID
+ */
+ private static final long serialVersionUID = 4707601844087591747L;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getGetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Getter getGetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getSetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Setter getSetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMember()
+ */
+ public Member getMember() {
+ return null;
+ }
+
+ /** Returns the id from the identifier cache */
+ public Object get(Object owner) throws HibernateException {
+ return IdentifierCacheHandler.getInstance().getID(owner);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getForInsert(java.lang.Object,
+ * java.util.Map, org.hibernate.engine.SessionImplementor)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getForInsert(Object arg0, Map arg1, SessionImplementor arg2)
+ throws HibernateException {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethod()
+ */
+ public Method getMethod() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethodName()
+ */
+ public String getMethodName() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getReturnType()
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getReturnType() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Setter#set(java.lang.Object,
+ * java.lang.Object, org.hibernate.engine.SessionFactoryImplementor)
+ */
+ public void set(Object target, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ IdentifierCacheHandler.getInstance().setID(target, value);
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierUtil.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierUtil.java
new file mode 100755
index 000000000..ab1c4fdc7
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierUtil.java
@@ -0,0 +1,179 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: IdentifierUtil.java,v 1.9 2010/11/12 09:33:33 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.identifier;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Hashtable;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.teneo.classloader.ClassLoaderResolver;
+import org.eclipse.emf.teneo.classloader.StoreClassLoadException;
+import org.eclipse.emf.teneo.hibernate.HbDataStore;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.hibernate.EntityMode;
+import org.hibernate.engine.ForeignKeys;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.impl.SessionFactoryImpl;
+import org.hibernate.impl.SessionImpl;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.type.AbstractStandardBasicType;
+import org.hibernate.type.Type;
+
+/**
+ * Different identifier related utilities. The current Elver store
+ * representation does not use the EMF id concept but uses the underlying
+ * hibernate identifier. This allows more flexibility than the EMF identifier.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.9 $
+ */
+
+public class IdentifierUtil {
+ /** The logger */
+ // private static Log log = LogFactory.getLog(IdentifierUtil.class);
+ /** Separator used in encoding the class name and value */
+ private static final String ENCODING_SEPARATOR = ";";
+
+ /** HashTable with identifier types hashed by entityname */
+ private static final Hashtable<String, Type> identifierTypeCache = new Hashtable<String, Type>();
+
+ /** HashTable with cached constructors */
+ private static final Hashtable<String, Constructor<?>> constructorCache = new Hashtable<String, Constructor<?>>();
+
+ /**
+ * Returns the identifiertype on the basis of the class of the passed object
+ */
+ public static Type getIdentifierType(String className,
+ SessionImplementor session) {
+ Type type = identifierTypeCache.get(className);
+ if (type != null) {
+ return type;
+ }
+
+ final Type identifierType = ((SessionImpl) session).getFactory()
+ .getClassMetadata(className).getIdentifierType();
+ identifierTypeCache.put(className, identifierType);
+ return identifierType;
+ }
+
+ /** Converts an id to a string representation */
+ public static String idToString(Object object, SessionImplementor session) {
+
+ return createIDString(
+ getIdentifierType(object.getClass().getName(), session),
+ getID(object, session));
+ }
+
+ /** String to id */
+ public static Serializable stringToId(String className,
+ SessionImplementor Session, String idStr) {
+ return extractID(getIdentifierType(className, Session), idStr);
+ }
+
+ /** Creates the serializable id object from a string */
+ private static Serializable extractID(Type type, String idString) {
+ // first handle the most common case
+ if (type instanceof AbstractStandardBasicType) {
+ final AbstractStandardBasicType<?> ntype = (AbstractStandardBasicType<?>) type;
+ return (Serializable) ntype.fromStringValue(idString);
+ }
+
+ // for all other cases the classname of the type is encoded into the
+ // field
+ final String className = idString.substring(0,
+ idString.indexOf(ENCODING_SEPARATOR));
+ final String strValue = idString.substring(1 + idString
+ .indexOf(ENCODING_SEPARATOR));
+
+ Constructor<?> constructor = constructorCache.get(className);
+ if (constructor == null) {
+ try {
+ final Class<?> clazz = ClassLoaderResolver
+ .classForName(className);
+ constructor = clazz
+ .getConstructor(new Class[] { String.class });
+ } catch (StoreClassLoadException e) {
+ throw new HbMapperException("Class " + className + " not found");
+ } catch (NoSuchMethodException e) {
+ throw new HbMapperException(
+ "Class "
+ + className
+ + " does not have a constructor with a String parameter!");
+ }
+ }
+ if (constructor == null) {
+ throw new HbMapperException("Class " + className
+ + " does not have a constructor with a String parameter!");
+ }
+
+ try {
+ return (Serializable) constructor
+ .newInstance(new Object[] { strValue });
+ } catch (InvocationTargetException e) {
+ throw new HbMapperException("Can not instantiate: " + className
+ + " using value " + strValue);
+ } catch (InstantiationException e) {
+ throw new HbMapperException("Can not instantiate: " + className
+ + " using value " + strValue);
+ } catch (IllegalAccessException e) {
+ throw new HbMapperException("Can not instantiate: " + className
+ + " using value " + strValue);
+ }
+ }
+
+ /** Returns the id of the passed object */
+ @SuppressWarnings("deprecation")
+ public static Serializable getID(EObject eobj, HbDataStore hd) {
+ final String entityName = hd.getEntityNameStrategy().toEntityName(
+ eobj.eClass());
+ final EntityPersister entityPersister = ((SessionFactoryImpl) hd
+ .getSessionFactory()).getEntityPersister(entityName);
+ return entityPersister.getIdentifier(eobj, EntityMode.MAP);
+ }
+
+ /** Returns the id of the passed object */
+ public static Serializable getID(Object object, SessionImplementor session) {
+ Serializable id = session.getContextEntityIdentifier(object);
+ if (id != null) {
+ return id;
+ }
+
+ // now with entity name
+ final String entityName = session.bestGuessEntityName(object);
+ id = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, object,
+ session);
+ if (id != null) {
+ return id;
+ }
+ // now the slow way
+ return (Serializable) IdentifierCacheHandler.getInstance()
+ .getID(object);
+ }
+
+ /** Creates an id string from a serializable object */
+ private static String createIDString(Type type, Serializable id) {
+ if (type instanceof AbstractStandardBasicType) {
+ @SuppressWarnings("unchecked")
+ final AbstractStandardBasicType<Object> ntype = (AbstractStandardBasicType<Object>) type;
+ return ntype.toString(id);
+ }
+
+ return id.getClass().getName() + ENCODING_SEPARATOR + id.toString();
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/internal/TeneoInternalEObject.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/internal/TeneoInternalEObject.java
new file mode 100755
index 000000000..7a85ff477
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/internal/TeneoInternalEObject.java
@@ -0,0 +1,14 @@
+package org.eclipse.emf.teneo.hibernate.mapping.internal;
+
+
+import org.eclipse.emf.ecore.InternalEObject;
+
+/**
+ * This interface ensures that the cglib proxyfactory does not encounter a security exception
+ * because the EMF InternalEObject is signed with a different signature.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.1 $
+ */
+public interface TeneoInternalEObject extends InternalEObject {
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/DummyPropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/DummyPropertyHandler.java
new file mode 100755
index 000000000..33463be2c
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/DummyPropertyHandler.java
@@ -0,0 +1,134 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: DummyPropertyHandler.java,v 1.6 2010/11/11 10:28:19 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.property;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+
+/**
+ * DummyAccessor, does nothing.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.6 $
+ */
+public class DummyPropertyHandler implements Getter, Setter, PropertyAccessor {
+ /**
+ * Generated Serial Version ID
+ */
+ private static final long serialVersionUID = -5512925601236993580L;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getGetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Getter getGetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getSetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Setter getSetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMember()
+ */
+ public Member getMember() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#get(java.lang.Object)
+ */
+ public Object get(Object owner) throws HibernateException {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getForInsert(java.lang.Object,
+ * java.util.Map, org.hibernate.engine.SessionImplementor)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getForInsert(Object arg0, Map arg1, SessionImplementor arg2)
+ throws HibernateException {
+ return get(arg0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethod()
+ */
+ public Method getMethod() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethodName()
+ */
+ public String getMethodName() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getReturnType()
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getReturnType() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Setter#set(java.lang.Object,
+ * java.lang.Object, org.hibernate.engine.SessionFactoryImplementor)
+ */
+ public void set(Object target, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EAttributePropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EAttributePropertyHandler.java
new file mode 100755
index 000000000..397311ac2
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EAttributePropertyHandler.java
@@ -0,0 +1,391 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EAttributePropertyHandler.java,v 1.20 2010/11/12 14:08:17 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.property;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.teneo.PersistenceOptions;
+import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierCacheHandler;
+import org.eclipse.emf.teneo.util.AssertUtil;
+import org.eclipse.emf.teneo.util.StoreUtil;
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+
+/**
+ * Is a getter and setter for EMF eattribute which uses eGet and eSet.Handles
+ * many==false properties.
+ *
+ * This class implements both the getter, setter and propertyaccessor
+ * interfaces. When the getGetter and getSetter methods are called it returns
+ * itself.
+ *
+ * This accessor also handles arrays of primitive types.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.20 $
+ */
+public class EAttributePropertyHandler implements Getter, Setter,
+ PropertyAccessor {
+ /**
+ * Generated Serial Version ID
+ */
+ private static final long serialVersionUID = 8953817672640618007L;
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(EAttributePropertyHandler.class);
+
+ /** The field name for which this elist getter operates */
+ protected final EAttribute eAttribute;
+
+ /** The instanceclass */
+ protected final Class<?> instanceClass;
+
+ private boolean handleUnsetAsNull = false;
+
+ private boolean convertUnsetToNull = false;
+
+ private boolean isObjectClass = false;
+
+ private boolean isId = false;
+
+ /** Constructor */
+ public EAttributePropertyHandler(EAttribute eAttribute) {
+ this.eAttribute = eAttribute;
+ instanceClass = eAttribute.getEType().getInstanceClass();
+ if (eAttribute.getEType().getInstanceClassName() != null) {
+ isObjectClass = eAttribute.getEType().getInstanceClassName()
+ .contains(".");
+ }
+ AssertUtil.assertTrue(eAttribute.getName()
+ + " is a many feature which is not handled by this accessor ",
+ !eAttribute.isMany());
+ log.debug("Created getter/setter for " + StoreUtil.toString(eAttribute));
+ }
+
+ public EAttribute getEAttribute() {
+ return eAttribute;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMember()
+ */
+ public Member getMember() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getGetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Getter getGetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getSetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Setter getSetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#get(java.lang.Object)
+ */
+ public Object get(Object owner) throws HibernateException {
+ if (handleUnsetAsNull || convertUnsetToNull) {
+ EObject eobj = (EObject) owner;
+ if (!eobj.eIsSet(eAttribute) && eAttribute.isUnsettable()) {
+ return null;
+ }
+ }
+ return ((EObject) owner).eGet(eAttribute);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getForInsert(java.lang.Object,
+ * java.util.Map, org.hibernate.engine.SessionImplementor)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getForInsert(Object arg0, Map arg1, SessionImplementor arg2)
+ throws HibernateException {
+ return get(arg0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethod()
+ */
+ public Method getMethod() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethodName()
+ */
+ public String getMethodName() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getReturnType()
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getReturnType() {
+ return eAttribute.getEType().getInstanceClass();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Setter#set(java.lang.Object,
+ * java.lang.Object, org.hibernate.engine.SessionFactoryImplementor)
+ */
+ public void set(Object target, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+
+ EObject eobj = (EObject) target;
+ if (value == null) {
+ if (handleUnsetAsNull && eAttribute.isUnsettable()) {
+ eobj.eUnset(eAttribute);
+ } else if (isObjectClass || eAttribute instanceof EEnum) {
+ eobj.eSet(eAttribute, value);
+ }
+ return;
+ }
+
+ if (isId()) {
+ IdentifierCacheHandler.getInstance().setID(target, value);
+ }
+
+ final Object curValue = get(target);
+
+ // do not set if not changed
+ // note: this does not handle unsettable correctly
+ // need to make this an option
+ if (curValue != null && curValue.equals(value)) {
+ return;
+ }
+ if (curValue == value) {
+ return;
+ }
+
+ final Object setValue;
+ if (value != null && instanceClass != null
+ && value.getClass() != instanceClass) {
+ final Class<?> valClass = value.getClass();
+ if (valClass == Integer[].class) {
+ setValue = convert((Integer[]) value);
+ } else if (valClass == Byte[].class) {
+ setValue = convert((Byte[]) value);
+ } else if (valClass == Boolean[].class) {
+ setValue = convert((Boolean[]) value);
+ } else if (valClass == Double[].class) {
+ setValue = convert((Double[]) value);
+ } else if (valClass == Float[].class) {
+ setValue = convert((Float[]) value);
+ } else if (valClass == Long[].class) {
+ setValue = convert((Long[]) value);
+ } else if (valClass == Short[].class) {
+ setValue = convert((Short[]) value);
+ } else {
+ setValue = convert(value);
+ }
+ } else {
+ setValue = value;
+ }
+ eobj.eSet(eAttribute, setValue);
+ }
+
+ /** Convert to a primitive type */
+ private Object convert(Integer[] arr) {
+ if (instanceClass != int[].class) {
+ if (log.isDebugEnabled()) {
+ log.debug("Expecting " + instanceClass.getName()
+ + " as instance class but it is: "
+ + arr.getClass().getName());
+ }
+ return arr;
+ }
+ final int[] res = new int[arr.length];
+ for (int i = 0; i < arr.length; i++) {
+ res[i] = arr[i].intValue();
+ }
+ return res;
+ }
+
+ /** Convert to a primitive type */
+ private Object convert(Boolean[] arr) {
+ if (instanceClass != boolean[].class) {
+ if (log.isDebugEnabled()) {
+ log.debug("Expecting " + instanceClass.getName()
+ + " as instance class but it is: "
+ + arr.getClass().getName());
+ }
+ return arr;
+ }
+ final boolean[] res = new boolean[arr.length];
+ for (int i = 0; i < arr.length; i++) {
+ res[i] = arr[i].booleanValue();
+ }
+ return res;
+ }
+
+ /** Convert to a primitive type */
+ private Object convert(Byte[] arr) {
+ if (instanceClass != byte[].class) {
+ if (log.isDebugEnabled()) {
+ log.debug("Expecting " + instanceClass.getName()
+ + " as instance class but it is: "
+ + arr.getClass().getName());
+ }
+ return arr;
+ }
+ final byte[] res = new byte[arr.length];
+ for (int i = 0; i < arr.length; i++) {
+ res[i] = arr[i].byteValue();
+ }
+ return res;
+ }
+
+ /** Convert to a primitive type */
+ private Object convert(Double[] arr) {
+ if (instanceClass != double[].class) {
+ if (log.isDebugEnabled()) {
+ log.debug("Expecting " + instanceClass.getName()
+ + " as instance class but it is: "
+ + arr.getClass().getName());
+ }
+ return arr;
+ }
+ final double[] res = new double[arr.length];
+ for (int i = 0; i < arr.length; i++) {
+ res[i] = arr[i].doubleValue();
+ }
+ return res;
+ }
+
+ /** Convert to a primitive type */
+ private Object convert(Float[] arr) {
+ if (instanceClass != float[].class) {
+ if (log.isDebugEnabled()) {
+ log.debug("Expecting " + instanceClass.getName()
+ + " as instance class but it is: "
+ + arr.getClass().getName());
+ }
+ return arr;
+ }
+ final float[] res = new float[arr.length];
+ for (int i = 0; i < arr.length; i++) {
+ res[i] = arr[i].floatValue();
+ }
+ return res;
+ }
+
+ /** Convert to a primitive type */
+ private Object convert(Long[] arr) {
+ if (instanceClass != long[].class) {
+ if (log.isDebugEnabled()) {
+ log.debug("Expecting [] as instance class but it is: "
+ + instanceClass.getName());
+ }
+ return arr;
+ }
+ final long[] res = new long[arr.length];
+ for (int i = 0; i < arr.length; i++) {
+ res[i] = arr[i].longValue();
+ }
+ return res;
+ }
+
+ /** Convert to a primitive type */
+ private Object convert(Short[] arr) {
+ if (instanceClass != short[].class) {
+ if (log.isDebugEnabled()) {
+ log.debug("Expecting short[] as instance class but it is: "
+ + instanceClass.getName());
+ }
+ return arr;
+ }
+ final short[] res = new short[arr.length];
+ for (int i = 0; i < arr.length; i++) {
+ res[i] = arr[i].shortValue();
+ }
+ return res;
+ }
+
+ /** Capature all, do not convert */
+ private Object convert(Object arr) {
+ if (arr != null
+ && instanceClass != null
+ && (!instanceClass.isPrimitive() || !arr.getClass()
+ .isPrimitive())) {
+ log.debug("Expecting " + instanceClass.getName()
+ + " as instance class but it is: "
+ + arr.getClass().getName());
+ }
+ return arr;
+ }
+
+ /**
+ * Pass in the persistion options.
+ */
+ public void setPersistenceOptions(PersistenceOptions po) {
+ handleUnsetAsNull = po.getHandleUnsetAsNull();
+ convertUnsetToNull = po.getConvertUnsetToNull();
+ }
+
+ public boolean isId() {
+ return isId;
+ }
+
+ public void setId(boolean isId) {
+ this.isId = isId;
+ }
+
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EListPropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EListPropertyHandler.java
new file mode 100755
index 000000000..2d33d4f61
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EListPropertyHandler.java
@@ -0,0 +1,535 @@
+/**
+ * <copyright> Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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: Martin Taal </copyright> $Id:
+ * EListPropertyHandler.java,v 1.12 2007/03/20 23:33:48 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.property;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.EMap;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.InternalEObject.EStore;
+import org.eclipse.emf.ecore.impl.BasicEObjectImpl;
+import org.eclipse.emf.ecore.util.BasicFeatureMap;
+import org.eclipse.emf.ecore.util.EcoreEMap;
+import org.eclipse.emf.teneo.extension.ExtensionManager;
+import org.eclipse.emf.teneo.extension.ExtensionManagerAware;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.mapping.elist.HbExtraLazyPersistableEList;
+import org.eclipse.emf.teneo.hibernate.mapping.elist.HbExtraLazyPersistableEMap;
+import org.eclipse.emf.teneo.hibernate.mapping.elist.HibernatePersistableEList;
+import org.eclipse.emf.teneo.hibernate.mapping.elist.HibernatePersistableEMap;
+import org.eclipse.emf.teneo.hibernate.mapping.elist.MapHibernatePersistableEMap;
+import org.eclipse.emf.teneo.mapping.elist.MapPersistableEMap;
+import org.eclipse.emf.teneo.mapping.elist.PersistableDelegateList;
+import org.eclipse.emf.teneo.mapping.elist.PersistableEList;
+import org.eclipse.emf.teneo.mapping.elist.PersistableEMap;
+import org.eclipse.emf.teneo.type.PersistentStoreAdapter;
+import org.eclipse.emf.teneo.util.AssertUtil;
+import org.eclipse.emf.teneo.util.FieldUtil;
+import org.eclipse.emf.teneo.util.StoreUtil;
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+
+/**
+ * Implements the accessor for EMF EList members for Hibernate. This can be an
+ * EReference or an Eattribute with many=true. This class implements both the
+ * getter, setter and propertyaccessor interfaces. When the getGetter and
+ * getSetter methods are called it returns itself.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.39 $
+ */
+@SuppressWarnings("unchecked")
+public class EListPropertyHandler implements Getter, Setter, PropertyAccessor,
+ ExtensionPoint, ExtensionManagerAware {
+ /**
+ * Generated Serial Version ID
+ */
+ private static final long serialVersionUID = 2255108246093951341L;
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(EListPropertyHandler.class);
+
+ /** The EStructuralFeature of this accessor */
+ protected EStructuralFeature eFeature;
+
+ /** Extra lazy behavior! */
+ private boolean extraLazy;
+
+ /** Map emap as a real map */
+ private boolean newEMapMapping;
+
+ /** It this a map */
+ private boolean isAMap;
+
+ /** The extension manager */
+ private ExtensionManager extensionManager;
+
+ /** Initialize this instance */
+ public void initialize(EStructuralFeature eFeature, boolean extraLazy,
+ boolean newEMapMapping) {
+ this.extraLazy = extraLazy;
+ this.eFeature = eFeature;
+ log.debug("Created getter/setter for " + StoreUtil.toString(eFeature));
+ AssertUtil.assertTrue("Many must be true but this isn't the case for "
+ + StoreUtil.toString(eFeature), eFeature.isMany());
+ isAMap = StoreUtil.isMap(eFeature);
+ this.newEMapMapping = newEMapMapping;
+ }
+
+ public EStructuralFeature getEFeature() {
+ return eFeature;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMember()
+ */
+ public Member getMember() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getGetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Getter getGetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getSetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Setter getSetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#get(java.lang.Object)
+ */
+ public Object get(Object owner) throws HibernateException {
+
+ final PersistentStoreAdapter adapter = StoreUtil
+ .getPersistentStoreAdapter((EObject) owner);
+ final Object value = adapter.getStoreCollection(eFeature);
+ if (value != null) {
+ return value;
+ }
+
+ Object obj = ((EObject) owner).eGet(eFeature);
+
+ if (StoreUtil.isEStoreList(obj)) {
+ final EStore eStore = ((InternalEObject) owner).eStore();
+ // the call to size forces a load, this is a trick to
+ // force the estore to create a list, otherwise the .get
+ // will return a null value.
+ if (eStore.size((InternalEObject) owner, eFeature) != -1) {
+ obj = eStore.get((InternalEObject) owner, eFeature,
+ EStore.NO_INDEX);
+ }
+ }
+
+ if (obj instanceof PersistableDelegateList<?>) {
+ return ((PersistableDelegateList<?>) obj).getDelegate();
+ }
+ if (obj instanceof EcoreEMap<?, ?> && newEMapMapping) {
+ return ((EcoreEMap<?, ?>) obj).map();
+ }
+
+ if (adapter.isTargetCreatedByORM() && obj instanceof BasicFeatureMap) {
+ // this one is replaced here
+ // because the entries
+ // need to be changed to hibernate entries
+ final PersistableDelegateList<?> pelist = (PersistableDelegateList<?>) createPersistableList(
+ (InternalEObject) owner, eFeature, (List<?>) obj);
+ final EObject eobj = (EObject) owner;
+ if (!EcoreAccess.isStaticFeature(eFeature, (BasicEObjectImpl) eobj)) {
+ if (log.isDebugEnabled()) {
+ log.debug("Dynamic elist, set using the esettings");
+ }
+ EcoreAccess.setManyEFeatureValue(eFeature, pelist,
+ (BasicEObjectImpl) owner);
+ } else {
+ // TODO: currently it is required to use the field setter
+ // instead of the eSet method
+ // because EMF does not support direct setting of the elist
+ // feature.
+ // UPDATE: for dynamic eclasses now elists are also supported
+ // the reason that the javafield is determined here and not at
+ // construction time
+ // is that the owner passed in the construction can be an
+ // interface while there
+ // are multiple implementors. FieldUtil does caching of
+ // fieldnames and fields.
+ final Field javaField = FieldUtil.getField(owner.getClass(),
+ getFieldName(owner));
+ try {
+ javaField.set(owner, pelist);
+ } catch (Exception e) {
+ throw new HbMapperException("The field "
+ + javaField.getName()
+ + " can not be set using object "
+ + pelist.getClass().getName() + " on target "
+ + owner.getClass().getName(), e);
+ }
+ }
+ }
+
+ if (obj instanceof EList<?>) {
+ return processList(obj);
+ }
+
+ return obj;
+ }
+
+ protected String getFieldName(Object owner) {
+ return eFeature.getName();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getForInsert(java.lang.Object,
+ * java.util.Map, org.hibernate.engine.SessionImplementor)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getForInsert(Object owner, Map mergeMap,
+ SessionImplementor session) throws HibernateException {
+ final PersistentStoreAdapter adapter = StoreUtil
+ .getPersistentStoreAdapter((EObject) owner);
+ final Object value = adapter.getStoreCollection(eFeature);
+ if (value != null) {
+ return value;
+ }
+
+ Object obj = ((EObject) owner).eGet(eFeature);
+
+ if (StoreUtil.isEStoreList(obj)) {
+ final EStore eStore = ((InternalEObject) owner).eStore();
+ // the call to size forces a load, this is a trick to
+ // force the estore to create a list, otherwise the .get
+ // will return a null value.
+ if (eStore.size((InternalEObject) owner, eFeature) != -1) {
+ obj = eStore.get((InternalEObject) owner, eFeature,
+ EStore.NO_INDEX);
+ }
+ }
+
+ if (obj instanceof PersistableDelegateList) {
+ return ((PersistableDelegateList) obj).getDelegate();
+ }
+ if (obj instanceof EcoreEMap && newEMapMapping) {
+ return ((EcoreEMap<?, ?>) obj).map();
+ }
+
+ // if this is a elist then give a normal arraylist to
+ // hibernate otherwise hb will wrap the elist, the hb wrapper
+ // is again wrapped by teneo resulting in notifications being send
+ // out by both the teneo wrapper as the wrapped elist
+ if (obj instanceof EList<?>) {
+ final List<Object> objects = processList(obj);
+ if (extraLazy) {
+ int index = 0;
+ for (Object object : objects) {
+ if (object instanceof EObject) {
+ final PersistentStoreAdapter elementAdapter = StoreUtil
+ .getPersistentStoreAdapter((EObject) object);
+ elementAdapter
+ .setSyntheticProperty(
+ StoreUtil
+ .getExtraLazyInverseIndexPropertyName(eFeature),
+ index);
+ elementAdapter.setSyntheticProperty(StoreUtil
+ .getExtraLazyInversePropertyName(eFeature),
+ owner);
+ }
+ index++;
+ }
+ }
+ return objects;
+ }
+
+ // todo maybe throw error in all other cases?
+ return obj;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethod()
+ */
+ public Method getMethod() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethodName()
+ */
+ public String getMethodName() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getReturnType()
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getReturnType() {
+ return EList.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Setter#set(java.lang.Object,
+ * java.lang.Object, org.hibernate.engine.SessionFactoryImplementor)
+ */
+ @SuppressWarnings("rawtypes")
+ public void set(Object target, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+
+ final PersistentStoreAdapter adapter = StoreUtil
+ .getPersistentStoreAdapter((EObject) target);
+ if (!adapter.isTargetCreatedByORM()) {
+ adapter.addStoreCollection(eFeature, value);
+ return;
+ }
+
+ if (!EcoreAccess.isStaticFeature(eFeature, (BasicEObjectImpl) target)) {
+ if (log.isDebugEnabled()) {
+ log.debug("Dynamic elist, set using the esettings");
+ }
+ Object currentValue = EcoreAccess.getManyEFeatureValue(eFeature,
+ (BasicEObjectImpl) target);
+
+ if (StoreUtil.isEStoreList(currentValue)) {
+ final EStore eStore = ((InternalEObject) target).eStore();
+ if (eStore.size((InternalEObject) target, eFeature) != -1) {
+ currentValue = eStore.get((InternalEObject) target,
+ eFeature, EStore.NO_INDEX);
+ }
+ }
+
+ // if currentvalue is not null then use the passed value
+ if (currentValue != null
+ && currentValue instanceof PersistableEList<?>) {
+ ((PersistableEList<?>) currentValue)
+ .replaceDelegate((List) value);
+ } else {
+ if (value instanceof Map<?, ?>) {
+ EcoreAccess.setManyEFeatureValue(
+ eFeature,
+ createPersistableMap((InternalEObject) target,
+ eFeature, (Map<?, ?>) value),
+ (BasicEObjectImpl) target);
+ } else {
+ EcoreAccess.setManyEFeatureValue(
+ eFeature,
+ createPersistableList((InternalEObject) target,
+ eFeature, (List<?>) value),
+ (BasicEObjectImpl) target);
+ }
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Set value " + value.getClass().getName()
+ + " for target " + target.getClass().getName()
+ + " field " + getFieldName(target));
+ }
+
+ } else {
+ // the reason that the javafield is determined here and not at
+ // construction time
+ // is that the owner passed in the construction can be an interface
+ // while there
+ // are multiple implementors. FieldUtil does caching of fieldnames
+ // and fields.
+ final Field javaField = FieldUtil.getField(target.getClass(),
+ getFieldName(target));
+
+ // do not set the java field if not present, but use the store
+ // adapter
+ // this happens in case of gmf see bugzilla: 280040
+ if (javaField == null) {
+ adapter.addStoreCollection(eFeature, value);
+ return;
+ }
+
+ try {
+ final Object currentValue = javaField.get(target);
+
+ // if already set then ignore it
+ if (currentValue == value) {
+ return; // nothing to do here
+ }
+
+ // the delegating map was passed to hibernate, now getting it
+ // back
+ if (value instanceof EMap.InternalMapView<?, ?>
+ && (currentValue == ((EMap.InternalMapView<?, ?>) value)
+ .eMap())) {
+ return;
+ }
+
+ // already handled
+ if (currentValue instanceof PersistableDelegateList<?>
+ && value == ((PersistableDelegateList<?>) currentValue)
+ .getDelegate()) {
+ return;
+ }
+
+ // the follow 3 if statements handle the refresh action, the
+ // underlying orm
+ // collection is replaced
+ if (currentValue != null
+ && currentValue instanceof PersistableEList<?>
+ && value != ((PersistableEList<?>) currentValue)
+ .getDelegate()) {
+ ((PersistableEList<?>) currentValue)
+ .replaceDelegate((List) value);
+ } else if (currentValue != null
+ && currentValue instanceof PersistableEMap<?, ?>
+ && value != ((PersistableEMap<?, ?>) currentValue)
+ .getDelegate()) {
+ ((PersistableEMap<?, ?>) currentValue)
+ .replaceDelegate(value);
+ } else if (currentValue != null
+ && currentValue instanceof MapPersistableEMap<?, ?>
+ && value != ((MapPersistableEMap<?, ?>) currentValue)
+ .getORMMapDelegate()) {
+ ((PersistableEMap<?, ?>) currentValue)
+ .replaceDelegate(value);
+ } else { // then wrap the hibernate collection
+ if (value instanceof Map<?, ?>) {
+ javaField.set(
+ target,
+ createPersistableMap((InternalEObject) target,
+ eFeature, (Map<?, ?>) value));
+ } else {
+ javaField.set(
+ target,
+ createPersistableList((InternalEObject) target,
+ eFeature, (List<?>) value));
+ }
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Set value " + value.getClass().getName()
+ + " for target " + target.getClass().getName()
+ + " field " + getFieldName(target));
+ }
+ } catch (Exception e) {
+ throw new HbMapperException("The field "
+ + (javaField != null ? javaField.getName()
+ : getFieldName(target))
+ + " can not be set using object "
+ + value.getClass().getName() + " on target "
+ + target.getClass().getName(), e);
+ }
+ }
+ }
+
+ /**
+ * Create a EMap. Create method can be overridden
+ */
+ protected EList<?> createPersistableMap(InternalEObject target,
+ EStructuralFeature estruct, Map<?, ?> map) {
+ final EReference eref = (EReference) estruct;
+ if (log.isDebugEnabled()) {
+ log.debug("Detected EMAP for " + estruct.getName());
+ }
+ assert (isAMap);
+ assert (newEMapMapping);
+ return getExtensionManager().getExtension(
+ MapHibernatePersistableEMap.class,
+ new Object[] { target, eref, map });
+ }
+
+ /** Creates a persistablemap or list */
+ protected EList<?> createPersistableList(InternalEObject target,
+ EStructuralFeature estruct, List<?> list) {
+ if (estruct instanceof EReference) {
+ final EReference eref = (EReference) estruct;
+ // the test for emap checks: the entry class must have a
+ // instanceclass: Map.Entry
+ // and the entry class must have two efeatures with the name key and
+ // value
+ if (StoreUtil.isMap(estruct)) {
+ if (log.isDebugEnabled()) {
+ log.debug("Detected EMAP for " + estruct.getName());
+ }
+ if (extraLazy) {
+ return getExtensionManager().getExtension(
+ HbExtraLazyPersistableEMap.class,
+ new Object[] { target, eref, list });
+ } else {
+ return getExtensionManager().getExtension(
+ HibernatePersistableEMap.class,
+ new Object[] { target, eref, list });
+ }
+ }
+ }
+ if (extraLazy) {
+ return getExtensionManager().getExtension(
+ HbExtraLazyPersistableEList.class,
+ new Object[] { target, estruct, list });
+ }
+ return getExtensionManager().getExtension(
+ HibernatePersistableEList.class,
+ new Object[] { target, estruct, list });
+ }
+
+ protected List<Object> processList(Object list) {
+ return new ArrayList<Object>((List<Object>) list);
+ }
+
+ /**
+ * @return the extensionManager
+ */
+ public ExtensionManager getExtensionManager() {
+ return extensionManager;
+ }
+
+ /**
+ * @param extensionManager
+ * the extensionManager to set
+ */
+ public void setExtensionManager(ExtensionManager extensionManager) {
+ this.extensionManager = extensionManager;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EReferencePropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EReferencePropertyHandler.java
new file mode 100755
index 000000000..9c411e6e7
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EReferencePropertyHandler.java
@@ -0,0 +1,252 @@
+/**
+ * <copyright> Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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: Martin Taal </copyright> $Id:
+ * EReferencePropertyHandler.java,v 1.4 2007/04/07 12:43:51 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.property;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.common.notify.NotificationChain;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.impl.DynamicEObjectImpl;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierCacheHandler;
+import org.eclipse.emf.teneo.hibernate.resource.HibernateResource;
+import org.eclipse.emf.teneo.util.StoreUtil;
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+
+/**
+ * Implements the getter for an EReference field. Normally uses the eget/eset
+ * methods with bidirectional relations the handling is a bit different using
+ * eInverseRemove and eInverseAdd. This class implements both the getter, setter
+ * and propertyaccessor interfaces. When the getGetter and getSetter methods are
+ * called it returns itself.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.21 $
+ */
+public class EReferencePropertyHandler implements Getter, Setter,
+ PropertyAccessor, ExtensionPoint {
+
+ /**
+ * Serial version id
+ */
+ private static final long serialVersionUID = -3712366809398761331L;
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(EReferencePropertyHandler.class);
+
+ /** The feature */
+ protected EReference eReference;
+
+ /** Two way reference */
+ protected boolean isBidirectional;
+
+ private int featureId = -1;
+
+ private boolean isId = false;
+
+ public void initialize(EReference eReference) {
+ this.eReference = eReference;
+ final EClass eClass = eReference.getEContainingClass();
+ featureId = eClass.getFeatureID(eReference);
+ isBidirectional = (eReference.getEOpposite() != null && !eReference
+ .getEOpposite().isTransient());
+ log.debug("Created getter/setter for " + StoreUtil.toString(eReference));
+ }
+
+ public EReference getEReference() {
+ return eReference;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getGetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Getter getGetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMember()
+ */
+ public Member getMember() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getSetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Setter getSetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#get(java.lang.Object)
+ */
+ public Object get(Object owner) throws HibernateException {
+ // see bugzilla: 283680, in case of cascading having this
+ // to false ment that Hibernate encountered unresolved/empty
+ // object
+ // return ((EObject) owner).eGet(eReference, false);
+ return ((EObject) owner).eGet(eReference, true);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getForInsert(java.lang.Object,
+ * java.util.Map, org.hibernate.engine.SessionImplementor)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getForInsert(Object owner, Map mergeMap,
+ SessionImplementor session) throws HibernateException {
+ return get(owner);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Setter#set(java.lang.Object,
+ * java.lang.Object, org.hibernate.engine.SessionFactoryImplementor)
+ */
+ public void set(Object target, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ final Object curValue = get(target);
+
+ if (isId()) {
+ IdentifierCacheHandler.getInstance().setID(target, value);
+ }
+
+ if (isBidirectional
+ || (target instanceof DynamicEObjectImpl && eReference
+ .isContainment())) {
+ // these are handled a bit differently because
+ // the opposite should not be set, this is
+ // done by hb
+ if (curValue != value) { // note that == works fine if the
+ // curValue and value have been read in
+ // the same
+ // pm.
+ // Note that the eInverseRemove is called on the target itself
+ // and the value is
+ // passed
+ // therefore the eReference featureid is passed and not the
+ // opposite
+ if (value == null) { // remove
+ final NotificationChain nots = ((InternalEObject) target)
+ .eInverseRemove((InternalEObject) curValue,
+ featureId, eReference.getEType()
+ .getInstanceClass(), null);
+ if (nots != null) {
+ nots.dispatch();
+ }
+ } else {
+ final NotificationChain nots = ((InternalEObject) target)
+ .eInverseAdd((InternalEObject) value, featureId,
+ eReference.getEType().getInstanceClass(),
+ null);
+ if (nots != null) {
+ nots.dispatch();
+ }
+ }
+ }
+ } else {
+ if (curValue == value) {
+ return; // do nothing in this case
+ }
+ final EObject eobj = (EObject) target;
+ eobj.eSet(eReference, value);
+ }
+ final EObject eobj = (EObject) target;
+ Resource res = eobj.eResource();
+ if (value != null && res instanceof HibernateResource
+ && ((EObject) value).eResource() == null) {
+ final boolean loading = ((HibernateResource) res).isLoading();
+ try {
+ ((HibernateResource) res).setIsLoading(true);
+ ((HibernateResource) res).addToContentOrAttach(
+ (InternalEObject) value, eReference);
+ } finally {
+ ((HibernateResource) res).setIsLoading(loading);
+ }
+ }
+
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=245634
+ // container relations should be modeled explicitly in the database or
+ // not at all
+ // see the relevant option in PersistenceOptions.
+ // if (eReference.isContainment() && target instanceof InternalEObject
+ // && value instanceof InternalEObject) {
+ // EContainerRepairControl.setContainer((InternalEObject) target,
+ // (InternalEObject) value, eReference);
+ // }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethod()
+ */
+ public Method getMethod() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethodName()
+ */
+ public String getMethodName() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getReturnType()
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getReturnType() {
+ return InternalEObject.class;
+ }
+
+ public boolean isId() {
+ return isId;
+ }
+
+ public void setId(boolean isId) {
+ this.isId = isId;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EcoreAccess.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EcoreAccess.java
new file mode 100755
index 000000000..56a50970d
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/EcoreAccess.java
@@ -0,0 +1,76 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EcoreAccess.java,v 1.9 2010/11/05 09:23:32 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.property;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EStructuralFeature.Internal.DynamicValueHolder;
+import org.eclipse.emf.ecore.impl.BasicEObjectImpl;
+import org.eclipse.emf.ecore.impl.DynamicEObjectImpl;
+import org.eclipse.emf.teneo.util.FieldUtil;
+
+/**
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.9 $
+ */
+public class EcoreAccess {
+
+ /** Return the DynamicValueHolder */
+ public static DynamicValueHolder getValueHolder(BasicEObjectImpl deo) {
+ if (deo instanceof DynamicValueHolder
+ && !(deo instanceof DynamicEObjectImpl)) {
+ return (DynamicValueHolder) deo;
+ }
+ return (DynamicValueHolder) FieldUtil
+ .callMethod(deo, "eSettings", null);
+ }
+
+ /** Sets an elist using the passed feature */
+ public static void setManyEFeatureValue(EStructuralFeature eFeature,
+ Object value, BasicEObjectImpl owner) {
+ final DynamicValueHolder dvh = getValueHolder(owner);
+ dvh.dynamicSet(getFeatureId(owner, eFeature), value);
+ }
+
+ /** Gets an elist using the passed feature */
+ public static EList<?> getManyEFeatureValue(EStructuralFeature eFeature,
+ BasicEObjectImpl owner) {
+ final DynamicValueHolder dvh = getValueHolder(owner);
+ return (EList<?>) dvh.dynamicGet(getFeatureId(owner, eFeature));
+ }
+
+ public static int getFeatureId(BasicEObjectImpl owner,
+ EStructuralFeature eFeature) {
+ int featureId = owner.eClass().getFeatureID(eFeature);
+ if (!isStaticFeature(eFeature, owner)) {
+ final int staticFeatureCount = (Integer) FieldUtil.callMethod(
+ owner, "eStaticFeatureCount", null);
+ featureId = featureId - staticFeatureCount;
+ }
+ return featureId;
+ }
+
+ /** Determines if a passed feature is a static feature */
+ public static boolean isStaticFeature(EStructuralFeature eFeature,
+ BasicEObjectImpl owner) {
+ Integer staticFeatureCount = (Integer) FieldUtil.callMethod(owner,
+ "eStaticFeatureCount", null);
+ return owner.eClass().getFeatureID(eFeature) < staticFeatureCount
+ .intValue();
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/FeatureMapEntryFeatureURIPropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/FeatureMapEntryFeatureURIPropertyHandler.java
new file mode 100755
index 000000000..38c16b8b7
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/FeatureMapEntryFeatureURIPropertyHandler.java
@@ -0,0 +1,138 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: FeatureMapEntryFeatureURIPropertyHandler.java,v 1.8 2010/11/11 10:28:19 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.property;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.mapping.elist.HibernateFeatureMapEntry;
+import org.eclipse.emf.teneo.util.StoreUtil;
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+
+/**
+ * Handles the string representation of the feature of the feature map entry in
+ * the database.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.8 $
+ */
+public class FeatureMapEntryFeatureURIPropertyHandler implements Getter,
+ Setter, PropertyAccessor, ExtensionPoint {
+ /**
+ * Generated Version ID
+ */
+ private static final long serialVersionUID = 7334975651233065801L;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getGetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Getter getGetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMember()
+ */
+ public Member getMember() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getSetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Setter getSetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /**
+ * Reads the version from the versioncache
+ */
+ public Object get(Object owner) throws HibernateException {
+ if (!(owner instanceof HibernateFeatureMapEntry)) {
+ final FeatureMap.Entry smf = (FeatureMap.Entry) owner;
+ return StoreUtil.structuralFeatureToString(smf
+ .getEStructuralFeature());
+ }
+ final HibernateFeatureMapEntry fme = (HibernateFeatureMapEntry) owner;
+ return fme.getFeatureURI();
+ }
+
+ /**
+ * Reads the version from the versioncache
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getForInsert(Object owner, Map mergeMap,
+ SessionImplementor session) throws HibernateException {
+ return get(owner);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethod()
+ */
+ public Method getMethod() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethodName()
+ */
+ public String getMethodName() {
+ return null;
+ }
+
+ /** Returns Integer.class */
+ @SuppressWarnings("rawtypes")
+ public Class getReturnType() {
+ return String.class;
+ }
+
+ /** Sets the version in the internal version cache */
+ public void set(Object target, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ if (!(target instanceof HibernateFeatureMapEntry)) {
+ // do nothing as value has not change...
+ return;
+ }
+ final HibernateFeatureMapEntry fme = (HibernateFeatureMapEntry) target;
+ fme.setEStructuralFeature((String) value);
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/FeatureMapEntryPropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/FeatureMapEntryPropertyHandler.java
new file mode 100755
index 000000000..ecedba9c1
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/FeatureMapEntryPropertyHandler.java
@@ -0,0 +1,177 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: FeatureMapEntryPropertyHandler.java,v 1.9 2010/11/11 10:28:19 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.property;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.mapping.elist.HibernateFeatureMapEntry;
+import org.eclipse.emf.teneo.util.StoreUtil;
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+
+/**
+ * Implements the getter/setter for the featuremap entry.
+ *
+ * This class implements both the getter, setter and propertyaccessor
+ * interfaces. When the getGetter and getSetter methods are called it returns
+ * itself.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.9 $
+ */
+public class FeatureMapEntryPropertyHandler implements Getter, Setter,
+ PropertyAccessor, ExtensionPoint {
+
+ /**
+ * Generated Version ID
+ */
+ private static final long serialVersionUID = -2659637883475733107L;
+
+ /** The logger */
+ private static Log log = LogFactory
+ .getLog(FeatureMapEntryPropertyHandler.class);
+
+ /** The feature */
+ protected EStructuralFeature eFeature;
+
+ /** Constructor */
+ public void initialize(EStructuralFeature eFeature) {
+ this.eFeature = eFeature;
+ log.debug("Created getter/setter for " + StoreUtil.toString(eFeature));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getGetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Getter getGetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getSetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Setter getSetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMember()
+ */
+ public Member getMember() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#get(java.lang.Object)
+ */
+ public Object get(Object owner) throws HibernateException {
+ if (!(owner instanceof HibernateFeatureMapEntry)) {
+ final FeatureMap.Entry smf = (FeatureMap.Entry) owner;
+ if (smf.getEStructuralFeature() == eFeature) {
+ return smf.getValue();
+ } else {
+ return null;
+ }
+ }
+ final HibernateFeatureMapEntry fme = (HibernateFeatureMapEntry) owner;
+ final Object value = fme.getValue(eFeature);
+ return value;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getForInsert(java.lang.Object,
+ * java.util.Map, org.hibernate.engine.SessionImplementor)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getForInsert(Object owner, Map mergeMap,
+ SessionImplementor session) throws HibernateException {
+ final Object value = get(owner);
+ return value;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Setter#set(java.lang.Object,
+ * java.lang.Object, org.hibernate.engine.SessionFactoryImplementor)
+ */
+ public void set(Object target, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ if (!(target instanceof HibernateFeatureMapEntry)) {
+ // happens during initial save, value has not changed do nothing!
+ return;
+ }
+ final HibernateFeatureMapEntry fme = (HibernateFeatureMapEntry) target;
+ fme.addFeatureValue(eFeature, value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethod()
+ */
+ public Method getMethod() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethodName()
+ */
+ public String getMethodName() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getReturnType()
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getReturnType() {
+ return HibernateFeatureMapEntry.class;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/FeatureMapPropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/FeatureMapPropertyHandler.java
new file mode 100755
index 000000000..af222c751
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/FeatureMapPropertyHandler.java
@@ -0,0 +1,76 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: FeatureMapPropertyHandler.java,v 1.10 2010/02/04 10:53:07 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.property;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.ecore.util.FeatureMapUtil;
+import org.eclipse.emf.teneo.extension.ExtensionManagerAware;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.mapping.elist.HibernateFeatureMapEntry;
+import org.eclipse.emf.teneo.hibernate.mapping.elist.HibernatePersistableFeatureMap;
+import org.eclipse.emf.teneo.util.AssertUtil;
+import org.eclipse.emf.teneo.util.StoreUtil;
+
+/**
+ * Implements the accessor for EMF FeatureMap members for Hibernate. Overrides the createPersistableList to create a
+ * HibernatePersistableFeatureMap instead of a normal list.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.10 $
+ */
+@SuppressWarnings("unchecked")
+public class FeatureMapPropertyHandler extends EListPropertyHandler implements ExtensionPoint, ExtensionManagerAware {
+ /**
+ * Generated Serial Version ID
+ */
+ private static final long serialVersionUID = -5220024660708935714L;
+
+ /** Initialize this instance */
+ public void initialize(EStructuralFeature eFeature) {
+ super.initialize(eFeature, false, false);
+ AssertUtil.assertTrue("Is not a featuremap feature " + StoreUtil.toString(eFeature), FeatureMapUtil
+ .isFeatureMap(eFeature));
+ }
+
+ /** Create method can be overridden */
+ @SuppressWarnings("rawtypes")
+ @Override
+ protected EList<?> createPersistableList(InternalEObject target, EStructuralFeature estruct, List list) {
+ return new HibernatePersistableFeatureMap(target, estruct, list);
+ }
+
+ // replaces all entries in a featuremap with a persistable one
+ @Override
+ protected List<Object> processList(Object list) {
+ final List<Object> result = new ArrayList<Object>();
+
+ final FeatureMap featureMap = (FeatureMap) list;
+ for (FeatureMap.Entry entry : featureMap) {
+ final HibernateFeatureMapEntry fme = new HibernateFeatureMapEntry();
+ fme.setFeatureValue(entry.getEStructuralFeature(), entry.getValue(), (FeatureMap.Internal) list);
+ result.add(fme);
+ }
+ return result;
+ }
+
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/SyntheticPropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/SyntheticPropertyHandler.java
new file mode 100644
index 000000000..63a9270f7
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/SyntheticPropertyHandler.java
@@ -0,0 +1,161 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: SyntheticPropertyHandler.java,v 1.5 2010/11/11 10:28:19 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.property;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.teneo.type.PersistentStoreAdapter;
+import org.eclipse.emf.teneo.util.StoreUtil;
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+
+/**
+ * Is a getter and setter for EMF eattribute which uses eGet and eSet.Handles
+ * many==false properties.
+ *
+ * This class implements both the getter, setter and propertyaccessor
+ * interfaces. When the getGetter and getSetter methods are called it returns
+ * itself.
+ *
+ * This accessor also handles arrays of primitive types.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.5 $
+ */
+public class SyntheticPropertyHandler implements Getter, Setter,
+ PropertyAccessor {
+
+ /**
+ * Generated Serial Version ID
+ */
+ private static final long serialVersionUID = 8953817672640618007L;
+
+ // private static Log log =
+ // LogFactory.getLog(SyntheticPropertyHandler.class);
+
+ private String propertyName;
+
+ /** Constructor */
+ public SyntheticPropertyHandler(String propertyName) {
+ this.propertyName = propertyName;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getGetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Getter getGetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMember()
+ */
+ public Member getMember() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getSetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Setter getSetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#get(java.lang.Object)
+ */
+ public Object get(Object owner) throws HibernateException {
+ final PersistentStoreAdapter adapter = StoreUtil
+ .getPersistentStoreAdapter((EObject) owner);
+ return adapter.getSyntheticProperty(propertyName);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getForInsert(java.lang.Object,
+ * java.util.Map, org.hibernate.engine.SessionImplementor)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getForInsert(Object arg0, Map arg1, SessionImplementor arg2)
+ throws HibernateException {
+ return get(arg0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethod()
+ */
+ public Method getMethod() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethodName()
+ */
+ public String getMethodName() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getReturnType()
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getReturnType() {
+ return Object.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Setter#set(java.lang.Object,
+ * java.lang.Object, org.hibernate.engine.SessionFactoryImplementor)
+ */
+ public void set(Object target, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ final PersistentStoreAdapter adapter = StoreUtil
+ .getPersistentStoreAdapter((EObject) target);
+ adapter.setSyntheticProperty(propertyName, value);
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/VersionPropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/VersionPropertyHandler.java
new file mode 100755
index 000000000..f9c21f4c3
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/VersionPropertyHandler.java
@@ -0,0 +1,124 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: VersionPropertyHandler.java,v 1.8 2010/11/11 10:28:18 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.property;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierCacheHandler;
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+
+/**
+ * Reads the version from the internal version cache.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.8 $
+ */
+public class VersionPropertyHandler implements Getter, Setter,
+ PropertyAccessor, ExtensionPoint {
+ /**
+ * Generated Serial Version ID
+ */
+ private static final long serialVersionUID = -7004553329654520847L;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getGetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Getter getGetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getSetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Setter getSetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /**
+ * Reads the version from the versioncache
+ */
+ public Object get(Object owner) throws HibernateException {
+ return IdentifierCacheHandler.getInstance().getVersion(owner);
+ }
+
+ /**
+ * Reads the version from the versioncache
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getForInsert(Object owner, Map mergeMap,
+ SessionImplementor session) throws HibernateException {
+ return IdentifierCacheHandler.getInstance().getVersion(owner);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMember()
+ */
+ public Member getMember() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethod()
+ */
+ public Method getMethod() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethodName()
+ */
+ public String getMethodName() {
+ return null;
+ }
+
+ /** Returns Integer.class */
+ @SuppressWarnings("rawtypes")
+ public Class getReturnType() {
+ return Integer.class;
+ }
+
+ /** Sets the version in the internal version cache */
+ public void set(Object target, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ IdentifierCacheHandler.getInstance().setVersion(target, value);
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/WildCardAttributePropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/WildCardAttributePropertyHandler.java
new file mode 100644
index 000000000..196fcae57
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/WildCardAttributePropertyHandler.java
@@ -0,0 +1,180 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: WildCardAttributePropertyHandler.java,v 1.3 2010/11/11 10:28:19 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.property;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.mapping.elist.HibernateFeatureMapEntry;
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+
+/**
+ * Implements the getter/setter for a wild card EAttribute property. This type
+ * of property is used in a feature map created for wild cards.
+ *
+ * This class implements both the getter, setter and propertyaccessor
+ * interfaces. When the getGetter and getSetter methods are called it returns
+ * itself.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.3 $
+ */
+public class WildCardAttributePropertyHandler implements Getter, Setter,
+ PropertyAccessor, ExtensionPoint {
+
+ /**
+ * Generated Version ID
+ */
+ private static final long serialVersionUID = -2659637883475733107L;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getGetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Getter getGetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getSetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Setter getSetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#get(java.lang.Object)
+ */
+ public Object get(Object owner) throws HibernateException {
+ final Object value;
+ final EStructuralFeature eFeature;
+ if (!(owner instanceof HibernateFeatureMapEntry)) {
+ final FeatureMap.Entry fme = (FeatureMap.Entry) owner;
+ value = fme.getValue();
+ eFeature = fme.getEStructuralFeature();
+ } else {
+ final HibernateFeatureMapEntry fme = (HibernateFeatureMapEntry) owner;
+ value = fme.getValue();
+ eFeature = fme.getEStructuralFeature();
+ }
+ // not handled by this one
+ if (value instanceof EObject) {
+ return null;
+ }
+ if (value == null) {
+ return null;
+ }
+ final EAttribute eAttribute = (EAttribute) eFeature;
+ final EDataType eDataType = eAttribute.getEAttributeType();
+ final String valueString = eDataType.getEPackage()
+ .getEFactoryInstance().convertToString(eDataType, value);
+ return valueString;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getForInsert(java.lang.Object,
+ * java.util.Map, org.hibernate.engine.SessionImplementor)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getForInsert(Object owner, Map mergeMap,
+ SessionImplementor session) throws HibernateException {
+ final Object value = get(owner);
+ return value;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMember()
+ */
+ public Member getMember() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Setter#set(java.lang.Object,
+ * java.lang.Object, org.hibernate.engine.SessionFactoryImplementor)
+ */
+ public void set(Object target, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ if (!(target instanceof HibernateFeatureMapEntry)) {
+ // happens during initial save
+ return;
+ }
+ final HibernateFeatureMapEntry fme = (HibernateFeatureMapEntry) target;
+ if (value != null && !(value instanceof EObject)) {
+ // will be converted inside the HibernateFeatureMapEntry
+ fme.setValue(value);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethod()
+ */
+ public Method getMethod() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethodName()
+ */
+ public String getMethodName() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getReturnType()
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getReturnType() {
+ return EObject.class;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/WildCardReferencePropertyHandler.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/WildCardReferencePropertyHandler.java
new file mode 100644
index 000000000..9be9862eb
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/property/WildCardReferencePropertyHandler.java
@@ -0,0 +1,166 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: WildCardReferencePropertyHandler.java,v 1.3 2010/11/11 10:28:18 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.property;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.mapping.elist.HibernateFeatureMapEntry;
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+
+/**
+ * Implements the getter/setter for a wild card reference property. This type of
+ * property is used in a feature map created for wild cards.
+ *
+ * This class implements both the getter, setter and propertyaccessor
+ * interfaces. When the getGetter and getSetter methods are called it returns
+ * itself.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.3 $
+ */
+public class WildCardReferencePropertyHandler implements Getter, Setter,
+ PropertyAccessor, ExtensionPoint {
+
+ /**
+ * Generated Version ID
+ */
+ private static final long serialVersionUID = -2659637883475733107L;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getGetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Getter getGetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.PropertyAccessor#getSetter(java.lang.Class,
+ * java.lang.String)
+ */
+ @SuppressWarnings("rawtypes")
+ public Setter getSetter(Class theClass, String propertyName)
+ throws PropertyNotFoundException {
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMember()
+ */
+ public Member getMember() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#get(java.lang.Object)
+ */
+ public Object get(Object owner) throws HibernateException {
+ Object value = null;
+ if (!(owner instanceof HibernateFeatureMapEntry)) {
+ value = ((FeatureMap.Entry) owner).getValue();
+ } else {
+ final HibernateFeatureMapEntry fme = (HibernateFeatureMapEntry) owner;
+ value = fme.getValue();
+ }
+ // handled by this one
+ if (value instanceof EObject) {
+ return value;
+ }
+ // are handled by other property handler
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getForInsert(java.lang.Object,
+ * java.util.Map, org.hibernate.engine.SessionImplementor)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getForInsert(Object owner, Map mergeMap,
+ SessionImplementor session) throws HibernateException {
+ final Object value = get(owner);
+ return value;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Setter#set(java.lang.Object,
+ * java.lang.Object, org.hibernate.engine.SessionFactoryImplementor)
+ */
+ public void set(Object target, Object value,
+ SessionFactoryImplementor factory) throws HibernateException {
+ if (!(target instanceof HibernateFeatureMapEntry)) {
+ // happens during initial save, value has not changed do nothing
+ return;
+ }
+ final HibernateFeatureMapEntry fme = (HibernateFeatureMapEntry) target;
+ if (value != null && value instanceof EObject) {
+ fme.setValue(value);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethod()
+ */
+ public Method getMethod() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getMethodName()
+ */
+ public String getMethodName() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.property.Getter#getReturnType()
+ */
+ @SuppressWarnings("rawtypes")
+ public Class getReturnType() {
+ return EObject.class;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HbResource.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HbResource.java
new file mode 100755
index 000000000..31d1ca7c4
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HbResource.java
@@ -0,0 +1,47 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HbResource.java,v 1.5 2008/02/28 07:08:24 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.resource;
+
+import org.eclipse.emf.teneo.hibernate.SessionWrapper;
+import org.hibernate.Session;
+
+/**
+ * Defines the common interface for HbResource Impls.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.5 $
+ */
+
+public interface HbResource {
+
+ /**
+ * Returns the session of the resource.
+ */
+ Session getSession();
+
+ /** Returns the session to the resource so that it can do clean up (or not) */
+ void returnSession(Session session);
+
+ /** Set isloading on the resource */
+ void setIsLoading(boolean isLoading);
+
+ /** Return the sessionwrapper */
+ public SessionWrapper getSessionWrapper();
+
+ /** Returns the sessionwrapper to the resource so that it can do clean up (or not) */
+ void returnSessionWrapper(SessionWrapper sessionWrapper);
+}
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HbResourceImpl.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HbResourceImpl.java
new file mode 100755
index 000000000..3ccbece35
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HbResourceImpl.java
@@ -0,0 +1,392 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HbResourceImpl.java,v 1.12 2011/02/21 05:06:13 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.resource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.URIConverter;
+import org.eclipse.emf.teneo.Constants;
+import org.eclipse.emf.teneo.hibernate.EMFInterceptor;
+import org.eclipse.emf.teneo.hibernate.HbConstants;
+import org.eclipse.emf.teneo.hibernate.HbDataStore;
+import org.eclipse.emf.teneo.hibernate.HbHelper;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.HbSessionWrapper;
+import org.eclipse.emf.teneo.hibernate.HbUtil;
+import org.eclipse.emf.teneo.hibernate.SessionWrapper;
+import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierUtil;
+import org.eclipse.emf.teneo.resource.StoreResource;
+import org.hibernate.FlushMode;
+import org.hibernate.LockOptions;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.util.IdentityMap;
+
+/**
+ * HbResource. This hibernate resource creates a new session for each load and
+ * save action. When elists are lazily loaded then a new Session is created and
+ * the current content is added to the session.
+ *
+ * When you create a HbDataStore through the appropriate method in the HbHelper
+ * class. The name you passed there can be used as a parameter in the uri used
+ * to create this resource (using the parameter pmfname). The uri is then:
+ * hibernate://?dsname=myemf.
+ *
+ * Another simple trick which is used to fool emf a bit is that the extension of
+ * the uri can also be used to init a hibernate resource!
+ *
+ * WARNING: This is an untested and experimental class, it is not intended to be
+ * used in production situations.
+ *
+ * This class does not support the SessionController.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.12 $
+ */
+
+public class HbResourceImpl extends StoreResource implements HbResource {
+ /** The logger */
+ private static Log log = LogFactory.getLog(HbResourceImpl.class);
+
+ /** This threadlocal can be used by lazy loaders to store a session */
+ // public static final ThreadLocal threadSession = new ThreadLocal();
+ /** The store used to determine where to query for the data */
+ protected HbDataStore emfDataStore;
+
+ /**
+ * The constructor, gets an uri and retrieves the backing OJBStore
+ */
+ public HbResourceImpl(URI uri) {
+ super(uri);
+
+ log.debug("Creating hibernateresource using uri: " + uri.toString());
+
+ final Map<String, String> params = decodeQueryString(uri.query());
+
+ String emfdsName = null;
+ if (uri.query() == null && uri.fileExtension() != null) // this is
+ // probably a
+ // platform uri!
+ {
+ if (HbConstants.EHB_FILE_EXTENSION.compareTo(uri.fileExtension()) == 0) {
+ log.debug("Assuming this is a property file " + uri.toString());
+ try {
+ final URIConverter uriConverter = getURIConverter();
+ final InputStream is = uriConverter.createInputStream(uri);
+ final Properties props = new Properties();
+ props.load(is);
+ is.close();
+ emfdsName = props.getProperty(Constants.PROP_NAME);
+ emfDataStore = HbUtil.getCreateDataStore(props);
+ setDefinedQueries(getQueries(props));
+ } catch (IOException e) {
+ throw new HbMapperException(
+ "Exception when reading properties from: "
+ + uri.toString(), e);
+ }
+ } else {
+ log.debug("Trying fileextension: " + uri.fileExtension());
+ // then try the extension of the resource
+ emfdsName = uri.fileExtension();
+ }
+ } else if (params.get(DS_NAME_PARAM) != null) // only the name
+ {
+ emfdsName = getParam(params, DS_NAME_PARAM, uri.query());
+ setDefinedQueries(getQueries(params));
+ }
+
+ if (emfdsName == null) {
+ throw new HbMapperException(
+ "The Resource can not be initialized using the querystring: "
+ + uri.query()
+ + ". Are all the required parameters present?");
+ }
+ log.debug("Looking for emf data store using " + emfdsName);
+
+ emfDataStore = HbHelper.INSTANCE.getDataStore(emfdsName);
+
+ super.init(emfDataStore.getTopEntities());
+ }
+
+ /** Returns the emfdatastore */
+ public HbDataStore getEMFDataStore() {
+ return emfDataStore;
+ }
+
+ /**
+ * Creates the session of this resource. As a default the FlushMode is set
+ * to Never. The loaded objects of this resource are merged into the
+ * session. It is the responsibility of the caller to close the session or
+ * call the returnSession method here.
+ */
+ public Session getSession() {
+ if (log.isDebugEnabled()) {
+ log.debug("Creating session");
+ }
+ final SessionFactory sessionFactory = emfDataStore.getSessionFactory();
+ final Session session = sessionFactory.openSession();
+ session.setFlushMode(FlushMode.MANUAL);
+
+ if (loadedEObjects.size() > 0) {
+ session.beginTransaction();
+
+ // merge the loaded objects into the session
+ if (log.isDebugEnabled()) {
+ log.debug("Merging " + loadedEObjects.size()
+ + " eobjects into new session ");
+ }
+ for (Object obj : loadedEObjects) {
+ session.buildLockRequest(LockOptions.NONE).lock(obj);
+ }
+ session.getTransaction().commit();
+ }
+
+ return session;
+ }
+
+ /** Return a sessionwrapper */
+ public SessionWrapper getSessionWrapper() {
+ return new HbSessionWrapper(getEMFDataStore(), getSession());
+ }
+
+ /**
+ * Returns the sessionwrapper to the resource so that it can do clean up (or
+ * not)
+ */
+ public void returnSessionWrapper(SessionWrapper sessionWrapper) {
+ returnSession(sessionWrapper.getHibernateSession());
+ }
+
+ /** Returns the session, closes it */
+ public void returnSession(Session theSession) {
+ // solves a bug with older versions of Hibernate, see the EMFInterceptor
+ Map.Entry<?, ?>[] collectionEntryArray = IdentityMap
+ .concurrentEntries(((SessionImplementor) theSession)
+ .getPersistenceContext().getCollectionEntries());
+ for (Entry<?, ?> element : collectionEntryArray) {
+ ((PersistentCollection) element.getKey())
+ .unsetSession((SessionImplementor) theSession);
+ }
+
+ theSession.close();
+ }
+
+ /**
+ * Returns an array of EObjects which refer to a certain EObject, note if
+ * the array is of length zero then no refering EObjects where found.
+ */
+ @Override
+ public Object[] getCrossReferencers(EObject referedTo) {
+ Transaction tx = null;
+ boolean err = true;
+ final Session mySession = getSession();
+ try {
+ tx = mySession.beginTransaction();
+ final Object[] result = emfDataStore.getCrossReferencers(mySession,
+ referedTo);
+ err = false;
+
+ return result;
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ throw new HbMapperException(
+ "Exception when doing cross reference search "
+ + emfDataStore.getName(), e);
+ } finally {
+ if (err) {
+ if (tx != null) {
+ tx.rollback();
+ }
+ mySession.close();
+ } else {
+ tx.commit();
+ }
+ }
+ }
+
+ /**
+ * Saves the changed objects or removes the detached objects from this
+ * resource.
+ */
+ @Override
+ protected void saveResource(Map<?, ?> options) {
+ log.debug("Saving resource with uri: " + getURI());
+
+ boolean err = true;
+ Transaction tx = null;
+ final Session mySession = getSession();
+ try {
+ tx = mySession.beginTransaction();
+
+ final List<EObject> list = super.getContents();
+ for (int i = 0; i < list.size(); i++) {
+ final Object obj = list.get(i);
+ // if (IdentifierCacheHandler.getInstance().getID(obj) == null)
+ // // new object
+ // {
+ mySession.saveOrUpdate(obj);
+ // }
+ // else do nothing because hibernate does this automatically??
+ }
+
+ // delete all deleted objects
+ for (Object obj : removedEObjects) {
+ if (IdentifierUtil.getID(obj, (SessionImplementor) mySession) != null) // persisted
+ // object
+ {
+ mySession.delete(obj);
+ EMFInterceptor
+ .registerCollectionsForDereferencing((EObject) obj);
+ }
+ }
+
+ // now flush everything
+ mySession.flush();
+ err = false;
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ throw new HbMapperException("Exception when saving resource "
+ + emfDataStore.getName(), e);
+ } finally {
+ if (err) {
+ if (tx != null) {
+ tx.rollback();
+ }
+ } else {
+ tx.commit();
+ }
+ returnSession(mySession);
+ }
+ }
+
+ /**
+ * Loads all the objects in the global list
+ */
+ @Override
+ protected List<EObject> loadResource(Map<?, ?> options) {
+ log.debug("Loading resource: " + getURI().toString());
+
+ // first clear the old list
+ Transaction tx = null;
+ boolean err = true;
+ final Session mySession = getSession();
+ try {
+ tx = mySession.beginTransaction();
+
+ // note we have to a call to the super class otherwise an infinite
+ // loop is created
+ final List<EObject> storeList = loadFromStore(mySession);
+ log.debug("Loaded " + storeList.size() + " objects");
+ err = false;
+ return storeList;
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ throw new HbMapperException("Exception when saving resource "
+ + emfDataStore.getName(), e);
+ } finally {
+ if (err) {
+ if (tx != null) {
+ tx.rollback();
+ }
+ } else {
+ tx.commit();
+ }
+ returnSession(mySession);
+ }
+ }
+
+ /**
+ * Rollsback the transaction if any and clears different lists to start with
+ * an empty resource again. Note that the super.dounload is not called
+ * because that clears the list resulting in all kinds of undesirable
+ * inverseremoves.
+ */
+ @Override
+ protected void doUnload() {
+ super.doUnload();
+ }
+
+ /**
+ * This method can be overridden to implement specific load behavior. Note
+ * that a transaction has already been started. The session is passed as a
+ * parameter, this is the same session which can be retrieved using the
+ * getSession method. The read objects should be returned in the list. Note
+ * that after this call the retrieved objects are put in the resource
+ * content.
+ */
+ protected List<EObject> loadFromStore(Session sess) {
+ if (definedQueriesPresent()) {
+ return loadUsingDefinedQueries(sess);
+ } else {
+ return loadUsingTopClasses(sess);
+ }
+ }
+
+ /** Reads data based on the topclasses list */
+ private ArrayList<EObject> loadUsingTopClasses(Session sess) {
+ log.debug("Loading resource " + getURI() + " using top classes");
+ final ArrayList<EObject> readObjects = new ArrayList<EObject>();
+ for (final String topClassName : topClassNames) {
+ log.debug("Loading objects using hql: FROM " + topClassName);
+
+ final Query qry = sess.createQuery("FROM " + topClassName);
+ final Iterator<?> it = qry.list().iterator();
+ while (it.hasNext()) {
+ final EObject eobj = (EObject) it.next();
+ // extra check on container because sometimes contained items
+ // are still read in
+ // case of multiple inheritance
+ if (eobj.eContainer() == null) {
+ readObjects.add(eobj);
+ }
+ }
+ }
+ return readObjects;
+ }
+
+ /** Reads data based using defined queries */
+ private ArrayList<EObject> loadUsingDefinedQueries(Session sess) {
+ log.debug("Loading resource " + getURI() + " using defined queries");
+ final ArrayList<EObject> readObjects = new ArrayList<EObject>();
+ final String[] qrys = getDefinedQueries();
+ for (String element : qrys) {
+ final Query qry = sess.createQuery(element);
+ log.debug("Loading objects using hql: " + element);
+ final Iterator<?> it = qry.list().iterator();
+ while (it.hasNext()) {
+ final Object obj = it.next();
+ readObjects.add((EObject) obj);
+ }
+ }
+ return readObjects;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateResource.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateResource.java
new file mode 100755
index 000000000..2b1b7000a
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateResource.java
@@ -0,0 +1,713 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008, 2011 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HibernateResource.java,v 1.29 2011/02/21 05:23:20 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.resource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.URIConverter;
+import org.eclipse.emf.teneo.hibernate.EMFInterceptor;
+import org.eclipse.emf.teneo.hibernate.HbDataStore;
+import org.eclipse.emf.teneo.hibernate.HbHelper;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.HbSessionWrapper;
+import org.eclipse.emf.teneo.hibernate.HbUtil;
+import org.eclipse.emf.teneo.hibernate.SessionWrapper;
+import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierCacheHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierUtil;
+import org.eclipse.emf.teneo.resource.StoreResource;
+import org.eclipse.emf.teneo.util.AssertUtil;
+import org.hibernate.Criteria;
+import org.hibernate.Session;
+import org.hibernate.criterion.Restrictions;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.impl.SessionImpl;
+import org.hibernate.metadata.ClassMetadata;
+
+/**
+ * Hibernate Resource. The hibernate resource has a Session during its lifetime.
+ * A transaction is started before the load and it is stopped just after the
+ * save. The session is disconnected and reconnected when loading and saving.
+ *
+ * When you create a HbDataStore through the appropriate method in the
+ * HibernateHelper class. The name you passed there can be used as a parameter
+ * in the uri used to create this resource (using the parameter pmfname). The
+ * uri is then: hibernate://?dsname=myemf.
+ *
+ * Another simple trick which is used to fool emf a bit is that the extension of
+ * the uri can also be used to init a hibernate resource!
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.29 $
+ */
+
+public class HibernateResource extends StoreResource implements HbResource {
+ /** The logger */
+ private static Log log = LogFactory.getLog(HibernateResource.class);
+
+ /** The fragment separator */
+ private static String SEPARATOR = "|";
+
+ /** The store used to determine where to query for the data */
+ protected HbDataStore emfDataStore;
+
+ /** The uri parameter under which to store a session controller */
+ public static String SESSION_CONTROLLER_PARAM = "sessionController";
+
+ /** The session wrapper used for long transactions */
+ protected SessionWrapper sessionWrapper = null; // is opened at first load
+
+ /** The session controller */
+ protected SessionController sessionController = null;
+
+ /** Is set to true if there is a sessionController */
+ private boolean hasSessionController = false;
+
+ /**
+ * The constructor, gets an uri and retrieves the backing OJBStore
+ */
+ public HibernateResource(URI uri) {
+ super(uri);
+
+ log.debug("Creating hibernateresource using uri: " + uri.toString());
+
+ final Map<String, String> params = decodeQueryString(uri.query());
+
+ if (params.get(DS_NAME_PARAM) != null) { // only the name
+ setDefinedQueries(getQueries(params));
+ emfDataStore = HbHelper.INSTANCE.getDataStore(getParam(params,
+ DS_NAME_PARAM, uri.query()));
+ } else if (params.get(SESSION_CONTROLLER_PARAM) != null) {
+
+ setDefinedQueries(getQueries(params));
+
+ final String scName = getParam(params, SESSION_CONTROLLER_PARAM,
+ uri.query());
+ sessionController = SessionController.getSessionController(scName);
+ log.debug("Using session controller " + scName);
+ emfDataStore = sessionController.getHbDataStore();
+ hasSessionController = true;
+ } else if (uri.fileExtension() != null) // this is probably a platform
+ // uri!
+ {
+ log.debug("Trying fileextension: " + uri.fileExtension());
+ // then try the extension of the resource
+ emfDataStore = HbHelper.INSTANCE.getDataStore(uri.fileExtension());
+
+ // if null then assume that this is a properties file
+ if (emfDataStore == null) {
+ log.debug("No datastore defined for extension, assuming this is a property file "
+ + uri.toString());
+ try {
+ final URIConverter uriConverter = getURIConverter();
+ final InputStream is = uriConverter.createInputStream(uri);
+ final Properties props = new Properties();
+ props.load(is);
+ is.close();
+ emfDataStore = HbUtil.getCreateDataStore(props);
+ setDefinedQueries(getQueries(props));
+ } catch (IOException e) {
+ throw new HbMapperException(
+ "Exception when reading properties from: "
+ + uri.toString(), e);
+ }
+ }
+ }
+ if (emfDataStore == null) {
+ throw new HbMapperException(
+ "No HbDataStore can be found using the uri "
+ + uri.toString());
+ }
+ log.debug("Using emf data store using " + emfDataStore.getName());
+ super.init(emfDataStore.getTopEntities());
+ }
+
+ /** Returns the emfdatastore */
+ public HbDataStore getEMFDataStore() {
+ return emfDataStore;
+ }
+
+ /**
+ * Returns the session of this resource, if no session is set yet then
+ * creates it using the datastore. As a default the FlushMode is set to
+ * Never.
+ *
+ * Deprecated, use getSessionWrapper (to support ejb3)
+ */
+ @Deprecated
+ public Session getSession() {
+ return (Session) getSessionWrapper().getSession();
+ }
+
+ /** Return the sessionwrapper */
+ public SessionWrapper getSessionWrapper() {
+ if (sessionWrapper == null) {
+ if (hasSessionController) {
+ sessionWrapper = sessionController.getSessionWrapper();
+ } else {
+ // session can be null when this is an xml import! ;
+ sessionWrapper = emfDataStore.createSessionWrapper();
+ sessionWrapper.setFlushModeManual();
+ }
+ }
+ return sessionWrapper;
+ }
+
+ /**
+ * Sets the session, overwrites current session. Deprecated use
+ * setSessionWrapper.
+ */
+ @Deprecated
+ public void setSession(Session session) {
+ if (session != null) {
+ this.sessionWrapper = new HbSessionWrapper(emfDataStore, session);
+ } else {
+ this.sessionWrapper = null;
+ }
+ }
+
+ /**
+ * Unpacks the id string and reads an object from the db, note for each read
+ * a transaction is opened, unless the session is controlled by the caller.
+ *
+ * @see org.eclipse.emf.ecore.resource.impl.ResourceImpl#getEObjectByID(java.lang.String)
+ */
+ @Override
+ protected EObject getEObjectByID(String id) {
+ // try to find the different parts of the id
+ if (id == null) {
+ return super.getEObjectByID(id);
+ }
+ if (getIntrinsicIDToEObjectMap() != null) {
+ final EObject firstCheck = getIntrinsicIDToEObjectMap().get(id);
+ if (firstCheck != null) {
+ return firstCheck;
+ }
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Reading eobject using urifragment " + id);
+ }
+ final String[] parts = id.split("\\" + SEPARATOR);
+
+ if (parts.length != 2) {
+ if (log.isDebugEnabled()) {
+ log.debug("Not a valid urifragment (" + id
+ + ") for the hibernate resource, trying the superclass");
+ }
+ return super.getEObjectByID(id);
+ }
+
+ // build a query
+ final EClass eclass = emfDataStore.getEntityNameStrategy().toEClass(
+ parts[0]);
+ final int splitIndex = parts[1].indexOf("=");
+ if (splitIndex == -1) {
+ if (log.isDebugEnabled()) {
+ log.debug("Not a valid urifragment (" + id
+ + ") for the hibernate resource, trying the superclass");
+ }
+ return super.getEObjectByID(id);
+ }
+ final String idStr = parts[1].substring(1 + splitIndex);
+
+ // try to find the object using the id-part
+ final EObject eObject = super.getEObjectByID(idStr);
+ if (eObject != null) {
+ return eObject;
+ }
+
+ final boolean oldLoading = isLoading();
+ boolean err = true;
+ try {
+ setIsLoading(true);
+ if (!hasSessionController) {
+ getSessionWrapper().beginTransaction();
+ }
+
+ final Object result = getSessionWrapper().get(
+ parts[0],
+ (Serializable) HbUtil.stringToId(eclass, emfDataStore,
+ idStr));
+ if (result == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Object not found in the db, trying the parent");
+ }
+ err = false;
+ return super.getEObjectByID(id);
+ }
+ final InternalEObject internalEObject = (InternalEObject) result;
+ // only add if not yet part of a resource
+ if (internalEObject.eResource() == null) {
+ addUsingContainmentStructure((InternalEObject) result);
+ }
+ err = false;
+ return (EObject) result;
+ } finally {
+ setIsLoading(oldLoading);
+ if (!hasSessionController) {
+ if (err) {
+ getSessionWrapper().rollbackTransaction();
+ getSessionWrapper().close();
+ } else {
+ getSessionWrapper().commitTransaction();
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates a unique id string from the eobject. The id string will contain a
+ * link to the type (eclass) and the string version of the id itself. This
+ * method assumes that the id can be converted from and to a string!
+ *
+ * @see org.eclipse.emf.ecore.resource.impl.ResourceImpl#getURIFragment(org.eclipse.emf.ecore.EObject)
+ */
+ @Override
+ public String getURIFragment(EObject object) {
+ if (object == null) {
+ return null;
+ }
+ final String theId = HbUtil.idToString(object, emfDataStore);
+ if (theId == null) {
+ return super.getURIFragment(object);
+ }
+ final StringBuffer idStr = new StringBuffer();
+ idStr.append(emfDataStore.getEntityNameStrategy().toEntityName(
+ object.eClass()));
+ idStr.append(SEPARATOR);
+ idStr.append("id=" + theId);
+ return idStr.toString();
+ }
+
+ /**
+ * Sets the sessionwrapper, overwrites current session.
+ */
+ public void setSessionWrapper(SessionWrapper sessionWrapper) {
+ this.sessionWrapper = sessionWrapper;
+ }
+
+ /** Returns the session, does nothing in this impl */
+ public void returnSession(Session theSession) {
+ // do nothing
+ }
+
+ /**
+ * Returns the sessionwrapper to the resource so that it can do clean up (or
+ * not)
+ */
+ public void returnSessionWrapper(SessionWrapper sessionWrapper) {
+
+ }
+
+ /**
+ * Returns an array of EObjects which refer to a certain EObject, note if
+ * the array is of length zero then no refering EObjects where found.
+ */
+ @Override
+ public Object[] getCrossReferencers(EObject referedTo) {
+ boolean err = true;
+ final SessionWrapper mySessionWrapper = getSessionWrapper();
+ try {
+ if (!hasSessionController) {
+ mySessionWrapper.beginTransaction();
+ }
+ final Object[] result = emfDataStore.getCrossReferencers(
+ mySessionWrapper, referedTo);
+ err = false;
+
+ return result;
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ throw new HbMapperException(
+ "Exception when doing cross reference search "
+ + emfDataStore.getName(), e);
+ } finally {
+ if (!hasSessionController) {
+ if (err) {
+ mySessionWrapper.rollbackTransaction();
+ mySessionWrapper.close();
+ } else {
+ mySessionWrapper.commitTransaction();
+ }
+ }
+ }
+ }
+
+ /**
+ * Saves the changed objects or removes the detached objects from this
+ * resource.
+ */
+ @Override
+ protected void saveResource(Map<?, ?> options) {
+ log.debug("Saving resource with uri: " + getURI());
+
+ boolean err = true;
+ final SessionWrapper mySessionWrapper = getSessionWrapper();
+ try {
+ if (!hasSessionController) {
+ mySessionWrapper.beginTransaction();
+ }
+
+ for (EObject eobject : super.getContents()) {
+ mySessionWrapper.saveOrUpdate(eobject);
+ }
+
+ // delete all deleted objects
+ for (Object obj : removedEObjects) {
+ final InternalEObject eobj = (InternalEObject) obj;
+ if (eobj.eResource() != null && eobj.eResource() != this) {
+ continue;
+ }
+
+ if (IdentifierUtil.getID(obj,
+ (SessionImplementor) mySessionWrapper
+ .getHibernateSession()) != null) // persisted
+ // object
+ {
+ if (eobj.eDirectResource() == null
+ || eobj.eDirectResource() == this) {
+ mySessionWrapper.delete(obj);
+ EMFInterceptor
+ .registerCollectionsForDereferencing((EObject) obj);
+ }
+ }
+ }
+
+ // now flush everything
+ if (!hasSessionController) {
+ mySessionWrapper.flush();
+ }
+
+ err = false;
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ throw new HbMapperException("Exception when saving resource "
+ + emfDataStore.getName(), e);
+ } finally {
+ if (!hasSessionController) {
+ if (err) {
+ beforeSaveRollback();
+ mySessionWrapper.rollbackTransaction();
+ afterSaveRollback();
+ // see bugzilla 221950
+ // mySessionWrapper.close();
+ } else {
+ mySessionWrapper.commitTransaction();
+ }
+ }
+ }
+ }
+
+ /**
+ * Override point, the default implementation will check if Hibernate
+ * already assigned an id to an eobject. If so it is restored back to null.
+ * See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=331953
+ */
+ protected void beforeSaveRollback() {
+ // assigned ids
+ Session session = sessionWrapper.getHibernateSession();
+ for (EObject eobject : super.getNewEObjects()) {
+ String entityName = session.getEntityName(eobject);
+ String identifierName = getIdentifierName(eobject, session);
+ Serializable id = session.getIdentifier(eobject);
+ Criteria exists = session.createCriteria(entityName).add(
+ Restrictions.eq(identifierName, id));
+ if (exists.uniqueResult() == null) {
+ rollbackID(eobject, identifierName);
+ }
+ }
+ }
+
+ /**
+ * Override point, default implementation is empty.
+ */
+ protected void afterSaveRollback() {
+
+ }
+
+ /**
+ * Resets the id back to null, identifierName can be null (in that case no
+ * action is done, only the cached id in the identifier cache handler is
+ * reset back).
+ *
+ * @see IdentifierCacheHandler#setID(Object, Object)
+ */
+ protected void rollbackID(EObject eobject, String identifierName) {
+ IdentifierCacheHandler.getInstance().setID(eobject, null);
+ if (identifierName == null) {
+ return;
+ }
+ EStructuralFeature identifier = eobject.eClass().getEStructuralFeature(
+ identifierName);
+ if (identifier == null) {
+ return;
+ }
+ eobject.eUnset(identifier);
+ }
+
+ protected String getIdentifierName(EObject eobject, Session hs) {
+ String entityName = hs.getEntityName(eobject);
+ if (entityName == null) {
+ return null;
+ }
+ ClassMetadata entityMetaData = hs.getSessionFactory().getClassMetadata(
+ entityName);
+ if (entityMetaData == null) {
+ return null;
+ }
+ String identifierName = entityMetaData.getIdentifierPropertyName();
+ return identifierName;
+ }
+
+ /**
+ * Loads all the objects in the global list
+ */
+ @Override
+ protected List<EObject> loadResource(Map<?, ?> options) {
+ log.debug("Loading resource: " + getURI().toString());
+
+ // first clear the old list
+ boolean err = true;
+ final SessionWrapper mySessionWrapper = getSessionWrapper();
+ try {
+ if (!hasSessionController) {
+ mySessionWrapper.beginTransaction();
+ }
+
+ // note we have to a call to the super class otherwise an infinite
+ // loop is created
+ final List<EObject> storeList = loadFromStore(mySessionWrapper);
+ log.debug("Loaded " + storeList.size() + " objects");
+ err = false;
+ return storeList;
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ throw new HbMapperException("Exception when saving resource "
+ + emfDataStore.getName(), e);
+ } finally {
+ if (!hasSessionController) {
+ if (err) {
+ mySessionWrapper.rollbackTransaction();
+ mySessionWrapper.close();
+ } else {
+ mySessionWrapper.commitTransaction();
+ }
+ }
+ }
+ }
+
+ /**
+ * Rollsback the transaction if any and clears different lists to start with
+ * an empty resource again.
+ */
+ @Override
+ protected void doUnload() {
+ super.doUnload();
+
+ if (!hasSessionController) {
+ if (!getSessionWrapper().isEJB3EntityManager()) {
+ AssertUtil.assertTrue("Session must be disconnected in unload",
+ !((SessionImpl) getSessionWrapper().getSession())
+ .isTransactionInProgress());
+ }
+ log.debug("Doing unload, closing and nullifying session");
+ getSessionWrapper().close();
+ setSessionWrapper(null);
+ } else {
+ log.debug("Doing unload, has session controller, sessioncontroller is therefor responsible for session close");
+ }
+ }
+
+ /**
+ * This method can be overridden to implement specific load behavior. Note
+ * that a transaction has already been started. The session is passed as a
+ * parameter, this is the same session which can be retrieved using the
+ * getSession method. The read objects should be returned in the list. Note
+ * that after this call the retrieved objects are put in the resource
+ * content.
+ */
+ protected List<EObject> loadFromStore(SessionWrapper sess) {
+ if (definedQueriesPresent()) {
+ return loadUsingDefinedQueries(sess);
+ } else {
+ return loadUsingTopClasses(sess);
+ }
+ }
+
+ /** Reads data based on the topclasses list */
+ private ArrayList<EObject> loadUsingTopClasses(SessionWrapper sess) {
+ log.debug("Loading resource " + getURI() + " using top classes");
+ final ArrayList<EObject> readObjects = new ArrayList<EObject>();
+ for (final String topClassName : topClassNames) {
+ log.debug("Loading objects using hql: FROM " + topClassName);
+
+ final List<?> qryResult;
+ if (sess.isEJB3EntityManager()) {
+ qryResult = sess.executeQuery("select o from " + topClassName
+ + " o");
+ } else {
+ qryResult = sess.executeQuery("from " + topClassName);
+ }
+ final Iterator<?> it = qryResult.iterator();
+ while (it.hasNext()) {
+ final EObject eobj = (EObject) it.next();
+ // extra check on container because sometimes contained items
+ // are still read in
+ // case of multiple inheritance
+ if (eobj.eContainer() == null) {
+ readObjects.add(eobj);
+ }
+ }
+ }
+ return readObjects;
+ }
+
+ /** Reads data based using defined queries */
+ private ArrayList<EObject> loadUsingDefinedQueries(SessionWrapper sess) {
+ log.debug("Loading resource " + getURI() + " using defined queries");
+ final ArrayList<EObject> readObjects = new ArrayList<EObject>();
+ final String[] qrys = getDefinedQueries();
+ for (String element : qrys) {
+ final List<?> qryResult = sess.executeQuery(element);
+ log.debug("Loading objects using hql: " + element);
+ final Iterator<?> it = qryResult.iterator();
+ while (it.hasNext()) {
+ final Object obj = it.next();
+ readObjects.add((EObject) obj);
+ }
+ }
+ return readObjects;
+ }
+
+ /** Reads a set of objects into the resource by using a query. */
+ public Object[] getObjectsByQuery(String query, boolean cache) {
+ log.debug("Started listing objects by query " + query + " in resource "
+ + getURI());
+ SessionWrapper mySessionWrapper = null;
+ boolean err = true;
+ setIsLoading(true);
+ try {
+ mySessionWrapper = getSessionWrapper();
+ if (!hasSessionController) {
+ mySessionWrapper.beginTransaction();
+ }
+ final List<?> qryResult = mySessionWrapper.executeQuery(query,
+ cache);
+ for (Object object : qryResult) {
+ if (object instanceof InternalEObject) {
+ final InternalEObject eObject = (InternalEObject) object;
+ // only add if the object is not already part of this
+ // resource.
+ // if already part of this resource then it should have been
+ // loaded through
+ // a containment relation.
+ assert (eObject.eResource() != this
+ || loadedEObjectSet.contains(eObject) || newEObjects
+ .contains(eObject));
+ addToContent(eObject);
+ }
+ }
+
+ err = false;
+ log.debug("Listed " + qryResult.size() + " objects using query "
+ + query + " in resource " + getURI());
+ return qryResult.toArray();
+ } finally {
+ if (!hasSessionController) {
+ if (err) {
+ mySessionWrapper.rollbackTransaction();
+ mySessionWrapper.close();
+ } else {
+ mySessionWrapper.commitTransaction();
+ }
+ }
+ setIsLoading(false);
+ log.debug("Finished getting objects by query " + query
+ + " in resource " + getURI());
+ }
+ }
+
+ /**
+ * @return the hasSessionController
+ */
+ public boolean isHasSessionController() {
+ return hasSessionController;
+ }
+
+ @Override
+ public boolean isLoading() {
+ return isLoading;
+ }
+
+ /** Load additional objects into the contents using a query */
+ public Object[] listByQuery(String query, boolean cache) {
+ log.debug("Started listing objects by query " + query + " in resource "
+ + getURI());
+ SessionWrapper mySessionWrapper = null;
+ boolean err = true;
+ setIsLoading(true);
+ final Notification notification = setLoaded(true);
+ try {
+ mySessionWrapper = getSessionWrapper();
+ if (!hasSessionController) {
+ mySessionWrapper.beginTransaction();
+ }
+ final List<?> qryResult = mySessionWrapper.executeQuery(query,
+ cache);
+ for (Object object : qryResult) {
+ if (object instanceof InternalEObject) {
+ addToContent((InternalEObject) object);
+ }
+ }
+
+ err = false;
+ log.debug("Listed " + qryResult.size() + " objects using query "
+ + query + " in resource " + getURI());
+ return qryResult.toArray();
+ } finally {
+ setIsLoading(false);
+ if (!hasSessionController) {
+ if (err) {
+ mySessionWrapper.rollbackTransaction();
+ mySessionWrapper.close();
+ } else {
+ mySessionWrapper.commitTransaction();
+ }
+ }
+ if (notification != null) {
+ eNotify(notification);
+ }
+ log.debug("Finished listing objects by query " + query
+ + " in resource " + getURI());
+ }
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateResourceFactory.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateResourceFactory.java
new file mode 100755
index 000000000..76345d15f
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateResourceFactory.java
@@ -0,0 +1,38 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HibernateResourceFactory.java,v 1.3 2008/02/28 07:08:24 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.resource;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+
+/**
+ * Creates hibernate resources based on an uri.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.3 $
+ */
+
+public class HibernateResourceFactory implements Resource.Factory {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.ecore.resource.Resource.Factory#createResource(org.eclipse.emf.common.util.URI)
+ */
+ public Resource createResource(URI uri) {
+ return new HibernateResource(uri);
+ }
+}
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateXMLResource.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateXMLResource.java
new file mode 100755
index 000000000..c613ce24a
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateXMLResource.java
@@ -0,0 +1,138 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HibernateXMLResource.java,v 1.1 2008/03/12 18:36:34 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.resource;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.xmi.DOMHandler;
+import org.eclipse.emf.ecore.xmi.DOMHelper;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;
+import org.eclipse.emf.ecore.xml.type.AnyType;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+/**
+ * Tries to add XMLResource behavior to the Hibernate Resource. Not that not all methods are
+ * implemented.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.1 $
+ */
+
+public class HibernateXMLResource extends HibernateResource implements XMLResource {
+
+ public HibernateXMLResource(URI uri) {
+ super(uri);
+ }
+
+ public Map<Object, Object> getDefaultLoadOptions() {
+ return new HashMap<Object, Object>();
+ }
+
+ public Map<Object, Object> getDefaultSaveOptions() {
+ return new HashMap<Object, Object>();
+ }
+
+ public DOMHelper getDOMHelper() {
+ return null;
+ }
+
+ public String getEncoding() {
+ return null;
+ }
+
+ public Map<EObject, AnyType> getEObjectToExtensionMap() {
+ return null;
+ }
+
+ public Map<EObject, String> getEObjectToIDMap() {
+ return new HashMap<EObject, String>();
+ }
+
+ public String getID(EObject object) {
+ return getURIFragment(object);
+ }
+
+ public Map<String, EObject> getIDToEObjectMap() {
+ return new HashMap<String, EObject>();
+ }
+
+ public String getPublicId() {
+ return null;
+ }
+
+ public String getSystemId() {
+ return null;
+ }
+
+ public String getXMLVersion() {
+ return null;
+ }
+
+ public void load(InputSource inputSource, Map<?, ?> options) throws IOException {
+ final XMLResource xmlResource = new XMLResourceImpl();
+ xmlResource.load(inputSource, options);
+ getContents().addAll(xmlResource.getContents());
+ setLoaded(true);
+ }
+
+ public void load(Node node, Map<?, ?> options) throws IOException {
+ final XMLResource xmlResource = new XMLResourceImpl();
+ xmlResource.load(node, options);
+ getContents().addAll(xmlResource.getContents());
+ setLoaded(true);
+ }
+
+ public Document save(Document document, Map<?, ?> options, DOMHandler handler) {
+ final XMLResource xmlResource = new XMLResourceImpl();
+ xmlResource.getContents().addAll(getContents());
+ return xmlResource.save(document, options, handler);
+ }
+
+ public void save(Writer writer, Map<?, ?> options) throws IOException {
+ final XMLResource xmlResource = new XMLResourceImpl();
+ xmlResource.getContents().addAll(getContents());
+ xmlResource.save(writer, options);
+ }
+
+ public void setDoctypeInfo(String publicId, String systemId) {
+ }
+
+ public void setEncoding(String encoding) {
+ }
+
+ public void setID(EObject object, String id) {
+ }
+
+ public void setUseZip(boolean useZip) {
+ }
+
+ public void setXMLVersion(String version) {
+ }
+
+ @Override
+ public boolean useZip() {
+ return false;
+ }
+}
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateXMLResourceFactory.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateXMLResourceFactory.java
new file mode 100755
index 000000000..67a6abd5a
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/HibernateXMLResourceFactory.java
@@ -0,0 +1,38 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HibernateXMLResourceFactory.java,v 1.1 2008/03/12 18:36:34 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.resource;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+
+/**
+ * Creates hibernate xml resources based on an uri.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.1 $
+ */
+
+public class HibernateXMLResourceFactory implements Resource.Factory {
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.emf.ecore.resource.Resource.Factory#createResource(org.eclipse.emf.common.util.URI)
+ */
+ public Resource createResource(URI uri) {
+ return new HibernateXMLResource(uri);
+ }
+}
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/SessionController.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/SessionController.java
new file mode 100755
index 000000000..296080d3d
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/resource/SessionController.java
@@ -0,0 +1,108 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: SessionController.java,v 1.8 2008/06/29 14:24:25 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.resource;
+
+import java.util.Hashtable;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.teneo.hibernate.HbDataStore;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.SessionWrapper;
+import org.hibernate.Session;
+
+/**
+ * A session controller handles one session. The session controller can be registered and retrieved
+ * by name. The session controller is used by resources to share one session over different
+ * resources. The resources get the session controller name as a parameter in the uri.
+ *
+ * This class offers the registry functionality as well as a default implementation of the session
+ * controller.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.8 $
+ */
+
+public class SessionController {
+ /** The logger */
+ private static Log log = LogFactory.getLog(SessionController.class);
+
+ /** The static map of session controllers */
+ private static Hashtable<String, SessionController> sessionControllers = new Hashtable<String, SessionController>();
+
+ /** Register a session controller */
+ public static synchronized void registerSessionController(String name, SessionController sc) {
+ if (sessionControllers.get(name) != null) {
+ throw new HbMapperException("There is already a session controller registered with the name: " + name);
+ }
+ log.debug("Registering session controller: " + name);
+ sessionControllers.put(name, sc);
+ }
+
+ /** Deregisters a session controller */
+ public static synchronized void deRegisterSessionController(String name) {
+ if (sessionControllers.get(name) == null) {
+ throw new HbMapperException("There is no session controller registered with the name: " + name);
+ }
+ log.debug("De-Registering session controller: " + name);
+ sessionControllers.remove(name);
+ }
+
+ /** Returns a session controller using the name */
+ public static synchronized SessionController getSessionController(String name) {
+ return sessionControllers.get(name);
+ }
+
+ /** The local session wrapper */
+ protected SessionWrapper sessionWrapper;
+
+ /** The hb datastore from which the sessions are retrieved */
+ protected HbDataStore hbDataStore;
+
+ /**
+ * @return the hbDataStore
+ */
+ public HbDataStore getHbDataStore() {
+ return hbDataStore;
+ }
+
+ /**
+ * @param hbDataStore
+ * the hbDataStore to set
+ */
+ public void setHbDataStore(HbDataStore hbDataStore) {
+ this.hbDataStore = hbDataStore;
+ }
+
+ /**
+ * Note fails when using ejb data store.
+ *
+ * @return the session
+ */
+ @Deprecated
+ public Session getSession() {
+ return (Session) getSessionWrapper().getSession();
+ }
+
+ /** Return the session wrapper */
+ public SessionWrapper getSessionWrapper() {
+ if (sessionWrapper == null) {
+ sessionWrapper = hbDataStore.createSessionWrapper();
+ }
+ return sessionWrapper;
+ }
+}
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFComponentTuplizer.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFComponentTuplizer.java
new file mode 100755
index 000000000..766fa93af
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFComponentTuplizer.java
@@ -0,0 +1,162 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EMFComponentTuplizer.java,v 1.14 2010/08/18 11:50:38 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.tuplizer;
+
+import java.lang.reflect.Method;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.teneo.ERuntime;
+import org.eclipse.emf.teneo.hibernate.HbDataStore;
+import org.eclipse.emf.teneo.hibernate.HbHelper;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.HbUtil;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.Property;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.tuple.component.AbstractComponentTuplizer;
+
+/**
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.14 $
+ */
+
+public class EMFComponentTuplizer extends AbstractComponentTuplizer {
+
+ /**
+ * Generated Serial ID
+ */
+ private static final long serialVersionUID = 6316160569897347041L;
+
+ private EClass eClass;
+
+ /** The logger */
+ // private static Log log = LogFactory.getLog(EMFComponentTuplizer.class);
+ /** Constructor */
+ public EMFComponentTuplizer(Component component) {
+ super(component);
+ }
+
+ private EClass getEClass(Component component) {
+ if (eClass == null) {
+ final HbDataStore ds = HbHelper.INSTANCE.getDataStore(component);
+ eClass = ds.getEntityNameStrategy().toEClass(component.getComponentClassName());
+ if (eClass == null) {
+ eClass = ERuntime.INSTANCE.getEClass(component.getComponentClass());
+ }
+ if (eClass == null) {
+ eClass = HbUtil.getEClassFromMeta(component);
+ }
+ }
+ if (eClass == null) {
+ throw new HbMapperException("No eclass found for entityname: " + component.getComponentClassName());
+ }
+ return eClass;
+ }
+
+ /** Creates an EMF Instantiator */
+ protected Instantiator buildInstantiator(Component component, Property property) {
+ return buildInstantiator(component);
+ }
+
+ /** Creates an EMF Instantiator */
+ @Override
+ protected Instantiator buildInstantiator(Component component) {
+ return new EMFInstantiator(getEClass(component), component);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.AbstractEntityTuplizer#buildPropertyGetter(org.hibernate.mapping.Property,
+ * org.hibernate.mapping.PersistentClass)
+ */
+ @Override
+ protected Getter buildGetter(Component component, Property mappedProperty) {
+ return getPropertyAccessor(mappedProperty, component).getGetter(null, mappedProperty.getName());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.AbstractEntityTuplizer#buildPropertySetter(org.hibernate.mapping.Property,
+ * org.hibernate.mapping.PersistentClass)
+ */
+ @Override
+ protected Setter buildSetter(Component component, Property mappedProperty) {
+ return getPropertyAccessor(mappedProperty, component).getSetter(null, mappedProperty.getName());
+ }
+
+ /** Returns the correct accessor on the basis of the type of property */
+ public PropertyAccessor getPropertyAccessor(Property mappedProperty, Component comp) {
+ final HbDataStore ds = HbHelper.INSTANCE.getDataStore(comp);
+ return HbUtil.getPropertyAccessor(mappedProperty, ds, comp.getComponentClassName(), getEClass(comp));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.Tuplizer#getMappedClass()
+ */
+ public Class<?> getMappedClass() {
+ return EObject.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.ComponentTuplizer#getParent(java.lang.Object)
+ */
+ @Override
+ public Object getParent(Object component) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.ComponentTuplizer#hasParentProperty()
+ */
+ @Override
+ public boolean hasParentProperty() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.ComponentTuplizer#isMethodOf(java.lang.reflect.Method)
+ */
+ @Override
+ public boolean isMethodOf(Method method) {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.ComponentTuplizer#setParent(java.lang.Object, java.lang.Object,
+ * org.hibernate.engine.SessionFactoryImplementor)
+ */
+ @Override
+ public void setParent(Object component, Object parent, SessionFactoryImplementor factory) {
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFEntityNameResolver.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFEntityNameResolver.java
new file mode 100755
index 000000000..6e41f508d
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFEntityNameResolver.java
@@ -0,0 +1,60 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EMFEntityNameResolver.java,v 1.1 2009/06/27 09:20:06 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.tuplizer;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.mapping.strategy.EntityNameStrategy;
+import org.hibernate.EntityNameResolver;
+
+/**
+ * Intercepts the getEntityName call to return the EClass name as the entity name.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.1 $
+ */
+
+public class EMFEntityNameResolver implements ExtensionPoint, EntityNameResolver {
+
+ /**
+ * Generated Serial Version ID
+ */
+ private static final long serialVersionUID = 1680117509182298808L;
+
+ /** The qualify property used to compute the eclassname */
+ private EntityNameStrategy qualifyStrategy;
+
+ public EntityNameStrategy getQualifyStrategy() {
+ return qualifyStrategy;
+ }
+
+ public void setQualifyStrategy(EntityNameStrategy qualifyStrategy) {
+ this.qualifyStrategy = qualifyStrategy;
+ }
+
+ /*
+ * @see org.hibernate.EntityNameResolver#resolveEntityName(java.lang.Object)
+ */
+ public String resolveEntityName(Object entity) {
+ if (entity instanceof EObject) {
+ // TODO handle featuremap
+ EObject eobj = (EObject) entity;
+ return qualifyStrategy.toEntityName(eobj.eClass());
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFInstantiator.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFInstantiator.java
new file mode 100755
index 000000000..4cddaa972
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFInstantiator.java
@@ -0,0 +1,141 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EMFInstantiator.java,v 1.11 2010/08/18 11:50:38 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.tuplizer;
+
+import java.io.Serializable;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.impl.DynamicEObjectImpl;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.mapping.SerializableDynamicEObjectImpl;
+import org.eclipse.emf.teneo.type.PersistentStoreAdapter;
+import org.eclipse.emf.teneo.util.StoreUtil;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.tuple.Instantiator;
+
+/**
+ * Instantiates eobjects using the efactory.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.11 $
+ */
+
+public class EMFInstantiator implements Instantiator {
+
+ /**
+ * Generated Serial Version ID
+ */
+ private static final long serialVersionUID = 6946442685247491904L;
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(EMFInstantiator.class);
+
+ /** The EClass for which we do all this */
+ private final EClass eclass;
+
+ /** The proxy interface if used */
+ private final Class<?> proxyInterface;
+
+ /** The mapped class */
+ private final Class<?> mappedClass;
+
+ private boolean isDynamicEObject = false;
+
+ /** Constructor */
+ public EMFInstantiator(EClass eclass, PersistentClass pc) {
+ log.debug("Creating eobject instantiator for " + pc.getEntityName()
+ + " and eclass " + eclass.getName());
+ proxyInterface = pc.getProxyInterface();
+ this.eclass = eclass;
+ mappedClass = eclass.getInstanceClass();
+ }
+
+ /** Constructor */
+ public EMFInstantiator(EClass eclass, Component component) {
+ log.debug("Creating eobject instantiator for component eclass "
+ + eclass.getName());
+ this.eclass = eclass;
+ mappedClass = eclass.getInstanceClass();
+ proxyInterface = null;
+ }
+
+ /** Instantiates using EcoreUtil.create() */
+ public Object instantiate() {
+ EObject eobject;
+ if (isDynamicEObject) {
+ eobject = new SerializableDynamicEObjectImpl(eclass);
+ } else {
+ eobject = EcoreUtil.create(eclass);
+ if (eobject instanceof DynamicEObjectImpl) {
+ eobject = new SerializableDynamicEObjectImpl(eclass);
+ isDynamicEObject = true;
+ }
+ }
+
+ final PersistentStoreAdapter adapter = StoreUtil
+ .getPersistentStoreAdapter(eobject);
+ adapter.setTargetCreatedByORM(true);
+
+ if (eobject == null) {
+ throw new HbMapperException(
+ "The mapped "
+ + mappedClass.getName()
+ + " class can not be instantiated."
+ + " Possibly the class it is not an eclass or it is abstract.");
+ }
+ return eobject;
+ }
+
+ /** Instantiates using EcoreUtil.create() */
+ public Object instantiate(Serializable id) {
+ return instantiate();
+ }
+
+ /** Checks using the mapped class or the proxy interface */
+ public boolean isInstance(Object object) {
+ if (!(object instanceof EObject)) {
+ return false;
+ }
+ final EObject eobject = (EObject) object;
+ if (eobject.eClass() == eclass) {
+ return true;
+ }
+ if (isSuperTypeOf(eclass, eobject.eClass())) {
+ return true;
+ }
+ return (proxyInterface != null && proxyInterface.isInstance(object));
+ }
+
+ /** Is eclass superclass */
+ private boolean isSuperTypeOf(EClass superEClass, EClass eclass) {
+ for (EClass testSuperEClass : eclass.getESuperTypes()) {
+ if (testSuperEClass == superEClass) {
+ return true;
+ }
+ if (isSuperTypeOf(superEClass, testSuperEClass)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+} \ No newline at end of file
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFTuplizer.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFTuplizer.java
new file mode 100755
index 000000000..8b0c32a70
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/tuplizer/EMFTuplizer.java
@@ -0,0 +1,367 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: EMFTuplizer.java,v 1.26 2011/02/21 05:06:13 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.tuplizer;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.impl.DynamicEObjectImpl;
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+import org.eclipse.emf.teneo.Constants;
+import org.eclipse.emf.teneo.hibernate.HbDataStore;
+import org.eclipse.emf.teneo.hibernate.HbHelper;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.HbStoreException;
+import org.eclipse.emf.teneo.hibernate.HbUtil;
+import org.eclipse.emf.teneo.hibernate.mapping.eav.EAVInstantiator;
+import org.eclipse.emf.teneo.hibernate.mapping.eav.EAVPropertyHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierCacheHandler;
+import org.eclipse.emf.teneo.hibernate.mapping.internal.TeneoInternalEObject;
+import org.hibernate.EntityMode;
+import org.hibernate.EntityNameResolver;
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.Subclass;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.Setter;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.ProxyFactory;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.tuple.entity.AbstractEntityTuplizer;
+import org.hibernate.tuple.entity.EntityMetamodel;
+import org.hibernate.type.CompositeType;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Overrides the get and setidentifier methods to get the identifier from an
+ * internal cache instead of from the EMF object itself. The same behavior for
+ * the getVersion methods. Also a specific object instantiator is used to make
+ * use of the emf efactories.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.26 $
+ */
+
+public class EMFTuplizer extends AbstractEntityTuplizer {
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(EMFTuplizer.class);
+
+ /**
+ * The mapped class, defaults to EObject for entities and to the real impl
+ * class for mapped classes
+ */
+ private Class<?> mappedClass;
+
+ private PersistentClass persistentClass;
+
+ /** The entitymetamodel for which this is all done */
+ // private final EntityMetamodel theEntityMetamodel;
+ /** Constructor */
+ public EMFTuplizer(EntityMetamodel entityMetamodel,
+ PersistentClass mappedEntity) {
+ super(entityMetamodel, mappedEntity);
+ // theEntityMetamodel = entityMetamodel;
+ if (mappedEntity.getMappedClass() != null) {
+ mappedClass = mappedEntity.getMappedClass();
+ } else {
+ mappedClass = EObject.class;
+ }
+ persistentClass = mappedEntity;
+ }
+
+ /**
+ * First checks the id cache and if not found uses the superclass.
+ */
+ @Override
+ public Serializable getIdentifier(Object object) throws HibernateException {
+ Serializable id = (Serializable) IdentifierCacheHandler.getInstance()
+ .getID(object);
+ if (id != null) {
+ return id;
+ }
+ return super.getIdentifier(object);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.hibernate.tuple.entity.EntityTuplizer#determineConcreteSubclassEntityName
+ * (java.lang.Object, org.hibernate.engine.SessionFactoryImplementor)
+ */
+ public String determineConcreteSubclassEntityName(Object entityInstance,
+ SessionFactoryImplementor factory) {
+ final Class<?> concreteEntityClass = entityInstance.getClass();
+ if (concreteEntityClass == getMappedClass()) {
+ return getEntityName();
+ } else {
+ String entityName = getEntityMetamodel()
+ .findEntityNameByEntityClass(concreteEntityClass);
+ if (entityName == null) {
+ throw new HibernateException(
+ "Unable to resolve entity name from Class ["
+ + concreteEntityClass.getName() + "]"
+ + " expected instance/subclass of ["
+ + getEntityName() + "]");
+ }
+ return entityName;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.entity.EntityTuplizer#getEntityNameResolvers()
+ */
+ public EntityNameResolver[] getEntityNameResolvers() {
+ final HbDataStore ds = HbHelper.INSTANCE.getDataStore(persistentClass);
+ return new EntityNameResolver[] { ds.getEntityNameResolver() };
+ }
+
+ /**
+ * Uses the identifiercache to get the version.
+ */
+ @Override
+ public Object getVersion(Object object) throws HibernateException {
+ final Object version = super.getVersion(object);
+ if (version != null) {
+ return version;
+ }
+
+ return IdentifierCacheHandler.getInstance().getVersion(object);
+ }
+
+ /**
+ * Sets the identifier in the cache.
+ */
+ @Override
+ public void setIdentifier(Object object, Serializable id)
+ throws HibernateException {
+ IdentifierCacheHandler.getInstance().setID(object, id);
+ super.setIdentifier(object, id);
+ }
+
+ /** Creates an EMF Instantiator */
+ @Override
+ protected Instantiator buildInstantiator(PersistentClass persistentClass) {
+ if (persistentClass.getEntityName().equals(
+ Constants.EAV_EOBJECT_ENTITY_NAME)) {
+ return new EAVInstantiator();
+ }
+ final HbDataStore ds = HbHelper.INSTANCE.getDataStore(persistentClass);
+ final EClass eclass = ds.getEntityNameStrategy().toEClass(
+ persistentClass.getEntityName());
+ if (eclass == null) {
+ throw new HbMapperException("No eclass found for entityname: "
+ + persistentClass.getEntityName());
+ }
+ return new EMFInstantiator(eclass, persistentClass);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.hibernate.tuple.AbstractEntityTuplizer#buildPropertyGetter(org.hibernate
+ * .mapping.Property , org.hibernate.mapping.PersistentClass)
+ */
+ @Override
+ protected Getter buildPropertyGetter(Property mappedProperty,
+ PersistentClass mappedEntity) {
+ if (HbUtil.isEAVMapped(mappedEntity)
+ && mappedProperty.getName()
+ .equals(Constants.EAV_EOBJECT_VALUES)) {
+ final HbDataStore ds = HbHelper.INSTANCE.getDataStore(mappedEntity);
+ final Getter getter = mappedProperty.getGetter(EObjectImpl.class);
+ if (getter instanceof EAVPropertyHandler) {
+ ((EAVPropertyHandler) getter).setHbDataStore(ds);
+ }
+ return getter;
+ }
+ return getPropertyAccessor(mappedProperty, mappedEntity).getGetter(
+ null, mappedProperty.getName());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.hibernate.tuple.AbstractEntityTuplizer#buildPropertySetter(org.hibernate
+ * .mapping.Property , org.hibernate.mapping.PersistentClass)
+ */
+ @Override
+ protected Setter buildPropertySetter(Property mappedProperty,
+ PersistentClass mappedEntity) {
+ if (HbUtil.isEAVMapped(mappedEntity)
+ && mappedProperty.getName()
+ .equals(Constants.EAV_EOBJECT_VALUES)) {
+ final HbDataStore ds = HbHelper.INSTANCE.getDataStore(mappedEntity);
+ final Setter setter = mappedProperty.getSetter(EObjectImpl.class);
+ if (setter instanceof EAVPropertyHandler) {
+ ((EAVPropertyHandler) setter).setHbDataStore(ds);
+ }
+ return setter;
+ }
+ return getPropertyAccessor(mappedProperty, mappedEntity).getSetter(
+ null, mappedProperty.getName());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.hibernate.tuple.AbstractEntityTuplizer#buildProxyFactory(org.
+ * hibernate.mapping. PersistentClass, org.hibernate.property.Getter,
+ * org.hibernate.property.Setter)
+ */
+ @Override
+ protected ProxyFactory buildProxyFactory(PersistentClass persistentClass,
+ Getter idGetter, Setter idSetter) {
+ if (persistentClass.getProxyInterface() == null) { // an entity, no
+ // proxy
+ return null;
+ }
+
+ final HbDataStore ds = HbHelper.INSTANCE.getDataStore(persistentClass);
+ final EClass eclass = ds.getEntityNameStrategy().toEClass(
+ persistentClass.getEntityName());
+ if (eclass == null
+ && !persistentClass.getEntityName().equals(
+ Constants.EAV_EOBJECT_ENTITY_NAME)) {
+ throw new HbMapperException("No eclass found for entityname: "
+ + persistentClass.getEntityName());
+ }
+
+ // get all the interfaces from the main class, add the real interface
+ // first
+ final Set<Class<?>> proxyInterfaces = new LinkedHashSet<Class<?>>();
+ final Class<?> pInterface = persistentClass.getProxyInterface();
+ if (pInterface != null && pInterface.isInterface()) {
+ proxyInterfaces.add(pInterface);
+ }
+ Class<?> mappedClass = persistentClass.getMappedClass();
+ if (mappedClass == null) {
+ mappedClass = DynamicEObjectImpl.class;
+ }
+ if (mappedClass.isInterface()) {
+ proxyInterfaces.add(mappedClass);
+ }
+ proxyInterfaces.add(HibernateProxy.class);
+ proxyInterfaces.add(TeneoInternalEObject.class);
+
+ for (Class<?> interfaces : mappedClass.getInterfaces()) {
+ proxyInterfaces.add(interfaces);
+ }
+
+ // iterate over all subclasses and add them also
+ final Iterator<?> iter = persistentClass.getSubclassIterator();
+ while (iter.hasNext()) {
+ final Subclass subclass = (Subclass) iter.next();
+ final Class<?> subclassProxy = subclass.getProxyInterface();
+ final Class<?> subclassClass = subclass.getMappedClass();
+ if (subclassProxy != null && subclassClass != null
+ && !subclassClass.equals(subclassProxy)) {
+ proxyInterfaces.add(subclassProxy);
+ }
+ }
+
+ // get the idgettters/setters
+ final Method theIdGetterMethod = idGetter == null ? null : idGetter
+ .getMethod();
+ final Method theIdSetterMethod = idSetter == null ? null : idSetter
+ .getMethod();
+
+ final Method proxyGetIdentifierMethod = theIdGetterMethod == null
+ || pInterface == null ? null : ReflectHelper.getMethod(
+ pInterface, theIdGetterMethod);
+ final Method proxySetIdentifierMethod = theIdSetterMethod == null
+ || pInterface == null ? null : ReflectHelper.getMethod(
+ pInterface, theIdSetterMethod);
+
+ ProxyFactory pf = Environment.getBytecodeProvider()
+ .getProxyFactoryFactory().buildProxyFactory();
+ try {
+ pf.postInstantiate(
+ getEntityName(),
+ mappedClass,
+ proxyInterfaces,
+ proxyGetIdentifierMethod,
+ proxySetIdentifierMethod,
+ persistentClass.hasEmbeddedIdentifier() ? (CompositeType) persistentClass
+ .getIdentifier().getType() : null);
+ } catch (HbStoreException e) {
+ log.warn("could not create proxy factory for:" + getEntityName(), e);
+ pf = null;
+ }
+ return pf;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.AbstractEntityTuplizer#getEntityMode()
+ */
+ public EntityMode getEntityMode() {
+ return EntityMode.POJO;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.EntityTuplizer#getConcreteProxyClass()
+ */
+ public Class<?> getConcreteProxyClass() {
+ return EObject.class;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.EntityTuplizer#isInstrumented()
+ */
+ public boolean isInstrumented() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.hibernate.tuple.Tuplizer#getMappedClass()
+ */
+ public Class<?> getMappedClass() {
+ return mappedClass;
+ }
+
+ /** Returns the correct accessor on the basis of the type of property */
+ protected PropertyAccessor getPropertyAccessor(Property mappedProperty,
+ PersistentClass pc) {
+ final HbDataStore ds = HbHelper.INSTANCE.getDataStore(pc);
+ return HbUtil.getPropertyAccessor(mappedProperty, ds,
+ pc.getEntityName(), null);
+ }
+} \ No newline at end of file

Back to the top