/******************************************************************************* * Copyright (c) 2009-2013 CWI * 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: * * Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI * * Paul Klint - Paul.Klint@cwi.nl - CWI * * Mark Hills - Mark.Hills@cwi.nl (CWI) * * Arnold Lankamp - Arnold.Lankamp@cwi.nl *******************************************************************************/ package org.rascalmpl.interpreter.load; import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import org.rascalmpl.interpreter.Configuration; import org.rascalmpl.uri.URIResolverRegistry; import org.rascalmpl.uri.URIUtil; import org.rascalmpl.value.ISourceLocation; /** * This class implements a search path for Rascal. It can be used to look up modules * by name or files by path relative to the roots of all path contributors. * It will return the first match found. */ public class RascalSearchPath { private final ArrayList<IRascalSearchPathContributor> contributors; private final URIResolverRegistry reg; public RascalSearchPath() { this.contributors = new ArrayList<IRascalSearchPathContributor>(); this.reg = URIResolverRegistry.getInstance(); } public void addPathContributor(IRascalSearchPathContributor contrib) { if(!contributors.contains(contrib)){ contributors.add(0, contrib); } } public ISourceLocation resolveModule(String module) { module = moduleToFile(module); try { for (ISourceLocation dir : collect()) { ISourceLocation full = getFullURI(module, dir); if (reg.exists(full)) { return full; } } return null; } catch (URISyntaxException e) { return null; } } private String moduleToDir(String module) { return module.replaceAll(Configuration.RASCAL_MODULE_SEP, Configuration.RASCAL_PATH_SEP); } private String moduleToFile(String module) { if (!module.endsWith(Configuration.RASCAL_FILE_EXT)) { module = module.concat(Configuration.RASCAL_FILE_EXT); } return module.replaceAll(Configuration.RASCAL_MODULE_SEP, Configuration.RASCAL_PATH_SEP); } public ISourceLocation resolvePath(String path) { try { for (ISourceLocation dir : collect()) { ISourceLocation full = getFullURI(path, dir); if (reg.exists(full)) { return full; } } return null; } catch (URISyntaxException e) { return null; } } public ISourceLocation getRootForModule(String module) { try { for (ISourceLocation dir : collect()) { ISourceLocation full = getFullURI(moduleToFile(module), dir); if (reg.exists(full)) { return dir; } } return null; } catch (URISyntaxException e) { return null; } } public List<ISourceLocation> collect() { List<ISourceLocation> paths = new LinkedList<ISourceLocation>(); for (IRascalSearchPathContributor c : contributors) { c.contributePaths(paths); } return paths; } public List<String> listModuleEntries(String moduleRoot) { assert !moduleRoot.endsWith("::"); try { String modulePath = moduleToDir(moduleRoot); List<String> result = new ArrayList<>(); for (ISourceLocation dir : collect()) { ISourceLocation full = getFullURI(modulePath, dir); if (reg.exists(full)) { try { String[] entries = reg.listEntries(full); if (entries == null) { continue; } for (String module: entries ) { if (module.endsWith(Configuration.RASCAL_FILE_EXT)) { result.add(module.substring(0, module.length() - Configuration.RASCAL_FILE_EXT.length())); } else if (module.indexOf('.') == -1 && reg.isDirectory(getFullURI(module, full))) { // a sub folder path result.add(module + "::"); } } } catch (IOException e) { } } } if (result.size() > 0) { return result; } return null; } catch (URISyntaxException e) { return null; } } private ISourceLocation getFullURI(String path, ISourceLocation dir) throws URISyntaxException { return URIUtil.getChildLocation(dir, path); } public URIResolverRegistry getRegistry() { return reg; } public void remove(IRascalSearchPathContributor contrib) { contributors.remove(contrib); } public String toString(){ StringBuffer sb = new StringBuffer("RascalSearchPath[ "); for(IRascalSearchPathContributor contrib : contributors){ sb.append(contrib.getName()).append(" "); } sb.append("])"); return sb.toString(); } }