blob: 67052f9bc5b3ded817efac89befaf444dac0c0fe [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2014 itemis and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
*
* Contributors:
* itemis - Initial API and implementation
* Siemens - [574930] Model load manager extension
*
* </copyright>
*/
package org.eclipse.sphinx.emf.workspace.loading.operations;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.osgi.util.NLS;
import org.eclipse.sphinx.emf.scoping.ResourceScopeProviderRegistry;
import org.eclipse.sphinx.emf.util.EcorePlatformUtil;
import org.eclipse.sphinx.emf.util.WorkspaceEditingDomainUtil;
import org.eclipse.sphinx.emf.workspace.Activator;
import org.eclipse.sphinx.emf.workspace.internal.messages.Messages;
import org.eclipse.sphinx.emf.workspace.loading.SchedulingRuleFactory;
import org.eclipse.sphinx.platform.operations.AbstractWorkspaceOperation;
import org.eclipse.sphinx.platform.util.PlatformLogUtil;
public class DefaultUpdateResourceURIOperation extends AbstractWorkspaceOperation implements IUpdateResourceURIOperation {
private Map<IFile, IPath> filesToUpdate;
public DefaultUpdateResourceURIOperation(Map<IFile, IPath> filesToUpdate) {
super(Messages.job_updatingResourceURIs);
this.filesToUpdate = filesToUpdate;
}
@Override
public void run(IProgressMonitor monitor) throws CoreException {
runDetectAndUpdateResourceURIs(filesToUpdate, monitor);
}
@Override
public ISchedulingRule getRule() {
return new SchedulingRuleFactory().createLoadSchedulingRule(filesToUpdate.keySet());
}
protected void runDetectAndUpdateResourceURIs(Map<IFile, IPath> filesToUpdate, IProgressMonitor monitor) throws OperationCanceledException {
Assert.isNotNull(filesToUpdate);
SubMonitor progress = SubMonitor.convert(monitor, Messages.task_updatingResourceURIs, 100);
if (progress.isCanceled()) {
throw new OperationCanceledException();
}
Map<TransactionalEditingDomain, Map<IFile, IPath>> filesToUpdateResourceURIFor = detectFilesToUpdateResourceURIFor(filesToUpdate,
progress.newChild(10));
// Nothing to update?
if (filesToUpdateResourceURIFor.size() == 0) {
progress.done();
return;
}
runUpdateResourceURIs(filesToUpdateResourceURIFor, progress.newChild(90));
}
protected void runUpdateResourceURIs(Map<TransactionalEditingDomain, Map<IFile, IPath>> filesToUpdateResourceURIFor, IProgressMonitor monitor)
throws OperationCanceledException {
Assert.isNotNull(filesToUpdateResourceURIFor);
SubMonitor progress = SubMonitor.convert(monitor, filesToUpdateResourceURIFor.keySet().size());
if (progress.isCanceled()) {
throw new OperationCanceledException();
}
for (TransactionalEditingDomain editingDomain : filesToUpdateResourceURIFor.keySet()) {
updateResourceURIsInEditingDomain(editingDomain, filesToUpdateResourceURIFor.get(editingDomain), progress.newChild(1));
}
}
protected void updateResourceURIsInEditingDomain(final TransactionalEditingDomain editingDomain,
final Map<IFile, IPath> filesToUpdateResourceURIForInEditingDomain, final IProgressMonitor monitor) throws OperationCanceledException {
Assert.isNotNull(editingDomain);
Assert.isNotNull(filesToUpdateResourceURIForInEditingDomain);
try {
editingDomain.runExclusive(new Runnable() {
@Override
public void run() {
SubMonitor progress = SubMonitor.convert(monitor, filesToUpdateResourceURIForInEditingDomain.size());
if (progress.isCanceled()) {
throw new OperationCanceledException();
}
for (IFile oldFile : filesToUpdateResourceURIForInEditingDomain.keySet()) {
progress.subTask(NLS.bind(Messages.subtask_updatingResourceURI, oldFile.getFullPath().toString()));
URI oldURI = EcorePlatformUtil.createURI(oldFile.getFullPath());
Resource resource = editingDomain.getResourceSet().getResource(oldURI, false);
if (resource != null) {
IPath newPath = filesToUpdateResourceURIForInEditingDomain.get(oldFile);
URI newURI = EcorePlatformUtil.createURI(newPath);
resource.setURI(newURI);
}
progress.worked(1);
progress.subTask(""); //$NON-NLS-1$
if (progress.isCanceled()) {
throw new OperationCanceledException();
}
editingDomain.yield();
}
}
});
} catch (InterruptedException ex) {
PlatformLogUtil.logAsWarning(Activator.getDefault(), ex);
}
}
protected Map<TransactionalEditingDomain, Map<IFile, IPath>> detectFilesToUpdateResourceURIFor(Map<IFile, IPath> files,
IProgressMonitor monitor) {
Assert.isNotNull(files);
SubMonitor progress = SubMonitor.convert(monitor, files.size());
if (progress.isCanceled()) {
throw new OperationCanceledException();
}
Map<TransactionalEditingDomain, Map<IFile, IPath>> filesToUpdateResourceURIFor = new HashMap<TransactionalEditingDomain, Map<IFile, IPath>>();
for (final IFile oldFile : files.keySet()) {
try {
/*
* Performance optimization: Check if current file is a potential model file inside an existing scope.
* This helps excluding obvious non-model files and model files that are out of scope right away and
* avoids potentially lengthy but useless processing of the same.
*/
if (!ResourceScopeProviderRegistry.INSTANCE.isNotInAnyScope(oldFile)) {
progress.subTask(NLS.bind(Messages.subtask_analyzingFile, oldFile.getFullPath()));
TransactionalEditingDomain editingDomain = WorkspaceEditingDomainUtil.getCurrentEditingDomain(oldFile);
if (editingDomain != null) {
Map<IFile, IPath> filesToUpdateResourceURIForInEditingDomain = filesToUpdateResourceURIFor.get(editingDomain);
if (filesToUpdateResourceURIForInEditingDomain == null) {
filesToUpdateResourceURIForInEditingDomain = new HashMap<IFile, IPath>();
filesToUpdateResourceURIFor.put(editingDomain, filesToUpdateResourceURIForInEditingDomain);
}
filesToUpdateResourceURIForInEditingDomain.put(oldFile, files.get(oldFile));
}
}
} catch (Exception ex) {
PlatformLogUtil.logAsWarning(Activator.getPlugin(), ex);
}
progress.worked(1);
progress.subTask(""); //$NON-NLS-1$
if (progress.isCanceled()) {
throw new OperationCanceledException();
}
}
return filesToUpdateResourceURIFor;
}
}