package org.ukiuni.pacifista.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.ukiuni.pacifista.Console;
import org.ukiuni.pacifista.Git;
import org.ukiuni.pacifista.Http;
import org.ukiuni.pacifista.Local;
import org.ukiuni.pacifista.PluginLoader;
import org.ukiuni.pacifista.PluginLoader.Plugin;
import org.ukiuni.pacifista.RemoteFactory;
import org.ukiuni.pacifista.Runtime;
import org.ukiuni.pacifista.Tester;
import org.ukiuni.pacifista.velocity.VelocityWrapper;
import org.ukiuni.pacifista.virtual.VirtualMachine;
public class ScriptingUtil {
public static void execFolder(File baseDir, File target, File templateDir, File pluginDir, Map<String, Object> parameters) throws ScriptException, IOException, ScriptEngineNotFoundException {
if (!target.exists()) {
throw new FileNotFoundException(target.getAbsolutePath());
}
File[] childlen = target.listFiles();
List<File> sortedList = new ArrayList<File>();
for (File file : childlen) {
sortedList.add(file);
}
Collections.sort(sortedList, new Comparator<File>() {
@Override
public int compare(File f1, File f2) {
if (f1.isDirectory()) {
if (f2.isDirectory()) {
return f1.compareTo(f2);
} else {
return 1;
}
} else {
if (f2.isDirectory()) {
return -1;
} else {
return f1.compareTo(f2);
}
}
}
});
for (File file : sortedList) {
if (file.isDirectory()) {
execFolder(baseDir, file, templateDir, pluginDir, parameters);
} else if (file.isFile()) {
String canonical = picupCanonical(baseDir, file);
execScript(baseDir, canonical, templateDir, pluginDir, parameters);
}
}
}
public static String picupCanonical(File baseDir, File file) {
String baseAbsolute = baseDir.getAbsolutePath();
String fileAbsolute = file.getAbsolutePath();
int compaireToLength = baseAbsolute.length() < fileAbsolute.length() ? baseAbsolute.length() : fileAbsolute.length();
String canonical = null;
for (int i = 0; i <= compaireToLength; i++) {
if (!baseAbsolute.startsWith(fileAbsolute.substring(0, i))) {
break;
}
}
if (null == canonical) {
canonical = fileAbsolute.substring(baseAbsolute.length() - 1);
}
return canonical;
}
public static void execScript(File baseDir, String script, File templateDir, File pluginDir, Map<String, Object> parameters) throws ScriptException, IOException, ScriptEngineNotFoundException {
if (script.endsWith(".js")) {
execScript("JavaScript", baseDir, script, templateDir, pluginDir, parameters);
} else if (script.endsWith(".rb")) {
execScript("jruby", baseDir, script, templateDir, pluginDir, parameters);
} else if (script.endsWith(".groovy")) {
execScript("groovy", baseDir, script, templateDir, pluginDir, parameters);
} else if (script.endsWith(".py")) {
execScript("python", baseDir, script, templateDir, pluginDir, parameters);
}
}
public static void execScript(String lang, File baseDir, String script, File templateDir, File pluginDir, Map<String, Object> parameters) throws ScriptException, IOException, ScriptEngineNotFoundException {
if (null == parameters) {
parameters = new HashMap<String, Object>();
}
ScriptEngineManager scriptManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptManager.getEngineByName(lang);
if (null == scriptEngine) {
throw new ScriptEngineNotFoundException(lang);
}
Runtime runtime = new Runtime(baseDir, templateDir, pluginDir, parameters);
scriptEngine.put("Remote", new RemoteFactory(baseDir, runtime));
scriptEngine.put("Template", new VelocityWrapper(templateDir));
scriptEngine.put("console", new Console());
scriptEngine.put("runtime", runtime);
scriptEngine.put("Tester", new Tester());
scriptEngine.put("local", new Local(baseDir, runtime));
scriptEngine.put("http", new Http(runtime));
scriptEngine.put("git", new Git(baseDir, runtime));
scriptEngine.put("VirtualMachine", new VirtualMachine(baseDir));
scriptEngine.put("VirtualMacine", new VirtualMachine(baseDir));
if (null != pluginDir && pluginDir.isDirectory()) {
for (File pluginJar : pluginDir.listFiles()) {
if (pluginJar.getName().equals("README")) {
continue;
}
try {
List<Plugin> plugins = new PluginLoader().loadPlugin(pluginJar);
for (Plugin plugin : plugins) {
scriptEngine.put(plugin.getName(), plugin.getInstance());
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}
if (script.startsWith("http://") || script.startsWith("https://")) {
URL url = new URL(script);
URLConnection connection = url.openConnection();
scriptEngine.put(ScriptEngine.FILENAME, script);
scriptEngine.eval(new InputStreamReader(connection.getInputStream()));
} else if (script.startsWith("/")) {
File file = new File(script);
scriptEngine.put(ScriptEngine.FILENAME, file.getName());
scriptEngine.eval(new FileReader(file));
} else {
File file = new File(baseDir, script);
scriptEngine.put(ScriptEngine.FILENAME, file.getName());
scriptEngine.eval(new FileReader(file));
}
}
public static Map<String, String> pickupParameters(String url) {
Map<String, String> map = new HashMap<String, String>();
if (url.contains("?")) {
String query = url.substring(url.indexOf("?") + 1);
parseParameters(map, query);
}
return map;
}
public static void parseParameters(Map<String, String> map, String query) {
String[] parameterSets = query.split("&");
for (int i = 0; i < parameterSets.length; i++) {
int questIndex = parameterSets[i].indexOf("=");
if (questIndex > 0) {
String key = parameterSets[i].substring(0, questIndex);
String value = parameterSets[i].substring(questIndex + 1);
map.put(key, value);
}
}
}
public static Map<String, String> parseParameters(String query) {
Map<String, String> map = new HashMap<String, String>();
parseParameters(map, query);
return map;
}
public static LsResult parseLs(String lsResultString) throws ParseException {
LsResult lsResult;
try {
String[] sprited = lsResultString.split(" ");
lsResult = new LsResult();
lsResult.isDir = sprited[0].startsWith("d");
lsResult.mode = sprited[0];
if (lsResult.mode.endsWith(".")) {
lsResult.mode = lsResult.mode.substring(1, lsResult.mode.length() - 1);
} else {
lsResult.mode = lsResult.mode.substring(1);
}
lsResult.group = sprited[2];
lsResult.owner = sprited[3];
lsResult.size = Long.parseLong(sprited[4]);
lsResult.date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(sprited[5] + " " + sprited[6]);
lsResult.name = sprited[7];
} catch (Throwable e) {
throw new RuntimeException("ls String \"" + lsResultString + "\" is not parseable.", e);
}
return lsResult;
}
public static class LsResult {
public boolean isDir;
public String mode;
public String group;
public String owner;
public Date date;
public long size;
public String name;
}
@SuppressWarnings("serial")
public static class ScriptEngineNotFoundException extends Exception {
public String script;
public ScriptEngineNotFoundException(String script) {
this.script = script;
}
public String getScript() {
return script;
}
public void setScript(String script) {
this.script = script;
}
}
}