| /* |
| * Copyright (c) 2009-2012, 2014 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: |
| * Simon McDuff - initial API and implementation |
| * Eike Stepper - maintenance |
| */ |
| package org.eclipse.emf.cdo.transaction; |
| |
| import org.eclipse.emf.cdo.CDOObject; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta; |
| import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta; |
| import org.eclipse.emf.cdo.eresource.CDOResource; |
| import org.eclipse.emf.cdo.util.CDOUtil; |
| |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EReference; |
| import org.eclipse.emf.spi.cdo.FSMUtil; |
| import org.eclipse.emf.spi.cdo.InternalCDOObject; |
| |
| import java.util.List; |
| |
| /** |
| * A {@link CDOTransactionHandler1 transaction handler} that automatically attaches cross-referenced objects to the |
| * {@link CDOResource resource} that contains the referencing {@link CDOObject object}. |
| * |
| * @author Simon McDuff |
| * @since 2.0 |
| */ |
| public class CDOAutoAttacher extends CDODefaultTransactionHandler1 |
| { |
| private CDOTransaction transaction; |
| |
| public CDOAutoAttacher(CDOTransaction transaction) |
| { |
| this.transaction = transaction; |
| transaction.addTransactionHandler(this); |
| } |
| |
| public CDOTransaction getTransaction() |
| { |
| return transaction; |
| } |
| |
| @Override |
| public void attachingObject(CDOTransaction transaction, CDOObject object) |
| { |
| if (object instanceof CDOResource) |
| { |
| return; |
| } |
| |
| // Persist the graph as well. |
| EObject obj = CDOUtil.getEObject(object); |
| handle(obj, obj); |
| } |
| |
| @Override |
| public void modifyingObject(CDOTransaction transaction, CDOObject object, CDOFeatureDelta featureChange) |
| { |
| if (object instanceof CDOResource) |
| { |
| return; |
| } |
| |
| if (featureChange != null) |
| { |
| CDOFeatureDeltaVisitorAutoAttach featureChangeVisitor = new CDOFeatureDeltaVisitorAutoAttach(object); |
| featureChange.accept(featureChangeVisitor); |
| } |
| } |
| |
| protected void persist(EObject res, Object object) |
| { |
| if (!(object instanceof CDOResource) && object instanceof InternalCDOObject) |
| { |
| InternalCDOObject cdoObject = (InternalCDOObject)object; |
| if (FSMUtil.isTransient(cdoObject)) |
| { |
| res.eResource().getContents().add(cdoObject); |
| } |
| } |
| } |
| |
| private void check(EObject referrer, EReference reference, EObject element) |
| { |
| if (element != null && element.eResource() == null) |
| { |
| if (reference != null && reference.isContainment()) |
| { |
| handle(referrer, element); |
| } |
| else |
| { |
| persist(referrer, CDOUtil.getCDOObject(element)); |
| } |
| } |
| } |
| |
| @SuppressWarnings("unchecked") |
| private void handle(EObject referrer, EObject eObject) |
| { |
| for (EReference reference : eObject.eClass().getEAllReferences()) |
| { |
| if (reference.isMany()) |
| { |
| List<EObject> list = (List<EObject>)eObject.eGet(reference); |
| for (EObject element : list) |
| { |
| check(referrer, reference, element); |
| } |
| } |
| else |
| { |
| check(referrer, reference, (EObject)eObject.eGet(reference)); |
| } |
| } |
| } |
| |
| /** |
| * @author Simon McDuff |
| * @since 2.0 |
| */ |
| private class CDOFeatureDeltaVisitorAutoAttach implements CDOFeatureDeltaVisitor |
| { |
| private EObject referrer; |
| |
| public CDOFeatureDeltaVisitorAutoAttach(EObject referrer) |
| { |
| this.referrer = referrer; |
| } |
| |
| public void visit(CDOAddFeatureDelta featureChange) |
| { |
| persist(referrer, featureChange.getValue()); |
| } |
| |
| public void visit(CDOClearFeatureDelta featureChange) |
| { |
| } |
| |
| public void visit(CDOListFeatureDelta featureChange) |
| { |
| } |
| |
| public void visit(CDOMoveFeatureDelta featureChange) |
| { |
| } |
| |
| public void visit(CDORemoveFeatureDelta featureChange) |
| { |
| } |
| |
| public void visit(CDOSetFeatureDelta featureChange) |
| { |
| persist(referrer, featureChange.getValue()); |
| } |
| |
| public void visit(CDOUnsetFeatureDelta featureChange) |
| { |
| } |
| |
| public void visit(CDOContainerFeatureDelta featureChange) |
| { |
| } |
| } |
| } |