blob: 08be6b002d79dcc55ff4f785057ffb7c39e26df2 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2013, 2017 CEA LIST and others.
*
* All rights reserved. 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:
* CEA LIST - Initial API and implementation
* Christian W. Damus (CEA) - bug 422257
* Eike Stepper (CEA) - bug 466520
*
*****************************************************************************/
package org.eclipse.papyrus.cdo.internal.core.exporter;
import java.util.Iterator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.emf.cdo.explorer.checkouts.CDOCheckout;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.papyrus.cdo.core.exporter.IModelExportMapping;
import org.eclipse.papyrus.cdo.core.exporter.IModelExporter;
import org.eclipse.papyrus.cdo.core.importer.IModelTransferConfiguration;
import org.eclipse.papyrus.cdo.core.importer.IModelTransferNode;
import org.eclipse.papyrus.cdo.core.importer.IModelTransferOperation;
import org.eclipse.papyrus.cdo.internal.core.Activator;
import org.eclipse.papyrus.cdo.internal.core.CDOProxyResolvingResourceSet;
import org.eclipse.papyrus.cdo.internal.core.CDOUtils;
import org.eclipse.papyrus.cdo.internal.core.l10n.Messages;
import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
/**
* This is the ModelExporter type. Enjoy.
*/
public class ModelExporter implements IModelExporter {
public ModelExporter() {
super();
}
@Override
public Diagnostic exportModels(final IModelExportMapping mapping) {
BasicDiagnostic result = new BasicDiagnostic();
add(result, mapping.getConfiguration().validate());
add(result, mapping.validate());
if (result.getSeverity() < Diagnostic.ERROR) {
add(result, mapping.getConfiguration().getOperationContext().run(new IModelTransferOperation() {
@Override
public Diagnostic run(IProgressMonitor monitor) {
return doExport(mapping, monitor);
}
}));
}
return result;
}
protected Diagnostic doExport(IModelExportMapping mapping, IProgressMonitor monitor) {
BasicDiagnostic result = new BasicDiagnostic();
IModelTransferConfiguration configuration = mapping.getConfiguration();
// 1/resource for loading, 1/resource for exporting,
// 1 for proxy resolution, 1 for resource saving, and 1 for clean-up
SubMonitor sub = SubMonitor.convert(monitor, Messages.ModelExporter_0, 2 * configuration.getModelsToTransfer().size() + 3);
CDOCheckout checkout = mapping.getCheckout();
CDOTransaction transaction = checkout.openTransaction(new CDOProxyResolvingResourceSet());
ResourceSet source = transaction.getResourceSet();
ResourceSet destination = new ResourceSetImpl();
try {
// load all models to be exported and resolve their cross-references so that CDO-style
// cross-resource proxies will be resolved
for (IModelTransferNode model : configuration.getModelsToTransfer()) {
add(result, loadModel(model, transaction, sub.newChild(1)));
}
EcoreUtil.resolveAll(source);
sub.worked(1);
for (IModelTransferNode model : configuration.getModelsToTransfer()) {
add(result, exportModel(model, transaction, mapping.getMapping(model), destination, sub.newChild(1)));
}
for (IModelTransferNode model : configuration.getModelsToTransfer()) {
add(result, saveModel(model, transaction, mapping.getMapping(model), destination));
}
sub.worked(1);
} finally {
// don't clean up the configuration's resource set because it is not owned by the configuration
EMFHelper.unload(destination);
CDOUtils.unload(transaction);
transaction.close();
EMFHelper.unload(source);
sub.worked(1);
}
sub.done();
return result;
}
protected Diagnostic loadModel(IModelTransferNode model, CDOView view, IProgressMonitor monitor) {
BasicDiagnostic result = new BasicDiagnostic();
SubMonitor sub = SubMonitor.convert(monitor, model.getName(), model.getResourceURIs().size());
for (URI next : model.getResourceURIs()) {
Resource source = view.getResourceSet().getResource(next, true);
for (Iterator<?> iter = source.getContents().iterator(); iter.hasNext(); iter.next()) {
// just iterate them to load the contents; we will walk over the content trees later to resolve proxies
}
sub.worked(1);
}
sub.done();
return result;
}
protected Diagnostic exportModel(IModelTransferNode model, CDOView view, IPath toPath, ResourceSet rset, IProgressMonitor monitor) {
BasicDiagnostic result = new BasicDiagnostic();
IPath basePath = toPath.removeFileExtension();
SubMonitor sub = SubMonitor.convert(monitor, model.getName(), model.getResourceURIs().size());
for (URI next : model.getResourceURIs()) {
Resource source = view.getResourceSet().getResource(next, true);
Resource destination = rset.createResource(URI.createPlatformResourceURI(basePath.addFileExtension(next.fileExtension()).toString(), true));
add(result, exportResource(source, destination));
sub.worked(1);
}
sub.done();
return result;
}
protected Diagnostic exportResource(Resource source, Resource destination) {
destination.getContents().addAll(source.getContents());
return Diagnostic.OK_INSTANCE;
}
protected Diagnostic saveModel(IModelTransferNode model, CDOView view, IPath toPath, ResourceSet rset) {
BasicDiagnostic result = new BasicDiagnostic();
IPath basePath = toPath.removeFileExtension();
for (URI next : model.getResourceURIs()) {
Resource destination = rset.getResource(URI.createPlatformResourceURI(basePath.addFileExtension(next.fileExtension()).toString(), true), false);
try {
destination.save(null);
} catch (Exception e) {
add(result, new BasicDiagnostic(IStatus.ERROR, Activator.PLUGIN_ID, 0, Messages.ModelExporter_1, new Object[] { e }));
}
}
return result;
}
private static void add(DiagnosticChain diagnostics, Diagnostic diagnostic) {
if (diagnostic.getSeverity() > Diagnostic.OK) {
diagnostics.merge(diagnostic);
}
}
}