001/* 002 * Copyright (c) 2009-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2014-08-15 18:04:13 +0000 (Fri, 15 Aug 2014) $' 007 * '$Revision: 32889 $' 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.modulemanager.gui; 031 032import java.awt.Color; 033import java.awt.event.ActionEvent; 034import java.awt.event.ActionListener; 035import java.io.File; 036import java.io.FileNotFoundException; 037import java.util.ArrayList; 038import java.util.List; 039 040import javax.swing.DefaultListModel; 041import javax.swing.JButton; 042import javax.swing.JFileChooser; 043import javax.swing.JLabel; 044import javax.swing.JList; 045import javax.swing.JOptionPane; 046import javax.swing.JPanel; 047import javax.swing.JScrollPane; 048import javax.swing.ListModel; 049import javax.swing.SwingWorker; 050import javax.swing.event.ListSelectionEvent; 051import javax.swing.event.ListSelectionListener; 052 053import org.apache.tools.ant.DefaultLogger; 054import org.apache.tools.ant.Project; 055import org.apache.tools.ant.taskdefs.Copy; 056import org.jdesktop.layout.GroupLayout; 057import org.kepler.build.Run; 058import org.kepler.build.modules.CurrentSuiteTxt; 059import org.kepler.build.modules.Module; 060import org.kepler.build.modules.ModuleTree; 061import org.kepler.build.modules.ModulesTxt; 062import org.kepler.build.project.ProjectLocator; 063import org.kepler.build.util.Version; 064import org.kepler.modulemanager.ModuleDownloader; 065import org.kepler.util.ShutdownNotifier; 066 067import ptolemy.gui.GraphicalMessageHandler; 068import ptolemy.gui.JFileChooserBugFix; 069import ptolemy.gui.PtFileChooser; 070import ptolemy.gui.PtFilenameFilter; 071import ptolemy.gui.PtGUIUtilities; 072import ptolemy.util.MessageHandler; 073 074/** 075 * Created by David Welker. 076 * Date: Oct 7, 2009 077 * Time: 6:33:12 PM 078 */ 079public class CurrentSuitePanel extends JPanel 080{ 081 private static String CURRENT_SUITE_LABEL_TEXT = 082 "<html><p><font color=blue>If you're seeing this dialog when trying to launch Kepler, " + 083 "Kepler had a problem starting up.</font></p><p><font color=blue>Please select a suite " + 084 "from the Available Suites and Modules tab and click Apply and Restart.</font></p>" + 085 "<p>Current Suite:</p></html>"; 086 private JLabel currentSuiteListLabel = new JLabel(CURRENT_SUITE_LABEL_TEXT); 087 private JList currentSuiteList = new JList(); 088 private JScrollPane activeModulesListScrollPane = new JScrollPane(currentSuiteList); 089 090 private JButton saveConfiguration = new JButton("Save Suite"); 091 private JButton loadConfiguration = new JButton("Load Suite"); 092 093 private ModuleDownloader downloader; 094 095 public CurrentSuitePanel() 096 { 097 super(); 098 initComponents(); 099 layoutComponents(); 100 } 101 102 private void initActiveModulesList() 103 { 104 String currentSuiteName = CurrentSuiteTxt.getName(); 105 if( currentSuiteName.equals("unknown") ) 106 { 107 currentSuiteName = "custom"; 108 } 109 currentSuiteListLabel.setText(CURRENT_SUITE_LABEL_TEXT + currentSuiteName ); 110 111 DefaultListModel listModel = new DefaultListModel(); 112 ModulesTxt.init(); 113 for(Module module : ModuleTree.instance()) 114 { 115 listModel.addElement(module.toString()); 116 } 117 currentSuiteList.setModel(listModel); 118 } 119 120 private void initComponents() 121 { 122 initActiveModulesList(); 123 downloader = new ModuleDownloader(); 124 ModuleDownloadProgressMonitor mdpm = new ModuleDownloadProgressMonitor(this); 125 downloader.addListener(mdpm); 126 127 currentSuiteList.addListSelectionListener(new ListSelectionListener() 128 { 129 @Override 130 public void valueChanged(ListSelectionEvent e) 131 { 132 currentSuiteList.clearSelection(); 133 } 134 }); 135 136 saveConfiguration.addActionListener( new ActionListener() 137 { 138 139 @Override 140 public void actionPerformed(ActionEvent e) 141 { 142 // Avoid white boxes in file chooser, see 143 // http://bugzilla.ecoinformatics.org/show_bug.cgi?id=3801 144 JFileChooserBugFix jFileChooserBugFix = new JFileChooserBugFix(); 145 Color background = null; 146 PtFileChooser fc = new PtFileChooser(null, "Save Suite", JFileChooser.SAVE_DIALOG); 147 try { 148 background = jFileChooserBugFix.saveBackground(); 149 fc.setSelectedFile(new File("unnamed.txt")); 150 int returnValue = fc.showDialog(CurrentSuitePanel.this, "Save"); 151 File saveToFile = fc.getSelectedFile(); 152 if(saveToFile.exists() && !PtGUIUtilities.useFileDialog()) { 153 if(MessageHandler.yesNoQuestion("Overwrite \"" 154 + saveToFile.getName() + "\"?")) { 155 returnValue = JFileChooser.APPROVE_OPTION; 156 } else { 157 returnValue = JFileChooser.CANCEL_OPTION; 158 } 159 } 160 if( returnValue == JFileChooser.APPROVE_OPTION ) 161 { 162 Copy copy = new Copy(); 163 copy.setFile(ModulesTxt.instance()); 164 copy.setTofile(saveToFile); 165 copy.execute(); 166 } 167 } finally { 168 jFileChooserBugFix.restoreBackground(background); 169 } 170 } 171 }); 172 173 loadConfiguration.addActionListener( new ActionListener() 174 { 175 176 @Override 177 public void actionPerformed(ActionEvent e) 178 { 179 PtFileChooser fc = new PtFileChooser(null, "Load Suite", JFileChooser.OPEN_DIALOG); 180 181 fc.addChoosableFileFilter(new PtFilenameFilter() 182 { 183 @Override 184 public boolean accept(File f) 185 { 186 return f.getName().endsWith(".txt"); 187 } 188 189 @Override 190 public String getDescription() 191 { 192 return "Module configuration files."; 193 } 194 }); 195 int returnValue = fc.showDialog(CurrentSuitePanel.this, "Load Configuration"); 196 if( returnValue == JFileChooser.APPROVE_OPTION ) 197 { 198 System.out.println("Load"); 199 200 File loadFromFile = fc.getSelectedFile(); 201 Copy copy = new Copy(); 202 copy.setOverwrite(true); 203 copy.setFile(loadFromFile); 204 copy.setTofile(ModulesTxt.instance()); 205 copy.execute(); 206 initActiveModulesList(); 207 208 JOptionPane.showMessageDialog(CurrentSuitePanel.this, "Restarting..."); 209 SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() 210 { 211 @Override 212 public Void doInBackground() throws Exception 213 { 214 saveConfiguration.setEnabled(false); 215 loadConfiguration.setEnabled(false); 216 217 ListModel listModel = currentSuiteList.getModel(); 218 List<String> moduleList = new ArrayList(); 219 for (int i = 0; i < listModel.getSize(); i++) 220 moduleList.add((String) listModel.getElementAt(i)); 221 try { 222 downloader.downloadModules(moduleList); 223 } catch (FileNotFoundException e) { 224 JOptionPane.showMessageDialog( 225 CurrentSuitePanel.this, 226 e.getMessage()); 227 } 228 return null; 229 } 230 231 @Override 232 protected void done() 233 { 234 Project project = new Project(); 235 project.setBaseDir(ProjectLocator.getProjectDir()); 236 DefaultLogger logger = new DefaultLogger(); 237 logger.setMessageOutputLevel(Project.MSG_INFO); 238 logger.setOutputPrintStream(System.out); 239 logger.setErrorPrintStream(System.out); 240 project.addBuildListener(logger); 241 242 //XXX call ShutdownNotifer.shutdown() before spawning new process, 243 // to avoid 2nd instance potentially interfering with quitting first. 244 // see: http://bugzilla.ecoinformatics.org/show_bug.cgi?id=5484 245 System.out.println("CurrentSuitePanel notifiying shutdown listeners " + 246 "of impending shutdown. Any open databases may take awhile to close..."); 247 ShutdownNotifier.shutdown(); 248 249 Run run = new Run(); 250 run.setTaskName("run"); 251 run.setProject(project); 252 run.init(); 253 run.setSpawn(true); 254 run.execute(); 255 256 //TODO why call exit with error arg here? 257 System.exit(1); 258 } 259 260 }; 261 worker.execute(); 262 } 263 } 264 }); 265 266 } 267 268 private void layoutComponents() 269 { 270 GroupLayout layout = new GroupLayout(this); 271 setLayout(layout); 272 layout.setAutocreateContainerGaps(true); 273 layout.setAutocreateGaps(true); 274 275 layout.setHorizontalGroup 276 ( 277 layout.createParallelGroup() 278 .add(currentSuiteListLabel) 279 .add(activeModulesListScrollPane) 280 .add( layout.createSequentialGroup() 281 .add(saveConfiguration) 282 .add(loadConfiguration)) 283 ); 284 285 layout.setVerticalGroup 286 ( 287 layout.createSequentialGroup() 288 .add(currentSuiteListLabel) 289 .add(activeModulesListScrollPane) 290 .add(layout.createParallelGroup() 291 .add(saveConfiguration) 292 .add(loadConfiguration)) 293 ); 294 } 295 296 /** Perform sanity checks on the suite to see if Kepler will start 297 * using that suite. If it appears that Kepler will not start, 298 * ask the user if they really want to exit the Module Manager. 299 * 300 * @return returns true if the Module Manager can exit. 301 */ 302 public static boolean canExit() { 303 304 //System.out.println("Performing sanity checks for selected suite."); 305 306 boolean retval = true; 307 308 GraphicalMessageHandler handler = new GraphicalMessageHandler(); 309 MessageHandler.setMessageHandler(handler); 310 311 final ModulesTxt modulesTxt = ModulesTxt.instance(); 312 313 // read the modules txt file 314 modulesTxt.read(); 315 316 // see if kepler suite is found 317 ModuleTree tree = new ModuleTree(modulesTxt); 318 if(tree.getModuleByStemName("kepler") == null) { 319 320 // check the suite name 321 CurrentSuiteTxt.init(); 322 String suiteName = CurrentSuiteTxt.getName(); 323 if(!suiteName.equals("kepler") && !Version.stem(suiteName).equals("kepler")) { 324 retval = MessageHandler.yesNoQuestion("The current suite does not contain the kepler module.\n" + 325 "Kepler will most likely not start with this suite.\n" + 326 "Do you still want to exit the Module Manager?"); 327 } 328 329 } 330 /* This is commented out since allModulesPresent() can incorrectly return false. 331 * If use.keplerdata exists, allModulesPresent() appears to only look for modules 332 * in kepler.modules and not where Kepler is installed. 333 else if(!tree.allModulesPresent()) { 334 StringBuilder message = new StringBuilder("The following modules are not present: "); 335 for(Module module : tree.getMissingModules()) { 336 message.append("\n" + module.getName()); 337 } 338 message.append("\n"); 339 message.append("Do you still want to exit the Module Manager?"); 340 retval = MessageHandler.yesNoQuestion(message.toString()); 341 } 342 */ 343 344 return retval; 345 346 } 347}