001/* 002 * The node controller for actor instances. 003 * Copyright (c) 2010 The Regents of the University of California. 004 * All rights reserved. 005 * Permission is hereby granted, without written agreement and without 006 * license or royalty fees, to use, copy, modify, and distribute this 007 * software and its documentation for any purpose, provided that the above 008 * copyright notice and the following two paragraphs appear in all copies 009 * of this software. 010 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 011 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 012 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 013 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 014 * SUCH DAMAGE. 015 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 016 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 017 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 018 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 019 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 020 * ENHANCEMENTS, OR MODIFICATIONS. 021 * PT_COPYRIGHT_VERSION_2 022 * COPYRIGHTENDKEY 023 */ 024 025package org.kepler.kar.handlers; 026 027import java.io.InputStream; 028import java.util.Hashtable; 029import java.util.Vector; 030 031import org.apache.commons.logging.Log; 032import org.apache.commons.logging.LogFactory; 033import org.kepler.kar.KAREntry; 034import org.kepler.kar.KAREntryHandler; 035import org.kepler.kar.KAREntryHandlerFactory; 036import org.kepler.kar.KARFile; 037import org.kepler.modulemanager.ModuleManagerEventListener; 038import org.kepler.objectmanager.cache.CacheObject; 039import org.kepler.objectmanager.lsid.KeplerLSID; 040 041import ptolemy.actor.gui.TableauFrame; 042import ptolemy.kernel.util.IllegalActionException; 043import ptolemy.kernel.util.NameDuplicationException; 044import ptolemy.kernel.util.NamedObj; 045 046/** 047 * a kar handler to handle downloading modules if a kar file needs them 048 * 049 * @author chad berkley 050 */ 051public class ModuleTxtKAREntryHandler implements KAREntryHandler 052{ 053 private String type = "moduleTxt"; 054 private static final Log log = LogFactory 055 .getLog(ActorMetadataKAREntryHandler.class.getName()); 056 private static final boolean isDebugging = log.isDebugEnabled(); 057 058 /** 059 * constructor 060 */ 061 public ModuleTxtKAREntryHandler() 062 { 063 064 } 065 066 /** 067 * The getTypeName() method must return the type of object that this 068 * KAREntryHandler saves. This method should return the KAR version 1.0 069 * type name or null if version 1.0 is not supported by this handler. 070 **/ 071 public String getTypeName() 072 { 073 return type; 074 } 075 076 /** 077 * This method should return true if this KAREntryHandler can handle the 078 * specified type. The type passed in is the binary class name of the file. 079 * 080 * @param typeName 081 **/ 082 public boolean handlesType(String typeName) 083 { 084 if (typeName.equals(type)) 085 { 086 return true; 087 } 088 return false; 089 } 090 091 /** 092 * The initialize method is called directly after instantiating this 093 * KAREntryHandler. 094 */ 095 public void initialize() 096 { 097 } 098 099 /** 100 * This method should return a CacheObject that will be put into the cache. 101 * Once all the contents of the KAR exist in the cache then the open method 102 * is called. In this way each entry in the kar can have access to all the 103 * other entries through the cache when they get opened. 104 * 105 * @param karFile 106 * @param entry 107 * @return the CacheObject that will be put into the CacheManager 108 * @throws Exception 109 */ 110 public CacheObject cache(KARFile karFile, KAREntry entry) throws Exception 111 { 112 System.out.println("caching from ModuleTxtKAREntryHandler " + karFile.getFileLocation().getName() + "," 113 + entry.toString()); 114 /*TextFileCacheObject cobj = new TextFileCacheObject(karFile 115 .getInputStream(entry), entry.getLSID(), entry.toString()); 116 String modulesTxtStr = (String)cobj.getObject(); 117 File f = new File(DotKeplerManager.getInstance().getTransientDir(), "modules.txt"); 118 //write this to a temp file 119 FileWriter fw = new FileWriter(f); 120 fw.write(modulesTxtStr, 0, modulesTxtStr.length()); 121 fw.flush(); 122 fw.close(); 123 124 //merge the modules.txt file in the kar with the currently loaded modules.txt file 125 ModulesTxt newModulesTxt = new ModulesTxt(f.toURI()); 126 System.out.println("downloading modules in modules.txt from kar " + karFile.getFileLocation().getName()); 127 System.out.println("modules.txt: " + ((String)cobj.getObject())); 128 ModuleDownloader downloader = ModuleDownloader.getInstance(); 129 downloader.addListener(new ModuleStartupDownloadListener(karFile.getFileLocation().getName())); 130 downloader.downloadFromModulesTxt(newModulesTxt); 131 //now that the module(s) are downloaded, we need to process them into 132 //the current ModuleTree so that they are available on the classpath 133 //to the kar that needs them. 134 //This could be tricky, because a kar could introduce conflicts between 135 //modules. 136 ModuleTree moduleTree = ModuleTree.instance(); 137 ModulesTxt mainModulesTxt = moduleTree.getModulesTxt(); 138 Iterator newModulesIt = newModulesTxt.modules.iterator(); 139 while(newModulesIt.hasNext()) 140 { 141 //add the new module 142 Module newModule = (Module)newModulesIt.next(); 143 mainModulesTxt.add(newModule, 0); 144 } 145 146 mainModulesTxt.write(); 147 //TODO: kepler should restart at this point to load the new classpath, 148 //but that might cause problems so I'm omitting that for now. 149 150 return cobj;*/ 151 return null; 152 } 153 154 /** 155 * When a KAR file is opened, any entries in the kar file that have the same 156 * type as this KAREntryHandler will be passed to this open method. This 157 * method will always be called after the cache method. 158 * 159 * @param karFile 160 * @param entry 161 * @param tableauFrame 162 * @return boolean true if the entry was opened successfully. 163 * @throws Exception 164 */ 165 public boolean open(KARFile karFile, KAREntry entry, TableauFrame tableauFrame) throws Exception 166 { 167 System.out.println("MTKEH opening " + karFile.toString() + "," 168 + entry.toString()); 169 //tell the module-manager to download the module here 170 System.out 171 .println("kar entry handler is telling moduleTxtKAREntryHandler to open " 172 + entry.getName()); 173 return true; 174 } 175 176 /** 177 * Return an array of KAREntry objects that are to be saved for the given 178 * lsid. All KAREntries must be of the same type of object that is returned 179 * by the getTypeName() method. 180 * 181 * @param lsid 182 * @param karLsid the lsid of the containing KAR 183 * @param tableauFrame 184 * @return an array of KAREntries to be saved with this LSID object. 185 * @throws Exception 186 */ 187 public Hashtable<KAREntry, InputStream> save(Vector<KeplerLSID> lsids, 188 KeplerLSID karLsid, TableauFrame tableauFrame) throws Exception 189 { 190 return null; 191 } 192 193 /** 194 * A factory that creates a KAREntryHandler object. 195 * 196 *@author Aaron Schultz 197 */ 198 public static class Factory extends KAREntryHandlerFactory 199 { 200 /** 201 * Create a factory with the given name and container. 202 * 203 *@param container 204 * The container. 205 *@param name 206 * The name of the entity. 207 *@exception IllegalActionException 208 * If the container is incompatible with this attribute. 209 *@exception NameDuplicationException 210 * If the name coincides with an attribute already in the 211 * container. 212 */ 213 public Factory(NamedObj container, String name) 214 throws IllegalActionException, NameDuplicationException 215 { 216 super(container, name); 217 } 218 219 /** 220 * Create a library pane that displays the given library of actors. 221 * 222 * @return A new LibraryPaneTab that displays the library 223 */ 224 public KAREntryHandler createKAREntryHandler() 225 { 226 if (isDebugging) 227 log.debug("moduleTxtKAREntryHandler()"); 228 return new ModuleTxtKAREntryHandler(); 229 } 230 } 231 232 /** 233 * listener for module download events 234 * @author berkley 235 * 236 */ 237 private class ModuleStartupDownloadListener implements ModuleManagerEventListener 238 { 239 private String karFileName; 240 241 public ModuleStartupDownloadListener(String karFileName) 242 { 243 this.karFileName = karFileName; 244 } 245 246 /** 247 * update progress for the progress monitor 248 */ 249 public void updateProgress(int totalSize, int bufferSize, int readCount, InputStream is) 250 { 251 System.out.println("downloading " + (bufferSize * readCount) + " of " + totalSize + " bytes."); 252 } 253 254 /** 255 * close the progress monitor at the end of the DL. 256 */ 257 public void downloadEnd() 258 { 259 System.out.println("Done downloading module."); 260 } 261 262 /** 263 * start up a new progress monitor at the beginning of a download. 264 */ 265 public void downloadBegin(int totalSize, String moduleName) 266 { 267 System.out.println("Downloading module " + moduleName + " from kar file " + karFileName); 268 } 269 270 /** 271 * create a new progress bar when an unzip begins 272 */ 273 public void unzipBegin(long totalSize, String moduleName) 274 { 275 System.out.println("Unzipping module " + moduleName + " from kar file " + karFileName); 276 } 277 278 /** 279 * get rid of the unzip progress bar 280 */ 281 public void unzipEnd() 282 { 283 System.out.println("Done unzipping."); 284 } 285 286 /** 287 * update the progress of an unzip 288 */ 289 public void unzipUpdateProgress(long totalSize, int bufferSize, int readCount) 290 { 291 292 } 293 } 294}