Mercurial > repos > yufei-luo > s_mart
view smart_toolShed/SMART/Java/Smart.java @ 1:30c5431d8ce4
Uploaded
author | yufei-luo |
---|---|
date | Thu, 17 Jan 2013 11:01:51 -0500 |
parents | e0f8dcca02ed |
children |
line wrap: on
line source
/** * * Copyright INRA-URGI 2009-2010 * * This software is governed by the CeCILL license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, * that may mean that it is complicated to manipulate, and that also * therefore means that it is reserved for developers and experienced * professionals having in-depth computer knowledge. Users are therefore * encouraged to load and test the software's suitability as regards their * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL license and that you accept its terms. * */ import java.util.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.awt.event.WindowAdapter; import java.io.*; import javax.swing.*; import javax.swing.filechooser.*; import javax.swing.border.*; import javax.swing.SwingUtilities; import java.util.prefs.BackingStoreException; public class Smart extends JPanel implements ActionListener { String version = "1.1.0"; JFrame mainFrame; JButton openButton; JButton resetFileButton; JComboBox formatTypes; JComboBox fileFormats; String[] emptyFormats = {"Choose a type first..."}; JFrame askFrame; JButton pythonButton; JButton mySqlButton; JButton rButton; HashMap <JButton, Program> callingProgram; static JList fileList; static JTextArea logArea; // progress bar static JLabel messageField; static JProgressBar progressBar; static JLabel etaField; // process Program currentProgram; Process process; javax.swing.Timer processTimer; int previousStatus; public Smart() { super(new BorderLayout()); callingProgram = new HashMap <JButton, Program> (); previousStatus = -1; processTimer = new javax.swing.Timer(1000, this); processTimer.stop(); // Ask frame buttons pythonButton = new JButton("find..."); mySqlButton = new JButton("find..."); rButton = new JButton("find..."); // Get available formats FormatsReader formatReader = new FormatsReader(Global.smartFormatsFileName); if (! formatReader.read()) { System.out.println("Something was wrong while reading file format..."); } // Get screen size Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); // Log logArea = new JTextArea(512, Global.logAreaSize); logArea.setPreferredSize(new Dimension(screenSize.width, (int) (screenSize.height * 0.22))); logArea.setFont(new Font("Monospaced", logArea.getFont().getStyle(), logArea.getFont().getSize())); JScrollPane logScroll = new JScrollPane(logArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); TitledBorder logBorder = BorderFactory.createTitledBorder("Log"); logScroll.setBorder(logBorder); logArea.append("Using S-MART " + version + "\n"); GridLayout horizontalLayout = new GridLayout(1, 0); // check configuration this.readConfigurationFile(); if (System.getProperty("os.name").matches("(?i).*Windows.*")) { if (! this.checkDefaultDir()) { this.checkRegistries(); } } this.checkConfiguration(); // Tabs JTabbedPane tabbedPane = new JTabbedPane(); tabbedPane.setPreferredSize(new Dimension(screenSize.width, (int) (screenSize.height * 0.75))); // File panel JPanel filePanel = new JPanel(false); filePanel.setLayout(new FlowLayout()); tabbedPane.add("Files", filePanel); // Format sub-panel JPanel formatComboPanel = new JPanel(false); JPanel formatPanel = new JPanel(false); Vector<String> formatTypesString = Global.formats.getFormatTypes(); formatPanel.setLayout(horizontalLayout); formatTypesString.insertElementAt("Choose the format type", 0); JLabel formatLabel = new JLabel("Format"); formatTypes = new JComboBox(formatTypesString); fileFormats = new JComboBox(emptyFormats); formatLabel.setLabelFor(fileFormats); formatTypes.addActionListener(this); formatComboPanel.add(formatTypes); formatComboPanel.add(fileFormats); formatPanel.add(formatLabel); formatPanel.add(formatComboPanel); // File chooser sub-panel JPanel fileChooserPanel = new JPanel(false); fileChooserPanel.setLayout(horizontalLayout); JLabel fileLabel = new JLabel("File"); openButton = new JButton("Open a File..."); openButton.addActionListener(this); fileChooserPanel.add(fileLabel); fileChooserPanel.add(openButton); // File list sub-panel JPanel existingFilesPanel = new JPanel(false); existingFilesPanel.setLayout(horizontalLayout); existingFilesPanel.setMinimumSize(new Dimension(10000, 10000)); JLabel existingFilesLabel = new JLabel("Existing files"); Box fileListBox = Box.createHorizontalBox(); fileListBox.add(Box.createRigidArea(new Dimension(0, 100))); fileList = new JList(new DefaultListModel()); fileList.setLayoutOrientation(JList.HORIZONTAL_WRAP); fileList.setVisibleRowCount(4); JScrollPane listScroller = new JScrollPane(fileList); fileListBox.add(listScroller); existingFilesPanel.add(existingFilesLabel); existingFilesPanel.add(fileListBox); // Reset sub-panel JPanel resetFilePanel = new JPanel(false); resetFileButton = new JButton("Reset"); resetFileButton.addActionListener(this); // File panel layout Box box = Box.createVerticalBox(); box.add(formatPanel); box.add(fileChooserPanel); box.add(existingFilesPanel); box.add(resetFileButton); filePanel.add(box); // Program panels TreeMap < String, JTabbedPane > panels = new TreeMap < String, JTabbedPane >(); PythonProgramFinder programFinder = new PythonProgramFinder("Python"); String comments = programFinder.findPrograms(); if (comments != null) { logArea.append(comments); } for (int i = 0; i < programFinder.getPrograms().size(); i++) { Program program = programFinder.getPrograms().get(i); JPanel programPanel = program.getPanel(); String section = program.getSection(); JTabbedPane sectionPane = null; if (panels.containsKey(section)) { sectionPane = panels.get(section); } else { sectionPane = new JTabbedPane(); tabbedPane.addTab(section, sectionPane); panels.put(section, sectionPane); } JScrollPane programScroll = new JScrollPane(programPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); sectionPane.addTab(program.getName(), programScroll); JButton button = program.getButton(); button.addActionListener(this); callingProgram.put(button, program); } // Progress bar JPanel progressPanel = new JPanel(new GridLayout(1, 0), false); progressPanel.setPreferredSize(new Dimension(screenSize.width, (int) (screenSize.height * 0.02))); messageField = new JLabel(); progressBar = new JProgressBar(0, 100); etaField = new JLabel(); messageField.setHorizontalAlignment(JLabel.LEFT); progressBar.setValue(0); etaField.setHorizontalAlignment(JLabel.RIGHT); progressBar.setStringPainted(true); progressPanel.add(messageField); progressPanel.add(progressBar); progressPanel.add(etaField); add(tabbedPane, BorderLayout.PAGE_START); add(logScroll, BorderLayout.CENTER); add(progressPanel, BorderLayout.PAGE_END); } public String checkSubKey(int hkey, String key, String subKey, String trace) { try { for (String currentSubKey: WindowsRegistry.readStringSubKeys(hkey, key)) { trace += "Looking at sub-key " + currentSubKey; if (currentSubKey.matches(subKey)) { trace += " OK"; return subKey; } trace += "\n"; } } catch (Exception e) { final Writer writer = new StringWriter(); final PrintWriter printWriter = new PrintWriter(writer); e.printStackTrace(printWriter); trace += writer.toString(); } return null; } public void debugRegistry(int hkey, String keys[], String valueName, String trace) { String concatenatedKeys = ""; String selectedKey = null; for (String key: keys) { selectedKey = checkSubKey(hkey, concatenatedKeys, key, trace); if (selectedKey != null) { concatenatedKeys += "\\" + selectedKey; } else { return; } } } public String checkRegistry(int hkey, String key, String valueName, String trace) { String result = null; try { result = WindowsRegistry.readString(hkey, key, valueName); } catch (Exception e) { final Writer writer = new StringWriter(); final PrintWriter printWriter = new PrintWriter(writer); e.printStackTrace(printWriter); trace += result.toString(); } return result; } public boolean checkDefaultDir() { String defaultPythonPath = System.getProperty("user.dir") + "\\Apps\\Python\\python.exe"; java.io.File defaultPythonFile = new java.io.File(defaultPythonPath); String defaultRPath = System.getProperty("user.dir") + "\\Apps\\R\\bin\\R.exe"; java.io.File defaultRFile = new java.io.File(defaultRPath); if (defaultPythonFile.exists()) { Global.pythonCommand = defaultPythonPath; logArea.append("Python found in default directory: " + defaultPythonPath + "\n"); } else { logArea.append("Python not found in default directory: " + defaultPythonPath + "\n"); return false; } if (defaultRFile.exists()) { logArea.append("R found in default directory: " + defaultRPath + "\n"); Global.rCommand = defaultRPath; return true; } logArea.append("Python not found in default directory: " + defaultPythonPath + "\n"); return false; } public boolean checkRegistries() { String pythonDir = null; String validValue = null; String rDir; String[] pythonFlavors = {"2.5", "2.6", "2.7"}; String[] pythonDirectories = {"Python25", "Python26", "Python27"}; String[] rDirectories = {"R-2.11.0", "R-2.11.0-x64"}; String trace = ""; for (String pythonFlavor: pythonFlavors) { pythonDir = checkRegistry(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Python\\PythonCore\\" + pythonFlavor + "\\InstallPath", "", trace); if (pythonDir != null) { break; } } if (pythonDir == null) { try { logArea.append("Using OS: " + WindowsRegistry.readString(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductName") + "\n"); } catch (Exception e) { logArea.append("Cannot do simple registry test. Strange...\n"); } String keys[] = {"SOFTWARE", "Python", "PythonCore", "2.[567]", "InstallPath"}; debugRegistry(WindowsRegistry.HKEY_LOCAL_MACHINE, keys, "", trace); logArea.append("S-MART cannot find Python installation directory using registry. Trying desperate move...\n"); for (String currentDirectory: pythonDirectories) { String fileName = "C:\\" + currentDirectory; java.io.File file = new java.io.File(fileName); if (file.exists()) { pythonDir = fileName; break; } } if (pythonDir == null) { logArea.append("S-MART cannot find Python installation directory despite all my efforts...\n" + trace); return false; } } rDir = checkRegistry(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\R-core\\R", "InstallPath", trace); if (rDir == null) { logArea.append("S-MART cannot find R installation directory using registry. Trying desperate move...\n"); for (String currentDirectory: rDirectories) { String fileName = "C:\\Program Files\\R\\" + currentDirectory; java.io.File file = new java.io.File(fileName); if (file.exists()) { rDir = fileName; break; } } if (rDir == null) { logArea.append("S-MART cannot find R installation directory despite all my efforts...\n" + trace); return false; } } Global.pythonCommand = pythonDir + "\\" + "python.exe"; Global.rCommand = rDir + "\\" + "bin\\R.exe"; return true; } public boolean checkConfiguration() { int status = this.testConfiguration(); if (status == previousStatus) { logArea.append("S-MART does not seem to work properly... Tried to manage it by myself, unsuccessfully... Check documentation for further explanation...\n"); return false; } switch (status) { case 0: return true; case 1: logArea.append("S-MART does not seem to work properly... Check documentation for further explanation...\n"); break; case 3: this.askWhereIsProgram("python"); break; case 4: break; case 5: this.askWhereIsProgram("mySQL"); break; case 6: this.askWhereIsProgram("R"); break; case 7: logArea.append("Please install 'ColorBrewer' R package...\n"); break; default: logArea.append("Weird configuration test status: " + status + "...\n"); } previousStatus = status; return true; } public int testConfiguration() { String[] command = {Global.pythonCommand, "Python" + java.io.File.separator + "testInstall.py"}; ProgramLauncher launcher = new ProgramLauncher(command, logArea, messageField, progressBar, etaField); String line; launcher.execute(); return launcher.getExitValue(); } public void readConfigurationFile() { java.io.File file = new java.io.File(Global.smartConfFileName); String line = null; if (! file.exists()) { return; } try { BufferedReader reader = new BufferedReader(new FileReader(file)); while ((line = reader.readLine()) != null) { line = line.trim(); if (line.startsWith("python:")) Global.pythonCommand = line.substring("python:".length()).trim(); else if (line.startsWith("mysql:")) Global.mysqlCommand = line.substring("mysql:".length()).trim(); else if (line.startsWith("r:")) Global.rCommand = line.substring("r:".length()).trim(); } reader.close(); } catch (FileNotFoundException e) { logArea.append("Configuration file is empty: " + e.getMessage() + "!\n"); return; } catch (IOException e) { logArea.append("Weird with configuration file: " + e.getMessage() + "!\n"); return; } } public void askWhereIsProgram(String program) { askFrame = new JFrame("Where is " + program + "?"); askFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JLabel label = new JLabel("Where is your " + program + " (or " + program + ".exe) file?"); JButton button = null; if ("python".equals(program)) { button = pythonButton; } else if ("mySQL".equals(program)) { button = mySqlButton; } else if ("R".equals(program)) { button = rButton; } else { logArea.append("Problem with the button!\n"); } askFrame.getContentPane().add(label, BorderLayout.WEST); askFrame.getContentPane().add(button, BorderLayout.EAST); button.addActionListener(this); askFrame.pack(); askFrame.setVisible(true); askFrame.setAlwaysOnTop(true); } public void actionPerformed(ActionEvent e) { // Python command chooser if (e.getSource() == pythonButton) { JFileChooser chooser = new JFileChooser(); if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) { Global.pythonCommand = chooser.getSelectedFile().getPath(); askFrame.setVisible(false); askFrame.dispose(); try { BufferedWriter out = new BufferedWriter(new FileWriter(Global.smartConfFileName, true)); out.write("python: " + Global.pythonCommand + "\n"); out.close(); } catch (IOException exception) { logArea.append("Cannot write configuration file!\n"); } } this.checkConfiguration(); } // MySQL command chooser else if (e.getSource() == mySqlButton) { JFileChooser chooser = new JFileChooser(); if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) { Global.mysqlCommand = chooser.getSelectedFile().getPath(); askFrame.setVisible(false); askFrame.dispose(); try { BufferedWriter out = new BufferedWriter(new FileWriter(Global.smartConfFileName, true)); out.write("mysql: " + Global.mysqlCommand + "\n"); out.close(); } catch (IOException exception) { logArea.append("Cannot write configuration file!\n"); } } this.checkConfiguration(); } // R command chooser else if (e.getSource() == rButton) { JFileChooser chooser = new JFileChooser(); if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) { Global.rCommand = chooser.getSelectedFile().getPath(); askFrame.setVisible(false); askFrame.dispose(); try { BufferedWriter out = new BufferedWriter(new FileWriter(Global.smartConfFileName, true)); out.write("r: " + Global.rCommand + "\n"); out.close(); } catch (IOException exception) { logArea.append("Cannot write configuration file!\n"); } } this.checkConfiguration(); } // Format type else if (e.getSource() == formatTypes) { if (((String) formatTypes.getSelectedItem()).startsWith("Choose")) { return; } fileFormats.removeAllItems(); Vector < String > selectedFormats = Global.formats.getFormats((String) formatTypes.getSelectedItem()).getFormats(); for (int i = 0; i < selectedFormats.size(); i++) { fileFormats.addItem(selectedFormats.get(i)); } } // Main file chooser else if (e.getSource() == openButton) { if (((String) formatTypes.getSelectedItem()).startsWith("Choose")) { logArea.append("Please choose a type and format before selecting a file!\n"); return; } JFileChooser chooser = new JFileChooser(); if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) { String fileName = chooser.getSelectedFile().getPath(); Global.fileNames.addElement(fileName); Global.files.addFile(fileName, (String) formatTypes.getSelectedItem(), (String) fileFormats.getSelectedItem()); DefaultListModel defaultListModel = (DefaultListModel) fileList.getModel(); defaultListModel.addElement(fileName); } } // Reset file chooser else if (e.getSource() == resetFileButton) { Global.files.clear(); Global.fileNames.clear(); DefaultListModel defaultListModel = (DefaultListModel) fileList.getModel(); defaultListModel.clear(); } // Other file choosers else if (Global.otherFilesChooser.containsKey(e.getSource())) { JTextField textField = Global.otherFilesChooser.get(e.getSource()); JFileChooser chooser = new JFileChooser(); if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) { textField.setText(chooser.getSelectedFile().getPath()); } } // Other directories choosers else if (Global.otherDirectoriesChooser.containsKey(e.getSource())) { JTextField textField = Global.otherDirectoriesChooser.get(e.getSource()); JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) { textField.setText(chooser.getSelectedFile().getPath()); } } else if (Global.otherFileConcatenationChooser.containsKey(e.getSource())) { JTextField textField = Global.otherDirectoriesChooser.get(e.getSource()); JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); if (chooser.showOpenDialog(mainFrame) == JFileChooser.APPROVE_OPTION) { String text = textField.getText(); if ((text == null) || ("".equals(text))) { textField.setText(chooser.getSelectedFile().getPath()); } else { textField.setText(text + "," + chooser.getSelectedFile().getPath()); } } } // Programs else { currentProgram = callingProgram.get(e.getSource()); String comment = currentProgram.checkValues(); if (comment != null) { logArea.append(comment); return; } LinkedList <String> command = currentProgram.getCommand(); ProgramLauncher launcher = new ProgramLauncher(command, logArea, messageField, progressBar, etaField); launcher.execute(); Vector < File > outputFiles = currentProgram.getOutputFiles(); for (int i = 0; i < outputFiles.size(); i++) { File file = outputFiles.get(i); if (file.getFormatType().compareToIgnoreCase("other") != 0) { Global.fileNames.addElement(file.getName()); Global.files.addFile(file); } } currentProgram = null; } } private static void removeTmpFiles() { logArea.append("You want to quit already?\nRemoving temporary files..."); String[] command = {Global.pythonCommand, "Python" + java.io.File.separator + "removeAllTmpTables.py"}; ProgramLauncher launcher = new ProgramLauncher(command, logArea, messageField, progressBar, etaField); launcher.execute(); logArea.append(" done.\nNow quitting.\nBye!"); } private static void printJavaVersions() { String[] pro = {"java.version", "java.vm.version", "java.runtime.version"}; Properties properties = System.getProperties(); for (int i = 0; i < pro.length; i++) { logArea.append(pro[i] + ": " + properties.getProperty(pro[i]) + "\n"); } } private static void createAndShowGUI() { // Create and set up the window. JFrame mainFrame = new JFrame("S-Mart"); mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create and set up the content pane. JComponent newContentPane = new Smart(); newContentPane.setOpaque(true); mainFrame.setContentPane(newContentPane); // Display the window. mainFrame.pack(); mainFrame.setVisible(true); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); mainFrame.setBounds(0, 0, screenSize.width, screenSize.height); printJavaVersions(); // Remove tmp file while quitting. mainFrame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { removeTmpFiles(); } }); } public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } }