blob: e6346b1a82fbc7239901bb21f88812e9051898f1 [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 - [358131] Make Xtend/Xpand/CheckJobs more robust against template file encoding mismatches
*
* </copyright>
*/
package org.eclipse.sphinx.xtendxpand.util;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.mwe.core.resources.ResourceLoader;
import org.eclipse.internal.xtend.type.baseimpl.TypesComparator;
import org.eclipse.sphinx.emf.mwe.IXtendXpandConstants;
import org.eclipse.sphinx.emf.mwe.resources.BasicWorkspaceResourceLoader;
import org.eclipse.xtend.typesystem.Callable;
import org.eclipse.xtend.typesystem.Feature;
import org.eclipse.xtend.typesystem.ParameterizedCallable;
import org.eclipse.xtend.typesystem.Type;
public final class XtendXpandUtil {
public static final String XTEND_SHARED_UI_PLUGIN_ID = "org.eclipse.xtend.shared.ui"; //$NON-NLS-1$
public static final String XTEND_XPAND_NATURE_ID = XTEND_SHARED_UI_PLUGIN_ID + ".xtendXPandNature"; //$NON-NLS-1$
public static final String PREFERENCE_KEY_PROJECT_SPECIFIC_METAMODEL = "project.specific.metamodel"; //$NON-NLS-1$
public static final String PREFERENCE_KEY_METAMODEL_CONTRIBUTOR = "metamodelContributor"; //$NON-NLS-1$
// Prevent from instantiation
private XtendXpandUtil() {
}
public static String getQualifiedName(IFile underlyingFile, String definitionOrFeatureName) {
Assert.isNotNull(underlyingFile);
if (underlyingFile.exists()) {
StringBuilder qualifiedName = new StringBuilder();
IPath path = underlyingFile.getProjectRelativePath().removeFileExtension();
for (Iterator<String> iter = Arrays.asList(path.segments()).iterator(); iter.hasNext();) {
String segment = iter.next();
qualifiedName.append(segment);
if (iter.hasNext()) {
qualifiedName.append(IXtendXpandConstants.NS_DELIMITER);
}
}
if (definitionOrFeatureName != null && definitionOrFeatureName.length() > 0) {
qualifiedName.append(IXtendXpandConstants.NS_DELIMITER);
qualifiedName.append(definitionOrFeatureName);
}
return qualifiedName.toString();
}
return null;
}
public static IFile getUnderlyingFile(String qualifiedName, String extension) {
return getUnderlyingFile(qualifiedName, extension, new BasicWorkspaceResourceLoader());
}
public static IFile getUnderlyingFile(String qualifiedName, String extension, ResourceLoader resourceLoader) {
Assert.isNotNull(resourceLoader);
if (qualifiedName != null) {
// Assume that given qualified name represents an Xpand or Xtend template and try resolve it as is
IPath path = new Path(qualifiedName.replace(IXtendXpandConstants.NS_DELIMITER, Character.toString(IPath.SEPARATOR)))
.addFileExtension(extension);
URL resourceURL = resourceLoader.getResource(path.toString());
if (resourceURL == null && path.segmentCount() > 1) {
// Assume that given qualified name represents a definition of feature inside an Xpand or Xtend
// template; so ignore the last segment and try to resolve only the file part of it
resourceURL = resourceLoader.getResource(path.removeLastSegments(1).addFileExtension(extension).toString());
}
if (resourceURL != null) {
// Avoid CoreException in
// org.eclipse.core.internal.filesystem.InternalFileSystemCore.getFileSystem(String)
if (!"bundleresource".equals(resourceURL.getProtocol())) { //$NON-NLS-1$
try {
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
// Find all files that are mapped to the given URI
/*
* !! Important Note !! The search result includes files located in the workspace as well as
* linked files or files contained in a linked folder that were located outside of the
* workspace.
*/
IFile[] files = workspaceRoot.findFilesForLocationURI(resourceURL.toURI());
if (files != null && files.length > 0) {
// Returns the first workspace file that match
return files[0];
}
} catch (Exception ex) {
// Ignore exception
}
}
}
}
return null;
}
public static List<Callable> getApplicableFeatures(final List<? extends Callable> features, Class<?> featureType, String featureName,
List<? extends Type> paramTypes) {
final List<Callable> applicableFeatures = new ArrayList<Callable>();
Comparator<List<? extends Type>> typesComparator = new TypesComparator();
for (Callable feature : features) {
if (featureType.isInstance(feature) && (featureName == null || feature.getName().equals(featureName))) {
final List<? extends Type> featureParamTypes = getParamTypes(feature);
if (featureParamTypes.size() == paramTypes.size() && typesComparator.compare(featureParamTypes, paramTypes) >= 0) {
applicableFeatures.add(feature);
}
}
}
return applicableFeatures;
}
private static List<? extends Type> getParamTypes(Callable feature) {
final List<Type> result = new ArrayList<Type>();
if (feature instanceof Feature) {
result.add(((Feature) feature).getOwner());
}
if (feature instanceof ParameterizedCallable) {
if (((ParameterizedCallable) feature).getParameterTypes() != null) {
result.addAll(((ParameterizedCallable) feature).getParameterTypes());
}
}
return result;
}
}