blob: bddf0f233ec1bbcd32861cf7f1210f641cbf87e9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.synchronizer;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.ext.base.Options;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
/**
* A refresh plan holds the list of operation : creation, refreshment or
* removing needed to update the output model.
*
* @author Cedric Brun <cedric.brun@obeo.fr>
*
*/
public class RefreshPlan {
private SignatureProvider signatureProvider;
private Map<Signature, OutputDescriptor> outputToCreate;
private Map<Signature, CreatedOutput> outputToRefresh;
private Map<Signature, CreatedOutput> outputToUpdateMapping;
private Multimap<Signature, CreatedOutput> outputToRemove;
/**
* Creates a new RefreshPlan.
*
* @param signProvider
* the {@link SignatureProvider} to use
*/
public RefreshPlan(SignatureProvider signProvider) {
outputToCreate = new LinkedHashMap<>();
outputToRefresh = new LinkedHashMap<>();
outputToRemove = HashMultimap.create();
outputToUpdateMapping = new HashMap<>();
this.signatureProvider = signProvider;
}
public Collection<CreatedOutput> getDescriptorToUpdateMapping() {
return outputToUpdateMapping.values();
}
/**
* Adds a PreRefreshStatus to the RefreshPlan.
*
* @param pre
* the PreRefreshStatus to add to the refresh plan
*/
public void addPreviousStatus(Iterable<? extends CreatedOutput> pre) {
for (CreatedOutput desc : pre) {
shouldBeRemoved(desc);
}
}
private void shouldBeRemoved(CreatedOutput desc) {
outputToRemove.put(signatureProvider.getSignature(desc.getDescriptor()), desc);
}
public void appendOutputDescritorsKeepingTheMostSpecific(Collection<? extends OutputDescriptor> computeDescriptors) {
for (OutputDescriptor newDescriptor : computeDescriptors) {
Option<CreatedOutput> wasHere = getDescriptorAlreadyHereWeWantToKeep(newDescriptor);
if (wasHere.some()) {
if (wasHere.get().getDescriptor().getIndex() != newDescriptor.getIndex()) {
shouldBeReordered(wasHere.get(), newDescriptor.getIndex());
}
if (wasHere.get().getDescriptor().getMapping() != newDescriptor.getMapping()) {
shouldUpdateTheMapping(wasHere.get(), newDescriptor.getMapping());
}
shouldBeRefreshed(wasHere.get());
} else {
shouldBeCreated(newDescriptor);
}
}
}
private void shouldUpdateTheMapping(CreatedOutput createdOutput, Mapping mapping) {
createdOutput.setNewMapping(mapping);
Signature signature = signatureProvider.getSignature(createdOutput.getDescriptor());
// CreatedOutput previousVersionOutput =
// outputToRemove.remove(signature);
// previousVersionOutput.setNewMapping(mapping);
outputToUpdateMapping.put(signature, createdOutput);
}
private void shouldBeCreated(OutputDescriptor newDescriptor) {
/*
* First let's check if an equivalent descriptor is already registered
* to be created.
*/
Signature signature = signatureProvider.getSignature(newDescriptor);
if (!outputToCreate.containsKey(signature) && !outputToRefresh.containsKey(signature)) {
outputToCreate.put(signature, newDescriptor);
}
}
private void shouldBeRefreshed(CreatedOutput outputDescriptor) {
Signature signature = signatureProvider.getSignature(outputDescriptor.getDescriptor());
Option<CreatedOutput> element = getDescriptorAlreadyHereWeWantToKeep(outputDescriptor.getDescriptor());
if (element.some()) {
outputToRemove.remove(signature, element.get());
if (!outputToRefresh.containsKey(signature)) {
outputToRefresh.put(signature, element.get());
}
}
}
private void shouldBeReordered(CreatedOutput newDescriptor, int nextIndex) {
newDescriptor.setNewIndex(nextIndex);
}
private Option<CreatedOutput> getDescriptorAlreadyHereWeWantToKeep(OutputDescriptor newDescriptor) {
Collection<CreatedOutput> toRemove = outputToRemove.get(signatureProvider.getSignature(newDescriptor));
if (toRemove.size() > 0) {
return Options.newSome(toRemove.iterator().next());
}
return Options.newNone();
}
public Collection<CreatedOutput> getDescriptorsToDelete() {
return outputToRemove.values();
}
public Collection<OutputDescriptor> getDescriptorsToCreate() {
return outputToCreate.values();
}
public Collection<CreatedOutput> getDescriptorsToRefresh() {
return outputToRefresh.values();
}
}