/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* This file was originally derived from the Polyglot extensible compiler framework.
*
* (C) Copyright 2000-2007 Polyglot project group, Cornell University
* (C) Copyright IBM Corporation 2007-2012.
*/
package polyglot.frontend;
import java.io.*;
import java.util.*;
import polyglot.main.Reporter;
import polyglot.types.QName;
import polyglot.util.FileUtil;
import polyglot.util.CollectionUtil; import x10.util.CollectionFactory;
/** A <code>SourceLoader</code> is responsible for loading source files. */
public class SourceLoader
{
protected ExtensionInfo sourceExt;
protected Reporter reporter;
protected List<File> sourcePath;
/** 0 if unknown, 1 if case insensitive, -1 if not. */
protected int caseInsensitive;
/** Set of sources already loaded. An attempt to load a source
* already loaded will cause an IOException. */
protected Map<Object,Source> loadedSources;
public SourceLoader(ExtensionInfo sourceExt, List<File> sourcePath) {
this.sourcePath = sourcePath;
this.sourceExt = sourceExt;
this.reporter = sourceExt.getOptions().reporter;
this.caseInsensitive = 0;
this.loadedSources = CollectionFactory.newHashMap();
}
/** Load a source from a specific file. */
public FileSource fileSource(String fileName) throws IOException {
return fileSource(fileName, false);
}
public FileSource fileSource(String fileName, boolean userSpecified) throws IOException {
File sourceFile = new File(fileName);
if (! sourceFile.exists()) {
throw new FileNotFoundException(fileName);
}
String[] exts = sourceExt.fileExtensions();
boolean ok = false;
for (int i = 0; i < exts.length; i++) {
String ext = exts[i];
if (fileName.endsWith("." + ext)) {
ok = true;
break;
}
}
if (! ok) {
String extString = "";
for (int i = 0; i < exts.length; i++) {
if (exts.length == 2 && i == exts.length-1) {
extString += " or ";
}
else if (exts.length != 1 && i == exts.length-1) {
extString += ", or ";
}
else if (i != 0) {
extString += ", ";
}
extString = extString + "\"." + exts[i] + "\"";
}
if (exts.length == 1) {
throw new IOException("Source \"" + fileName +
"\" does not have the extension "
+ extString + ".");
}
else {
throw new IOException("Source \"" + fileName +
"\" does not have any of the extensions "
+ extString + ".");
}
}
if (reporter.should_report(Reporter.loader, 2))
reporter.report(2, "Loading class from " + sourceFile);
Resource r = new FileResource(sourceFile);
FileSource s = (FileSource) loadedSources.get(fileKey(r));
if (s != null) {
if (!s.userSpecified && userSpecified) {
s.setUserSpecified(true);
}
return s;
}
s = sourceExt.createFileSource(r, userSpecified);
loadedSources.put(fileKey(r), s);
return s;
}
/**
* The current user directory. We make it static so we don't need to
* keep on making copies of it.
*/
protected static File current_dir = null;
/**
* The current user directory.
*/
protected static File current_dir() {
if (current_dir == null) {
current_dir = new File(System.getProperty("user.dir"));
}
return current_dir;
}
/** Check if a directory for a package exists. */
public boolean packageExists(QName name) {
String fileName = name.toString().replace('.', '/');
/* Search the source path. */
boolean result = pathloader().dirExists(fileName);
return result;
}
ClassPathResourceLoader pathloader;
private ClassPathResourceLoader pathloader() {
if (pathloader == null)
pathloader = new ClassPathResourceLoader(sourcePath,reporter);
return pathloader;
}
/** Load the source file for the given class name using the source path. */
public FileSource classSource(QName className) {
ClassPathResourceLoader loader = pathloader();
/* Search the source path. */
String[] exts = sourceExt.fileExtensions();
for (int k = 0; k < exts.length; k++) {
String fileName = className.toString().replace('.', File.separatorChar) +
"." + exts[k];
Resource r = loader.loadResource(fileName);
if (r != null) {
try {
if (reporter.should_report(Reporter.loader, 2))
reporter.report(2, "Loading " + className + " from " + r);
FileSource s = sourceExt.createFileSource(r, false);
loadedSources.put(fileKey(r), s);
return s;
}
catch (IOException e) {
}
}
}
return null;
}
public Object fileKey(Resource r) {
File file = r.file();
String suffix = r instanceof FileResource ? "" : ":" + r.name();
try {
return file.getCanonicalPath() + suffix;
}
catch (IOException e) {
return file.getAbsolutePath() + suffix;
}
}
}