
com.github.bordertech.wcomponents.lde.StandaloneLauncher Maven / Gradle / Ivy
package com.github.bordertech.wcomponents.lde;
import com.github.bordertech.wcomponents.util.Config;
import com.github.bordertech.wcomponents.util.ConfigurationProperties;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.MapConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* This launcher is intended to be run in a stand-alone environment, i.e. directly From a jar file rather than through
* an IDE. It provides basic controls to interact with the LDE.
*
* @author Yiannis Paschalidis
* @since 1.0.0
*/
public final class StandaloneLauncher {
/**
* The singleton instance of the StandaloneLauncher UI.
*/
private static final StandaloneLauncher INSTANCE = new StandaloneLauncher();
/**
* The WComponent LDE launcher.
*/
private final MyLauncher launcher = new MyLauncher();
/**
* This text area is used to display the log output.
*/
private final JTextArea log = new JTextArea();
/**
* Creates a StandaloneLauncher.
*/
private StandaloneLauncher() {
final JFrame frame = new JFrame("WComponent stand-alone LDE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel content = new JPanel();
content.setLayout(new BorderLayout());
frame.setContentPane(content);
content.add(new JLabel("Log:"), BorderLayout.NORTH);
log.setColumns(120);
log.setRows(30);
log.setFont(new Font("Monospaced", Font.PLAIN, 12));
content.add(new JScrollPane(log, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0));
content.add(buttonPanel, BorderLayout.SOUTH);
JButton button = new JButton("Clear log");
buttonPanel.add(button);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent event) {
log.setText("");
}
});
button = new JButton("Launch browser");
buttonPanel.add(button);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent event) {
// Use of reflections here is required as we still need to compile under java 1.5.
//Desktop.getDesktop().open(index);
try {
Class> clazz = Class.forName("java.awt.Desktop");
Object instance = clazz.getMethod("getDesktop").invoke(null);
clazz.getMethod("browse", URI.class).invoke(instance, new URI(
getInstance().launcher.getUrl()));
} catch (ClassNotFoundException e) {
//Desktop isn't available in Java 1.5, so we'll just use a
// windows specific cmdline for now
String cmd = "rundll32 url.dll,FileProtocolHandler "
+ getInstance().launcher.getUrl();
try {
Runtime.getRuntime().exec(cmd);
} catch (Exception e2) {
LogFactory.getLog(getClass()).error("Failed to launch browser", e);
}
} catch (Exception e) {
LogFactory.getLog(getClass()).error("Failed to launch browser", e);
}
}
});
button = new JButton("Exit");
buttonPanel.add(button);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent event) {
// Trigger closing of the frame rather than forcefully terminating the VM.
// This allows clean-up routines registered in window listeners to run.
WindowEvent closeEvent = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(closeEvent);
}
});
frame.pack();
frame.setVisible(true);
}
/**
* @return the Singleton instance of the StandaloneLauncher.
*/
public static StandaloneLauncher getInstance() {
return INSTANCE;
}
/**
* Logs a message to the console (text area).
*
* @param message the message to log.
*/
public void log(final String message) {
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
log(message);
}
});
} else {
log.append(message);
}
}
/**
* The entry point when the launcher is run as a java application.
*
* @param args command-line arguments, ignored.
* @throws Exception on error
*/
public static void main(final String[] args) throws Exception {
// Set the logger to use the text area logger
System.setProperty("org.apache.commons.logging.Log",
"com.github.bordertech.wcomponents.lde.StandaloneLauncher$TextAreaLogger");
// Set the port number to a random port
Configuration internalWComponentConfig = Config.getInstance();
CompositeConfiguration config = new CompositeConfiguration(new MapConfiguration(
new HashMap()));
config.addConfiguration(internalWComponentConfig); // Internal WComponent config next
config.setProperty(ConfigurationProperties.LDE_SERVER_PORT, 0);
Config.setConfiguration(config);
getInstance().launcher.run();
getInstance().log("LDE now running on " + getInstance().launcher.getUrl() + '\n');
}
/**
* Extension of PlainLauncher to make getUrl() public.
*/
public static final class MyLauncher extends PlainLauncher {
/**
* {@inheritDoc}
*/
@Override
public String getUrl() {
return super.getUrl();
}
}
/**
* A commons-logging Log implementation which logs to the StandaloneLauncher log.
*/
public static final class TextAreaLogger implements Log {
/**
* The TRACE log-level should be used to output even more fine-grained information than DEBUG.
*/
public static final int TRACE = 0;
/**
* The DEBUG log-level should be used for fine-grained information useful for debugging an application.
*/
public static final int DEBUG = 1;
/**
* The INFO log-level is used to output application processing at a course level.
*/
public static final int INFO = 2;
/**
* The WARN log-level is used to log information about potentially damaging situations.
*/
public static final int WARN = 3;
/**
* The ERROR log-level is used to log application errors where the application can recover.
*/
public static final int ERROR = 4;
/**
* The FATAL log-level is used to log application errors where the application can not recover.
*/
public static final int FATAL = 5;
/**
* The current log level.
*/
private int logLevel = DEBUG;
/**
* Creates a TextAreaLogger.
*
* @param name the logger name.
*/
public TextAreaLogger(final String name) {
// Warning, commons logging requires this (currently unused) constructor.
}
/**
* Sets the log level.
*
* @param level the new log level to set.
*/
public void setLogLevel(final int level) {
logLevel = level;
}
/**
* Logs a message.
*
* @param message the message to log.
* @param throwable the throwable which caused the message to be logged (if applicable).
* @param level the logging level to log the message at.
*/
private void log(final Object message, final Throwable throwable, final int level) {
if (level < logLevel) {
return;
}
if (message != null) {
String prefix = new SimpleDateFormat("dd/MM/yy HH:mm:ss").format(new Date()) + ": ";
StandaloneLauncher.getInstance().log(prefix + message.toString() + '\n');
}
if (throwable != null) {
StringWriter writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
throwable.printStackTrace(printWriter);
printWriter.close();
StandaloneLauncher.getInstance().log(writer.toString());
}
}
/**
* {@inheritDoc}
*/
@Override
public void debug(final Object message, final Throwable cause) {
log(message, cause, DEBUG);
}
/**
* {@inheritDoc}
*/
@Override
public void debug(final Object message) {
log(message, null, DEBUG);
}
/**
* {@inheritDoc}
*/
@Override
public void error(final Object message, final Throwable cause) {
log(message, cause, ERROR);
}
/**
* {@inheritDoc}
*/
@Override
public void error(final Object message) {
log(message, null, ERROR);
}
/**
* {@inheritDoc}
*/
@Override
public void fatal(final Object message, final Throwable cause) {
log(message, cause, FATAL);
}
/**
* {@inheritDoc}
*/
@Override
public void fatal(final Object message) {
log(message, null, FATAL);
}
/**
* {@inheritDoc}
*/
@Override
public void info(final Object message, final Throwable cause) {
log(message, cause, INFO);
}
/**
* {@inheritDoc}
*/
@Override
public void info(final Object message) {
log(message, null, INFO);
}
/**
* {@inheritDoc}
*/
@Override
public void warn(final Object message, final Throwable cause) {
log(message, cause, WARN);
}
/**
* {@inheritDoc}
*/
@Override
public void warn(final Object message) {
log(message, null, WARN);
}
/**
* {@inheritDoc}
*/
@Override
public boolean isDebugEnabled() {
return logLevel <= DEBUG;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isErrorEnabled() {
return logLevel <= ERROR;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isFatalEnabled() {
return logLevel <= FATAL;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isInfoEnabled() {
return logLevel <= INFO;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isWarnEnabled() {
return logLevel <= WARN;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isTraceEnabled() {
return logLevel <= TRACE;
}
/**
* {@inheritDoc}
*/
@Override
public void trace(final Object message, final Throwable cause) {
log(message, cause, TRACE);
}
/**
* {@inheritDoc}
*/
@Override
public void trace(final Object message) {
log(message, null, TRACE);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy