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 }