| /* |
| * Copyright (c) 2008-2013, 2015 Eike Stepper (Berlin, Germany) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Eike Stepper - initial API and implementation |
| * Martin Taal - changed handling of propertygetters/setters |
| */ |
| package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer; |
| |
| import org.eclipse.emf.cdo.common.model.EMFUtil; |
| import org.eclipse.emf.cdo.common.revision.CDORevision; |
| import org.eclipse.emf.cdo.eresource.EresourcePackage; |
| import org.eclipse.emf.cdo.server.internal.hibernate.CDOHibernateConstants; |
| import org.eclipse.emf.cdo.server.internal.hibernate.HibernateStore; |
| import org.eclipse.emf.cdo.server.internal.hibernate.HibernateUtil; |
| import org.eclipse.emf.cdo.server.internal.hibernate.bundle.OM; |
| import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; |
| |
| import org.eclipse.net4j.util.om.trace.ContextTracer; |
| |
| import org.eclipse.emf.ecore.EAnnotation; |
| import org.eclipse.emf.ecore.EAttribute; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EPackage; |
| import org.eclipse.emf.ecore.EReference; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.ecore.EcoreFactory; |
| |
| import org.hibernate.EntityMode; |
| import org.hibernate.EntityNameResolver; |
| import org.hibernate.HibernateException; |
| import org.hibernate.engine.spi.SessionFactoryImplementor; |
| import org.hibernate.mapping.PersistentClass; |
| import org.hibernate.mapping.Property; |
| import org.hibernate.metamodel.binding.AttributeBinding; |
| import org.hibernate.metamodel.binding.EntityBinding; |
| 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 static final String EPACKAGE_META = "epackage"; //$NON-NLS-1$ |
| |
| private static final String ECLASSNAME_META = "eclassName"; //$NON-NLS-1$ |
| |
| private EClass eClass; |
| |
| public CDORevisionTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappingInfo) |
| { |
| super(entityMetamodel, mappingInfo); |
| if (TRACER.isEnabled()) |
| { |
| TRACER.trace("Created CDORevisionTuplizer for entity " + mappingInfo.getEntityName()); //$NON-NLS-1$ |
| } |
| |
| initEClass(mappingInfo); |
| } |
| |
| private void initEClass(PersistentClass mappingInfo) |
| { |
| if (eClass != null) |
| { |
| return; |
| } |
| |
| HibernateStore hbStore = HibernateStore.getCurrentHibernateStore(); |
| |
| // find the EClass/Package |
| String entityName = mappingInfo.getEntityName(); |
| String ePackageURI = mappingInfo.getMetaAttribute(EPACKAGE_META).getValue(); |
| String eClassName = mappingInfo.getMetaAttribute(ECLASSNAME_META).getValue(); |
| |
| if (ePackageURI == null || eClassName == null) |
| { |
| throw new IllegalArgumentException("The mapping for the persistentclass " + mappingInfo.getEntityName() //$NON-NLS-1$ |
| + " is incorrect, there should be meta data tags for both epackage and " //$NON-NLS-1$ |
| + "eclassname, one or both are missing."); //$NON-NLS-1$ |
| } |
| |
| if (TRACER.isEnabled()) |
| { |
| TRACER.trace("EntityName/eclassname/packageURI " + entityName + "/" + eClassName + "/" + ePackageURI); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| } |
| |
| for (EPackage ePackage : hbStore.getPackageHandler().getEPackages()) |
| { |
| if (ePackage.getNsURI().compareTo(ePackageURI) != 0) |
| { |
| continue; |
| } |
| |
| for (EClass localCdoClass : EMFUtil.getPersistentClasses(ePackage)) |
| { |
| if (localCdoClass.getName().compareTo(eClassName) == 0) |
| { |
| eClass = localCdoClass; |
| break; |
| } |
| } |
| } |
| |
| if (eClass == null && ePackageURI.compareTo(EresourcePackage.eINSTANCE.getNsURI()) == 0) |
| { |
| for (EClass localCdoClass : EMFUtil.getPersistentClasses(EresourcePackage.eINSTANCE)) |
| { |
| if (localCdoClass.getName().compareTo(eClassName) == 0) |
| { |
| eClass = localCdoClass; |
| if (TRACER.isEnabled()) |
| { |
| TRACER.trace("Class is CDOResource class"); //$NON-NLS-1$ |
| } |
| |
| break; |
| } |
| } |
| } |
| |
| // add the entityName <--> EClass mapping |
| HibernateStore.getCurrentHibernateStore().addEntityNameEClassMapping(entityName, eClass); |
| |
| if (eClass == null) |
| { |
| throw new IllegalArgumentException("The mapped class " + mappingInfo.getEntityName() //$NON-NLS-1$ |
| + " does not have a eClass equivalent"); //$NON-NLS-1$ |
| } |
| } |
| |
| /* |
| * (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(); |
| } |
| |
| String entityName = getEntityMetamodel().findEntityNameByEntityClass(concreteEntityClass); |
| if (entityName == null) |
| { |
| throw new HibernateException("Unable to resolve entity name from Class [" + concreteEntityClass.getName() + "]" //$NON-NLS-1$ //$NON-NLS-2$ |
| + " expected instance/subclass of [" + getEntityName() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| return entityName; |
| } |
| |
| public EntityMode getEntityMode() |
| { |
| return EntityMode.MAP; |
| } |
| |
| public EntityNameResolver[] getEntityNameResolvers() |
| { |
| return new EntityNameResolver[0]; |
| // return new EntityNameResolver[] { new CDOEntityNameResolver() }; |
| } |
| |
| // private class CDOEntityNameResolver implements EntityNameResolver |
| // { |
| // public String resolveEntityName(Object object) |
| // { |
| // return getEntityName(); |
| // } |
| // } |
| |
| public EClass getEClass() |
| { |
| return eClass; |
| } |
| |
| @Override |
| protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) |
| { |
| initEClass(mappedEntity); |
| if (TRACER.isEnabled()) |
| { |
| TRACER.trace("Building property getter for " + eClass.getName() + "." + mappedProperty.getName()); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| if (mappedProperty.isBackRef()) |
| { |
| return mappedProperty.getGetter(mappedEntity.getMappedClass()); |
| } |
| final CDOPropertyGetter getter; |
| if (mappedProperty == mappedEntity.getIdentifierProperty()) |
| { |
| getter = new CDOIDPropertyGetter(this, mappedProperty.getName()); |
| } |
| else if (mappedProperty.getMetaAttribute("version") != null) |
| { |
| getter = new CDOVersionPropertyGetter(this, mappedProperty.getName()); |
| } |
| else if (mappedProperty.getName().compareTo(CDOHibernateConstants.RESOURCE_PROPERTY) == 0) |
| { |
| getter = new CDOResourceIDGetter(this, mappedProperty.getName()); |
| } |
| else if (mappedProperty.getName().compareTo(CDOHibernateConstants.CONTAINER_PROPERTY) == 0) |
| { |
| getter = new CDOContainerGetter(this, mappedProperty.getName()); |
| } |
| else if (mappedProperty.getName().compareTo(CDOHibernateConstants.COMMITTIMESTAMP_PROPERTY) == 0) |
| { |
| getter = new CDOBranchTimeStampGetter(this, mappedProperty.getName()); |
| } |
| else |
| { |
| EStructuralFeature feature = getEClass().getEStructuralFeature(mappedProperty.getName()); |
| if (feature instanceof EReference && feature.isMany() |
| && HibernateUtil.getInstance().isCDOResourceContents(feature)) |
| { |
| getter = new CDOManyAttributeGetter(this, mappedProperty.getName()); |
| } |
| else if (feature instanceof EReference && feature.isMany()) |
| { |
| getter = new CDOManyReferenceGetter(this, mappedProperty.getName()); |
| } |
| else if (feature instanceof EReference) |
| { |
| getter = new CDOReferenceGetter(this, mappedProperty.getName()); |
| } |
| else if (feature instanceof EAttribute && feature.isMany()) |
| { |
| getter = new CDOManyAttributeGetter(this, mappedProperty.getName()); |
| } |
| else |
| { |
| getter = new CDOPropertyGetter(this, mappedProperty.getName()); |
| } |
| } |
| |
| HibernateStore hbStore = HibernateStore.getCurrentHibernateStore(); |
| getter.setPersistenceOptions(hbStore.getCDODataStore().getPersistenceOptions()); |
| return getter; |
| } |
| |
| @Override |
| protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) |
| { |
| initEClass(mappedEntity); |
| if (TRACER.isEnabled()) |
| { |
| TRACER.trace("Building property setter for " + eClass.getName() + "." + mappedProperty.getName()); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| if (mappedProperty.isBackRef()) |
| { |
| return mappedProperty.getSetter(mappedEntity.getMappedClass()); |
| } |
| |
| final CDOPropertySetter setter; |
| if (mappedProperty == mappedEntity.getIdentifierProperty()) |
| { |
| setIdentifierTypeAsAnnotation(mappedProperty); |
| setter = new CDOIDPropertySetter(this, mappedProperty.getName()); |
| } |
| else if (mappedProperty.getMetaAttribute("version") != null) |
| { |
| setter = new CDOVersionPropertySetter(this, mappedProperty.getName()); |
| } |
| else if (mappedProperty.getName().compareTo(CDOHibernateConstants.RESOURCE_PROPERTY) == 0) |
| { |
| setter = new CDOResourceIDSetter(this, mappedProperty.getName()); |
| } |
| else if (mappedProperty.getName().compareTo(CDOHibernateConstants.CONTAINER_PROPERTY) == 0) |
| { |
| setter = new CDOContainerSetter(this, mappedProperty.getName()); |
| } |
| else if (mappedProperty.getName().compareTo(CDOHibernateConstants.COMMITTIMESTAMP_PROPERTY) == 0) |
| { |
| setter = new CDOBranchTimeStampSetter(this, mappedProperty.getName()); |
| } |
| else |
| { |
| EStructuralFeature feature = getEClass().getEStructuralFeature(mappedProperty.getName()); |
| if (feature instanceof EReference && feature.isMany() |
| && HibernateUtil.getInstance().isCDOResourceContents(feature)) |
| { |
| setter = new CDOManyAttributeSetter(this, mappedProperty.getName()); |
| } |
| else if (feature instanceof EReference && feature.isMany()) |
| { |
| setter = new CDOManyReferenceSetter(this, mappedProperty.getName()); |
| } |
| else if (feature instanceof EAttribute && feature.isMany()) |
| { |
| setter = new CDOManyAttributeSetter(this, mappedProperty.getName()); |
| } |
| else |
| |
| if (feature instanceof EReference) |
| { |
| setter = new CDOReferenceSetter(this, mappedProperty.getName()); |
| } |
| else |
| { |
| setter = new CDOPropertySetter(this, mappedProperty.getName()); |
| } |
| } |
| |
| HibernateStore hbStore = HibernateStore.getCurrentHibernateStore(); |
| setter.setPersistenceOptions(hbStore.getCDODataStore().getPersistenceOptions()); |
| return setter; |
| } |
| |
| @Override |
| protected Instantiator buildInstantiator(PersistentClass mappingInfo) |
| { |
| return new CDORevisionInstantiator(this, mappingInfo); |
| } |
| |
| @Override |
| protected ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter) |
| { |
| CDORevisionProxyFactory pf = new CDORevisionProxyFactory(); |
| pf.setEntityName(getEntityName()); |
| |
| try |
| { |
| pf.postInstantiate(getEntityName(), null, null, null, null, null); |
| } |
| catch (HibernateException ex) |
| { |
| OM.LOG.error("Could not create proxy factory for " + getEntityName(), ex); //$NON-NLS-1$ |
| pf = null; |
| } |
| |
| return pf; |
| } |
| |
| @SuppressWarnings("rawtypes") |
| public Class getMappedClass() |
| { |
| return InternalCDORevision.class; |
| } |
| |
| @SuppressWarnings("rawtypes") |
| public Class getConcreteProxyClass() |
| { |
| return InternalCDORevision.class; |
| } |
| |
| public boolean isInstrumented() |
| { |
| return false; |
| } |
| |
| private void setIdentifierTypeAsAnnotation(Property prop) |
| { |
| EAnnotation eAnnotation = getEClass().getEAnnotation(HibernateStore.ID_TYPE_EANNOTATION_SOURCE); |
| if (eAnnotation == null) |
| { |
| eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation(); |
| eAnnotation.setSource(HibernateStore.ID_TYPE_EANNOTATION_SOURCE); |
| eAnnotation.getDetails().put(HibernateStore.ID_TYPE_EANNOTATION_KEY, prop.getType().getName()); |
| getEClass().getEAnnotations().add(eAnnotation); |
| } |
| else if (!eAnnotation.getDetails().containsKey(HibernateStore.ID_TYPE_EANNOTATION_KEY)) |
| { |
| eAnnotation.getDetails().put(HibernateStore.ID_TYPE_EANNOTATION_KEY, prop.getType().getName()); |
| } |
| } |
| |
| @Override |
| protected Instantiator buildInstantiator(EntityBinding arg0) |
| { |
| return null; |
| } |
| |
| @Override |
| protected Getter buildPropertyGetter(AttributeBinding arg0) |
| { |
| return null; |
| } |
| |
| @Override |
| protected Setter buildPropertySetter(AttributeBinding arg0) |
| { |
| return null; |
| } |
| |
| @Override |
| protected ProxyFactory buildProxyFactory(EntityBinding arg0, Getter arg1, Setter arg2) |
| { |
| return null; |
| } |
| |
| @Override |
| public Object getVersion(Object entity) throws HibernateException |
| { |
| if (entity instanceof CDORevision) |
| { |
| return ((CDORevision)entity).getVersion(); |
| } |
| return super.getVersion(entity); |
| } |
| } |