001 package toolbus.viewer;
002
003 import java.io.File;
004 import java.io.FileInputStream;
005 import java.io.IOException;
006 import java.nio.ByteBuffer;
007 import java.nio.channels.FileChannel;
008 import toolbus.ToolBus;
009 import toolbus.util.collections.ConcurrentHashMap;
010
011 /**
012 * This store provides access to all, for the ToolBus, reachable source code. Additionally it
013 * caches the already loaded code.
014 *
015 * @author Arnold Lankamp
016 */
017 public class ScriptCodeStore{
018 private final ToolBus toolbus;
019 private final ConcurrentHashMap<String, byte[]> scriptCodeCache;
020
021 /**
022 * Constructor.
023 *
024 * @param toolbus
025 * The ToolBus with which this store will be associated.
026 */
027 public ScriptCodeStore(ToolBus toolbus){
028 super();
029
030 this.toolbus = toolbus;
031
032 scriptCodeCache = new ConcurrentHashMap<String, byte[]>();
033 }
034
035 /**
036 * Returns the list of absolute paths to all, for the ToolBus, reachable scripts. Returns null
037 * in case the scripts haven't been parsed yet.
038 *
039 * @return The list of absolute paths to all, for the ToolBus, reachable scripts; null in case
040 * the scripts haven't been parsed yet.
041 */
042 public String[] getScriptNames(){
043 return toolbus.getIncludedScripts();
044 }
045
046 /**
047 * Retrieves the source code of the script indicated by the given path.
048 *
049 * @param scriptPath
050 * The path to the script we want to load.
051 * @return The retrieved source code of the script.
052 * @throws IOException Thrown when something I/O related goes wrong (obviously).
053 */
054 public byte[] getCode(String scriptPath) throws IOException{
055 byte[] scriptCode = scriptCodeCache.get(scriptPath);
056 if(scriptCode != null) return scriptCode;
057
058 File scriptFile = new File(scriptPath);
059 if(!scriptFile.exists() || !scriptFile.isFile()) throw new IOException("No such script file: "+scriptPath);
060
061 int fileSize = (int) scriptFile.length();
062 scriptCode = new byte[fileSize];
063
064 FileInputStream fis = new FileInputStream(scriptFile);
065 FileChannel fc = fis.getChannel();
066
067 ByteBuffer byteBuffer = ByteBuffer.wrap(scriptCode);
068 try{
069 fc.read(byteBuffer);
070 }finally{
071 try{
072 fc.close();
073 }finally{
074 fis.close();
075 }
076 }
077
078 scriptCodeCache.put(scriptPath, scriptCode); // Put the retrieved code in the cache.
079
080 return scriptCode;
081 }
082 }