001/* 002 * Copyright (c) 2007-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2012-11-26 22:22:25 +0000 (Mon, 26 Nov 2012) $' 007 * '$Revision: 31122 $' 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.gui; 031 032import java.awt.Component; 033import java.awt.event.ActionEvent; 034import java.lang.reflect.Method; 035import java.util.Set; 036import java.util.Vector; 037 038import javax.swing.tree.TreePath; 039 040import org.kepler.kar.KARCacheContent; 041import org.kepler.kar.KARCacheManager; 042import org.kepler.kar.KarDoclet; 043import org.kepler.kar.SuperClassPathFinderDoclet; 044import org.kepler.objectmanager.ActorMetadata; 045import org.kepler.objectmanager.ObjectManager; 046import org.kepler.objectmanager.cache.ActorCacheObject; 047import org.kepler.objectmanager.cache.CacheManager; 048import org.kepler.objectmanager.cache.CacheObject; 049import org.kepler.objectmanager.lsid.KeplerLSID; 050 051import ptolemy.actor.gui.Configuration; 052import ptolemy.actor.gui.Effigy; 053import ptolemy.actor.gui.PtolemyFrame; 054import ptolemy.actor.gui.TableauFrame; 055import ptolemy.kernel.util.ConfigurableAttribute; 056import ptolemy.kernel.util.NamedObj; 057import ptolemy.util.MessageHandler; 058import ptolemy.vergil.actor.DocEffigy; 059import ptolemy.vergil.basic.GetDocumentationAction; 060import ptolemy.vergil.basic.KeplerDocumentationAttribute; 061import ptolemy.vergil.toolbox.FigureAction; 062 063 064/** 065 * This action displays Kepler documentation. Created to display when actor in 066 * library tree is right clicked. 067 * 068 *@author Chad Berkley 069 *@since 6/5/2007 070 */ 071public class ShowDocumentationAction extends FigureAction { 072 private final static String LABEL = "View Documentation"; 073 private TableauFrame parent = null; 074 private PtolemyFrame pFrame = null; 075 private KeplerLSID _lsidToView = null; 076 private TreePath _path; 077 078 /** 079 * Constructor 080 * 081 *@param path 082 * the TreePath where the actor is being removed. 083 */ 084 public ShowDocumentationAction(TreePath path, Component parent) { 085 super(LABEL); 086 _path = path; 087 } 088 089 public ShowDocumentationAction(TableauFrame parent) { 090 super(""); 091 if (parent == null) { 092 IllegalArgumentException iae = new IllegalArgumentException( 093 "ShowDocumentationAction constructor received NULL argument for TableauFrame"); 094 iae.fillInStackTrace(); 095 throw iae; 096 } 097 this.parent = parent; 098 } 099 100 public void setLsidToView(KeplerLSID lsid) { 101 _lsidToView = lsid; 102 } 103 public KeplerLSID getLsidToView() { 104 return _lsidToView; 105 } 106 107 /** 108 * Invoked when an action occurs. 109 * 110 *@param e 111 * ActionEvent 112 */ 113 public void actionPerformed(ActionEvent e) { 114 super.actionPerformed(e); 115 NamedObj target = null; 116 KeplerLSID lsidToView = getLsidToView(); 117 118 try { 119 120 if (lsidToView != null) { 121 target = ObjectManager.getInstance().getObjectRevision(lsidToView); 122 } else { 123 target = getTarget(); 124 } 125 126 if(target == null) { 127 Object object = _path.getLastPathComponent(); 128 if(object instanceof NamedObj) { 129 target = (NamedObj) object; 130 } 131 } 132 133 134 NamedObj container = null; 135 if (pFrame != null){ 136 container = pFrame.getModel(); 137 } 138 139 if (container == null) { 140 container = target.getContainer(); 141 } 142 143 Effigy ee = Configuration.findEffigy(container); 144 Configuration c = null; 145 146 if (ee != null){ 147 c = (Configuration) ee.toplevel(); 148 } 149 else{ 150 if (parent != null){ 151 c = parent.getConfiguration(); 152 } 153 } 154 GetDocumentationAction gda = new GetDocumentationAction(1); 155 gda.setConfiguration(c); 156 DocEffigy de = null; 157 if (ee != null){ 158 try { 159 de = new DocEffigy(ee, ee.uniqueName("DocEffigy")); 160 gda.setEffigy(de); 161 } catch (Exception exc) { 162 exc.printStackTrace(); 163 } 164 } 165 if (target != null) { 166 167 boolean missingDocs = false; 168 169 final KeplerDocumentationAttribute keplerDocumentationAttribute = (KeplerDocumentationAttribute) target 170 .getAttribute("KeplerDocumentation"); 171 172 // see if the docs are missing or empty 173 if(keplerDocumentationAttribute == null) { 174 System.out.println("No KeplerDocumentation attribute."); 175 missingDocs = true; 176 } else { 177 ConfigurableAttribute userLevelDoc = 178 (ConfigurableAttribute) keplerDocumentationAttribute.getAttribute("userLevelDocumentation"); 179 if(userLevelDoc == null) { 180 System.out.println("No userLevelDocumentation attribute."); 181 missingDocs = true; 182 } else { 183 String uldStr = userLevelDoc.getConfigureText(); 184 if(uldStr == null || uldStr.trim().isEmpty() || uldStr.trim().equals("null")) { 185 System.out.println("UserLevelDocumentation appears to be empty."); 186 missingDocs = true; 187 } 188 } 189 } 190 191 if(missingDocs) { 192 193 System.out.println("Missing documentation for " + target.getFullName()); 194 System.out.println("Will try to generate from javadocs."); 195 196 // see if we have javadoc api 197 198 Method javadocMethod = null; 199 try { 200 Class<?> clazz = Class.forName("com.sun.tools.javadoc.Main"); 201 javadocMethod = clazz.getMethod("execute", String[].class); 202 } catch(Exception e1) { 203 System.err.println("ERROR: javadoc API not in class path."); 204 } 205 206 if(javadocMethod != null) { 207 208 final String fileName = SuperClassPathFinderDoclet.getFileNameForClassName(target.getClassName()); 209 if(fileName == null) { 210 System.err.println("ERROR: unable to get file name for class " + target.getClassName()); 211 } else { 212 213 // find parent files for this class 214 javadocMethod.invoke(null, new Object[]{ new String[] { 215 "-quiet", 216 "-doclet", 217 "org.kepler.kar.SuperClassPathFinderDoclet", fileName }}); 218 219 final String className = SuperClassPathFinderDoclet.getClassName(); 220 final Set<String> classFiles = SuperClassPathFinderDoclet.getClassFiles(); 221 222 if(classFiles.isEmpty()) { 223 System.out.println("ERROR: could not find files of super classes of " + fileName); 224 } else { 225 226 // construct documentation for the class using its source file, and 227 // those of its super classes 228 final String[] args = new String[3 + classFiles.size()]; 229 args[0] = "-quiet"; 230 args[1] = "-doclet"; 231 args[2] = "org.kepler.kar.KarDoclet"; 232 int j = 3; 233 for(String filename : classFiles) { 234 args[j] = filename; 235 j++; 236 } 237 238 javadocMethod.invoke(null, new Object[]{args}); 239 240 // replace the kepler documentation attribute with the generated one 241 final KeplerDocumentationAttribute docletDocAttribute = KarDoclet.getDoc(className); 242 target.removeAttribute(keplerDocumentationAttribute); 243 ((KeplerDocumentationAttribute) docletDocAttribute.clone(target.workspace())).setContainer(target); 244 missingDocs = false; 245 } 246 } 247 } 248 } 249 250 // see if docs are still missing 251 if(missingDocs) { 252 253 System.out.println("Will try to load from Kepler cache."); 254 255 // try to load from cache 256 final KARCacheManager kcm = KARCacheManager.getInstance(); 257 final Vector<KARCacheContent> list = kcm.getKARCacheContents(); 258 259 final String targetClassName = target.getClassName(); 260 for(KARCacheContent content : list) { 261 String cacheClassName = content.getCacheContent().getClassName(); 262 263 // make sure class name is not null. 264 // it's null for, e.g., workflow runs and report layouts 265 if(cacheClassName != null) { 266 267 if(cacheClassName.equals(targetClassName)) { 268 269 KeplerLSID lsid = content.getLsid(); 270 if(lsid != null) { 271 CacheObject cacheObject = CacheManager.getInstance().getHighestCacheObjectRevision(lsid); 272 if(cacheObject != null && (cacheObject instanceof ActorCacheObject)) { 273 ActorMetadata metadata = ((ActorCacheObject)cacheObject).getMetadata(); 274 if(metadata != null) { 275 final KeplerDocumentationAttribute cacheDocAttribute = metadata.getDocumentationAttribute(); 276 if(cacheDocAttribute != null) { 277 target.removeAttribute(keplerDocumentationAttribute); 278 ((KeplerDocumentationAttribute) cacheDocAttribute.clone(target.workspace())).setContainer(target); 279 missingDocs = false; 280 } 281 } 282 } 283 } 284 break; 285 } 286 } 287 } 288 } 289 290 if(!missingDocs) { 291 gda.showDocumentation(target); 292 } else { 293 MessageHandler.error("Could not find documentation for " + target.getName() + 294 ". To generate documentation, download Kepler from svn and run 'ant update-actor-doc'."); 295 } 296 } 297 } catch (Exception ee) { 298 ee.printStackTrace(); 299 } 300 } 301 302 /** 303 * allows you to set the ptolemyFrame that should be used as the parent of 304 * this action. 305 */ 306 public void setPtolemyFrame(PtolemyFrame pFrame) { 307 this.pFrame = pFrame; 308 } 309}