com.redhat.ceylon.common.tools.ModuleWildcardsHelper Maven / Gradle / Ivy
package com.redhat.ceylon.common.tools;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import com.redhat.ceylon.common.Backend;
import com.redhat.ceylon.common.Constants;
import com.redhat.ceylon.common.FileUtil;
import com.redhat.ceylon.common.ModuleDescriptorReader;
import com.redhat.ceylon.common.ModuleSpec;
import com.redhat.ceylon.common.ModuleUtil;
/**
* Class with helper methods for expanding a list of module names/specs
* that possibly contain wildcards into an expanded list of actual modules
* that were found on the file system
* @author Tako Schotanus
*/
public abstract class ModuleWildcardsHelper {
/**
* Given a source directory and a list of ModuleSpecs
* that possibly contain wildcards it returns a expanded list of
* ModuleSpecs of modules that were actually found in the given
* source directory. ModuleSpecs that didn't contain wildcards
* are left alone (it's not checked if they exist or not).
* If a Backend is passed expanded modules will be checked if
* they support it (they either don't have a native annotation
* or it is for the correct backend).
* @param dirs The source directory
* @param names The list of ModuleSpecs
* @param forBackend The Backend for which we work or null
* @return An expanded list of ModuleSpecs
*/
public static List expandSpecWildcards(File dir, List modules, Backend forBackend) {
List dirs = new ArrayList();
dirs.add(dir);
return expandSpecWildcards(dirs, modules, forBackend);
}
/**
* Given a list of source directories and a list of ModuleSpecs
* that possibly contain wildcards it returns a expanded list of
* ModuleSpecs of modules that were actually found in the given
* source directories. ModuleSpecs that didn't contain wildcards
* are left alone (it's not checked if they exist or not).
* If a Backend is passed expanded modules will be checked if
* they support it (they either don't have a native annotation
* or it is for the correct backend).
* @param dirs The list of source directories
* @param names The list of ModuleSpecs
* @param forBackend The Backend for which we work or null
* @return An expanded list of ModuleSpecs
*/
public static List expandSpecWildcards(List dirs, List modules, Backend forBackend) {
List result = new ArrayList(modules.size());
for (ModuleSpec spec : modules) {
List names = new ArrayList();
expandWildcard(names, dirs, spec.getName(), forBackend);
for (String name : names) {
result.add(new ModuleSpec(spec.getNamespace(), name, spec.getVersion()));
}
}
return result;
}
/**
* Given a source directory and a list of module names
* that possibly contain wildcards it returns a expanded list of
* module names of modules that were actually found in the given
* source directory. Module names that didn't contain wildcards
* are left alone (it's not checked if they exist or not).
* If a Backend is passed expanded modules will be checked if
* they support it (they either don't have a native annotation
* or it is for the correct backend).
* @param dirs The source directory
* @param names The list of module names
* @param forBackend The Backend for which we work or null
* @return An expanded list of module names
*/
public static List expandWildcards(File dir, Collection modules, Backend forBackend) {
List dirs = new ArrayList();
dirs.add(dir);
return expandWildcards(dirs, modules, forBackend);
}
/**
* Given a list of source directories and a list of module names
* that possibly contain wildcards it returns a expanded list of
* module names of modules that were actually found in the given
* source directories. Module names that didn't contain wildcards
* are left alone (it's not checked if they exist or not).
* If a Backend is passed expanded modules will be checked if
* they support it (they either don't have a native annotation
* or it is for the correct backend).
* @param dirs The list of source directories
* @param names The list of module names
* @param forBackend The Backend for which we work or null
* @return An expanded list of module names
*/
public static List expandWildcards(Iterable dirs, Collection names, Backend forBackend) {
List result = new ArrayList(names.size());
for (String name : names) {
expandWildcard(result, dirs, name, forBackend);
}
return result;
}
public static void expandWildcard(List result, Iterable dirs, String name, Backend forBackend) {
if (name.endsWith("*")) {
int p = name.lastIndexOf('.');
String parentPath = ".";
String namePrefix = "";
if (p >= 0) {
String parentName = name.substring(0, p);
parentPath = parentName.replace('.', File.separatorChar);
namePrefix = name.substring(p + 1, name.length() - 1);
} else {
namePrefix = name.substring(0, name.length() - 1);
}
Set modules = findModules(dirs, parentPath, namePrefix, forBackend);
result.addAll(modules);
} else {
result.add(name);
}
}
public static boolean isValidModuleDir(Iterable dirs, String name) {
if (isModuleName(name)) {
String path = name.replace('.', File.separatorChar);
if (existsSourceSubDir(dirs, path)) {
return true;
}
}
return false;
}
public static boolean isModuleName(String name) {
String[] parts = name.split("\\.");
for (String part : parts) {
if (!isNamePart(part)) {
return false;
}
}
return true;
}
public static boolean isNamePart(String part) {
if (part.isEmpty()) {
return false;
}
Matcher m = ModuleUtil.moduleIdPattern.matcher(part);
return m.matches();
}
public static boolean onlyGlobArgs(List names) {
for (String name : names) {
if (!name.endsWith("*")) {
return false;
}
}
return true;
}
private static boolean existsSourceSubDir(Iterable dirs, String file) {
for (File dir : dirs) {
File subDir = new File(dir, file);
if (subDir.isDirectory() && subDir.canRead()) {
return true;
}
}
return false;
}
private static Set findModules(Iterable dirs, String modPath, String prefix, Backend forBackend) {
Set modules = new LinkedHashSet();
for (File dir : dirs) {
File modDir = new File(dir, modPath);
if (modDir.isDirectory() && modDir.canRead()) {
findModules(modules, dir, modDir, prefix, forBackend, true);
}
}
return modules;
}
private static void findModules(Set modules, File root, File dir, String prefix, Backend forBackend, boolean first) {
File descriptor = new File(dir, Constants.MODULE_DESCRIPTOR);
if (descriptor.isFile()) {
File modDir = FileUtil.relativeFile(root, dir);
String modName = modDir.getPath().replace(File.separatorChar, '.');
if (includeModule(modName, root, prefix, forBackend)) {
modules.add(modName);
}
} else if (first || prefix == null || prefix.isEmpty()) {
File[] files = dir.listFiles();
for (File f : files) {
if (f.isDirectory() && f.canRead() && isNamePart(f.getName())) {
findModules(modules, root, f, prefix, forBackend, false);
} else if (f.isFile() && f.canRead()
&& f.getName().endsWith(Constants.CEYLON_SUFFIX)
&& (prefix == null || prefix.isEmpty())) {
modules.add("default");
}
}
}
}
private static boolean includeModule(String name, File sourceRoot, String prefix, Backend forBackend) {
if (prefix != null) {
int p = name.lastIndexOf('.');
String lastPart = (p >= 0) ? name.substring(p + 1) : name;
if (!lastPart.startsWith(prefix)) {
return false;
}
}
if (forBackend != null) {
try {
ModuleDescriptorReader mdr = new ModuleDescriptorReader(name, sourceRoot);
List backends = mdr.getModuleBackends();
return backends.isEmpty() || backends.contains(forBackend.nativeAnnotation);
} catch(ModuleDescriptorReader.NoSuchModuleException x) {
x.printStackTrace();
}
}
return true;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy