package org.lemsml.jlems.io.reader;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import org.lemsml.jlems.core.sim.AbstractInclusionReader;
import org.lemsml.jlems.core.sim.ContentError;
import org.lemsml.jlems.io.util.FileUtil;
import org.lemsml.jlems.io.util.JUtil;
/*
* Will be replaced by features in api branch!
*/
public class JarResourceInclusionReader extends AbstractInclusionReader {
private File rootFile;
private static ArrayList<File> searchDirs = new ArrayList<File>();
private static ArrayList<String> searchPathsInJar = new ArrayList<String>();
private File prefDir;
private String content;
public JarResourceInclusionReader(String content) {
this.content = content;
rootFile = null;
prefDir = null;
searchDirs.add(new File(System.getProperty("user.dir")));
}
public JarResourceInclusionReader(File f) {
super();
rootFile = f;
File rootDir = rootFile.getParentFile();
if (rootDir != null) {
searchDirs.add(rootDir);
//searchDirs.add(rootDir.getParentFile());
}
prefDir = rootDir;
searchDirs.add(new File(System.getProperty("user.dir")));
}
public static void addSearchPathInJar(String path) {
if (!searchPathsInJar.contains(path))
searchPathsInJar.add(path);
}
public static void addSearchPath(File f) {
if (!searchDirs.contains(f))
searchDirs.add(f);
}
public void addSearchPath(String s) {
addSearchPath(new File(s));
}
public void addSearchPaths(String sp) {
String[] bits = sp.split(":");
for (String s : bits) {
addSearchPath(s);
}
}
@Override
public String getRelativeContent(String attribute, String s) throws ContentError {
if(attribute.equals(URL))
{
throw new IllegalArgumentException("URL is not supported when using the FileInclusionReader!");
}
String ret = "";
//E.info("Getting rel path for: "+s+", searchPathsInJar: "+ searchPathsInJar);
if (searchPathsInJar.isEmpty())
searchPathsInJar.add("");
for (String path: searchPathsInJar) {
String toTry = path+"/"+s;
//System.out.println("Trying: "+toTry);
if (toTry.contains("..")) {
ArrayList<String> elements = new ArrayList<String>();
for (String el: toTry.split("/")) {
if (!el.equals(".."))
elements.add(el);
else
if (elements.size()>0) {
elements.remove(elements.size()-1);
}
}
toTry = "";
for (String el:elements)
toTry += "/"+el;
toTry = toTry.substring(1);
}
try {
ret = JUtil.getRelativeResource(toTry);
//System.out.println("Resource found in jar: "+toTry);
return ret;
} catch (ContentError ce) {
//System.out.println("Resource not found in jar: "+toTry);
}
}
File f = new File(prefDir, s);
///E.info("Trying for: "+f.getAbsolutePath()+", searchDirs: "+ searchDirs);
if (f.exists()) {
// we're OK
} else {
f = new File(s);
if (!f.exists()) {
for (File fd : searchDirs) {
File ftry = new File(fd, s);
if (ftry.exists()) {
f = ftry;
break;
}
}
}
}
if (f.exists()) {
// NB its possible that fpar is different from one of the search dirs because s could be a
// path rather than a single file name. So, if s is "dir1/dir2/filename" and we resolve it
// relative to one of the current serach paths, we need to add dir2 to the search list because its
// contents may include files with only the last part of the path.
File fpar = f.getParentFile();
if (searchDirs.contains(fpar)) {
// already there.
} else {
searchDirs.add(0, fpar);
}
} else {
final StringBuilder sb = new StringBuilder();
sb.append("Can't find file at path: " + s + "\n");
sb.append("Search directories are: " + searchDirs + "\n");
sb.append("Search paths in jar are: " + searchPathsInJar + "\n");
throw new ContentError(sb.toString());
}
boolean readOK;
try {
// E.info("Reading " + f.getCanonicalPath());
ret = FileUtil.readStringFromFile(f);
readOK = true;
} catch (IOException ex) {
readOK = false;
// not readable - readOK remains false and will be reported later
}
if (!readOK) {
throw new ContentError("Error reading fole " + f.getAbsolutePath());
}
return ret;
}
@Override
public String getRootContent() throws ContentError {
try {
if (content!=null) {
return content;
}
return FileUtil.readStringFromFile(rootFile);
}
catch (IOException ex) {
throw new ContentError("Problem reading from file: " + rootFile.getAbsolutePath(), ex);
}
}
public static void main(String[] argv) throws IOException, ContentError
{
JarResourceInclusionReader jrir = new JarResourceInclusionReader("target/jlems-0.9.8.4.jar");
String path = "../jLEMS/lems";
System.out.println(">> "+path+" -> "+jrir.getRelativeContent(FILE,path));
}
}