org.eclipse.emf.cdo.server.internal.hibernate.tuplizer.CDORevisionTuplizer.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.emf.cdo.server.internal.hibernate.tuplizer.CDORevisionTuplizer.java

Source

/*
 * 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);
    }
}