001/** 002 * '$Author: crawl $' 003 * '$Date: 2012-11-26 22:23:27 +0000 (Mon, 26 Nov 2012) $' 004 * '$Revision: 31127 $' 005 * 006 * For Details: 007 * http://www.kepler-project.org 008 * 009 * Copyright (c) 2009-2010 The Regents of the 010 * University of California. All rights reserved. Permission is hereby granted, 011 * without written agreement and without license or royalty fees, to use, copy, 012 * modify, and distribute this software and its documentation for any purpose, 013 * provided that the above copyright notice and the following two paragraphs 014 * appear in all copies of this software. IN NO EVENT SHALL THE UNIVERSITY OF 015 * CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, 016 * OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS 017 * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE 018 * POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY 019 * DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 020 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 021 * SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023 * ENHANCEMENTS, OR MODIFICATIONS. 024 */ 025 026package org.kepler.kar; 027 028import java.io.File; 029import java.util.ArrayList; 030import java.util.List; 031import java.util.ListIterator; 032 033import org.kepler.moml.NamedObjId; 034import org.kepler.objectmanager.ObjectManager; 035import org.kepler.objectmanager.cache.LocalRepositoryManager; 036import org.kepler.objectmanager.library.LibraryManager; 037import org.kepler.objectmanager.lsid.KeplerLSID; 038import org.kepler.provenance.Queryable; 039import org.kepler.util.ProvenanceStore; 040import org.kepler.util.WorkflowRun; 041import org.kepler.util.WorkflowRunUtil; 042import org.kepler.workflowrunmanager.WRMDefaults; 043import org.kepler.workflowrunmanager.WorkflowRunManager; 044import org.kepler.workflowrunmanager.WorkflowRunManagerManager; 045 046import ptolemy.actor.CompositeActor; 047import ptolemy.kernel.ComponentEntity; 048import ptolemy.kernel.util.IllegalActionException; 049import ptolemy.kernel.util.NamedObj; 050import ptolemy.moml.MoMLParser; 051 052 053/** 054 * This class allows for exporting runs to a KAR 055 * without user interaction 056 * 057 */ 058public class ExportRunsToKAR 059{ 060 061 private Queryable _queryable = null; 062 063 /** 064 * The SaveKAR object is a GUI free helper class for saving KARs. 065 */ 066 protected SaveKAR _savekar = null; 067 068 private KeplerLSID _workflowLSID = null; 069 070 private WorkflowRunManager workflowRunManager = null; 071 072 /** 073 * Constructor 074 */ 075 public ExportRunsToKAR(Queryable q, KeplerLSID wfLSID){ 076 _queryable = q; 077 _savekar = new SaveKAR(); 078 _workflowLSID = wfLSID; 079 080 try { 081 082 // FIXME this should use the proper prov store instead of just the default 083 // we're only ok with this currently because ExportRunsToKAR is only used 084 // in headless, which currently only supports using the default store 085 WorkflowRunManagerManager wrmm = WorkflowRunManagerManager.getInstance(); 086 ProvenanceStore provenanceStore = new ProvenanceStore(WRMDefaults.provenanceDefaultsProperty); 087 workflowRunManager = wrmm.getWRM(null, provenanceStore); 088 089 workflowRunManager.connect(); 090 ArrayList<WorkflowRun> runs = 091 workflowRunManager.queryForAndSetRuns("%", "%", "%", "%", "%", "%", false); 092 if (runs.isEmpty()){ 093 System.out.println("WARN ExportRunsToKAR got no runs back from provenance!"); 094 } 095 } catch (Exception e) { 096 // TODO Auto-generated catch block 097 e.printStackTrace(); 098 } 099 } 100 101 102 /** 103 * Export a list of runs and their associated workflow MoML into a KAR. 104 * 105 * @param runLSIDs 106 * @param karFile 107 * @param addToLibraryAndCache 108 * @param overrideKARModuleDependencies - if true, use run's mod deps for kar's mod deps 109 * @return success 110 * @throws Exception 111 */ 112 public boolean exportRunsToKAR(List<KeplerLSID> runLSIDs, 113 File karFile, boolean addToLibraryAndCache, boolean overrideKARModuleDependencies) throws Exception{ 114 115 String runModDeps = null; 116 String lastRunModDeps = null; 117 118 // first clear any runs previously added to the "selected" list: 119 workflowRunManager.clearSelectedRuns(); 120 121 int i=0; 122 for (KeplerLSID runLSID : runLSIDs) { 123 try { 124 // Here we store the Run LSID in the workflowRunManager 125 // so the WorkflowRunEntryHandler can figure out which runs for which 126 // workflows to save 127 128 workflowRunManager.addRunToSelectedRuns(runLSID); 129 130 WorkflowRun wr = workflowRunManager.getRun(runLSID); 131 runModDeps = wr.getModuleDependencies(); 132 // if overriding KAR module dependencies, make sure all runs have same module dependencies 133 if (overrideKARModuleDependencies && i != 0 && !lastRunModDeps.equals(runModDeps)){ 134 System.out.println("ExportRunsToKAR exportRunsToKAR ERROR trying to override KAR module " + 135 "dependencies but runs have different module dependencies, this " + 136 "is not currently allowed, NOT creating KAR file!"); 137 return false; 138 } 139 140 lastRunModDeps = runModDeps; 141 i++; 142 } catch (Exception exc) { 143 exc.printStackTrace(); 144 } 145 } 146 147 148 ArrayList<NamedObj> namedObjs = prepareNamedObjs(runLSIDs); 149 150 KARBuilder karBuilder = new KARBuilder(); 151 karBuilder.setKarFile(karFile); 152 _savekar.setFile(karFile); 153 154 try{ 155 for (NamedObj no : namedObjs) { 156 if (no instanceof ComponentEntity) { 157 karBuilder.addSaveInitiator((ComponentEntity)no); 158 } 159 } 160 karBuilder.setRegisterLSID(false); 161 karBuilder.setRevision(false); 162 163 //WARNING - using null TableauFrame here 164 karBuilder.generateKAR(null, runModDeps); 165 _savekar.specifyLSID(karBuilder.getKarLSID()); 166 if (addToLibraryAndCache){ 167 _savekar.saveToCache(); 168 } 169 } 170 catch (IllegalActionException iae) { 171 System.out.println("Failed to create kar file: " 172 + iae.getMessage()); 173 iae.printStackTrace(); 174 return false; 175 } 176 177 if (addToLibraryAndCache){ 178 LibraryManager lm = LibraryManager.getInstance(); 179 LocalRepositoryManager lrm = LocalRepositoryManager.getInstance(); 180 // make sure there's a folder to put it in 181 if(lrm.isInLocalRepository(_savekar.getFile())){ 182 try { 183 lm.addKAR(_savekar.getFile()); 184 } 185 catch (Exception e2) { 186 System.out.println("Exception when trying to add kar to library:"+e2); 187 } 188 } 189 else{ 190 //System.out.println("Not adding to library since not kar not in local repo"); 191 } 192 try { 193 lm.refreshJTrees(); //TODO check will this cause problems in headless kepler? 194 } 195 catch (IllegalActionException e2) { 196 e2.printStackTrace(); 197 } 198 } 199 200 System.out.println("Successfully exported to kar file: "+karBuilder.getKarFile().toString()); 201 202 //queryable.disconnect(); 203 204 // now clear any runs added to the "selected" list 205 // in prep for any subsequent saves 206 workflowRunManager.clearSelectedRuns(); 207 208 return true; 209 210 } 211 212 213 /** 214 * 215 * helper method prepares list of NamedObjs (workflows) for KAR from list of run LSIDs 216 * 217 * @param runLSIDs 218 * @return 219 * @throws Exception 220 */ 221 public ArrayList<NamedObj> prepareNamedObjs(List<KeplerLSID> runLSIDs) throws Exception{ 222 223 //get workflowRuns for run lsids 224 ListIterator<KeplerLSID> lsidItr = runLSIDs.listIterator(); 225 ArrayList<NamedObj> namedObjs = new ArrayList<NamedObj>(); 226 ArrayList<KeplerLSID> momlLsids = new ArrayList<KeplerLSID>(); 227 228 while (lsidItr.hasNext()){ 229 KeplerLSID runLSID = lsidItr.next(); 230 231 //TODO this section may be unnecessary now 232 //WorkflowRun wfRun = (WorkflowRun)ObjectManager.getInstance().getHighestObjectRevision(runLSID); 233 WorkflowRun wfRun = (WorkflowRun)ObjectManager.getInstance().getObjectRevision(runLSID); 234 235 // make sure we have the run object in the object manager 236 if (wfRun == null) { 237 wfRun = WorkflowRunUtil.lookupWorkflowRun(runLSID, _queryable); 238 ObjectManager.getInstance().addNamedObj(wfRun); 239 } 240 //end TODO possibly unnecessary. 241 242 //add moml associated with run 243 String moml = _queryable.getMoMLForExecution(runLSID); 244 MoMLParser parser = new MoMLParser(); 245 CompositeActor toplevel = ((CompositeActor) parser.parse(moml)); 246 ObjectManager.getInstance().addNamedObj(toplevel); 247 KeplerLSID momlLsid = NamedObjId.getIdFor(toplevel); 248 NamedObjId.assignIdTo(toplevel, momlLsid); 249 if (!momlLsids.contains(momlLsid)){ 250 namedObjs.add(toplevel); 251 } 252 momlLsids.add(momlLsid); 253 } 254 255 return namedObjs; 256 } 257 258 259}