/*******************************************************************************
* Copyright (c) 2014 Obeo.
* 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:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.logical.view;
import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.mapping.IModelProviderDescriptor;
import org.eclipse.core.resources.mapping.ModelProvider;
import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.resources.mapping.ResourceMappingContext;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
import org.eclipse.emf.compare.ide.ui.internal.logical.EMFModelProvider;
import org.eclipse.emf.compare.ide.ui.internal.logical.EMFResourceMapping;
import org.eclipse.emf.compare.ide.ui.logical.SynchronizationModel;
/**
* Util methods, for the Logical Model View handlers.
*
* @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
*/
public final class LogicalModelViewHandlerUtil {
/**
* Number of ticks consumed by the
* {@link EMFResourceMapping#getTraversals(ResourceMappingContext, IProgressMonitor)} method.
*/
private static final int GET_TRAVERSALS_TICKS = 15;
/** Number of ticks consumed by the {@link #getResourceMappings(IFile, IProgressMonitor)} method. */
private static final int GET_RESOURCES_MAPPING_TICKS = 85;
/** The model descriptor of the EMF Model Provider. Used to check EMF Compare compliance on files. */
private static IModelProviderDescriptor modelDescriptor = ModelProvider
.getModelProviderDescriptor(EMFModelProvider.PROVIDER_ID);
/**
* Constructor.
*/
private LogicalModelViewHandlerUtil() {
}
/**
* Get the logical model associated with the given file.
*
* @param file
* the given file to compute the logical model.
* @param monitor
* to monitor the process.
* @return the synchronization model associated with the given file.
*/
public static Collection<SynchronizationModel> getSynchronizationModels(IFile file,
IProgressMonitor monitor) {
final Collection<SynchronizationModel> logicalModels = Sets.newHashSet();
if (file == null) {
return null;
}
SubMonitor subMonitor = SubMonitor.convert(monitor, 100);
Collection<EMFResourceMapping> resourceMappings = getResourceMappings(file,
subMonitor.newChild(GET_RESOURCES_MAPPING_TICKS));
subMonitor.worked(GET_RESOURCES_MAPPING_TICKS);
SubMonitor subMonitorLoop = subMonitor.newChild(GET_TRAVERSALS_TICKS)
.setWorkRemaining(resourceMappings.size());
for (ResourceMapping resourceMapping : resourceMappings) {
if (resourceMapping instanceof EMFResourceMapping) {
try {
((EMFResourceMapping)resourceMapping).getTraversals(ResourceMappingContext.LOCAL_CONTEXT,
subMonitorLoop.newChild(1));
logicalModels.add(((EMFResourceMapping)resourceMapping).getLatestModel());
} catch (CoreException e) {
EMFCompareIDEUIPlugin.getDefault().log(e);
}
}
}
return logicalModels;
}
/**
* Get the resources of the given logical models.
*
* @param logicalModels
* the logical models.
* @param monitor
* to monitor the process.
* @return the resources of the given logical models.
*/
public static Collection<IResource> getLogicalModelResources(
Collection<SynchronizationModel> logicalModels, IProgressMonitor monitor) {
SubMonitor subMonitor = SubMonitor.convert(monitor, 100);
SubMonitor subMonitorLoop = subMonitor.newChild(100).setWorkRemaining(logicalModels.size());
final Collection<IResource> resources = Sets.newHashSet();
for (Iterator<SynchronizationModel> it = logicalModels.iterator(); it.hasNext();) {
SynchronizationModel logicalModel = it.next();
resources.addAll(logicalModel.getResources());
subMonitorLoop.newChild(1);
}
return resources;
}
/**
* Check if the given file is a model compliant with EMF Compare.
*
* @param file
* the file to test.
* @return true if the file is compliant, false otherwise.
*/
public static boolean isEMFCompareCompliantFile(IFile file) {
try {
IResource[] resources = modelDescriptor.getMatchingResources(new IResource[] {file, });
if (resources.length > 0) {
return true;
}
} catch (CoreException e) {
EMFCompareIDEUIPlugin.getDefault().log(e);
}
return false;
}
/**
* This will query the EMF model provider on the given file and list all EMF mappings available for that
* file.
*
* @param file
* The file for which we need the associated resource mappings.
* @param monitor
* to monitor the process.
* @return All EMF mappings available for that file.
*/
private static Collection<EMFResourceMapping> getResourceMappings(IFile file, IProgressMonitor monitor) {
final Set<EMFResourceMapping> mappings = Sets.newLinkedHashSet();
if (isEMFCompareCompliantFile(file)) {
try {
// get mappings from model provider if there are matching resources
ModelProvider model = modelDescriptor.getModelProvider();
ResourceMapping[] modelMappings = model.getMappings(file,
ResourceMappingContext.LOCAL_CONTEXT, monitor);
for (ResourceMapping mapping : modelMappings) {
if (mapping instanceof EMFResourceMapping) {
mappings.add((EMFResourceMapping)mapping);
}
}
} catch (CoreException e) {
EMFCompareIDEUIPlugin.getDefault().log(e);
}
}
return mappings;
}
}