/** * (C) Copyright 2013 Jabylon (http://www.jabylon.org) 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 */ package org.jabylon.cdo.connector; import java.util.Collection; import java.util.List; import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.CDOObjectReference; import org.eclipse.emf.cdo.net4j.CDONet4jSession; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.util.CommitException; import org.eclipse.emf.cdo.view.CDOView; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.net4j.util.transaction.TransactionException; import org.jabylon.cdo.connector.internal.RetryingStaleReferencePolicy; public class TransactionUtil { public static <T extends EObject, R extends EObject> R commit(T parent, Modification<T,R> op) throws CommitException { if (parent instanceof CDOObject) { CDOObject cdoObject = (CDOObject) parent; CDOView view = cdoObject.cdoView(); CDOTransaction transaction = getTransaction(cdoObject); T writableObject = transaction.getObject(parent); R returnValue = null; try{ returnValue = op.apply(writableObject); transaction.commit(); return returnValue; } finally { if(view!=transaction) { transaction.close(); if(returnValue!=null) return view.getObject(returnValue); } } } throw new TransactionException("could not obtain a transaction"); } /** * deletes the given eobject as well as all cross references pointing to it * @param object * @param features the features to consider for cross references, or null if all features are relevant * @throws CommitException */ public static void deleteWithCrossRefs(CDOObject object, final EReference... features) throws CommitException { commit(object, new Modification<CDOObject, CDOObject>() { @Override public CDOObject apply(CDOObject object) { List<CDOObjectReference> refs = object.cdoView().queryXRefs(object, features); for (CDOObjectReference reference : refs) { EStructuralFeature sourceFeature = reference.getSourceFeature(); if(sourceFeature.isMany()) { Object result = reference.getSourceObject().eGet(sourceFeature); if (result instanceof Collection) { Collection collection = (Collection) result; collection.remove(object); } } else { reference.getSourceObject().eUnset(sourceFeature); } } EcoreUtil.remove(object); return null; } }); } private static CDOTransaction getTransaction(CDOObject object) { CDOView view = object.cdoView(); if (view instanceof CDOTransaction) { CDOTransaction transaction = (CDOTransaction) view; return transaction; } else if (view != null) { return configureView(view.getSession().openTransaction()); } throw new TransactionException("could not obtain a transaction"); } public static <T extends CDOView> T configureView(T view){ view.options().setStaleReferencePolicy(RetryingStaleReferencePolicy.INSTANCE); return view; } }