/* Copyright (c) 2008-2010, developers of the Ascension Log Visualizer
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package com.googlecode.logVisualizer.gui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import javax.swing.filechooser.FileFilter;
import net.java.swingfx.waitwithstyle.PerformanceInfiniteProgressPanel;
import org.jfree.ui.RefineryUtilities;
import com.googlecode.logVisualizer.Settings;
/**
* A dialog to give the possibility to use the AFH MafiaLog Parser from inside
* the Ascension Log Visualizer as long as the command line of the machine which
* is running this program can correctly handle the command {@code perl}.
* (Basically, this means that there has to be a Perl Runtime Environment
* installed on the given machine)
*/
final class ExternalMafiaLogParserDialog extends JDialog {
/**
*
*/
private static final long serialVersionUID = 6892809291961419988L;
private static final FileFilter PERL_SCRIPT_FILTER = new FileFilter() {
@Override
public boolean accept(final File f) {
return f.isDirectory() || f.getName().toLowerCase().endsWith(".pl");
}
@Override
public String getDescription() {
return "Perl Script";
}
};
private final ActionListener runAFHParserAction = new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
if (!ExternalMafiaLogParserDialog.this.fileLocationField.getText()
.equals("")
&& !ExternalMafiaLogParserDialog.this.argumentsField
.getText().equals("")
&& !ExternalMafiaLogParserDialog.this.userNameField
.getText().equals("")) {
ExternalMafiaLogParserDialog.this.setWaitingForProcessEnd(true);
ExternalMafiaLogParserDialog.this.runAFHParser();
} else {
JOptionPane.showMessageDialog(null,
"Please fill out all text fields.", "Missing input",
JOptionPane.WARNING_MESSAGE);
}
}
};
private JTextField fileLocationField;
private JTextField argumentsField;
private JTextField userNameField;
ExternalMafiaLogParserDialog(final JFrame owner) {
super(owner, true);
this.setLayout(new BorderLayout(5, 10));
this.setTitle("External Mafia Log Parser");
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
this.setGlassPane(new PerformanceInfiniteProgressPanel());
final JButton runButton = new JButton("Run parser");
final JButton cancelButton = new JButton("Cancel");
runButton.addActionListener(this.runAFHParserAction);
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
ExternalMafiaLogParserDialog.this.dispose();
}
});
final JPanel afhParserPanel = new JPanel(new GridLayout(0, 1, 5, 5));
afhParserPanel.add(this.createAFHParserLocationPanel());
afhParserPanel.add(this.createAFHParserOptionsPanel());
this.add(afhParserPanel, BorderLayout.NORTH);
this.add(
new JLabel(
"<html>Please refer to the AFH MafiaLog Parser documention on how to use that parser."
+ "<p>Note that the AFH MafiaLog Parser is not distributed together with this program.</html>"),
BorderLayout.CENTER);
final JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 10, 0));
buttonPanel.setPreferredSize(new Dimension(150, 50));
buttonPanel.add(runButton);
buttonPanel.add(cancelButton);
this.add(buttonPanel, BorderLayout.SOUTH);
this.pack();
RefineryUtilities.centerFrameOnScreen(this);
this.setVisible(true);
}
private JPanel createAFHParserLocationPanel() {
final JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(BorderFactory
.createTitledBorder("AFH MafiaLog Parser location"));
this.fileLocationField = new JTextField(
Settings.getSettingString("AFH Parser location"));
final JButton fileChooserButton = new JButton("Find File");
GridBagConstraints gbc;
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.insets = new Insets(5, 10, 5, 0);
panel.add(this.fileLocationField, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 2;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.EAST;
gbc.insets = new Insets(5, 25, 5, 10);
panel.add(fileChooserButton, gbc);
this.fileLocationField.addActionListener(this.runAFHParserAction);
File mafiaLogsDirectory = new File(
Settings.getSettingString("Mafia logs location"));
if (!mafiaLogsDirectory.exists()) {
mafiaLogsDirectory = null;
}
final JFileChooser logChooser = new JFileChooser(mafiaLogsDirectory);
logChooser
.setFileFilter(ExternalMafiaLogParserDialog.PERL_SCRIPT_FILTER);
fileChooserButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
final int state = logChooser.showOpenDialog(null);
if (state == JFileChooser.APPROVE_OPTION) {
ExternalMafiaLogParserDialog.this.fileLocationField
.setText(logChooser.getSelectedFile()
.getAbsolutePath());
}
}
});
return panel;
}
private JPanel createAFHParserOptionsPanel() {
final JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(BorderFactory
.createTitledBorder("AFH MafiaLog Parser options"));
this.argumentsField = new JTextField(
Settings.getSettingString("AFH Parser arguments"));
this.userNameField = new JTextField(
Settings.getSettingString("AFH Parser user name"));
final JLabel argumentsLabel = new JLabel("Arguments:");
final JLabel userNameLabel = new JLabel("User Name:");
GridBagConstraints gbc;
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(5, 10, 5, 0);
panel.add(argumentsLabel, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 2;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(5, 10, 5, 0);
panel.add(userNameLabel, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.insets = new Insets(5, 25, 5, 10);
panel.add(this.argumentsField, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 2;
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.insets = new Insets(5, 25, 5, 10);
panel.add(this.userNameField, gbc);
this.argumentsField.addActionListener(this.runAFHParserAction);
this.userNameField.addActionListener(this.runAFHParserAction);
return panel;
}
/**
* @param isProcessNotDone
* A flag showing whether the process has ended or not.
*/
void setWaitingForProcessEnd(final boolean isProcessNotDone) {
this.getGlassPane().setVisible(isProcessNotDone);
}
/**
* Runs the parser with the data from the TextFields of the GUI.
*/
void runAFHParser() {
// Save the used text field inputs.
Settings.setSettingString("AFH Parser location",
this.fileLocationField.getText());
Settings.setSettingString("AFH Parser arguments",
this.argumentsField.getText());
Settings.setSettingString("AFH Parser user name",
this.userNameField.getText());
final ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(new Runnable() {
@Override
public void run() {
try {
final File workingDirectory = new File(
ExternalMafiaLogParserDialog.this.fileLocationField
.getText()).getParentFile();
final Process process = Runtime
.getRuntime()
.exec("perl "
+ ExternalMafiaLogParserDialog.this.fileLocationField
.getText()
+ " "
+ ExternalMafiaLogParserDialog.this.argumentsField
.getText()
+ " "
+ ExternalMafiaLogParserDialog.this.userNameField
.getText(), null, workingDirectory);
try (final BufferedReader br = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
final ParserOutputViewer outputViewer = new ParserOutputViewer();
ExternalMafiaLogParserDialog.this.toFront();
String tmp;
while ((tmp = br.readLine()) != null) {
outputViewer.addParserOutput(tmp);
}
br.close();
ExternalMafiaLogParserDialog.this.dispose();
outputViewer.toFront();
}
} catch (final IOException e) {
ExternalMafiaLogParserDialog.this
.setWaitingForProcessEnd(false);
JOptionPane
.showMessageDialog(
null,
"There was a problem while running the parser. Please check whether the parsed logs were created.",
"Problem occurred",
JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
}
});
executor.shutdown();
}
/**
* A small class to display the output of the parser inside another frame.
*/
private static final class ParserOutputViewer extends JFrame {
/**
*
*/
private static final long serialVersionUID = -5574892142460463233L;
private static final String NEW_LINE = "\n";
private final JTextArea parserOutput;
ParserOutputViewer() {
super("Parser output");
this.setLayout(new GridLayout(1, 0));
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
this.parserOutput = new JTextArea();
this.parserOutput.setLineWrap(true);
this.parserOutput.setWrapStyleWord(true);
this.add(new JScrollPane(this.parserOutput));
this.pack();
this.setSize(640, 480);
RefineryUtilities.centerFrameOnScreen(this);
this.setVisible(true);
}
void addParserOutput(final String s) {
this.parserOutput.append(s);
this.parserOutput.append(ParserOutputViewer.NEW_LINE);
}
}
}