| /* |
| * Copyright (c) 2012, 2013, 2015, 2016, 2018 Eike Stepper (Loehne, 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: |
| * Martin Taal - initial API and implementation |
| * Eike Stepper - maintenance |
| */ |
| package org.eclipse.emf.cdo.server.internal.hibernate; |
| |
| import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; |
| import org.eclipse.emf.cdo.common.id.CDOID; |
| import org.eclipse.emf.cdo.common.id.CDOIDUtil; |
| import org.eclipse.emf.cdo.common.model.CDOClassifierRef; |
| import org.eclipse.emf.cdo.common.revision.CDORevision; |
| import org.eclipse.emf.cdo.common.revision.CDORevisionData; |
| import org.eclipse.emf.cdo.common.revision.CDORevisionHandler; |
| import org.eclipse.emf.cdo.eresource.EresourcePackage; |
| import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision; |
| import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; |
| |
| import org.eclipse.emf.common.util.Enumerator; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EEnum; |
| import org.eclipse.emf.ecore.EEnumLiteral; |
| import org.eclipse.emf.ecore.EReference; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.teneo.hibernate.HbDataStore; |
| import org.eclipse.emf.teneo.hibernate.auditing.AuditHandler; |
| import org.eclipse.emf.teneo.hibernate.auditing.AuditVersionProvider; |
| import org.eclipse.emf.teneo.hibernate.auditing.model.teneoauditing.TeneoAuditEntry; |
| import org.eclipse.emf.teneo.hibernate.auditing.model.teneoauditing.TeneoAuditKind; |
| |
| import org.hibernate.Query; |
| import org.hibernate.Session; |
| |
| import java.util.Collection; |
| import java.util.List; |
| |
| /** |
| * Utility methods to support auditing in the hibernate store. |
| * An internal class. |
| * |
| * @author Martin Taal |
| */ |
| public class HibernateAuditHandler |
| { |
| private HibernateStore hibernateStore; |
| |
| private HbDataStore cdoDataStore; |
| |
| public CDOAuditHandler getCDOAuditHandler() |
| { |
| return (CDOAuditHandler)cdoDataStore.getAuditHandler(); |
| } |
| |
| public InternalCDORevision readRevisionByVersion(Session session, CDOID id, int version) |
| { |
| final CDOClassifierRef classifierRef = CDOIDUtil.getClassifierRef(id); |
| if (classifierRef == null) |
| { |
| throw new IllegalArgumentException("This CDOID type of " + id + " is not supported by this store."); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| final EClass eClass = HibernateUtil.getInstance().getEClass(classifierRef); |
| AuditVersionProvider auditVersionProvider = cdoDataStore.getAuditVersionProvider(); |
| auditVersionProvider.setSession(session); |
| final TeneoAuditEntry auditEntry = auditVersionProvider.getAuditEntryForVersion(eClass, id, version); |
| return (InternalCDORevision)getCDORevision(session, auditEntry); |
| } |
| |
| public InternalCDORevision readRevision(Session session, CDOID id, long timeStamp) |
| { |
| final CDOClassifierRef classifierRef = CDOIDUtil.getClassifierRef(id); |
| if (classifierRef == null) |
| { |
| throw new IllegalArgumentException("This CDOID type of " + id + " is not supported by this store."); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| final EClass eClass = HibernateUtil.getInstance().getEClass(classifierRef); |
| final CDORevision revision = getCDORevision(session, eClass, id, timeStamp); |
| return (InternalCDORevision)revision; |
| } |
| |
| public CDORevision getCDORevision(Session session, EClass eClass, Object id, long timeStamp) |
| { |
| AuditVersionProvider auditVersionProvider = cdoDataStore.getAuditVersionProvider(); |
| auditVersionProvider.setSession(session); |
| long useTimeStamp = timeStamp; |
| if (useTimeStamp == 0) |
| { |
| // use the last revision |
| useTimeStamp = Long.MAX_VALUE; |
| } |
| final TeneoAuditEntry auditEntry = auditVersionProvider.getAuditEntry(eClass, id, useTimeStamp); |
| return getCDORevision(session, auditEntry); |
| } |
| |
| public CDORevision getCDORevision(Session session, TeneoAuditEntry teneoAuditEntry) |
| { |
| final CDORevision revision = convertAuditEntryToCDORevision(teneoAuditEntry); |
| return revision; |
| } |
| |
| protected CDORevision convertAuditEntryToCDORevision(TeneoAuditEntry teneoAuditEntry) |
| { |
| if (teneoAuditEntry == null) |
| { |
| return null; |
| } |
| final HibernateStoreAccessor storeAccessor = HibernateThreadContext.getCurrentStoreAccessor(); |
| final EClass domainEClass = getCDOAuditHandler().getModelElement(teneoAuditEntry.eClass()); |
| final CDOID cdoID = HibernateUtil.getInstance().convertStringToCDOID(teneoAuditEntry.getTeneo_object_id()); |
| final InternalCDORevision revision; |
| if (teneoAuditEntry.getTeneo_audit_kind() == TeneoAuditKind.DELETE) |
| { |
| revision = new DetachedCDORevision(domainEClass, cdoID, hibernateStore.getRepository().getBranchManager().getMainBranch(), |
| new Long(teneoAuditEntry.getTeneo_object_version()).intValue(), teneoAuditEntry.getTeneo_start(), CDOBranchPoint.UNSPECIFIED_DATE); |
| revision.setRevised(CDOBranchPoint.UNSPECIFIED_DATE); |
| } |
| else |
| { |
| revision = hibernateStore.createRevision(domainEClass, cdoID); |
| revision.setVersion(new Long(teneoAuditEntry.getTeneo_object_version()).intValue()); |
| revision.setBranchPoint(storeAccessor.getStore().getMainBranchHead().getBranch().getPoint(teneoAuditEntry.getTeneo_start())); |
| if (teneoAuditEntry.getTeneo_end() > 0) |
| { |
| revision.setRevised(teneoAuditEntry.getTeneo_end()); |
| } |
| else |
| { |
| revision.setRevised(CDOBranchPoint.UNSPECIFIED_DATE); |
| } |
| convertContent(teneoAuditEntry, revision); |
| } |
| return revision; |
| } |
| |
| protected void convertContent(TeneoAuditEntry auditEntry, InternalCDORevision cdoRevision) |
| { |
| final EClass auditingEClass = auditEntry.eClass(); |
| for (EStructuralFeature targetEFeature : cdoRevision.getEClass().getEAllStructuralFeatures()) |
| { |
| final EStructuralFeature sourceEFeature = auditingEClass.getEStructuralFeature(targetEFeature.getName()); |
| if (sourceEFeature == null) |
| { |
| continue; |
| } |
| if (!auditEntry.eIsSet(sourceEFeature) && !sourceEFeature.isMany()) |
| { |
| continue; |
| } |
| if (sourceEFeature.isMany()) |
| { |
| for (Object value : (Collection<?>)auditEntry.eGet(sourceEFeature)) |
| { |
| cdoRevision.getOrCreateList(targetEFeature).add(convertValue(targetEFeature, value)); |
| } |
| } |
| else |
| { |
| final Object value = auditEntry.eGet(sourceEFeature); |
| cdoRevision.setValue(targetEFeature, convertValue(targetEFeature, value)); |
| } |
| } |
| |
| if (auditEntry.getTeneo_container_id() != null) |
| { |
| cdoRevision.setContainerID(HibernateUtil.getInstance().convertStringToCDOID(auditEntry.getTeneo_container_id())); |
| cdoRevision.setContainingFeatureID(auditEntry.getTeneo_container_feature_id()); |
| } |
| |
| final String resourceID = auditEntry.getTeneo_resourceid(); |
| if (resourceID != null) |
| { |
| cdoRevision.setResourceID(HibernateUtil.getInstance().convertStringToCDOID(resourceID)); |
| } |
| } |
| |
| private Object convertValue(EStructuralFeature targetEFeature, Object value) |
| { |
| if (value == null) |
| { |
| final Object defaultValue = targetEFeature.getDefaultValue(); |
| if (defaultValue == null) |
| { |
| return null; |
| } |
| final boolean handleUnsetAsNull = getCdoDataStore().getPersistenceOptions().getHandleUnsetAsNull(); |
| if (!handleUnsetAsNull && targetEFeature.isUnsettable()) |
| { |
| // there was a default value so was explicitly set to null |
| // otherwise the default value would be in the db |
| return CDORevisionData.NIL; |
| } |
| return null; |
| } |
| if (targetEFeature instanceof EReference) |
| { |
| final CDOID cdoID = value instanceof CDOID ? (CDOID)value : HibernateUtil.getInstance().convertStringToCDOID((String)value); |
| return cdoID; |
| } |
| if (value instanceof Enumerator) |
| { |
| return ((Enumerator)value).getValue(); |
| } |
| if (value instanceof EEnumLiteral) |
| { |
| return ((EEnumLiteral)value).getValue(); |
| } |
| if (value instanceof String && targetEFeature.getEType() instanceof EEnum) |
| { |
| return ((EEnum)targetEFeature.getEType()).getEEnumLiteralByLiteral((String)value).getValue(); |
| } |
| return value; |
| } |
| |
| public List<?> getCDOResources(Session session, CDOID folderId, long timeStamp) |
| { |
| final AuditHandler auditHandler = getCDOAuditHandler(); |
| final EClass auditEClass = auditHandler.getAuditingModelElement(EresourcePackage.eINSTANCE.getCDOResourceNode()); |
| final String entityName = cdoDataStore.toEntityName(auditEClass); |
| return getCDOResources(session, folderId, timeStamp, entityName); |
| } |
| |
| public List<?> getCDOResources(Session session, CDOID folderId, long timeStamp, String entityName) |
| { |
| final AuditHandler auditHandler = getCDOAuditHandler(); |
| String idStr = null; |
| if (folderId != null) |
| { |
| idStr = auditHandler.idToString(EresourcePackage.eINSTANCE.getCDOResourceFolder(), CDOIDUtil.getLong(folderId)); |
| } |
| |
| final String qryStr = "select e from " + entityName + " e where e.folder" + (idStr == null ? " is null " : "=:folder") |
| + " and (e.teneo_end=-1 or e.teneo_end>:end) and e.teneo_start<=:start"; |
| final Query qry = session.createQuery(qryStr); |
| if (idStr != null) |
| { |
| qry.setParameter("folder", idStr); |
| } |
| qry.setParameter("start", timeStamp); |
| qry.setParameter("end", timeStamp); |
| return qry.list(); |
| } |
| |
| public void handleRevisionsByEClass(Session session, EClass eClass, CDORevisionHandler handler, long timeStamp) |
| { |
| AuditVersionProvider auditVersionProvider = cdoDataStore.getAuditVersionProvider(); |
| auditVersionProvider.setSession(session); |
| final List<TeneoAuditEntry> teneoAuditEntries = auditVersionProvider.getSpecificAuditEntries(eClass, timeStamp); |
| for (TeneoAuditEntry teneoAuditEntry : teneoAuditEntries) |
| { |
| final CDORevision cdoRevision = getCDORevision(session, teneoAuditEntry); |
| |
| // if a subclass ignore |
| if (cdoRevision.getEClass() != eClass) |
| { |
| continue; |
| } |
| |
| if (!handler.handleRevision(cdoRevision)) |
| { |
| return; |
| } |
| } |
| } |
| |
| public HbDataStore getCdoDataStore() |
| { |
| return cdoDataStore; |
| } |
| |
| public void setCdoDataStore(HbDataStore cdoDataStore) |
| { |
| this.cdoDataStore = cdoDataStore; |
| } |
| |
| public HibernateStore getHibernateStore() |
| { |
| return hibernateStore; |
| } |
| |
| public void setHibernateStore(HibernateStore hibernateStore) |
| { |
| this.hibernateStore = hibernateStore; |
| } |
| } |