diff options
author | Eike Stepper | 2008-02-23 08:26:22 +0000 |
---|---|---|
committer | Eike Stepper | 2008-02-23 08:26:22 +0000 |
commit | c5a3c052177759f9be3d6694bf16f591ba98208a (patch) | |
tree | 3791ce00048eeac3a646888b55120762b3dc75f0 /plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer | |
parent | df3b1fdd17dfabb7925a02139def2084203a8c2d (diff) | |
download | cdo-c5a3c052177759f9be3d6694bf16f591ba98208a.tar.gz cdo-c5a3c052177759f9be3d6694bf16f591ba98208a.tar.xz cdo-c5a3c052177759f9be3d6694bf16f591ba98208a.zip |
[217117] Develop a HibernateStore
https://bugs.eclipse.org/bugs/show_bug.cgi?id=217117
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer')
22 files changed, 2292 insertions, 0 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOIDMetaRangeUserType.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOIDMetaRangeUserType.java new file mode 100644 index 0000000000..313c7d98d9 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOIDMetaRangeUserType.java @@ -0,0 +1,120 @@ +/*************************************************************************** + * Copyright (c) 2008 - 2008 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.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.internal.protocol.id.CDOIDMetaImpl; +import org.eclipse.emf.cdo.internal.protocol.id.CDOIDMetaRangeImpl; +import org.eclipse.emf.cdo.protocol.id.CDOIDMeta; +import org.eclipse.emf.cdo.protocol.id.CDOIDMetaRange; + +import org.hibernate.Hibernate; +import org.hibernate.usertype.UserType; + +import java.io.Serializable; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +/** + * @author Martin Taal + */ +public class CDOIDMetaRangeUserType implements UserType +{ + + private static final int[] SQL_TYPES = { Types.INTEGER, Types.INTEGER }; + + public int[] sqlTypes() + { + return SQL_TYPES; + } + + public Class<?> returnedClass() + { + return CDOIDMetaRange.class; + } + + public boolean isMutable() + { + return true; + } + + public CDOIDMetaRangeUserType() + { + } + + public Object deepCopy(Object value) + { + final CDOIDMetaRange cdoRange = (CDOIDMetaRange)value; + final CDOIDMeta newCdoIDMeta = new CDOIDMetaImpl(((CDOIDMetaImpl)cdoRange.getLowerBound()).getLongValue()); + return new CDOIDMetaRangeImpl(newCdoIDMeta, cdoRange.size()); + } + + 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 Integer start = (Integer)Hibernate.INTEGER.nullSafeGet(rs, names[0]); + final Integer size = (Integer)Hibernate.INTEGER.nullSafeGet(rs, names[1]); + if (size == null || start == null) + { + return null; + } + final CDOIDMeta newCdoIDMeta = new CDOIDMetaImpl(start); + return new CDOIDMetaRangeImpl(newCdoIDMeta, size); + } + + public void nullSafeSet(PreparedStatement statement, Object value, int index) throws SQLException + { + if (value != null) + { + final CDOIDMetaRange cdoRange = (CDOIDMetaRange)value; + statement.setLong(index, ((CDOIDMeta)cdoRange.getLowerBound()).getLongValue()); + statement.setInt(index + 1, cdoRange.size()); + } + else + { + statement.setNull(index, Types.INTEGER); + statement.setNull(index + 1, Types.INTEGER); + } + } + + 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(); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOIDPropertyGetter.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOIDPropertyGetter.java new file mode 100644 index 0000000000..440eee16c6 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOIDPropertyGetter.java @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Martin Taal + * 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 - copied from CDORevisionPropertyHandler and adapted + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; +import org.eclipse.emf.cdo.server.hibernate.CDOIDHibernate; + +import org.hibernate.HibernateException; + +/** + * @author Martin Taal + */ +public class CDOIDPropertyGetter extends CDOPropertyGetter +{ + private static final long serialVersionUID = 1L; + + public CDOIDPropertyGetter(CDORevisionTuplizer tuplizer, String propertyName) + { + super(tuplizer, propertyName); + } + + @Override + public Object get(Object target) throws HibernateException + { + final InternalCDORevision revision = (InternalCDORevision)target; + if (!(revision.getID() instanceof CDOIDHibernate)) + { + return null; + } + final CDOIDHibernate cdoID = (CDOIDHibernate)revision.getID(); + if (isVirtualProperty()) + { + return cdoID.getId(); + } + else + { + final Object id = super.get(target); + // TODO: does this make sense? + // if (cdoID.getId() == null) + // { + // cdoID.setId((Serializable)id); + // } + return id; + } + } + + @Override + protected boolean isVirtualPropertyAllowed() + { + return true; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOIDPropertySetter.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOIDPropertySetter.java new file mode 100644 index 0000000000..d1f68bade2 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOIDPropertySetter.java @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Martin Taal + * 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 - copied from CDORevisionPropertyHandler and adapted + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; +import org.eclipse.emf.cdo.protocol.id.CDOID; +import org.eclipse.emf.cdo.protocol.id.CDOIDTemp; +import org.eclipse.emf.cdo.server.IStoreWriter.CommitContext; +import org.eclipse.emf.cdo.server.hibernate.CDOIDHibernate; +import org.eclipse.emf.cdo.server.internal.hibernate.CDOHibernateThreadContext; +import org.eclipse.emf.cdo.server.internal.hibernate.CDOIDHibernateImpl; + +import org.hibernate.HibernateException; +import org.hibernate.engine.SessionFactoryImplementor; + +import java.io.Serializable; + +/** + * @author Martin Taal + */ +public class CDOIDPropertySetter extends CDOPropertySetter +{ + private static final long serialVersionUID = 1L; + + public CDOIDPropertySetter(CDORevisionTuplizer tuplizer, String propertyName) + { + super(tuplizer, propertyName); + } + + @Override + public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException + { + if (value == null) + { + return; + } + final InternalCDORevision revision = (InternalCDORevision)target; + final CDOID cdoID = revision.getID(); + if (cdoID == null) + { + final CDOIDHibernate newCDOID = new CDOIDHibernateImpl(); + newCDOID.setId((Serializable)value); + newCDOID.setEntityName(revision.getCDOClass().getName()); + revision.setID(newCDOID); + } + else if (cdoID instanceof CDOIDTemp) + { + final CommitContext commitContext = CDOHibernateThreadContext.getCommitContext(); + final CDOIDHibernate newCDOID = new CDOIDHibernateImpl(); + newCDOID.setId((Serializable)value); + newCDOID.setEntityName(revision.getCDOClass().getName()); + revision.setID(newCDOID); + commitContext.addIDMapping((CDOIDTemp)cdoID, newCDOID); + } + else + { + final CDOIDHibernate hbCDOID = (CDOIDHibernate)revision.getID(); + if (!hbCDOID.getId().equals(value)) + { + throw new IllegalStateException("Current id and new id are different " + value + "/" + hbCDOID.getId()); + } + } + } + + @Override + protected boolean isVirtualPropertyAllowed() + { + return true; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOIDUserType.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOIDUserType.java new file mode 100644 index 0000000000..c59903b5a1 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOIDUserType.java @@ -0,0 +1,136 @@ +/*************************************************************************** + * Copyright (c) 2008 - 2008 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.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.protocol.id.CDOID; +import org.eclipse.emf.cdo.protocol.id.CDOIDTemp; +import org.eclipse.emf.cdo.protocol.revision.CDORevision; +import org.eclipse.emf.cdo.server.hibernate.CDOIDHibernate; +import org.eclipse.emf.cdo.server.internal.hibernate.CDOHibernateUtil; +import org.eclipse.emf.cdo.server.internal.hibernate.CDOIDHibernateImpl; + +import org.hibernate.Hibernate; +import org.hibernate.usertype.UserType; + +import java.io.Serializable; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +/** + * Persists a cdoid in the db. + */ +public class CDOIDUserType implements UserType +{ + + // second varchar is just for informational purposes + private static final int[] SQL_TYPES = { Types.VARCHAR, Types.VARCHAR, Types.VARBINARY }; + + public int[] sqlTypes() + { + return SQL_TYPES; + } + + public Class<?> returnedClass() + { + return CDOID.class; + } + + public boolean isMutable() + { + return false; + } + + public CDOIDUserType() + { + } + + 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 entityName = (String)Hibernate.STRING.nullSafeGet(rs, names[0]); + if (rs.wasNull() || entityName == null) + { + return null; + } + final byte[] content = (byte[])Hibernate.BINARY.nullSafeGet(rs, names[2]); + final CDOIDHibernate cdoID = new CDOIDHibernateImpl(); + cdoID.setContent(content); + return cdoID; + } + + public void nullSafeSet(PreparedStatement statement, Object value, int index) throws SQLException + { + if (value == null) + { + statement.setNull(index, Types.VARCHAR); + statement.setNull(index, Types.VARCHAR); + statement.setNull(index, Types.VARBINARY); + } + if (value != null) + { + final CDOIDHibernate cdoID; + if (value instanceof CDOIDTemp) + { + cdoID = CDOHibernateUtil.getInstance().getCDOIDHibernate((CDOID)value); + } + else if (value instanceof CDORevision) + { + cdoID = (CDOIDHibernate)((CDORevision)value).getID(); + } + else + { + cdoID = (CDOIDHibernate)value; + } + statement.setString(index, cdoID.getEntityName()); + statement.setString(index + 1, cdoID.getId().toString()); + statement.setBytes(index + 2, cdoID.getContent()); + } + } + + 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(); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOManyReferenceGetter.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOManyReferenceGetter.java new file mode 100644 index 0000000000..c8169bd6af --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOManyReferenceGetter.java @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 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 - copied from CDORevisionPropertyHandler and adapted + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; + +import org.eclipse.net4j.internal.util.collection.MoveableArrayList; + +import org.hibernate.HibernateException; +import org.hibernate.collection.PersistentCollection; + +/** + * @author Martin Taal + */ + +// Howto handle hibernate lists: +// - a new owner: the owner is persisted and its lists are replaced with hibernate +// persistentlist, the hibernate persitentlist will have a delegate (internally) which is the list which was previously +// present in the owner. +// - an existing owner: the owner is read from the db and hibernate will set a persistentlist +// directly +// +// The solution also needs to handle the following: +// - cdo does not have direct java references but stores cdoids in the list while hibernate expects real java object +// references. +// - cdo uses a moveablearraylist and not the standard arraylist +// +// The solution: +// - never return null when hibernate asks for the current value of the manyreference, always +// return a MoveableArrayList so that hibernate uses that as the delegate, set the MoveableArrayList +public class CDOManyReferenceGetter extends CDOPropertyGetter +{ + private static final long serialVersionUID = 1L; + + public CDOManyReferenceGetter(CDORevisionTuplizer tuplizer, String propertyName) + { + super(tuplizer, propertyName); + } + + @Override + public Object get(Object target) throws HibernateException + { + // check if there is already a persistentcollection + final PersistentCollection collection = PersistableListHolder.getInstance().getListMapping(target, getCDOFeature()); + if (collection != null) + { + return collection; + } + + // not yet, get the moveablearraylist + @SuppressWarnings("unchecked") + MoveableArrayList<Object> list = (MoveableArrayList<Object>)super.get(target); + if (list == null) + { + // TODO: what initial size? + list = new MoveableArrayList<Object>(10); + final InternalCDORevision revision = (InternalCDORevision)target; + revision.setValue(getCDOFeature(), list); + } + + // wrap the moveablearraylist + final HibernateMoveableListWrapper wrapper = new HibernateMoveableListWrapper(); + wrapper.setDelegate(list); + + // and return it + return wrapper; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOManyReferenceSetter.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOManyReferenceSetter.java new file mode 100644 index 0000000000..8f57dacad3 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOManyReferenceSetter.java @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Martin Taal + * 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 - copied from CDORevisionPropertyHandler and adapted + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.hibernate.HibernateException; +import org.hibernate.collection.PersistentCollection; +import org.hibernate.collection.PersistentList; +import org.hibernate.engine.SessionFactoryImplementor; + +/** + * @author Martin Taal + */ +public class CDOManyReferenceSetter extends CDOPropertySetter +{ + private static final long serialVersionUID = 1L; + + public CDOManyReferenceSetter(CDORevisionTuplizer tuplizer, String propertyName) + { + super(tuplizer, propertyName); + } + + @Override + public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException + { + // do some checking + if (!(value instanceof PersistentList)) + { + throw new IllegalArgumentException("Value is not a persistentlist but a " + value.getClass().getName()); + } + + // only set it in the listholder + PersistableListHolder.getInstance().putListMapping(target, getCDOFeature(), (PersistentCollection)value); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertyGetter.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertyGetter.java new file mode 100644 index 0000000000..44c680e15a --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertyGetter.java @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Martin Taal + * 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 - copied from CDORevisionPropertyHandler and adapted + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; + +import org.hibernate.HibernateException; +import org.hibernate.engine.SessionImplementor; +import org.hibernate.property.Getter; + +import java.lang.reflect.Method; +import java.util.Map; + +/** + * @author Martin Taal + */ +public class CDOPropertyGetter extends CDOPropertyHandler implements Getter +{ + private static final long serialVersionUID = 1L; + + public CDOPropertyGetter(CDORevisionTuplizer tuplizer, String propertyName) + { + super(tuplizer, propertyName); + } + + public Object get(Object target) throws HibernateException + { + InternalCDORevision revision = (InternalCDORevision)target; + return revision.getValue(getCDOFeature()); + } + + @SuppressWarnings("unchecked") + public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) throws HibernateException + { + return get(target); + } + + public Method getMethod() + { + return null; + } + + public String getMethodName() + { + return null; + } + + @SuppressWarnings("unchecked") + public Class getReturnType() + { + return Object.class; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertyHandler.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertyHandler.java new file mode 100644 index 0000000000..ee887657fc --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertyHandler.java @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Martin Taal + * 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 - copied from CDORevisionPropertyHandler and adapted + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.protocol.model.CDOFeature; +import org.eclipse.emf.cdo.server.internal.hibernate.bundle.OM; + +import org.eclipse.net4j.internal.util.om.trace.ContextTracer; + +/** + * @author Martin Taal + */ +public abstract class CDOPropertyHandler +{ + private CDORevisionTuplizer tuplizer; + + private CDOFeature cdoFeature; + + private boolean virtualProperty = false; + + private final ContextTracer tracer = new ContextTracer(OM.DEBUG, this.getClass()); + + public CDOPropertyHandler(CDORevisionTuplizer tuplizer, String propertyName) + { + this.tuplizer = tuplizer; + cdoFeature = tuplizer.getCDOClass().lookupFeature(propertyName); + getTracer().trace( + "Created " + this.getClass().getName() + " for cdoClass/feature: " + tuplizer.getCDOClass().getName() + "." + + propertyName); + if (cdoFeature == null) + { + if (isVirtualPropertyAllowed()) + { + virtualProperty = true; + getTracer().trace("This is a virtualproperty"); + } + else + { + throw new IllegalStateException("Feature not found: " + propertyName); + } + } + } + + protected ContextTracer getTracer() + { + return tracer; + } + + public CDORevisionTuplizer getTuplizer() + { + return tuplizer; + } + + public CDOFeature getCDOFeature() + { + return cdoFeature; + } + + protected boolean isVirtualPropertyAllowed() + { + return false; + } + + /** + * @return the virtualProperty + */ + public boolean isVirtualProperty() + { + return virtualProperty; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertySetter.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertySetter.java new file mode 100644 index 0000000000..d0c7578356 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertySetter.java @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Martin Taal + * 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 - copied from CDORevisionPropertyHandler and adapted + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; + +import org.hibernate.HibernateException; +import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.property.Setter; + +import java.lang.reflect.Method; + +/** + * @author Martin Taal + */ +public class CDOPropertySetter extends CDOPropertyHandler implements Setter +{ + private static final long serialVersionUID = 1L; + + public CDOPropertySetter(CDORevisionTuplizer tuplizer, String propertyName) + { + super(tuplizer, propertyName); + } + + public Method getMethod() + { + return null; + } + + public String getMethodName() + { + return null; + } + + public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException + { + InternalCDORevision revision = (InternalCDORevision)target; + revision.setValue(getCDOFeature(), value); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOReferenceGetter.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOReferenceGetter.java new file mode 100644 index 0000000000..55b50ccd93 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOReferenceGetter.java @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Martin Taal + * 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 - copied from CDORevisionPropertyHandler and adapted + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.protocol.id.CDOID; +import org.eclipse.emf.cdo.server.internal.hibernate.CDOHibernateUtil; + +import org.hibernate.HibernateException; + +/** + * @author Martin Taal + */ +public class CDOReferenceGetter extends CDOPropertyGetter +{ + private static final long serialVersionUID = 1L; + + public CDOReferenceGetter(CDORevisionTuplizer tuplizer, String propertyName) + { + super(tuplizer, propertyName); + } + + @Override + public Object get(Object target) throws HibernateException + { + final Object o = super.get(target); + if (o instanceof CDOID) + { + return CDOHibernateUtil.getInstance().getCDORevision((CDOID)o); + } + return o; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOReferenceSetter.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOReferenceSetter.java new file mode 100644 index 0000000000..1c14778466 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOReferenceSetter.java @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Martin Taal + * 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 - copied from CDORevisionPropertyHandler and adapted + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.protocol.revision.CDORevision; + +import org.hibernate.HibernateException; +import org.hibernate.engine.SessionFactoryImplementor; + +/** + * @author Martin Taal + */ +public class CDOReferenceSetter extends CDOPropertySetter +{ + private static final long serialVersionUID = 1L; + + public CDOReferenceSetter(CDORevisionTuplizer tuplizer, String propertyName) + { + super(tuplizer, propertyName); + } + + @Override + public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException + { + final CDORevision cdoValue = (CDORevision)value; + super.set(target, cdoValue.getID(), factory); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionInstantiator.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionInstantiator.java new file mode 100644 index 0000000000..dcfacafb1d --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionInstantiator.java @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; +import org.eclipse.emf.cdo.protocol.id.CDOID; +import org.eclipse.emf.cdo.protocol.model.CDOClass; +import org.eclipse.emf.cdo.protocol.revision.CDORevisionUtil; +import org.eclipse.emf.cdo.server.IPackageManager; +import org.eclipse.emf.cdo.server.IRepository; +import org.eclipse.emf.cdo.server.IRevisionManager; + +import org.hibernate.mapping.PersistentClass; +import org.hibernate.tuple.Instantiator; + +import java.io.Serializable; + +/** + * @author Eike Stepper + */ +public class CDORevisionInstantiator implements Instantiator +{ + private static final long serialVersionUID = 1L; + + private CDOClass cdoClass; + + private IRevisionManager revisionManager; + + public CDORevisionInstantiator(CDORevisionTuplizer tuplizer, PersistentClass mappingInfo) + { + cdoClass = tuplizer.getCDOClass(); + IPackageManager packageManager = (IPackageManager)cdoClass.getPackageManager(); + IRepository repository = packageManager.getRepository(); + revisionManager = repository.getRevisionManager(); + } + + public Object instantiate() + { + // TODO CDO can't create a revision w/o CDOID + return instantiate(null); + } + + public Object instantiate(Serializable id) + { + return CDORevisionUtil.create(revisionManager, cdoClass, (CDOID)id);// TODO Is simply casting ok? + } + + public boolean isInstance(Object object) + { + return object instanceof InternalCDORevision; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionLazyInitializer.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionLazyInitializer.java new file mode 100644 index 0000000000..d80557b13d --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionLazyInitializer.java @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; + +import org.hibernate.engine.SessionImplementor; +import org.hibernate.proxy.AbstractLazyInitializer; + +import java.io.Serializable; + +/** + * @author Eike Stepper + */ +public class CDORevisionLazyInitializer extends AbstractLazyInitializer implements Serializable +{ + private static final long serialVersionUID = 1L; + + CDORevisionLazyInitializer(String entityName, Serializable id, SessionImplementor session) + { + super(entityName, id, session); + } + + public InternalCDORevision getRevision() + { + return (InternalCDORevision)getImplementation(); + } + + @SuppressWarnings("unchecked") + public Class getPersistentClass() + { + throw new UnsupportedOperationException(); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionPropertyAccessor.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionPropertyAccessor.java new file mode 100644 index 0000000000..1a80a78ac0 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionPropertyAccessor.java @@ -0,0 +1,155 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; +import org.eclipse.emf.cdo.protocol.model.CDOFeature; + +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; + +import java.lang.reflect.Method; +import java.util.Map; + +/** + * @author Eike Stepper + */ +public class CDORevisionPropertyAccessor implements PropertyAccessor +{ + private CDORevisionTuplizer tuplizer; + + public CDORevisionPropertyAccessor(CDORevisionTuplizer tuplizer) + { + this.tuplizer = tuplizer; + } + + public CDORevisionTuplizer getTuplizer() + { + return tuplizer; + } + + @SuppressWarnings("unchecked") + public Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException + { + return new CDORevisionGetter(this, propertyName); + } + + @SuppressWarnings("unchecked") + public Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException + { + return new CDORevisionSetter(this, propertyName); + } + + /** + * @author Eike Stepper + */ + public static class BaseAccessor + { + private CDORevisionPropertyAccessor propertyAccessor; + + private CDOFeature cdoFeature; + + public BaseAccessor(CDORevisionPropertyAccessor propertyAccessor, String propertyName) + { + this.propertyAccessor = propertyAccessor; + cdoFeature = propertyAccessor.getTuplizer().getCDOClass().lookupFeature(propertyName); + if (cdoFeature == null) + { + throw new IllegalStateException("Feature not found: " + propertyName); + } + } + + public CDORevisionPropertyAccessor getPropertyAccessor() + { + return propertyAccessor; + } + + public CDOFeature getCDOFeature() + { + return cdoFeature; + } + } + + /** + * @author Eike Stepper + */ + public static class CDORevisionGetter extends BaseAccessor implements Getter + { + private static final long serialVersionUID = 1L; + + public CDORevisionGetter(CDORevisionPropertyAccessor propertyAccessor, String propertyName) + { + super(propertyAccessor, propertyName); + } + + public Object get(Object target) throws HibernateException + { + InternalCDORevision revision = (InternalCDORevision)target; + return revision.getValue(getCDOFeature()); + } + + @SuppressWarnings("unchecked") + public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) throws HibernateException + { + return get(target); + } + + public Method getMethod() + { + return null; + } + + public String getMethodName() + { + return null; + } + + @SuppressWarnings("unchecked") + public Class getReturnType() + { + return Object.class; + } + } + + /** + * @author Eike Stepper + */ + public static class CDORevisionSetter extends BaseAccessor implements Setter + { + private static final long serialVersionUID = 1L; + + public CDORevisionSetter(CDORevisionPropertyAccessor propertyAccessor, String propertyName) + { + super(propertyAccessor, propertyName); + } + + public Method getMethod() + { + return null; + } + + public String getMethodName() + { + return null; + } + + public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException + { + InternalCDORevision revision = (InternalCDORevision)target; + revision.setValue(getCDOFeature(), value); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionProxy.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionProxy.java new file mode 100644 index 0000000000..da85d7d8a6 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionProxy.java @@ -0,0 +1,302 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; +import org.eclipse.emf.cdo.protocol.id.CDOID; +import org.eclipse.emf.cdo.protocol.id.CDOIDProvider; +import org.eclipse.emf.cdo.protocol.id.CDOIDTemp; +import org.eclipse.emf.cdo.protocol.model.CDOClass; +import org.eclipse.emf.cdo.protocol.model.CDOFeature; +import org.eclipse.emf.cdo.protocol.revision.CDORevision; +import org.eclipse.emf.cdo.protocol.revision.CDORevisionData; +import org.eclipse.emf.cdo.protocol.revision.CDORevisionResolver; +import org.eclipse.emf.cdo.protocol.revision.delta.CDORevisionDelta; + +import org.eclipse.net4j.util.collection.MoveableList; +import org.eclipse.net4j.util.io.ExtendedDataOutput; + +import org.hibernate.proxy.HibernateProxy; +import org.hibernate.proxy.LazyInitializer; + +import java.io.IOException; +import java.io.Serializable; +import java.util.Map; + +/** + * @author Eike Stepper + */ +public class CDORevisionProxy implements HibernateProxy, InternalCDORevision, Serializable +{ + private static final long serialVersionUID = 1L; + + private CDORevisionLazyInitializer li; + + CDORevisionProxy(CDORevisionLazyInitializer li) + { + this.li = li; + } + + public Object writeReplace() + { + return this; + } + + public LazyInitializer getHibernateLazyInitializer() + { + return li; + } + + public void add(CDOFeature feature, int index, Object value) + { + li.getRevision().add(feature, index, value); + } + + public void adjustReferences(Map<CDOIDTemp, CDOID> idMappings) + { + li.getRevision().adjustReferences(idMappings); + } + + public void clear(CDOFeature feature) + { + li.getRevision().clear(feature); + } + + public CDORevisionDelta compare(CDORevision origin) + { + return li.getRevision().compare(origin); + } + + public boolean contains(CDOFeature feature, Object value) + { + return li.getRevision().contains(feature, value); + } + + public Object get(CDOFeature feature, int index) + { + return li.getRevision().get(feature, index); + } + + public CDOClass getCDOClass() + { + return li.getRevision().getCDOClass(); + } + + public CDOID getContainerID() + { + return li.getRevision().getContainerID(); + } + + public int getContainingFeatureID() + { + return li.getRevision().getContainingFeatureID(); + } + + public long getCreated() + { + return li.getRevision().getCreated(); + } + + public CDORevisionData getData() + { + return li.getRevision().getData(); + } + + public CDOID getID() + { + return li.getRevision().getID(); + } + + public MoveableList<Object> getList(CDOFeature feature, int size) + { + return li.getRevision().getList(feature, size); + } + + public MoveableList<Object> getList(CDOFeature feature) + { + return li.getRevision().getList(feature); + } + + public CDOID getResourceID() + { + return li.getRevision().getResourceID(); + } + + public long getRevised() + { + return li.getRevision().getRevised(); + } + + public CDORevision getRevision() + { + return li.getRevision().getRevision(); + } + + public CDORevisionResolver getRevisionResolver() + { + return li.getRevision().getRevisionResolver(); + } + + public Object getValue(CDOFeature feature) + { + return li.getRevision().getValue(feature); + } + + public int getVersion() + { + return li.getRevision().getVersion(); + } + + public int hashCode(CDOFeature feature) + { + return li.getRevision().hashCode(feature); + } + + public int indexOf(CDOFeature feature, Object value) + { + return li.getRevision().indexOf(feature, value); + } + + public boolean isCurrent() + { + return li.getRevision().isCurrent(); + } + + public boolean isEmpty(CDOFeature feature) + { + return li.getRevision().isEmpty(feature); + } + + public boolean isResource() + { + return li.getRevision().isResource(); + } + + public boolean isSet(CDOFeature feature) + { + return li.getRevision().isSet(feature); + } + + public boolean isTransactional() + { + return li.getRevision().isTransactional(); + } + + public boolean isValid(long timeStamp) + { + return li.getRevision().isValid(timeStamp); + } + + public int lastIndexOf(CDOFeature feature, Object value) + { + return li.getRevision().lastIndexOf(feature, value); + } + + public void merge(CDORevisionDelta delta) + { + li.getRevision().merge(delta); + } + + public Object move(CDOFeature feature, int targetIndex, int sourceIndex) + { + return li.getRevision().move(feature, targetIndex, sourceIndex); + } + + public Object remove(CDOFeature feature, int index) + { + return li.getRevision().remove(feature, index); + } + + public Object set(CDOFeature feature, int index, Object value) + { + return li.getRevision().set(feature, index, value); + } + + public void setContainerID(CDOID containerID) + { + li.getRevision().setContainerID(containerID); + } + + public void setContainingFeatureID(int containingFeatureID) + { + li.getRevision().setContainingFeatureID(containingFeatureID); + } + + public void setCreated(long created) + { + li.getRevision().setCreated(created); + } + + public void setID(CDOID id) + { + li.getRevision().setID(id); + } + + public void setListSize(CDOFeature feature, int size) + { + li.getRevision().setListSize(feature, size); + } + + public void setResourceID(CDOID resourceID) + { + li.getRevision().setResourceID(resourceID); + } + + public void setRevised(long revised) + { + li.getRevision().setRevised(revised); + } + + public int setTransactional() + { + return li.getRevision().setTransactional(); + } + + public void setUntransactional() + { + li.getRevision().setUntransactional(); + } + + public Object setValue(CDOFeature feature, Object value) + { + return li.getRevision().setValue(feature, value); + } + + public void setVersion(int version) + { + li.getRevision().setVersion(version); + } + + public int size(CDOFeature feature) + { + return li.getRevision().size(feature); + } + + public <T> T[] toArray(CDOFeature feature, T[] array) + { + return li.getRevision().toArray(feature, array); + } + + public Object[] toArray(CDOFeature feature) + { + return li.getRevision().toArray(feature); + } + + public void unset(CDOFeature feature) + { + li.getRevision().unset(feature); + } + + public void write(ExtendedDataOutput out, CDOIDProvider idProvider, int referenceChunk) throws IOException + { + li.getRevision().write(out, idProvider, referenceChunk); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionProxyFactory.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionProxyFactory.java new file mode 100644 index 0000000000..320f6e1469 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionProxyFactory.java @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.hibernate.HibernateException; +import org.hibernate.engine.SessionImplementor; +import org.hibernate.proxy.HibernateProxy; +import org.hibernate.proxy.ProxyFactory; +import org.hibernate.type.AbstractComponentType; + +import java.io.Serializable; +import java.lang.reflect.Method; +import java.util.Set; + +/** + * @author Eike Stepper + */ +public class CDORevisionProxyFactory implements ProxyFactory +{ + private String entityName; + + public CDORevisionProxyFactory() + { + } + + @SuppressWarnings("unchecked") + public void postInstantiate(String entityName, Class persistentClass, Set interfaces, Method getIdentifierMethod, + Method setIdentifierMethod, AbstractComponentType componentIdType) throws HibernateException + { + this.entityName = entityName; + } + + public HibernateProxy getProxy(Serializable id, SessionImplementor session) throws HibernateException + { + return new CDORevisionProxy(new CDORevisionLazyInitializer(entityName, id, session)); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionTuplizer.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionTuplizer.java new file mode 100644 index 0000000000..423b357370 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionTuplizer.java @@ -0,0 +1,283 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Eike Stepper, Germany, and others + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + * Martin Taal - changed handling of propertygetters/setters + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; +import org.eclipse.emf.cdo.protocol.model.CDOClass; +import org.eclipse.emf.cdo.protocol.model.CDOFeature; +import org.eclipse.emf.cdo.protocol.model.CDOPackage; +import org.eclipse.emf.cdo.protocol.model.resource.CDOResourcePackage; +import org.eclipse.emf.cdo.server.internal.hibernate.HibernateStore; +import org.eclipse.emf.cdo.server.internal.hibernate.bundle.OM; + +import org.eclipse.net4j.internal.util.om.trace.ContextTracer; + +import org.hibernate.EntityMode; +import org.hibernate.HibernateException; +import org.hibernate.mapping.PersistentClass; +import org.hibernate.mapping.Property; +import org.hibernate.property.Getter; +import org.hibernate.property.Setter; +import org.hibernate.proxy.ProxyFactory; +import org.hibernate.tuple.Instantiator; +import org.hibernate.tuple.entity.AbstractEntityTuplizer; +import org.hibernate.tuple.entity.EntityMetamodel; + +/** + * @author Eike Stepper + */ +public class CDORevisionTuplizer extends AbstractEntityTuplizer +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, CDORevisionTuplizer.class); + + private CDOClass cdoClass; + + public CDORevisionTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappingInfo) + { + super(entityMetamodel, mappingInfo); + TRACER.trace("Created CDORevisionTuplizer for entity " + mappingInfo.getEntityName()); + initCDOClass(mappingInfo); + } + + private void initCDOClass(PersistentClass mappingInfo) + { + if (cdoClass != null) + { + return; + } + final HibernateStore hbStore = HibernateStore.getCurrentHibernateStore(); + + // find the CDOClass/Package + // TODO: error handling if meta attribute not present + // TODO: error handling if entityname not set + final String entityName = mappingInfo.getEntityName(); + final String ePackageURI = mappingInfo.getMetaAttribute("epackage").getValue(); + + TRACER.trace("EntityName/packageURI " + entityName + " " + ePackageURI); + + for (CDOPackage cdoPackage : hbStore.getPackageHandler().getCDOPackages()) + { + if (cdoPackage.getPackageURI().compareTo(ePackageURI) != 0) + { + continue; + } + for (CDOClass localCdoClass : cdoPackage.getClasses()) + { + if (localCdoClass.getName().compareTo(entityName) == 0) + { + cdoClass = localCdoClass; + break; + } + } + } + if (cdoClass == null && ePackageURI.compareTo(CDOResourcePackage.PACKAGE_URI) == 0) + { + for (CDOClass localCdoClass : hbStore.getRepository().getPackageManager().getCDOResourcePackage().getClasses()) + { + if (localCdoClass.getName().compareTo(entityName) == 0) + { + cdoClass = localCdoClass; + TRACER.trace("Class is CDOResource class"); + break; + } + } + } + + if (cdoClass == null) + { + throw new IllegalArgumentException("The mapped class " + mappingInfo.getEntityName()); + } + } + + // MT: probably not required as the property getter/setter do all the work + // /* + // * (non-Javadoc) + // * + // * @see org.hibernate.tuple.entity.AbstractEntityTuplizer#getVersion(java.lang.Object) + // */ + // @Override + // public Object getVersion(Object entity) throws HibernateException + // { + // if (entity instanceof CDORevision) + // { + // final CDORevision cdoRevision = (CDORevision)entity; + // return cdoRevision.getVersion(); + // } + // throw new IllegalArgumentException("Entity of type: " + entity.getClass().getName() + // + " not supported by this tuplizer"); + // } + // + // @Override + // public Serializable getIdentifier(Object entity) throws HibernateException + // { + // if (entity instanceof CDORevision) + // { + // final CDOID cdoID = ((CDORevision)entity).getID(); + // if (cdoID instanceof CDOIDHibernate) + // { + // return ((CDOIDHibernate)cdoID).getId(); + // } + // } + // throw new IllegalArgumentException("Entity of type: " + entity.getClass().getName() + // + " not supported by this tuplizer"); + // } + // + // @Override + // public void setIdentifier(Object entity, Serializable id) throws HibernateException + // { + // if (entity instanceof InternalCDORevision) + // { + // final InternalCDORevision cdoRevision = (InternalCDORevision)entity; + // final CDOID cdoID = cdoRevision.getID(); + // if (cdoID == null) + // { + // CDOIDHibernate hid = (CDOIDHibernate)HibernateStore.CDOID_OBJECT_FACTORY.createCDOIDObject(null); + // hid.setId(id); + // cdoRevision.setID(hid); + // return; + // } + // else if (cdoID instanceof CDOIDHibernate) + // { + // ((CDOIDHibernate)cdoID).setId(id); + // return; + // } + // } + // throw new IllegalArgumentException("Entity of type: " + entity.getClass().getName() + // + " not supported by this tuplizer"); + // } + + @Override + public EntityMode getEntityMode() + { + return EntityMode.MAP; + } + + public CDOClass getCDOClass() + { + return cdoClass; + } + + @Override + protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) + { + initCDOClass(mappedEntity); + + TRACER.trace("Building property getter for " + cdoClass.getName() + "." + mappedProperty.getName()); + + if (mappedProperty.isBackRef()) + { + return mappedProperty.getGetter(mappedEntity.getMappedClass()); + } + else if (mappedProperty == mappedEntity.getIdentifierProperty()) + { + return new CDOIDPropertyGetter(this, mappedProperty.getName()); + } + else if (mappedProperty == mappedEntity.getVersion()) + { + return new CDOVersionPropertyGetter(this, mappedProperty.getName()); + } + else + { + final CDOFeature cdoFeature = getCDOClass().lookupFeature(mappedProperty.getName()); + if (cdoFeature.isReference() && cdoFeature.isMany()) + { + return new CDOManyReferenceGetter(this, mappedProperty.getName()); + } + else if (cdoFeature.isReference()) + { + return new CDOReferenceGetter(this, mappedProperty.getName()); + } + else + { + return new CDOPropertyGetter(this, mappedProperty.getName()); + } + } + } + + @Override + protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) + { + initCDOClass(mappedEntity); + + TRACER.trace("Building property setter for " + cdoClass.getName() + "." + mappedProperty.getName()); + + if (mappedProperty.isBackRef()) + { + return mappedProperty.getSetter(mappedEntity.getMappedClass()); + } + else if (mappedProperty == mappedEntity.getIdentifierProperty()) + { + return new CDOIDPropertySetter(this, mappedProperty.getName()); + } + else if (mappedProperty == mappedEntity.getVersion()) + { + return new CDOVersionPropertySetter(this, mappedProperty.getName()); + } + else + { + final CDOFeature cdoFeature = getCDOClass().lookupFeature(mappedProperty.getName()); + if (cdoFeature.isReference() && cdoFeature.isMany()) + { + return new CDOManyReferenceSetter(this, mappedProperty.getName()); + } + else if (cdoFeature.isReference()) + { + return new CDOReferenceSetter(this, mappedProperty.getName()); + } + else + { + return new CDOPropertySetter(this, mappedProperty.getName()); + } + } + } + + @Override + protected Instantiator buildInstantiator(PersistentClass mappingInfo) + { + return new CDORevisionInstantiator(this, mappingInfo); + } + + @Override + protected ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter) + { + ProxyFactory pf = new CDORevisionProxyFactory(); + + try + { + pf.postInstantiate(getEntityName(), null, null, null, null, null); + } + catch (HibernateException ex) + { + OM.LOG.error("Could not create proxy factory for " + getEntityName(), ex); + pf = null; + } + + return pf; + } + + @SuppressWarnings("unchecked") + public Class getMappedClass() + { + return InternalCDORevision.class; + } + + @SuppressWarnings("unchecked") + public Class getConcreteProxyClass() + { + return InternalCDORevision.class; + } + + public boolean isInstrumented() + { + return false; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOTypeUserType.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOTypeUserType.java new file mode 100644 index 0000000000..979f17b4cb --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOTypeUserType.java @@ -0,0 +1,115 @@ +/*************************************************************************** + * Copyright (c) 2008 - 2008 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.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.internal.protocol.model.CDOTypeImpl; +import org.eclipse.emf.cdo.protocol.model.CDOType; + +import org.hibernate.Hibernate; +import org.hibernate.usertype.UserType; + +import java.io.Serializable; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +/** + * @author Martin Taal + */ +public class CDOTypeUserType implements UserType +{ + + private static final int[] SQL_TYPES = { Types.INTEGER }; + + public int[] sqlTypes() + { + return SQL_TYPES; + } + + public Class<?> returnedClass() + { + return CDOType.class; + } + + public boolean isMutable() + { + return false; + } + + public CDOTypeUserType() + { + } + + 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 Integer value = (Integer)Hibernate.INTEGER.nullSafeGet(rs, names[0]); + if (rs.wasNull()) + { + return null; + } + if (value == null) + { + return null; + } + return CDOTypeImpl.index.get(value); + } + + public void nullSafeSet(PreparedStatement statement, Object value, int index) throws SQLException + { + if (value != null) + { + statement.setInt(index, ((CDOType)value).getTypeID()); + } + else + { + statement.setNull(index, Types.INTEGER); + } + } + + 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(); + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOVersionPropertyGetter.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOVersionPropertyGetter.java new file mode 100644 index 0000000000..e928f551ff --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOVersionPropertyGetter.java @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Martin Taal + * 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 - copied from CDORevisionPropertyHandler and adapted + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; + +import org.hibernate.HibernateException; + +/** + * @author Martin Taal + */ +public class CDOVersionPropertyGetter extends CDOPropertyGetter +{ + private static final long serialVersionUID = 1L; + + public CDOVersionPropertyGetter(CDORevisionTuplizer tuplizer, String propertyName) + { + super(tuplizer, propertyName); + } + + @Override + public Object get(Object target) throws HibernateException + { + final InternalCDORevision revision = (InternalCDORevision)target; + if (isVirtualProperty()) + { + return revision.getVersion(); + } + else + { + final Object version = super.get(target); + // TODO: does this make sense? + // revision.setVersion(((Number)value).intValue()); + return version; + } + } + + @Override + protected boolean isVirtualPropertyAllowed() + { + return true; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOVersionPropertySetter.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOVersionPropertySetter.java new file mode 100644 index 0000000000..4aa93a25ca --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOVersionPropertySetter.java @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Martin Taal + * 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 - copied from CDORevisionPropertyHandler and adapted + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; + +import org.hibernate.HibernateException; +import org.hibernate.engine.SessionFactoryImplementor; + +/** + * @author Martin Taal + */ +public class CDOVersionPropertySetter extends CDOPropertySetter +{ + private static final long serialVersionUID = 1L; + + public CDOVersionPropertySetter(CDORevisionTuplizer tuplizer, String propertyName) + { + super(tuplizer, propertyName); + } + + @Override + public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException + { + final InternalCDORevision revision = (InternalCDORevision)target; + revision.setVersion(((Number)value).intValue()); + if (!isVirtualProperty()) + { + super.set(target, value, factory); + } + } + + @Override + protected boolean isVirtualPropertyAllowed() + { + return true; + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/HibernateMoveableListWrapper.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/HibernateMoveableListWrapper.java new file mode 100644 index 0000000000..f21e67e45a --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/HibernateMoveableListWrapper.java @@ -0,0 +1,314 @@ +/*************************************************************************** + * Copyright (c) 2008 - 2008 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.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.protocol.id.CDOID; +import org.eclipse.emf.cdo.protocol.revision.CDORevision; +import org.eclipse.emf.cdo.server.internal.hibernate.CDOHibernateUtil; + +import org.eclipse.net4j.internal.util.collection.MoveableArrayList; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +/** + * Wraps a moveable list so that hibernate always sees an object view while cdo always sees a cdoid view. + * + * @author Martin Taal + */ +public class HibernateMoveableListWrapper implements List<Object> +{ + private MoveableArrayList<Object> delegate; + + /** + * @return the delegate + */ + public MoveableArrayList<Object> getDelegate() + { + return delegate; + } + + /** + * @param delegate + * the delegate to set + */ + public void setDelegate(MoveableArrayList<Object> delegate) + { + this.delegate = delegate; + } + + protected Object getObject(Object o) + { + if (o == null) + { + return null; + } + + // is already resolved + if (!(o instanceof CDOID)) + { + return o; + } + + return CDOHibernateUtil.getInstance().getCDORevision((CDOID)o); + } + + protected List<Object> getObjects(List<?> cdoIDs) + { + final List<Object> result = new ArrayList<Object>(); + for (Object o : cdoIDs) + { + result.add(getObject(o)); + } + return result; + } + + protected CDOID getCDOID(Object o) + { + final CDORevision cdoRevision = (CDORevision)o; + return cdoRevision.getID(); + } + + protected List<CDOID> getCDOIDs(Collection<?> c) + { + final List<CDOID> newC = new ArrayList<CDOID>(); + for (Object o : c) + { + newC.add(getCDOID(o)); + } + return newC; + } + + public void add(int index, Object element) + { + getDelegate().add(index, getCDOID(element)); + } + + public boolean add(Object o) + { + return getDelegate().add(getCDOID(o)); + } + + public boolean addAll(Collection<? extends Object> c) + { + return getDelegate().addAll(getCDOIDs(c)); + } + + public boolean addAll(int index, Collection<? extends Object> c) + { + return getDelegate().addAll(index, getCDOIDs(c)); + } + + public void clear() + { + getDelegate().clear(); + } + + public boolean contains(Object o) + { + return getDelegate().contains(getCDOID(o)); + } + + public boolean containsAll(Collection<?> c) + { + return getDelegate().containsAll(getCDOIDs(c)); + } + + public Object get(int index) + { + return getObject(getDelegate().get(index)); + } + + public int indexOf(Object o) + { + return getDelegate().indexOf(getCDOID(o)); + } + + public boolean isEmpty() + { + return getDelegate().isEmpty(); + } + + public Iterator<Object> iterator() + { + return new CDOHibernateIterator(getDelegate().iterator()); + } + + public int lastIndexOf(Object o) + { + return getDelegate().lastIndexOf(getCDOID(o)); + } + + public ListIterator<Object> listIterator() + { + return new CDOHibernateListIterator(getDelegate().listIterator()); + } + + public ListIterator<Object> listIterator(int index) + { + return new CDOHibernateListIterator(getDelegate().listIterator(index)); + } + + public Object remove(int index) + { + return getDelegate().remove(index); + } + + public boolean remove(Object o) + { + return getDelegate().remove(getCDOID(o)); + } + + public boolean removeAll(Collection<?> c) + { + return getDelegate().removeAll(getCDOIDs(c)); + } + + public boolean retainAll(Collection<?> c) + { + return getDelegate().retainAll(getCDOIDs(c)); + } + + public Object set(int index, Object element) + { + return getDelegate().set(index, getCDOID(element)); + } + + public int size() + { + return getDelegate().size(); + } + + public List<Object> subList(int fromIndex, int toIndex) + { + return getObjects(getDelegate().subList(fromIndex, toIndex)); + } + + public Object[] toArray() + { + final Object[] result = new Object[size()]; + int i = 0; + for (Object o : this) + { + result[i++] = o; + } + return result; + } + + @SuppressWarnings("unchecked") + public <T> T[] toArray(T[] a) + { + int i = 0; + for (Object o : this) + { + a[i++] = (T)o; + } + return a; + } + + private static class CDOHibernateIterator implements Iterator<Object> + { + final Iterator<?> delegate; + + CDOHibernateIterator(Iterator<?> delegate) + { + this.delegate = delegate; + } + + public boolean hasNext() + { + return delegate.hasNext(); + } + + public Object next() + { + final Object o = this.delegate.next(); + if (o instanceof CDOID) + { + return CDOHibernateUtil.getInstance().getCDORevision((CDOID)o); + } + return o; + } + + public void remove() + { + delegate.remove(); + } + } + + private class CDOHibernateListIterator implements ListIterator<Object> + { + final ListIterator<Object> delegate; + + CDOHibernateListIterator(ListIterator<Object> delegate) + { + this.delegate = delegate; + } + + public void add(Object o) + { + delegate.add(((CDORevision)o).getID()); + } + + public boolean hasNext() + { + return delegate.hasNext(); + } + + public boolean hasPrevious() + { + return delegate.hasPrevious(); + } + + public Object next() + { + final Object o = this.delegate.next(); + if (o instanceof CDOID) + { + return CDOHibernateUtil.getInstance().getCDORevision((CDOID)delegate.next()); + } + return o; + } + + public int nextIndex() + { + return delegate.nextIndex(); + } + + public Object previous() + { + final Object o = this.delegate.previous(); + if (o instanceof CDOID) + { + return CDOHibernateUtil.getInstance().getCDORevision((CDOID)delegate.next()); + } + return o; + } + + public int previousIndex() + { + return delegate.previousIndex(); + } + + public void remove() + { + delegate.remove(); + } + + public void set(Object o) + { + delegate.set(((CDORevision)o).getID()); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/PersistableListHolder.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/PersistableListHolder.java new file mode 100644 index 0000000000..91962e873a --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/PersistableListHolder.java @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 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 - copied from CDORevisionPropertyHandler and adapted + **************************************************************************/ +package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; + +import org.eclipse.emf.cdo.protocol.model.CDOFeature; +import org.eclipse.emf.cdo.protocol.revision.CDORevision; +import org.eclipse.emf.cdo.server.internal.hibernate.bundle.OM; + +import org.eclipse.net4j.internal.util.om.trace.ContextTracer; + +import org.hibernate.collection.PersistentCollection; + +import java.util.HashMap; +import java.util.Map; + +/** + * Keeps mappings from object/feature combinations to a hibernate persistable list. This works because the write action + * is done in one thread. + * + * @author Martin Taal + */ + +public class PersistableListHolder +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, PersistableListHolder.class); + + private static PersistableListHolder instance = new PersistableListHolder(); + + public static PersistableListHolder getInstance() + { + return instance; + } + + public static void setInstance(PersistableListHolder instance) + { + PersistableListHolder.instance = instance; + } + + private ThreadLocal<Map<Key, PersistentCollection>> listMapping = new ThreadLocal<Map<Key, PersistentCollection>>(); + + public void putListMapping(Object target, CDOFeature cdoFeature, PersistentCollection collection) + { + final Key key = new Key(target, cdoFeature); + getListMapping().put(key, collection); + TRACER.trace("Stored hb list in threadlocal: " + ((CDORevision)target).getCDOClass().getName() + "." + + cdoFeature.getName()); + } + + public PersistentCollection getListMapping(Object target, CDOFeature cdoFeature) + { + final Key key = new Key(target, cdoFeature); + return getListMapping().get(key); + } + + private Map<Key, PersistentCollection> getListMapping() + { + if (listMapping.get() == null) + { + listMapping.set(new HashMap<Key, PersistentCollection>()); + } + return listMapping.get(); + } + + private class Key + { + private Object owner; + + private CDOFeature cdoFeature; + + Key(Object owner, CDOFeature cdoFeature) + { + this.owner = owner; + this.cdoFeature = cdoFeature; + } + + @Override + public boolean equals(Object obj) + { + if (!(obj instanceof Key)) + { + return false; + } + final Key otherKey = (Key)obj; + // the owner is uniquely present in mem, the same applies for the cdoFeature + // therefore == is allowed + return owner == otherKey.owner && cdoFeature == otherKey.cdoFeature; + } + + @Override + public int hashCode() + { + return owner.hashCode() + cdoFeature.hashCode(); + } + } +} |