001/* 002 * Copyright (c) 2003-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2013-02-21 21:33:59 +0000 (Thu, 21 Feb 2013) $' 007 * '$Revision: 31478 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.kepler.objectmanager.repository; 031 032import java.io.File; 033import java.io.FileOutputStream; 034import java.io.InputStream; 035import java.util.ArrayList; 036import java.util.List; 037import java.util.Vector; 038import java.util.concurrent.atomic.AtomicBoolean; 039 040import org.apache.commons.logging.Log; 041import org.apache.commons.logging.LogFactory; 042import org.ecoinformatics.ecogrid.queryservice.resultset.ResultsetTypeRecord; 043import org.kepler.gui.GraphicalActorMetadata; 044import org.kepler.kar.karxml.KarXml; 045import org.kepler.objectmanager.cache.ActorCacheObject; 046import org.kepler.objectmanager.cache.CacheException; 047import org.kepler.objectmanager.cache.CacheObject; 048import org.kepler.objectmanager.lsid.KeplerLSID; 049 050import ptolemy.kernel.ComponentEntity; 051import ptolemy.kernel.util.NamedObj; 052import ptolemy.kernel.util.StringAttribute; 053/** 054 * This class represents a single result from a search of the ecogrid 055 * repository. If there are many results (as in a resultset), then multiple 056 * EcogridRepositoryResults can be put into an iterator. 057 * 058 * @author Chad Berkley 059 */ 060public class EcogridRepositoryResults { 061 private static final Log log = LogFactory.getLog(EcogridRepositoryResults.class.getName()); 062 private static final boolean isDebugging = log.isDebugEnabled(); 063 064 private String docid; 065 private String name; 066 private KarXml.KarEntry karEntry; 067 private String lsid; 068 private String karLSID; 069 private Vector<String> semTypes; 070 private ComponentEntity component; 071 private CacheObject cachedComponent; 072 private AtomicBoolean isReady = new AtomicBoolean(false); 073 private AtomicBoolean hasException = new AtomicBoolean(false); 074 private String repositoryName; 075 private File karFile; 076 private Integer indexValue = null; 077 private org.kepler.objectmanager.repository.KARDownloader downloader; 078 079 public static List<EcogridRepositoryResults> parseKarXml(String docid, 080 String repositoryName, int indexValue, boolean authenticate) throws RepositoryException { 081 //System.out 082 // .println("EcogridRepositoryResults parseKarXml Parsing KAR XML: " 083 // + docid); 084 List<EcogridRepositoryResults> results = new ArrayList<EcogridRepositoryResults>(); 085 try { 086 RepositoryManager rm = RepositoryManager.getInstance(); 087 Repository rep = rm.getRepository(repositoryName); 088 if (rep instanceof EcogridRepository) { 089 } else { 090 log.error("EcogridRepositoryResults is trying to search " 091 + "a non-Ecogrid Repository"); 092 return null; 093 } 094 EcogridRepository erep = (EcogridRepository) rep; 095 InputStream is = erep.get(docid, authenticate); 096 097 KarXml karXml = KarXml.of(is); 098 String karLSID = karXml.getLsid(); 099 if (karXml != null) { 100 karXml.setRepositoryName(repositoryName); 101 for (KarXml.KarEntry entry : karXml.getKarEntries()) { 102 EcogridRepositoryResults ecogridResult = new EcogridRepositoryResults( 103 entry, repositoryName, indexValue, karLSID); 104 ecogridResult.setDocId(docid); 105 results.add(ecogridResult); 106 } 107 } 108 109 } catch (Exception ex) { 110 ex.printStackTrace(); 111 } 112 return results; 113 } 114 115 public EcogridRepositoryResults(String karLSID, String repositoryName, boolean authenticate) { 116 // Initialize just the karLsid and repositoryName variables. This is 117 // intended to be used just to cache the KAR to local storage. 118 this.karLSID = karLSID; 119 this.repositoryName = repositoryName; 120 } 121 122 public EcogridRepositoryResults(KarXml.KarEntry karEntry, String repositoryName, 123 int indexValue, String karLSID) throws RepositoryException { 124 this.indexValue = indexValue; 125 this.karEntry = karEntry; 126 this.repositoryName = repositoryName; 127 this.karLSID = karLSID; 128 try { 129 if (karEntry.getType().endsWith(".TypedCompositeActor")) { 130 cachedComponent = new ActorCacheObject(karEntry.asInputStream()); 131 } 132 } 133 catch(CacheException ex) { 134 log.error("Cache exception", ex); 135 } 136 name = karEntry.getName(); 137 lsid = karEntry.getLsid(); 138 semTypes = new Vector<String>(karEntry.getSemanticTypes()); 139 } 140 141 /** 142 * All EcogridRepositoryResults produced by a single call to parseKarXml() 143 * will be assigned the same index value so they can later be put under a 144 * common KAR file. The index value is guaranteed to be unique to the 145 * contents of one KAR file only within the results produced by a single 146 * call to EcogridRepository.search(). Subsequent calls *will* produce 147 * colliding values. 148 * @return The index value shared by all EcogridRepositoryResults instances 149 * generated from the same KAR file. Calls to this method by 150 * EcogridRepositoryResults instances that were not generated through 151 * parsing a KAR XML file will produce null. 152 */ 153 public Integer getIndexValue() { 154 return indexValue; 155 } 156 157 public KarXml.KarEntry getKarEntry() { 158 return karEntry; 159 } 160 /** 161 * default constructor 162 */ 163 public EcogridRepositoryResults(ResultsetTypeRecord record, 164 String repositoryName, boolean authenticate) throws RepositoryException { 165 this.repositoryName = repositoryName; 166 try { 167 semTypes = new Vector<String>(); 168 docid = record.getIdentifier(); 169 // get the document from the repository and parse it into an 170 // actormetadata 171 // object 172 173 RepositoryManager rm = RepositoryManager.getInstance(); 174 Repository rep = rm.getRepository(repositoryName); 175 if (rep instanceof EcogridRepository) { 176 } else { 177 log.error("EcogridRepositoryResults is trying to search " 178 + "a non-Ecogrid Repository"); 179 return; 180 } 181 182 EcogridRepository erep = (EcogridRepository) rep; 183 184 InputStream is = erep.get(docid, authenticate); 185 186 GraphicalActorMetadata gam = new GraphicalActorMetadata(is); 187 NamedObj obj = gam.getActorAsNamedObj(null); 188 189 component = (ComponentEntity) obj; 190 name = gam.getName(); 191 lsid = gam.getId(); 192 193 StringAttribute sa = (StringAttribute) obj.getAttribute("karId"); 194 if (sa != null) { 195 karLSID = sa.getExpression(); 196 197 if (isDebugging) { 198 log.debug("karLSID: " + karLSID); 199 } 200 // possibly here, kick off a thread to start downloading the kar 201 // files into 202 // the classpath 203 } 204 205 semTypes = gam.getSemanticTypes(); 206 } catch (Exception e) { 207 // e.printStackTrace(); 208 throw new RepositoryException("Error getting actor metadata for " 209 + "resultset document: " + e.getMessage()); 210 } 211 } 212 213 /** 214 * download the kar file and get it ready to be imported into the local 215 * system. 216 */ 217 public File cacheKAR(boolean authenticate) throws RepositoryException { 218 // break off a new thread 219 // run the download in that thread 220 // set isReady to true; 221 (new KARDownloader(downloader, authenticate)).start(); 222 while (!isReady()) { 223 } // wait for the download. this can be done away with when the 224 // interface 225 // is fixed to download upon drag n drop 226 227 if (hasException()) { 228 throw new RepositoryException("Error caching the kar file for the " 229 + "component " + lsid); 230 } 231 return karFile; 232 } 233 234 /** 235 * returns true of the kar file from this result is ready for use 236 */ 237 public boolean isReady() { 238 return isReady.get(); 239 } 240 241 /** 242 * returns true if the kar caching thread has thrown an exception 243 */ 244 public boolean hasException() { 245 return hasException.get(); 246 } 247 248 /** 249 * return a string rep of this object 250 */ 251 public String toString() { 252 StringBuffer sb = new StringBuffer(); 253 sb.append("{name: " + name); 254 sb.append(", docid: " + docid); 255 sb.append(", lsid: " + lsid); 256 sb.append(", karId: " + karLSID); 257 sb.append(", semanticTypes: " + semTypes.toString()); 258 sb.append("}"); 259 return sb.toString(); 260 } 261 262 /** 263 * return the docid of the result 264 */ 265 public String getDocid() { 266 return docid; 267 } 268 269 /** 270 * return the name of the component 271 */ 272 public String getName() { 273 return name; 274 } 275 276 /** 277 * return the lsid (entityId) of the component 278 */ 279 public String getLSID() { 280 return lsid; 281 } 282 283 /** 284 * return the lsid of the kar file associated with this component 285 */ 286 public String getKarLSID() { 287 return karLSID; 288 } 289 290 /** 291 * return any semantic types associated with this component 292 */ 293 public Vector<String> getSemanticTypes() { 294 return semTypes; 295 } 296 297 public CacheObject getCacheObject() { 298 return cachedComponent; 299 } 300 301 /** 302 * return the instantiated 303 */ 304 public ComponentEntity getComponent() { 305 return component; 306 } 307 308 /** 309 * Set the docid (kar xml id) 310 * @param docid 311 */ 312 public void setDocId(String docid) 313 { 314 this.docid =docid; 315 } 316 317 public void setDownloader(org.kepler.objectmanager.repository.KARDownloader downloader) { 318 this.downloader = downloader; 319 } 320 321 /** 322 * a class to download the kar file in a new thread. 323 */ 324 private class KARDownloader extends Thread { 325 // location to download the kar file to 326 String tempPath = org.kepler.objectmanager.cache.CacheManager.tmpPath; 327 private org.kepler.objectmanager.repository.KARDownloader downloader; 328 329 private boolean authenticate = false; 330 331 public void setAuthenticate(boolean authenticate){ 332 this.authenticate = authenticate; 333 } 334 public boolean getAuthenticate(){ 335 return authenticate; 336 } 337 338 public KARDownloader() { 339 super(); 340 } 341 342 public KARDownloader(org.kepler.objectmanager.repository.KARDownloader downloader, boolean authenticate) { 343 this(); 344 this.downloader = downloader; 345 this.authenticate = authenticate; 346 } 347 348 /** 349 * get the kar and download it to the cache 350 */ 351 public void run() { 352 try { 353 if (karLSID == null){ 354 System.out.println("EcogridRepositoryResults KARDownloader.run() ERROR karLSID is null"); 355 } 356 KeplerLSID karlsid = new KeplerLSID(karLSID); 357 String karSavePath = this.downloader.getKarPath(); 358 if (karSavePath == null) { 359 karSavePath = tempPath; 360 } 361 String karFilename = this.downloader.getKarName(); 362 if (karFilename == null) { 363 karFilename = karlsid.createFilename() + ".kar"; 364 System.out.println("No KAR name found in XML, using LSID for filename instead:"+karFilename); 365 } 366 File karPath = new File(karSavePath); 367 karFile = new File(karPath, karFilename); 368 karPath.mkdirs(); 369 FileOutputStream fos = null; 370 try { 371 fos = new FileOutputStream(karFile); 372 EcogridRepository repository = (EcogridRepository) RepositoryManager 373 .getInstance().getRepository(repositoryName); 374 InputStream is = repository.get(karlsid, authenticate); 375 byte[] b = new byte[1024]; 376 int numread = is.read(b, 0, 1024); 377 downloader.updateDownloadProgress(numread); 378 while (numread != -1) { 379 fos.write(b, 0, numread); 380 numread = is.read(b, 0, 1024); 381 downloader.updateDownloadProgress(numread); 382 } 383 fos.flush(); 384 isReady.set(true); 385 } finally { 386 if(fos != null) { 387 fos.close(); 388 } 389 } 390 } catch (Exception e) { 391 System.out.println("Error downloading kar file: " 392 + e.getMessage()); 393 // e.printStackTrace(); 394 hasException.set(true); 395 isReady.set(true); 396 } 397 } 398 } 399}