blob: b43bf8a39ecbcb183715605a655ee46dd2547876 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015 EclipseSource Muenchen GmbH 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:
* Edgar Mueller - initial API and implementation
******************************************************************************/
package org.eclipse.emf.emfstore.internal.server.core.subinterfaces;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.emfstore.internal.common.model.util.FileUtil;
import org.eclipse.emf.emfstore.internal.common.model.util.ModelUtil;
import org.eclipse.emf.emfstore.internal.server.model.versioning.ChangePackage;
import org.eclipse.emf.emfstore.internal.server.model.versioning.FileBasedChangePackage;
import org.eclipse.emf.emfstore.internal.server.model.versioning.VersioningFactory;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.AbstractOperation;
import org.eclipse.emf.emfstore.server.ESCloseableIterable;
import org.eclipse.emf.emfstore.server.exceptions.ESException;
import com.google.common.base.Optional;
/**
* Adapter that is meant to be attached to a session and stores all change package fragments.
*
* @author emueller
*
*/
public class ChangePackageFragmentUploadAdapter extends AdapterImpl {
// maps proxy ID to file-based change package
private final Map<String, FileBasedChangePackage> proxyIdToChangePackageFragments = new LinkedHashMap<String, FileBasedChangePackage>();
private final Map<String, FileBasedChangePackage> proxyIdToCompletedChangePackages = new LinkedHashMap<String, FileBasedChangePackage>();
/**
* Adds a single fragment.
*
* @param proxyId
* the ID identifying the list of fragments this fragment belongs to
* @param fragment
* the actual fragment to be added
* @throws ESException in case the fragment could not be added
*/
public void addFragment(String proxyId, List<AbstractOperation> fragment) throws ESException {
FileBasedChangePackage fileBasedChangePackage = proxyIdToChangePackageFragments.get(proxyId);
if (fileBasedChangePackage == null) {
fileBasedChangePackage = VersioningFactory.eINSTANCE.createFileBasedChangePackage();
fileBasedChangePackage.initialize(
FileUtil.createLocationForTemporaryChangePackage());
proxyIdToChangePackageFragments.put(proxyId, fileBasedChangePackage);
}
fileBasedChangePackage.addAll(fragment);
try {
fileBasedChangePackage.save();
} catch (final IOException ex) {
throw new ESException(Messages.ChangePackageFragmentAdapter_SaveChangePackageFailed, ex);
}
}
/**
* Mark a list of change package as completed.
*
* @param proxyId
* the ID of the set of change package fragments that is supposed to be completed
* @throws ESException in case
*/
public void markAsComplete(String proxyId) throws ESException {
final FileBasedChangePackage possiblyCompletedChangePackage = proxyIdToCompletedChangePackages.get(proxyId);
final FileBasedChangePackage fileBasedChangePackage = proxyIdToChangePackageFragments.get(proxyId);
if (possiblyCompletedChangePackage != null) {
throw new ESException(Messages.ChangePackageFragmentUploadAdapter_ChangePackageAlreadyComplete);
}
if (fileBasedChangePackage == null) {
throw new ESException(
MessageFormat.format(
Messages.ChangePackageFragmentUploadAdapter_NoChangePackageFragmentsFound, proxyId));
}
proxyIdToCompletedChangePackages.put(proxyId, fileBasedChangePackage);
proxyIdToChangePackageFragments.remove(proxyId);
}
/**
* Returns the aggregated change package. Fragments considered as complete need to be marked as such by
* calling {{@link #markAsComplete(String)}.
*
* @param proxyId
* the ID that identifies a list of change package fragments from which the change package
* will be created
* @return the aggregated {@link ChangePackage} as an {@link Optional}
*/
public Optional<ChangePackage> getCompletedChangePackage(String proxyId) {
final FileBasedChangePackage fileBasedChangePackage = proxyIdToCompletedChangePackages.get(proxyId);
if (fileBasedChangePackage == null) {
return Optional.absent();
}
final ESCloseableIterable<AbstractOperation> operationsHandle = fileBasedChangePackage.operations();
final ChangePackage changePackage = VersioningFactory.eINSTANCE.createChangePackage();
try {
for (final AbstractOperation operation : operationsHandle.iterable()) {
changePackage.add(ModelUtil.clone(operation));
}
} finally {
operationsHandle.close();
}
return Optional.of(changePackage);
}
/**
* Removes the completed change package matching the given ID.
*
* @param proxyId
* the ID of the change package proxy
*/
public void clearCompleted(final String proxyId) {
proxyIdToCompletedChangePackages.remove(proxyId);
}
}