blob: ec5ae13d5e208288ee422f61399a38b6ffc357e6 [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2011 See4sys, 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:
* See4sys - Initial API and implementation
* itemis - Extracted AbstractResultObjectHandler and derived SaveAsNewFileHandler from it.
* itemis - [358591] ResultObjectHandler and ResultMessageHandler used by M2xConfigurationWizards are difficult to customize and should be usable in BasicM2xActions too
*
* </copyright>
*/
package org.eclipse.sphinx.xtendxpand.jobs;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.jobs.IJobChangeListener;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.sphinx.emf.metamodel.IMetaModelDescriptor;
import org.eclipse.sphinx.emf.metamodel.MetaModelDescriptorRegistry;
import org.eclipse.sphinx.emf.resource.ModelResourceDescriptor;
import org.eclipse.sphinx.emf.util.EcorePlatformUtil;
import org.eclipse.sphinx.emf.util.WorkspaceEditingDomainUtil;
import org.eclipse.sphinx.platform.util.ExtendedPlatform;
import org.eclipse.sphinx.platform.util.PlatformLogUtil;
import org.eclipse.sphinx.xtendxpand.internal.Activator;
/**
* An {@link IJobChangeListener} implementation that can be registered on an {@link XtendJob} instance or a
* {@link M2MJob} instance that encloses the latter and saves the {@link XtendJob#getResultObjects() result objects}
* produced by the {@link XtendJob} as new files in the workspace.
*
* @see XtendJob
* @see M2MJob
*/
public class SaveAsNewFileHandler extends AbstractResultObjectHandler {
/*
* @see org.eclipse.sphinx.xtendxpand.jobs.AbstractResultObjectHandler#handleResultObjects(java.util.Map)
*/
@Override
protected void handleResultObjects(Map<Object, Collection<?>> resultObjects) {
// Create descriptors for resources in which to save result objects
Set<ModelResourceDescriptor> allModelResourceDescriptors = new HashSet<ModelResourceDescriptor>();
Set<IPath> allocatedResultPaths = new HashSet<IPath>();
for (Object inputObject : resultObjects.keySet()) {
for (Object resultObject : resultObjects.get(inputObject)) {
if (resultObject instanceof EObject && shouldSave((EObject) resultObject)) {
IPath resultPath = getUniqueResultPath(inputObject, (EObject) resultObject, allocatedResultPaths);
if (resultPath != null) {
allocatedResultPaths.add(resultPath);
String resultContentTypeId = getContentTypeIdFor((EObject) resultObject);
allModelResourceDescriptors.add(new ModelResourceDescriptor(resultPath, resultContentTypeId, (EObject) resultObject));
}
}
}
}
// Sort model resource descriptors according to editing domain which they should belong to
Map<TransactionalEditingDomain, Collection<ModelResourceDescriptor>> modelResourceDescriptors = new HashMap<TransactionalEditingDomain, Collection<ModelResourceDescriptor>>();
for (ModelResourceDescriptor modelResourceDescriptor : allModelResourceDescriptors) {
IMetaModelDescriptor mmDescriptor = MetaModelDescriptorRegistry.INSTANCE.getDescriptor(modelResourceDescriptor.getContents().iterator()
.next());
IFile modelFile = ResourcesPlugin.getWorkspace().getRoot().getFile(modelResourceDescriptor.getPath());
TransactionalEditingDomain editingDomain = WorkspaceEditingDomainUtil.getEditingDomain(modelFile.getParent(), mmDescriptor);
Collection<ModelResourceDescriptor> modelResourceDescriptorsForEditingDomain = modelResourceDescriptors.get(editingDomain);
if (modelResourceDescriptorsForEditingDomain == null) {
modelResourceDescriptorsForEditingDomain = new HashSet<ModelResourceDescriptor>();
modelResourceDescriptors.put(editingDomain, modelResourceDescriptorsForEditingDomain);
}
modelResourceDescriptorsForEditingDomain.add(modelResourceDescriptor);
}
// Save model resources
for (TransactionalEditingDomain editingDomain : modelResourceDescriptors.keySet()) {
try {
EcorePlatformUtil.saveNewModelResources(editingDomain, modelResourceDescriptors.get(editingDomain), true, null);
} catch (Exception ex) {
PlatformLogUtil.logAsError(Activator.getPlugin(), ex);
}
}
}
protected boolean shouldSave(EObject object) {
Assert.isNotNull(object);
// Return true if given object is not already contained in any resource
return object.eResource() == null;
}
protected IPath getUniqueResultPath(Object inputObject, EObject resultObject, Set<IPath> allocatedResultPaths) {
IPath candidateResultPath = getResultPath(inputObject, resultObject);
if (candidateResultPath != null) {
return ExtendedPlatform.createUniquePath(candidateResultPath, allocatedResultPaths);
}
return null;
}
protected IPath getResultPath(Object inputObject, EObject resultObject) {
IFile inputFile = EcorePlatformUtil.getFile(inputObject);
IPath projectRelativeResultPath = getProjectRelativeResultPath(inputFile, resultObject);
if (projectRelativeResultPath != null) {
return inputFile.getProject().getFullPath().append(projectRelativeResultPath);
}
return null;
}
protected IPath getProjectRelativeResultPath(IFile inputFile, EObject resultObject) {
if (inputFile != null) {
String resultFileExtension = getFileExtensionFor(resultObject);
return inputFile.getProjectRelativePath().removeFileExtension().addFileExtension(resultFileExtension);
}
return null;
}
protected String getFileExtensionFor(EObject object) {
// Try to retrieve file extension supported by content type behind given EObject
String contentTypeId = getContentTypeIdFor(object);
if (contentTypeId != null) {
Collection<String> possibleExtensions = ExtendedPlatform.getContentTypeFileExtensions(contentTypeId);
if (!possibleExtensions.isEmpty()) {
return possibleExtensions.iterator().next();
}
}
// Return name of given EObject's EPackage as file extension
return object.eClass().getEPackage().getName();
}
protected String getContentTypeIdFor(EObject object) {
IMetaModelDescriptor mmDescriptor = MetaModelDescriptorRegistry.INSTANCE.getDescriptor(object.eClass());
if (mmDescriptor != null) {
return mmDescriptor.getDefaultContentTypeId();
}
return null;
}
}