001/** 002 * Copyright (c) 2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: tao $' 006 * '$Date: 2010-06-03 16:45:10 -0700 (Thu, 03 Jun 2010) $' 007 * '$Revision: 24730 $' 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 */ 029package org.kepler.workflowscheduler.gui; 030 031import java.awt.event.ActionEvent; 032import java.util.Hashtable; 033import java.util.concurrent.atomic.AtomicBoolean; 034 035import javax.swing.AbstractAction; 036import javax.swing.JOptionPane; 037 038import org.apache.commons.logging.Log; 039import org.apache.commons.logging.LogFactory; 040import org.kepler.authentication.AuthenticationListener; 041import org.kepler.authentication.AuthenticationManager; 042import org.kepler.authentication.Domain; 043import org.kepler.gui.AuthenticationWithDomainNameAction; 044import org.kepler.module.workflowschedulergui.Initialize; 045import org.kepler.objectmanager.repository.Repository; 046import org.kepler.objectmanager.repository.RepositoryManager; 047 048import ptolemy.actor.gui.TableauFrame; 049 050/** 051 * Represent an abstract actions which operates a workflow scheduler server. The subclasses 052 * include ScheduleWorkflowAction, RemoveScheduleAction, EnableScheduleAction and 053 * DisableScheduleAction 054 */ 055public class SchedulerAbstractAction extends AbstractAction implements AuthenticationListener 056{ 057 private static final Log log = LogFactory.getLog(SchedulerAbstractAction.class 058 .getName()); 059 protected static final String SCHEDULER = "scheduler"; 060 protected static final String URL = "url"; 061 protected static final String ERROR = "Error"; 062 protected static String SLASHCONNECTOR = "://"; 063 public static final String NOREPORTWARNING ="The selected workflow's KAR doesn't contain "+ 064 "a report design, and so no run KAR will be created as a result of execution.\n"+ 065 "Continue?"; 066 067 protected static Hashtable <String, String>domainSessionHash = new Hashtable<String, String>(); 068 protected static String authenDomainForSourceKar = null; 069 //protected static String sessionId = null; //all subclass will share this session id 070 protected static String authenticationServiceURLForSourceKar = null; 071 protected static String sourceRepositoryName = null; 072 protected static Repository source = null; 073 protected String schedulerURL = null; 074 protected Schedule schedule = null; 075 protected TableauFrame parent = null; 076 //protected AuthenticateAction authAction = null; 077 protected ScheduleChangeController scheduleChangeController = null; 078 protected WorkflowSchedulerParentPanel schedulerParentPanel = null; 079 protected static volatile AtomicBoolean isActionWithAuthenticationDone = new AtomicBoolean(true); 080 protected static boolean hasReportLayout = true; 081 082 083 084 085 /** 086 * Constructor 087 * @param parent the parent frame of this action 088 * @param scheduleChangeController the GUI controller to handle the schedule change. 089 */ 090 public SchedulerAbstractAction(TableauFrame parent, WorkflowSchedulerParentPanel schedulerParentPanel, 091 ScheduleChangeController scheduleChangeController) 092 { 093 this.parent = parent; 094 this.schedulerParentPanel = schedulerParentPanel; 095 this.scheduleChangeController = scheduleChangeController; 096 schedulerURL = Initialize.getSchedulerURL(); 097 //this.authenDomainForSourceKar = authenDomainForSourceKar; 098 } 099 100 /** 101 * Perform an action to a workflow 102 */ 103 public void actionPerformed(ActionEvent e) 104 { 105 //check scheduler url is available. 106 if(schedulerURL == null || schedulerURL.trim().equals("")) 107 { 108 JOptionPane.showMessageDialog(parent, 109 "Kepler couldn't find the workflow scheduler url in the configuration file.", 110 "Error", JOptionPane.ERROR_MESSAGE); 111 return; 112 } 113 114 //check if a search process is done 115 if(schedulerParentPanel != null && !schedulerParentPanel.isSelectingRemoteWorkflowDone()) 116 { 117 String message = "Kepler hasn't finished the search on existing schedules from the remote scheduler.\n Please click the button later."; 118 JOptionPane.showMessageDialog(parent, 119 message, "Warning", JOptionPane.WARNING_MESSAGE); 120 return; 121 } 122 123 int choice = JOptionPane.YES_OPTION; 124 if(!hasReportLayout && this instanceof ScheduleWorkflowAction && 125 scheduleChangeController != null && scheduleChangeController.showWarningMessageOnNoReporting()) 126 { 127 choice = JOptionPane.showConfirmDialog(parent, 128 NOREPORTWARNING, "Warning", JOptionPane.YES_NO_OPTION); 129 } 130 131 if(choice == JOptionPane.NO_OPTION) 132 { 133 //System.out.println("Choosing no=============== "); 134 return; 135 } 136 137 try 138 { 139 //check Action with authentication(we login only once) is done 140 checkActionWithAuthentication(); 141 } 142 catch(Exception ee) 143 { 144 log.warn(ee.getMessage()); 145 return; 146 } 147 148 if(scheduleChangeController != null) 149 { 150 scheduleChangeController.startProgressBar(); 151 } 152 boolean success = getAuthenticationService(); 153 if(!success) 154 { 155 return; 156 } 157 String sessionID = null; 158 if(authenDomainForSourceKar != null) 159 { 160 sessionID = domainSessionHash.get(authenDomainForSourceKar); 161 } 162 163 //check if the cached sessionID is still valid 164 if(sessionID != null) 165 { 166 boolean existing = AuthenticationManager.getManager().proxyExists(sessionID, authenDomainForSourceKar); 167 if(!existing) 168 { 169 //not existing any more, set it to null 170 sessionID = null; 171 } 172 } 173 174 if (sessionID == null) 175 { 176 //login first 177 try 178 { 179 authenticate(); 180 } 181 catch(Exception ee) 182 { 183 log.warn(ee.getMessage()); 184 } 185 } 186 else 187 { 188 try 189 { 190 doAction(); 191 } 192 catch(Exception ee) 193 { 194 log.warn(ee.getMessage()); 195 } 196 if(scheduleChangeController != null) 197 { 198 scheduleChangeController.stopProgressBar(); 199 } 200 } 201 202 } 203 204 /** 205 *Do the real action. Every subclass should implement this method 206 */ 207 protected void doAction() throws Exception 208 { 209 String error = "Couldn't do schedule-related action to the workflow since the source repository is unknown"; 210 if(source == null) 211 { 212 JOptionPane.showMessageDialog(parent, error, ERROR, JOptionPane.ERROR_MESSAGE); 213 throw new Exception(error); 214 } 215 216 } 217 218 /** 219 * Check if an action with authentication process is done 220 * @throws Exception 221 */ 222 public void checkActionWithAuthentication() throws Exception 223 { 224 //check if the the authentication process is done. 225 if(isActionWithAuthenticationDone.get()== false) 226 { 227 String message = "Login and a schedule-related action are being processed right now. Please wait, then click the button later."; 228 JOptionPane.showMessageDialog(parent, 229 message, "Warning", JOptionPane.WARNING_MESSAGE); 230 throw new Exception(message); 231 } 232 } 233 234 /* 235 * Get the authentication service url 236 */ 237 private boolean getAuthenticationService() 238 { 239 boolean success = true; 240 Repository repository = null; 241 try 242 { 243 repository= RepositoryManager.getInstance().getRepository(sourceRepositoryName); 244 if(repository == null) 245 { 246 throw new Exception("Kepler couldn't find the reposiotry in its configuration file for the name "+sourceRepositoryName); 247 } 248 } 249 catch(Exception e) 250 { 251 JOptionPane.showMessageDialog(parent, "Kepler couldn't get the repository information for "+sourceRepositoryName 252 + " and so you couldn't continue to do a schedule-related action -"+e.getMessage(), ERROR, JOptionPane.ERROR_MESSAGE); 253 success = false; 254 return success; 255 } 256 authenDomainForSourceKar = repository.getAuthDomain(); 257 try 258 { 259 Domain domain = AuthenticationManager.getManager().getDomain(authenDomainForSourceKar); 260 if(domain == null) 261 { 262 throw new Exception("The authentication domain couldn't be found for the name"+authenDomainForSourceKar); 263 } 264 else 265 { 266 authenticationServiceURLForSourceKar = domain.getServiceURL(); 267 //System.out.println("Get the NEW!!! authentication service url is ====== "+authenticationServiceURL); 268 } 269 } 270 catch(Exception e) 271 { 272 JOptionPane.showMessageDialog(parent, "Couldn't get the authentication domanin and you could NOT continue to do a schedule-related action - \n"+e.getMessage(), ERROR, JOptionPane.ERROR_MESSAGE); 273 success = false; 274 } 275 276 //System.out.println("The authentication service url is ====== "+authenticationServiceURL); 277 return success; 278 } 279 280 281 /** 282 * Set the sourceRepositoryName associated with the action 283 * @param name 284 */ 285 public static void setSourceRespositoryName(String name) throws Exception 286 { 287 sourceRepositoryName = name; 288 source = RepositoryManager.getInstance().getRepository(sourceRepositoryName); 289 } 290 291 /* 292 * Fire authentication command 293 */ 294 private void authenticate() throws Exception 295 { 296 isActionWithAuthenticationDone.set(false); 297 if(scheduleChangeController != null) 298 { 299 scheduleChangeController.disableTreeSelection(); 300 } 301 AuthenticationWithDomainNameAction authAction = 302 new AuthenticationWithDomainNameAction(parent, this, authenDomainForSourceKar); 303 ActionEvent event = new ActionEvent(this, 100, "command"); 304 authAction.actionPerformed(event); 305 } 306 /** 307 * Call back method of AuthenticatListener. 308 * 309 */ 310 public void authenticationComplete(int status, String sessionId, String domainName) 311 { 312 if(status == AuthenticationListener.FAILURE) 313 { 314 //System.out.println("failure ============== in authenticationCompleted"); 315 JOptionPane.showMessageDialog(parent, "Authentication failed and you could NOT do a schedule-related action.", ERROR, JOptionPane.ERROR_MESSAGE); 316 } 317 else if(status == AuthenticationListener.CANCEL) 318 { 319 //System.out.println("cancel ============== in authenticationCompleted"); 320 } 321 else if(status == AuthenticationListener.SUCCESS) 322 { 323 //System.out.println("sccuess ============== in authenticationCompleted"); 324 //this.sessionID = sessionId; 325 //System.out.println("===============put the session id "+sessionId+ " and domain name "+domainName+" into the hashtable"); 326 domainSessionHash.put(domainName, sessionId); 327 try 328 { 329 doAction(); 330 } 331 catch(Exception ee) 332 { 333 log.error(ee.getMessage()); 334 } 335 } 336 isActionWithAuthenticationDone.set(true); 337 if(scheduleChangeController != null) 338 { 339 scheduleChangeController.enableTreeSelection(); 340 scheduleChangeController.stopProgressBar(); 341 } 342 //System.out.println("authentication is done ============== in authenticationCompleted"); 343 } 344 345 /** 346 * Set the schedule object 347 * @param schedule 348 */ 349 public void setSchedule(Schedule schedule) 350 { 351 this.schedule = schedule; 352 } 353 354 /** 355 * Set true if the workflow associated with action has a report layout. 356 * @param hasReportingLayout 357 */ 358 public static void setHasReportLayout(boolean hasReportingLayout) 359 { 360 hasReportLayout = hasReportingLayout; 361 } 362}