aboutsummaryrefslogtreecommitdiff
path: root/subsonic-booter/src/main/java/net
diff options
context:
space:
mode:
authorScott Jackson <daneren2005@gmail.com>2013-07-27 14:33:25 -0700
committerScott Jackson <daneren2005@gmail.com>2013-07-27 14:33:38 -0700
commit4738428c2c205f42200386ae09b44b9ec07b9144 (patch)
treea6402978fe1b4655f90c3c8a181f4d246fbc5e89 /subsonic-booter/src/main/java/net
parent82ec8315f777c319f2372540098e21111019d629 (diff)
downloaddsub-4738428c2c205f42200386ae09b44b9ec07b9144.tar.gz
dsub-4738428c2c205f42200386ae09b44b9ec07b9144.tar.bz2
dsub-4738428c2c205f42200386ae09b44b9ec07b9144.zip
Move subsonic-android to root
Diffstat (limited to 'subsonic-booter/src/main/java/net')
-rw-r--r--subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/Main.java65
-rw-r--r--subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SettingsPanel.java375
-rw-r--r--subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/StatusPanel.java116
-rw-r--r--subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SubsonicAgent.java201
-rw-r--r--subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SubsonicFrame.java113
-rw-r--r--subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SubsonicListener.java28
-rw-r--r--subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/TrayController.java125
-rw-r--r--subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/deployer/DeploymentStatus.java44
-rw-r--r--subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/deployer/SubsonicDeployer.java326
-rw-r--r--subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/deployer/SubsonicDeployerService.java17
-rw-r--r--subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/mac/StatusPanel.java115
-rw-r--r--subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/mac/SubsonicController.java89
-rw-r--r--subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/mac/SubsonicFrame.java82
13 files changed, 0 insertions, 1696 deletions
diff --git a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/Main.java b/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/Main.java
deleted file mode 100644
index b7879e12..00000000
--- a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/Main.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package net.sourceforge.subsonic.booter;
-
-import java.util.Arrays;
-import java.util.List;
-
-import javax.swing.JOptionPane;
-
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-
-import net.sourceforge.subsonic.booter.agent.SettingsPanel;
-import net.sourceforge.subsonic.booter.agent.SubsonicAgent;
-
-/**
- * Application entry point for Subsonic booter.
- * <p/>
- * Use command line argument "-agent" to start the Windows service monitoring agent,
- * or "-mac" to start the Mac version of the deployer.
- *
- * @author Sindre Mehus
- */
-public class Main {
-
- public Main(String contextName, List<String> args) {
- ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext" + contextName + ".xml");
-
- if ("-agent".equals(contextName)) {
-
- SubsonicAgent agent = (SubsonicAgent) context.getBean("agent");
- SettingsPanel settingsPanel = (SettingsPanel) context.getBean("settingsPanel");
-
- agent.setElevated(args.contains("-elevated"));
-
- if (args.contains("-balloon")) {
- agent.showTrayIconMessage();
- }
-
- if (args.contains("-stop")) {
- agent.startOrStopService(false);
- agent.showStatusPanel();
- } else if (args.contains("-start")) {
- agent.startOrStopService(true);
- agent.showStatusPanel();
- }
-
- if (args.contains("-settings")) {
- String[] settings = args.get(args.indexOf("-settings") + 1).split(",");
- try {
- agent.showSettingsPanel();
- settingsPanel.saveSettings(Integer.valueOf(settings[0]), Integer.valueOf(settings[1]), Integer.valueOf(settings[2]), settings[3]);
- settingsPanel.readValues();
- } catch (Exception x) {
- JOptionPane.showMessageDialog(settingsPanel, x.getMessage(), "Error", JOptionPane.WARNING_MESSAGE);
- }
- }
- }
- }
-
- public static void main(String[] args) {
- String context = "-deployer";
- if (args.length > 0) {
- context = args[0];
- }
- new Main(context, Arrays.asList(args));
- }
-}
diff --git a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SettingsPanel.java b/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SettingsPanel.java
deleted file mode 100644
index c225410f..00000000
--- a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SettingsPanel.java
+++ /dev/null
@@ -1,375 +0,0 @@
-package net.sourceforge.subsonic.booter.agent;
-
-import com.jgoodies.forms.builder.DefaultFormBuilder;
-import com.jgoodies.forms.factories.Borders;
-import com.jgoodies.forms.factories.ButtonBarFactory;
-import com.jgoodies.forms.layout.FormLayout;
-import net.sourceforge.subsonic.booter.deployer.DeploymentStatus;
-import net.sourceforge.subsonic.booter.deployer.SubsonicDeployer;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.Writer;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.Format;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Panel displaying the settings of the Subsonic service.
- *
- * @author Sindre Mehus
- */
-public class SettingsPanel extends JPanel implements SubsonicListener {
-
- private static final Format INTEGER_FORMAT = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.UK));
-
- private final SubsonicAgent subsonicAgent;
- private JFormattedTextField portTextField;
- private JCheckBox httpsPortCheckBox;
- private JFormattedTextField httpsPortTextField;
- private JComboBox contextPathComboBox;
- private JFormattedTextField memoryTextField;
- private JButton defaultButton;
- private JButton saveButton;
- public SettingsPanel(SubsonicAgent subsonicAgent) {
- this.subsonicAgent = subsonicAgent;
- createComponents();
- configureComponents();
- layoutComponents();
- addBehaviour();
- readValues();
- subsonicAgent.addListener(this);
- }
-
- public void readValues() {
- portTextField.setValue(getPortFromOptionsFile());
- memoryTextField.setValue(getMemoryLimitFromOptionsFile());
- contextPathComboBox.setSelectedItem(getContextPathFromOptionsFile());
- int httpsPort = getHttpsPortFromOptionsFile();
- boolean httpsEnabled = httpsPort != 0;
- httpsPortTextField.setValue(httpsEnabled ? httpsPort : 4443);
- httpsPortTextField.setEnabled(httpsEnabled);
- httpsPortCheckBox.setSelected(httpsEnabled);
- }
-
- private int getHttpsPortFromOptionsFile() {
- try {
- String s = grep("-Dsubsonic.httpsPort=(\\d+)");
- return Integer.parseInt(s);
- } catch (Exception x) {
- x.printStackTrace();
- return SubsonicDeployer.DEFAULT_HTTPS_PORT;
- }
- }
-
- private int getPortFromOptionsFile() {
- try {
- String s = grep("-Dsubsonic.port=(\\d+)");
- return Integer.parseInt(s);
- } catch (Exception x) {
- x.printStackTrace();
- return SubsonicDeployer.DEFAULT_PORT;
- }
- }
-
- private int getMemoryLimitFromOptionsFile() {
- try {
- String s = grep("-Xmx(\\d+)m");
- return Integer.parseInt(s);
- } catch (Exception x) {
- x.printStackTrace();
- return SubsonicDeployer.DEFAULT_MEMORY_LIMIT;
- }
- }
-
- private String getContextPathFromOptionsFile() {
- try {
- String s = grep("-Dsubsonic.contextPath=(.*)");
- if (s == null) {
- throw new NullPointerException();
- }
- return s;
- } catch (Exception x) {
- x.printStackTrace();
- return SubsonicDeployer.DEFAULT_CONTEXT_PATH;
- }
- }
-
- private void createComponents() {
- portTextField = new JFormattedTextField(INTEGER_FORMAT);
- httpsPortTextField = new JFormattedTextField(INTEGER_FORMAT);
- httpsPortCheckBox = new JCheckBox("Enable https on port");
- contextPathComboBox = new JComboBox();
- memoryTextField = new JFormattedTextField(INTEGER_FORMAT);
- defaultButton = new JButton("Restore defaults");
- saveButton = new JButton("Save settings");
- }
-
- private void configureComponents() {
- contextPathComboBox.setEditable(true);
- contextPathComboBox.addItem("/");
- contextPathComboBox.addItem("/subsonic");
- contextPathComboBox.addItem("/music");
- }
-
- private void layoutComponents() {
- FormLayout layout = new FormLayout("d, 6dlu, max(d;30dlu):grow");
- DefaultFormBuilder builder = new DefaultFormBuilder(layout);
- builder.append("Port number", portTextField);
- builder.append(httpsPortCheckBox, httpsPortTextField);
- builder.append("Memory limit (MB)", memoryTextField);
- builder.append("Context path", contextPathComboBox);
-
- setBorder(Borders.DIALOG_BORDER);
-
- setLayout(new BorderLayout(12, 12));
- add(builder.getPanel(), BorderLayout.CENTER);
- add(ButtonBarFactory.buildCenteredBar(defaultButton, saveButton), BorderLayout.SOUTH);
- }
-
- private void addBehaviour() {
- saveButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- try {
- subsonicAgent.checkElevation("-settings", getMemoryLimit() + "," + getPort() + "," + getHttpsPort() + "," + getContextPath());
- saveSettings(getMemoryLimit(), getPort(), getHttpsPort(), getContextPath());
- } catch (Exception x) {
- JOptionPane.showMessageDialog(SettingsPanel.this, x.getMessage(), "Error", JOptionPane.WARNING_MESSAGE);
- }
- }
- });
-
- defaultButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- portTextField.setValue(SubsonicDeployer.DEFAULT_PORT);
- httpsPortTextField.setValue(4443);
- httpsPortTextField.setEnabled(false);
- httpsPortCheckBox.setSelected(false);
- memoryTextField.setValue(SubsonicDeployer.DEFAULT_MEMORY_LIMIT);
- contextPathComboBox.setSelectedItem(SubsonicDeployer.DEFAULT_CONTEXT_PATH);
- }
- });
-
- httpsPortCheckBox.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- httpsPortTextField.setEnabled(httpsPortCheckBox.isSelected());
- }
- });
- }
-
- private String getContextPath() throws SettingsException {
- String contextPath = (String) contextPathComboBox.getSelectedItem();
- if (contextPath.contains(" ") || !contextPath.startsWith("/")) {
- throw new SettingsException("Please specify a valid context path.");
- }
- return contextPath;
- }
-
- private int getMemoryLimit() throws SettingsException {
- int memoryLimit;
- try {
- memoryLimit = ((Number) memoryTextField.getValue()).intValue();
- if (memoryLimit < 5) {
- throw new Exception();
- }
- } catch (Exception x) {
- throw new SettingsException("Please specify a valid memory limit.", x);
- }
- return memoryLimit;
- }
-
- private int getPort() throws SettingsException {
- int port;
- try {
- port = ((Number) portTextField.getValue()).intValue();
- if (port < 1 || port > 65535) {
- throw new Exception();
- }
- } catch (Exception x) {
- throw new SettingsException("Please specify a valid port number.", x);
- }
- return port;
- }
-
- private int getHttpsPort() throws SettingsException {
- if (!httpsPortCheckBox.isSelected()) {
- return 0;
- }
-
- int port;
- try {
- port = ((Number) httpsPortTextField.getValue()).intValue();
- if (port < 1 || port > 65535) {
- throw new Exception();
- }
- } catch (Exception x) {
- throw new SettingsException("Please specify a valid https port number.", x);
- }
- return port;
- }
-
- public void saveSettings(int memoryLimit, int port, int httpsPort, String contextPath) throws SettingsException {
- File file = getOptionsFile();
-
- java.util.List<String> lines = readLines(file);
- java.util.List<String> newLines = new ArrayList<String>();
-
- boolean memoryLimitAdded = false;
- boolean portAdded = false;
- boolean httpsPortAdded = false;
- boolean contextPathAdded = false;
-
- for (String line : lines) {
- if (line.startsWith("-Xmx")) {
- newLines.add("-Xmx" + memoryLimit + "m");
- memoryLimitAdded = true;
- } else if (line.startsWith("-Dsubsonic.port=")) {
- newLines.add("-Dsubsonic.port=" + port);
- portAdded = true;
- } else if (line.startsWith("-Dsubsonic.httpsPort=")) {
- newLines.add("-Dsubsonic.httpsPort=" + httpsPort);
- httpsPortAdded = true;
- } else if (line.startsWith("-Dsubsonic.contextPath=")) {
- newLines.add("-Dsubsonic.contextPath=" + contextPath);
- contextPathAdded = true;
- } else {
- newLines.add(line);
- }
- }
-
- if (!memoryLimitAdded) {
- newLines.add("-Xmx" + memoryLimit + "m");
- }
- if (!portAdded) {
- newLines.add("-Dsubsonic.port=" + port);
- }
- if (!httpsPortAdded) {
- newLines.add("-Dsubsonic.httpsPort=" + httpsPort);
- }
- if (!contextPathAdded) {
- newLines.add("-Dsubsonic.contextPath=" + contextPath);
- }
-
- writeLines(file, newLines);
-
- JOptionPane.showMessageDialog(SettingsPanel.this,
- "Please restart Subsonic for the new settings to take effect.",
- "Settings changed", JOptionPane.INFORMATION_MESSAGE);
-
- }
-
- private File getOptionsFile() throws SettingsException {
- File file = new File("subsonic-service.exe.vmoptions");
- if (!file.isFile() || !file.exists()) {
- throw new SettingsException("File " + file.getAbsolutePath() + " not found.");
- }
- return file;
- }
-
- private List<String> readLines(File file) throws SettingsException {
- List<String> lines = new ArrayList<String>();
- BufferedReader reader = null;
- try {
- reader = new BufferedReader(new FileReader(file));
- for (String line = reader.readLine(); line != null; line = reader.readLine()) {
- lines.add(line);
- }
- return lines;
- } catch (IOException x) {
- throw new SettingsException("Failed to read from file " + file.getAbsolutePath(), x);
- } finally {
- closeQuietly(reader);
- }
- }
-
- private void writeLines(File file, List<String> lines) throws SettingsException {
- PrintWriter writer = null;
- try {
- writer = new PrintWriter(new FileWriter(file));
- for (String line : lines) {
- writer.println(line);
- }
- } catch (IOException x) {
- throw new SettingsException("Failed to write to file " + file.getAbsolutePath(), x);
- } finally {
- closeQuietly(writer);
- }
- }
-
- private String grep(String regexp) throws SettingsException {
- Pattern pattern = Pattern.compile(regexp);
- File file = getOptionsFile();
- for (String line : readLines(file)) {
- Matcher matcher = pattern.matcher(line);
- if (matcher.matches()) {
- return matcher.group(1);
- }
- }
- return null;
- }
-
- private void closeQuietly(Reader reader) {
- if (reader == null) {
- return;
- }
-
- try {
- reader.close();
- } catch (IOException x) {
- // Intentionally ignored.
- }
- }
-
- private void closeQuietly(Writer writer) {
- if (writer == null) {
- return;
- }
-
- try {
- writer.close();
- } catch (IOException x) {
- // Intentionally ignored.
- }
- }
-
- public void notifyDeploymentStatus(DeploymentStatus deploymentStatus) {
- // Nothing here yet.
- }
-
- public void notifyServiceStatus(String serviceStatus) {
- // Nothing here yet.
- }
-
- public static class SettingsException extends Exception {
-
- public SettingsException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public SettingsException(String message) {
- this(message, null);
- }
-
- @Override
- public String getMessage() {
- if (getCause() == null || getCause().getMessage() == null) {
- return super.getMessage();
- }
- return super.getMessage() + " " + getCause().getMessage();
- }
- }
-}
diff --git a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/StatusPanel.java b/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/StatusPanel.java
deleted file mode 100644
index 91625f19..00000000
--- a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/StatusPanel.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package net.sourceforge.subsonic.booter.agent;
-
-import com.jgoodies.forms.builder.DefaultFormBuilder;
-import com.jgoodies.forms.factories.Borders;
-import com.jgoodies.forms.factories.ButtonBarFactory;
-import com.jgoodies.forms.layout.FormLayout;
-import net.sourceforge.subsonic.booter.deployer.DeploymentStatus;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.text.DateFormat;
-import java.util.Locale;
-
-/**
- * Panel displaying the status of the Subsonic service.
- *
- * @author Sindre Mehus
- */
-public class StatusPanel extends JPanel implements SubsonicListener {
-
- private static final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US);
-
- private final SubsonicAgent subsonicAgent;
-
- private JTextField statusTextField;
- private JTextField startedTextField;
- private JTextField memoryTextField;
- private JTextArea errorTextField;
- private JButton startButton;
- private JButton stopButton;
- private JButton urlButton;
-
- public StatusPanel(SubsonicAgent subsonicAgent) {
- this.subsonicAgent = subsonicAgent;
- createComponents();
- configureComponents();
- layoutComponents();
- addBehaviour();
- subsonicAgent.addListener(this);
- }
-
- private void createComponents() {
- statusTextField = new JTextField();
- startedTextField = new JTextField();
- memoryTextField = new JTextField();
- errorTextField = new JTextArea(3, 24);
- startButton = new JButton("Start");
- stopButton = new JButton("Stop");
- urlButton = new JButton();
- }
-
- private void configureComponents() {
- statusTextField.setEditable(false);
- startedTextField.setEditable(false);
- memoryTextField.setEditable(false);
- errorTextField.setEditable(false);
-
- errorTextField.setLineWrap(true);
- errorTextField.setBorder(startedTextField.getBorder());
-
- urlButton.setBorderPainted(false);
- urlButton.setContentAreaFilled(false);
- urlButton.setForeground(Color.BLUE.darker());
- urlButton.setHorizontalAlignment(SwingConstants.LEFT);
- }
-
- private void layoutComponents() {
- JPanel buttons = ButtonBarFactory.buildRightAlignedBar(startButton, stopButton);
-
- FormLayout layout = new FormLayout("right:d, 6dlu, max(d;30dlu):grow");
- DefaultFormBuilder builder = new DefaultFormBuilder(layout, this);
- builder.append("Service status", statusTextField);
- builder.append("", buttons);
- builder.appendParagraphGapRow();
- builder.nextRow();
- builder.append("Started on", startedTextField);
- builder.append("Memory used", memoryTextField);
- builder.append("Error message", errorTextField);
- builder.append("Server address", urlButton);
-
- setBorder(Borders.DIALOG_BORDER);
- }
-
- private void addBehaviour() {
- urlButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- subsonicAgent.openBrowser();
- }
- });
- startButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- subsonicAgent.checkElevation("-start");
- subsonicAgent.startOrStopService(true);
- }
- });
- stopButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- subsonicAgent.checkElevation("-stop");
- subsonicAgent.startOrStopService(false);
- }
- });
- }
-
- public void notifyDeploymentStatus(DeploymentStatus status) {
- startedTextField.setText(status == null ? null : DATE_FORMAT.format(status.getStartTime()));
- memoryTextField.setText(status == null ? null : status.getMemoryUsed() + " MB");
- errorTextField.setText(status == null ? null : status.getErrorMessage());
- urlButton.setText(status == null ? null : status.getURL());
- }
-
- public void notifyServiceStatus(String serviceStatus) {
- statusTextField.setText(serviceStatus);
- }
-}
diff --git a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SubsonicAgent.java b/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SubsonicAgent.java
deleted file mode 100644
index a9bb526e..00000000
--- a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SubsonicAgent.java
+++ /dev/null
@@ -1,201 +0,0 @@
-package net.sourceforge.subsonic.booter.agent;
-
-import java.awt.Desktop;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.swing.JOptionPane;
-import javax.swing.UIManager;
-
-import org.apache.commons.io.IOUtils;
-
-import com.jgoodies.looks.plastic.PlasticXPLookAndFeel;
-
-import net.sourceforge.subsonic.booter.deployer.DeploymentStatus;
-import net.sourceforge.subsonic.booter.deployer.SubsonicDeployerService;
-
-/**
- * Responsible for deploying the Subsonic web app in
- * the embedded Jetty container.
- *
- * @author Sindre Mehus
- */
-public class SubsonicAgent {
-
- private final List<SubsonicListener> listeners = new ArrayList<SubsonicListener>();
- private final TrayController trayController;
- private SubsonicFrame frame;
- private final SubsonicDeployerService service;
- private static final int POLL_INTERVAL_DEPLOYMENT_INFO_SECONDS = 5;
- private static final int POLL_INTERVAL_SERVICE_STATUS_SECONDS = 5;
- private String url;
- private boolean serviceStatusPollingEnabled;
- private boolean elevated;
-
- public SubsonicAgent(SubsonicDeployerService service) {
- this.service = service;
- setLookAndFeel();
- trayController = new TrayController(this);
- startPolling();
- }
-
- public void setFrame(SubsonicFrame frame) {
- this.frame = frame;
- }
-
- private void setLookAndFeel() {
- // Set look-and-feel.
- try {
- UIManager.setLookAndFeel(new PlasticXPLookAndFeel());
- } catch (Throwable x) {
- System.err.println("Failed to set look-and-feel.\n" + x);
- }
- }
-
- private void startPolling() {
- ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
- Runnable runnable = new Runnable() {
- public void run() {
- try {
- notifyDeploymentInfo(service.getDeploymentInfo());
- } catch (Throwable x) {
- notifyDeploymentInfo(null);
- }
- }
- };
- executor.scheduleWithFixedDelay(runnable, 0, POLL_INTERVAL_DEPLOYMENT_INFO_SECONDS, TimeUnit.SECONDS);
-
- runnable = new Runnable() {
- public void run() {
- if (serviceStatusPollingEnabled) {
- try {
- notifyServiceStatus(getServiceStatus());
- } catch (Throwable x) {
- notifyServiceStatus(null);
- }
- }
- }
- };
- executor.scheduleWithFixedDelay(runnable, 0, POLL_INTERVAL_SERVICE_STATUS_SECONDS, TimeUnit.SECONDS);
- }
-
- private String getServiceStatus() throws Exception {
- Process process = Runtime.getRuntime().exec("subsonic-service.exe -status");
- return IOUtils.toString(process.getInputStream());
- }
-
- public void setServiceStatusPollingEnabled(boolean enabled) {
- serviceStatusPollingEnabled = enabled;
- }
-
- public void startOrStopService(boolean start) {
- try {
- String cmd = "subsonic-service.exe " + (start ? "-start" : "-stop");
- System.err.println("Executing: " + cmd);
-
- Runtime.getRuntime().exec(cmd);
- } catch (Exception x) {
- x.printStackTrace();
- }
- }
-
- /**
- * If necessary, restart agent with elevated rights.
- */
- public void checkElevation(String... args) {
-
- if (isElevationNeeded() && !isElevated()) {
- try {
- List<String> command = new ArrayList<String>();
- command.add("cmd");
- command.add("/c");
- command.add("subsonic-agent-elevated.exe");
- command.addAll(Arrays.asList(args));
-
- ProcessBuilder builder = new ProcessBuilder();
- builder.command(command);
- System.err.println("Executing: " + command + " with current dir: " + System.getProperty("user.dir"));
- builder.start();
- System.exit(0);
- } catch (Exception x) {
- JOptionPane.showMessageDialog(frame, "Failed to elevate Subsonic Control Panel. " + x, "Error", JOptionPane.WARNING_MESSAGE);
- x.printStackTrace();
- }
- }
- }
-
- public void setElevated(boolean elevated) {
- this.elevated = elevated;
- }
-
- private boolean isElevated() {
- return elevated;
- }
-
- /**
- * Returns whether UAC elevation is necessary (to start/stop services etc).
- */
- private boolean isElevationNeeded() {
-
- String osVersion = System.getProperty("os.version");
- try {
- int majorVersion = Integer.parseInt(osVersion.substring(0, osVersion.indexOf(".")));
-
- // Elevation is necessary in Windows Vista (os.version=6.1) and later.
- return majorVersion >= 6;
- } catch (Exception x) {
- System.err.println("Failed to resolve OS version from '" + osVersion + "'\n" + x);
- return false;
- }
- }
-
- public void addListener(SubsonicListener listener) {
- listeners.add(listener);
- }
-
- private void notifyDeploymentInfo(DeploymentStatus status) {
- if (status != null) {
- url = status.getURL();
- }
-
- for (SubsonicListener listener : listeners) {
- listener.notifyDeploymentStatus(status);
- }
- }
-
- private void notifyServiceStatus(String status) {
- for (SubsonicListener listener : listeners) {
- listener.notifyServiceStatus(status);
- }
- }
-
- public void showStatusPanel() {
- frame.showStatusPanel();
- }
-
- public void showSettingsPanel() {
- frame.showSettingsPanel();
- }
-
- public void showTrayIconMessage() {
- trayController.showMessage();
- }
-
- public void exit() {
- trayController.uninstallComponents();
- System.exit(0);
- }
-
- public void openBrowser() {
- try {
- Desktop.getDesktop().browse(new URI(url));
- } catch (Throwable x) {
- x.printStackTrace();
- }
- }
-}
diff --git a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SubsonicFrame.java b/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SubsonicFrame.java
deleted file mode 100644
index 32ee5230..00000000
--- a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SubsonicFrame.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package net.sourceforge.subsonic.booter.agent;
-
-import com.jgoodies.forms.factories.Borders;
-import com.jgoodies.forms.factories.ButtonBarFactory;
-import net.sourceforge.subsonic.booter.Main;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-
-/**
- * Frame that is activated by the tray icon. Contains a tabbed pane
- * with status and settings panels.
- *
- * @author Sindre Mehus
- */
-public class SubsonicFrame extends JFrame {
-
- private final SubsonicAgent subsonicAgent;
-
- private final StatusPanel statusPanel;
- private final SettingsPanel settingsPanel;
- private JTabbedPane tabbedPane;
- private JButton closeButton;
-
- public SubsonicFrame(SubsonicAgent subsonicAgent, StatusPanel statusPanel, SettingsPanel settingsPanel) {
- super("Subsonic Control Panel");
- this.subsonicAgent = subsonicAgent;
- this.statusPanel = statusPanel;
- this.settingsPanel = settingsPanel;
- createComponents();
- layoutComponents();
- addBehaviour();
- setupIcons();
-
- pack();
- centerComponent();
- }
-
- private void setupIcons() {
- Toolkit toolkit = Toolkit.getDefaultToolkit();
-
- // Window.setIconImages() was added in Java 1.6. Since Subsonic only requires 1.5, we
- // use reflection to invoke it.
- try {
- Method method = Window.class.getMethod("setIconImages", java.util.List.class);
- java.util.List<Image> images = Arrays.asList(
- toolkit.createImage(Main.class.getResource("/images/subsonic-16.png")),
- toolkit.createImage(Main.class.getResource("/images/subsonic-32.png")),
- toolkit.createImage(Main.class.getResource("/images/subsonic-512.png")));
- method.invoke(this, images);
- } catch (Throwable x) {
- // Fallback to old method.
- setIconImage(toolkit.createImage(Main.class.getResource("/images/subsonic-32.png")));
- }
- }
-
- public void centerComponent() {
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- setLocation(screenSize.width / 2 - getWidth() / 2,
- screenSize.height / 2 - getHeight() / 2);
- }
-
- private void createComponents() {
- tabbedPane = new JTabbedPane();
- closeButton = new JButton("Close");
- }
-
- private void layoutComponents() {
- tabbedPane.add("Status", statusPanel);
- tabbedPane.add("Settings", settingsPanel);
-
- JPanel pane = (JPanel) getContentPane();
- pane.setLayout(new BorderLayout(10, 10));
- pane.add(tabbedPane, BorderLayout.CENTER);
- pane.add(ButtonBarFactory.buildCloseBar(closeButton), BorderLayout.SOUTH);
-
- pane.setBorder(Borders.TABBED_DIALOG_BORDER);
- }
-
- private void addBehaviour() {
- closeButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- setVisible(false);
- }
- });
- }
-
- @Override
- public void setVisible(boolean b) {
- super.setVisible(b);
- subsonicAgent.setServiceStatusPollingEnabled(b);
- }
-
- public void showStatusPanel() {
- settingsPanel.readValues();
- tabbedPane.setSelectedComponent(statusPanel);
- pack();
- setVisible(true);
- toFront();
- }
-
- public void showSettingsPanel() {
- settingsPanel.readValues();
- tabbedPane.setSelectedComponent(settingsPanel);
- pack();
- setVisible(true);
- toFront();
- }
-}
diff --git a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SubsonicListener.java b/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SubsonicListener.java
deleted file mode 100644
index d6239c0d..00000000
--- a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/SubsonicListener.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.sourceforge.subsonic.booter.agent;
-
-import net.sourceforge.subsonic.booter.deployer.DeploymentStatus;
-
-/**
- * Callback interface implemented by GUI classes that wants to be notified when
- * the state of the Subsonic deployment changes.
- *
- * @author Sindre Mehus
- */
-public interface SubsonicListener {
-
- /**
- * Invoked when new information about the Subsonic deployment is available.
- *
- * @param deploymentStatus The new deployment status, or <code>null</code> if an
- * error occurred while retrieving the status.
- */
- void notifyDeploymentStatus(DeploymentStatus deploymentStatus);
-
- /**
- * Invoked when new information about the Subsonic Windows service is available.
- *
- * @param serviceStatus The new service status, or <code>null</code> if an
- * error occurred while retrieving the status.
- */
- void notifyServiceStatus(String serviceStatus);
-}
diff --git a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/TrayController.java b/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/TrayController.java
deleted file mode 100644
index 2be918e8..00000000
--- a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/agent/TrayController.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package net.sourceforge.subsonic.booter.agent;
-
-import java.awt.Image;
-import java.awt.MenuItem;
-import java.awt.PopupMenu;
-import java.awt.SystemTray;
-import java.awt.Toolkit;
-import java.awt.TrayIcon;
-import java.awt.event.ActionEvent;
-import java.net.URL;
-
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-
-import net.sourceforge.subsonic.booter.deployer.DeploymentStatus;
-
-/**
- * Controls the Subsonic tray icon.
- *
- * @author Sindre Mehus
- */
-public class TrayController implements SubsonicListener {
-
- private final SubsonicAgent subsonicAgent;
- private TrayIcon trayIcon;
-
- private Action openAction;
- private Action controlPanelAction;
- private Action hideAction;
- private Image startedImage;
- private Image stoppedImage;
-
- public TrayController(SubsonicAgent subsonicAgent) {
- this.subsonicAgent = subsonicAgent;
- try {
- createActions();
- createComponents();
- addBehaviour();
- installComponents();
- subsonicAgent.addListener(this);
- } catch (Throwable x) {
- System.err.println("Disabling tray support.");
- }
- }
-
- public void showMessage() {
- trayIcon.displayMessage("Subsonic", "Subsonic is now running. Click this balloon to get started.",
- TrayIcon.MessageType.INFO);
- }
-
- private void createActions() {
- openAction = new AbstractAction("Open Subsonic in Browser") {
- public void actionPerformed(ActionEvent e) {
- subsonicAgent.openBrowser();
- }
- };
-
- controlPanelAction = new AbstractAction("Subsonic Control Panel") {
- public void actionPerformed(ActionEvent e) {
- subsonicAgent.showStatusPanel();
- }
- };
-
-
- hideAction = new AbstractAction("Hide Tray Icon") {
- public void actionPerformed(ActionEvent e) {
- subsonicAgent.exit();
- }
- };
- }
-
- private void createComponents() {
- startedImage = createImage("/images/subsonic-started-16.png");
- stoppedImage = createImage("/images/subsonic-stopped-16.png");
-
- PopupMenu menu = new PopupMenu();
- menu.add(createMenuItem(openAction));
- menu.add(createMenuItem(controlPanelAction));
- menu.addSeparator();
- menu.add(createMenuItem(hideAction));
-
- trayIcon = new TrayIcon(stoppedImage, "Subsonic Music Streamer", menu);
- }
-
- private Image createImage(String resourceName) {
- URL url = getClass().getResource(resourceName);
- return Toolkit.getDefaultToolkit().createImage(url);
- }
-
- private MenuItem createMenuItem(Action action) {
- MenuItem menuItem = new MenuItem((String) action.getValue(Action.NAME));
- menuItem.addActionListener(action);
- return menuItem;
- }
-
- private void addBehaviour() {
- trayIcon.addActionListener(controlPanelAction);
- }
-
- private void installComponents() throws Throwable {
- SystemTray.getSystemTray().add(trayIcon);
- }
-
- public void uninstallComponents() {
- try {
- SystemTray.getSystemTray().remove(trayIcon);
- } catch (Throwable x) {
- System.err.println("Disabling tray support.");
- }
- }
-
- private void setTrayImage(Image image) {
- if (trayIcon.getImage() != image) {
- trayIcon.setImage(image);
- }
- }
-
- public void notifyDeploymentStatus(DeploymentStatus deploymentStatus) {
- setTrayImage(deploymentStatus == null ? stoppedImage : startedImage);
- }
-
- public void notifyServiceStatus(String serviceStatus) {
- // Nothing here, but could potentially change tray icon and menu.
- }
-}
diff --git a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/deployer/DeploymentStatus.java b/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/deployer/DeploymentStatus.java
deleted file mode 100644
index 3b237dc1..00000000
--- a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/deployer/DeploymentStatus.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package net.sourceforge.subsonic.booter.deployer;
-
-import java.util.Date;
-import java.io.Serializable;
-
-/**
- * @author Sindre Mehus
- */
-public class DeploymentStatus implements Serializable {
-
- private final Date startTime;
- private final String url;
- private final String httpsUrl;
- private final int memoryUsed;
- private final String errorMessage;
-
- public DeploymentStatus(Date startTime, String url, String httpsUrl, int memoryUsed, String errorMessage) {
- this.startTime = startTime;
- this.url = url;
- this.httpsUrl = httpsUrl;
- this.memoryUsed = memoryUsed;
- this.errorMessage = errorMessage;
- }
-
- public String getURL() {
- return url;
- }
-
- public String getHttpsUrl() {
- return httpsUrl;
- }
-
- public Date getStartTime() {
- return startTime;
- }
-
- public int getMemoryUsed() {
- return memoryUsed;
- }
-
- public String getErrorMessage() {
- return errorMessage;
- }
-}
diff --git a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/deployer/SubsonicDeployer.java b/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/deployer/SubsonicDeployer.java
deleted file mode 100644
index b066c635..00000000
--- a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/deployer/SubsonicDeployer.java
+++ /dev/null
@@ -1,326 +0,0 @@
-package net.sourceforge.subsonic.booter.deployer;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Writer;
-import java.net.BindException;
-import java.util.Date;
-import java.util.jar.JarFile;
-import java.util.zip.ZipEntry;
-
-import org.apache.commons.io.IOUtils;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.security.Constraint;
-import org.mortbay.jetty.security.ConstraintMapping;
-import org.mortbay.jetty.security.SslSocketConnector;
-import org.mortbay.jetty.nio.SelectChannelConnector;
-import org.mortbay.jetty.webapp.WebAppContext;
-
-/**
- * Responsible for deploying the Subsonic web app in
- * the embedded Jetty container.
- * <p/>
- * The following system properties may be used to customize the behaviour:
- * <ul>
- * <li><code>subsonic.contextPath</code> - The context path at which Subsonic is deployed. Default "/".</li>
- * <li><code>subsonic.port</code> - The port Subsonic will listen to. Default 4040.</li>
- * <li><code>subsonic.httpsPort</code> - The port Subsonic will listen to for HTTPS. Default 0, which disables HTTPS.</li>
- * <li><code>subsonic.war</code> - Subsonic WAR file, or exploded directory. Default "subsonic.war".</li>
- * <li><code>subsonic.createLinkFile</code> - If set to "true", a Subsonic.url file is created in the working directory.</li>
- * <li><code>subsonic.ssl.keystore</code> - Path to an alternate SSL keystore.</li>
- * <li><code>subsonic.ssl.password</code> - Password of the alternate SSL keystore.</li>
- * </ul>
- *
- * @author Sindre Mehus
- */
-public class SubsonicDeployer implements SubsonicDeployerService {
-
- public static final String DEFAULT_HOST = "0.0.0.0";
- public static final int DEFAULT_PORT = 4040;
- public static final int DEFAULT_HTTPS_PORT = 0;
- public static final int DEFAULT_MEMORY_LIMIT = 150;
- public static final String DEFAULT_CONTEXT_PATH = "/";
- public static final String DEFAULT_WAR = "subsonic.war";
- private static final int MAX_IDLE_TIME_MILLIS = 7 * 24 * 60 * 60 * 1000; // One week.
- private static final int HEADER_BUFFER_SIZE = 64 * 1024;
-
- // Subsonic home directory.
- private static final File SUBSONIC_HOME_WINDOWS = new File("c:/subsonic");
- private static final File SUBSONIC_HOME_OTHER = new File("/var/subsonic");
-
- private Throwable exception;
- private File subsonicHome;
- private final Date startTime;
-
- public SubsonicDeployer() {
-
- // Enable shutdown hook for Ehcache.
- System.setProperty("net.sf.ehcache.enableShutdownHook", "true");
-
- startTime = new Date();
- createLinkFile();
- deployWebApp();
- }
-
- private void createLinkFile() {
- if ("true".equals(System.getProperty("subsonic.createLinkFile"))) {
- Writer writer = null;
- try {
- writer = new FileWriter("subsonic.url");
- writer.append("[InternetShortcut]");
- writer.append(System.getProperty("line.separator"));
- writer.append("URL=").append(getUrl());
- writer.flush();
- } catch (Throwable x) {
- System.err.println("Failed to create subsonic.url.");
- x.printStackTrace();
- } finally {
- if (writer != null) {
- try {
- writer.close();
- } catch (IOException x) {
- // Ignored
- }
- }
- }
- }
- }
-
- private void deployWebApp() {
- try {
- Server server = new Server();
- SelectChannelConnector connector = new SelectChannelConnector();
- connector.setMaxIdleTime(MAX_IDLE_TIME_MILLIS);
- connector.setHeaderBufferSize(HEADER_BUFFER_SIZE);
- connector.setHost(getHost());
- connector.setPort(getPort());
- if (isHttpsEnabled()) {
- connector.setConfidentialPort(getHttpsPort());
- }
- server.addConnector(connector);
-
- if (isHttpsEnabled()) {
- SslSocketConnector sslConnector = new SslSocketConnector();
- sslConnector.setMaxIdleTime(MAX_IDLE_TIME_MILLIS);
- sslConnector.setHeaderBufferSize(HEADER_BUFFER_SIZE);
- sslConnector.setHost(getHost());
- sslConnector.setPort(getHttpsPort());
- sslConnector.setKeystore(System.getProperty("subsonic.ssl.keystore", getClass().getResource("/subsonic.keystore").toExternalForm()));
- sslConnector.setPassword(System.getProperty("subsonic.ssl.password", "subsonic"));
- server.addConnector(sslConnector);
- }
-
- WebAppContext context = new WebAppContext();
- context.setTempDirectory(getJettyDirectory());
- context.setContextPath(getContextPath());
- context.setWar(getWar());
-
- if (isHttpsEnabled()) {
- ConstraintMapping constraintMapping = new ConstraintMapping();
- Constraint constraint = new Constraint();
- constraint.setDataConstraint(Constraint.DC_CONFIDENTIAL);
- constraintMapping.setPathSpec("/");
- constraintMapping.setConstraint(constraint);
- context.getSecurityHandler().setConstraintMappings(new ConstraintMapping[]{constraintMapping});
- }
-
- server.addHandler(context);
- server.start();
-
- System.err.println("Subsonic running on: " + getUrl());
- if (isHttpsEnabled()) {
- System.err.println(" and: " + getHttpsUrl());
- }
-
- } catch (Throwable x) {
- x.printStackTrace();
- exception = x;
- }
- }
-
- private File getJettyDirectory() {
- File dir = new File(getSubsonicHome(), "jetty");
- String buildNumber = getSubsonicBuildNumber();
- if (buildNumber != null) {
- dir = new File(dir, buildNumber);
- }
- System.err.println("Extracting webapp to " + dir);
-
- if (!dir.exists() && !dir.mkdirs()) {
- System.err.println("Failed to create directory " + dir);
- }
-
- return dir;
- }
-
- private String getSubsonicBuildNumber() {
- File war = new File(getWar());
- InputStream in = null;
- try {
- if (war.isFile()) {
- JarFile jar = new JarFile(war);
- ZipEntry entry = jar.getEntry("WEB-INF\\classes\\build_number.txt");
- if (entry == null) {
- entry = jar.getEntry("WEB-INF/classes/build_number.txt");
- }
- in = jar.getInputStream(entry);
- } else {
- in = new FileInputStream(war.getPath() + "/WEB-INF/classes/build_number.txt");
- }
- return IOUtils.toString(in);
-
- } catch (Exception x) {
- System.err.println("Failed to resolve build number from WAR: " + war);
- x.printStackTrace();
- return null;
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
-
- private String getContextPath() {
- return System.getProperty("subsonic.contextPath", DEFAULT_CONTEXT_PATH);
- }
-
-
- private String getWar() {
- String war = System.getProperty("subsonic.war");
- if (war == null) {
- war = DEFAULT_WAR;
- }
-
- File file = new File(war);
- if (file.exists()) {
- System.err.println("Using WAR file: " + file.getAbsolutePath());
- } else {
- System.err.println("Error: WAR file not found: " + file.getAbsolutePath());
- }
-
- return war;
- }
-
- private String getHost() {
- return System.getProperty("subsonic.host", DEFAULT_HOST);
- }
-
- private int getPort() {
- int port = DEFAULT_PORT;
-
- String portString = System.getProperty("subsonic.port");
- if (portString != null) {
- port = Integer.parseInt(portString);
- }
-
- // Also set it so that the webapp can read it.
- System.setProperty("subsonic.port", String.valueOf(port));
-
- return port;
- }
-
- private int getHttpsPort() {
- int port = DEFAULT_HTTPS_PORT;
-
- String portString = System.getProperty("subsonic.httpsPort");
- if (portString != null) {
- port = Integer.parseInt(portString);
- }
-
- // Also set it so that the webapp can read it.
- System.setProperty("subsonic.httpsPort", String.valueOf(port));
-
- return port;
- }
-
- private boolean isHttpsEnabled() {
- return getHttpsPort() > 0;
- }
-
- public String getErrorMessage() {
- if (exception == null) {
- return null;
- }
- if (exception instanceof BindException) {
- return "Address already in use. Please change port number.";
- }
-
- return exception.toString();
- }
-
- public int getMemoryUsed() {
- long freeBytes = Runtime.getRuntime().freeMemory();
- long totalBytes = Runtime.getRuntime().totalMemory();
- long usedBytes = totalBytes - freeBytes;
- return (int) Math.round(usedBytes / 1024.0 / 1024.0);
- }
-
- private String getUrl() {
- String host = DEFAULT_HOST.equals(getHost()) ? "localhost" : getHost();
- StringBuffer url = new StringBuffer("http://").append(host);
- if (getPort() != 80) {
- url.append(":").append(getPort());
- }
- url.append(getContextPath());
- return url.toString();
- }
-
- private String getHttpsUrl() {
- if (!isHttpsEnabled()) {
- return null;
- }
-
- String host = DEFAULT_HOST.equals(getHost()) ? "localhost" : getHost();
- StringBuffer url = new StringBuffer("https://").append(host);
- if (getHttpsPort() != 443) {
- url.append(":").append(getHttpsPort());
- }
- url.append(getContextPath());
- return url.toString();
- }
-
- /**
- * Returns the Subsonic home directory.
- *
- * @return The Subsonic home directory, if it exists.
- * @throws RuntimeException If directory doesn't exist.
- */
- private File getSubsonicHome() {
-
- if (subsonicHome != null) {
- return subsonicHome;
- }
-
- File home;
-
- String overrideHome = System.getProperty("subsonic.home");
- if (overrideHome != null) {
- home = new File(overrideHome);
- } else {
- boolean isWindows = System.getProperty("os.name", "Windows").toLowerCase().startsWith("windows");
- home = isWindows ? SUBSONIC_HOME_WINDOWS : SUBSONIC_HOME_OTHER;
- }
-
- // Attempt to create home directory if it doesn't exist.
- if (!home.exists() || !home.isDirectory()) {
- boolean success = home.mkdirs();
- if (success) {
- subsonicHome = home;
- } else {
- String message = "The directory " + home + " does not exist. Please create it and make it writable. " +
- "(You can override the directory location by specifying -Dsubsonic.home=... when " +
- "starting the servlet container.)";
- System.err.println("ERROR: " + message);
- }
- } else {
- subsonicHome = home;
- }
-
- return home;
- }
-
- public DeploymentStatus getDeploymentInfo() {
- return new DeploymentStatus(startTime, getUrl(), getHttpsUrl(), getMemoryUsed(), getErrorMessage());
- }
-}
diff --git a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/deployer/SubsonicDeployerService.java b/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/deployer/SubsonicDeployerService.java
deleted file mode 100644
index a0bf087f..00000000
--- a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/deployer/SubsonicDeployerService.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package net.sourceforge.subsonic.booter.deployer;
-
-/**
- * RMI interface implemented by the Subsonic deployer and used by the agent.
- *
- * @author Sindre Mehus
- */
-public interface SubsonicDeployerService {
-
- /**
- * Returns information about the Subsonic deployment, such
- * as URL, memory consumption, start time etc.
- *
- * @return Deployment information.
- */
- DeploymentStatus getDeploymentInfo();
-}
diff --git a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/mac/StatusPanel.java b/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/mac/StatusPanel.java
deleted file mode 100644
index f20671f8..00000000
--- a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/mac/StatusPanel.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package net.sourceforge.subsonic.booter.mac;
-
-import java.awt.Color;
-import java.awt.Desktop;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.net.URI;
-import java.text.DateFormat;
-import java.util.Locale;
-
-import javax.swing.JButton;
-import javax.swing.JPanel;
-import javax.swing.JTextArea;
-import javax.swing.JTextField;
-import javax.swing.SwingConstants;
-import javax.swing.Timer;
-
-import com.jgoodies.forms.builder.DefaultFormBuilder;
-import com.jgoodies.forms.factories.Borders;
-import com.jgoodies.forms.layout.FormLayout;
-
-import net.sourceforge.subsonic.booter.deployer.DeploymentStatus;
-import net.sourceforge.subsonic.booter.deployer.SubsonicDeployerService;
-
-/**
- * Panel displaying the status of the Subsonic service.
- *
- * @author Sindre Mehus
- */
-public class StatusPanel extends JPanel {
-
- private static final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US);
-
- private final SubsonicDeployerService deployer;
-
- private JTextField startedTextField;
- private JTextField memoryTextField;
- private JTextArea errorTextField;
- private JButton urlButton;
-
- public StatusPanel(SubsonicDeployerService deployer) {
- this.deployer = deployer;
- createComponents();
- configureComponents();
- layoutComponents();
- addBehaviour();
- }
-
- private void createComponents() {
- startedTextField = new JTextField();
- memoryTextField = new JTextField();
- errorTextField = new JTextArea(3, 24);
- urlButton = new JButton();
- }
-
- private void configureComponents() {
- startedTextField.setEditable(false);
- memoryTextField.setEditable(false);
- errorTextField.setEditable(false);
-
- errorTextField.setLineWrap(true);
- errorTextField.setBorder(startedTextField.getBorder());
-
- urlButton.setBorderPainted(false);
- urlButton.setContentAreaFilled(false);
- urlButton.setForeground(Color.BLUE.darker());
- urlButton.setHorizontalAlignment(SwingConstants.LEFT);
- }
-
- private void layoutComponents() {
- FormLayout layout = new FormLayout("right:d, 6dlu, max(d;30dlu):grow");
- DefaultFormBuilder builder = new DefaultFormBuilder(layout, this);
- builder.append("Started on", startedTextField);
- builder.append("Memory used", memoryTextField);
- builder.append("Error message", errorTextField);
- builder.append("Server address", urlButton);
-
- setBorder(Borders.DIALOG_BORDER);
- }
-
- private void addBehaviour() {
- urlButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- openBrowser();
- }
- });
-
- Timer timer = new Timer(3000, new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- updateStatus(deployer.getDeploymentInfo());
- }
- });
- updateStatus(deployer.getDeploymentInfo());
- timer.start();
- }
-
- private void openBrowser() {
- String url = urlButton.getText();
- if (url == null) {
- return;
- }
- try {
- Desktop.getDesktop().browse(new URI(url));
- } catch (Throwable x) {
- x.printStackTrace();
- }
- }
-
- private void updateStatus(DeploymentStatus status) {
- startedTextField.setText(status == null ? null : DATE_FORMAT.format(status.getStartTime()));
- memoryTextField.setText(status == null ? null : status.getMemoryUsed() + " MB");
- errorTextField.setText(status == null ? null : status.getErrorMessage());
- urlButton.setText(status == null ? null : status.getURL());
- }
-} \ No newline at end of file
diff --git a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/mac/SubsonicController.java b/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/mac/SubsonicController.java
deleted file mode 100644
index 65731f31..00000000
--- a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/mac/SubsonicController.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package net.sourceforge.subsonic.booter.mac;
-
-import net.sourceforge.subsonic.booter.deployer.SubsonicDeployerService;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.net.URL;
-import java.net.URI;
-
-/**
- * Controller for the Mac booter.
- *
- * @author Sindre Mehus
- */
-public class SubsonicController {
-
- private final SubsonicDeployerService deployer;
- private final SubsonicFrame frame;
- private Action openAction;
- private Action controlPanelAction;
- private Action quitAction;
-
- public SubsonicController(SubsonicDeployerService deployer, SubsonicFrame frame) {
- this.deployer = deployer;
- this.frame = frame;
- createActions();
- createComponents();
- }
-
- private void createActions() {
- openAction = new AbstractAction("Open Subsonic Web Page") {
- public void actionPerformed(ActionEvent e) {
- openBrowser();
- }
- };
-
- controlPanelAction = new AbstractAction("Subsonic Control Panel") {
- public void actionPerformed(ActionEvent e) {
- frame.setActive(false);
- frame.setActive(true);
- }
- };
-
- quitAction = new AbstractAction("Quit Subsonic") {
- public void actionPerformed(ActionEvent e) {
- System.exit(0);
- }
- };
- }
-
- private void createComponents() {
- PopupMenu menu = new PopupMenu();
- menu.add(createMenuItem(openAction));
- menu.add(createMenuItem(controlPanelAction));
- menu.addSeparator();
- menu.add(createMenuItem(quitAction));
-
- URL url = getClass().getResource("/images/subsonic-21.png");
- Image image = Toolkit.getDefaultToolkit().createImage(url);
- TrayIcon trayIcon = new TrayIcon(image, "Subsonic Music Streamer", menu);
- trayIcon.setImageAutoSize(false);
-
- try {
- SystemTray.getSystemTray().add(trayIcon);
- } catch (Throwable x) {
- System.err.println("Failed to add tray icon.");
- }
- }
-
- private MenuItem createMenuItem(Action action) {
- MenuItem menuItem = new MenuItem((String) action.getValue(Action.NAME));
- menuItem.addActionListener(action);
- return menuItem;
- }
-
- private void openBrowser() {
- String url = deployer.getDeploymentInfo().getURL();
- if (url == null) {
- return;
- }
- try {
- Desktop.getDesktop().browse(new URI(url));
- } catch (Throwable x) {
- x.printStackTrace();
- }
- }
-
-} \ No newline at end of file
diff --git a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/mac/SubsonicFrame.java b/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/mac/SubsonicFrame.java
deleted file mode 100644
index 2a492e45..00000000
--- a/subsonic-booter/src/main/java/net/sourceforge/subsonic/booter/mac/SubsonicFrame.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package net.sourceforge.subsonic.booter.mac;
-
-import com.jgoodies.forms.factories.Borders;
-import com.jgoodies.forms.factories.ButtonBarFactory;
-import net.sourceforge.subsonic.booter.Main;
-import net.sourceforge.subsonic.booter.deployer.SubsonicDeployerService;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.net.URL;
-
-/**
- * Frame with Subsonic status. Used on Mac installs.
- *
- * @author Sindre Mehus
- */
-public class SubsonicFrame extends JFrame {
-
- private final SubsonicDeployerService deployer;
- private StatusPanel statusPanel;
- private JButton hideButton;
- private JButton exitButton;
-
- public SubsonicFrame(SubsonicDeployerService deployer) {
- super("Subsonic");
- this.deployer = deployer;
- createComponents();
- layoutComponents();
- addBehaviour();
-
- URL url = Main.class.getResource("/images/subsonic-512.png");
- setIconImage(Toolkit.getDefaultToolkit().createImage(url));
- }
-
- public void setActive(boolean active) {
- if (active) {
- pack();
- centerComponent();
- setVisible(true);
- toFront();
- } else {
- dispose();
- }
- }
-
- private void centerComponent() {
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- setLocation(screenSize.width / 2 - getWidth() / 2,
- screenSize.height / 2 - getHeight() / 2);
- }
-
- private void createComponents() {
- statusPanel = new StatusPanel(deployer);
- hideButton = new JButton("Hide");
- exitButton = new JButton("Exit");
- }
-
- private void layoutComponents() {
- JPanel pane = (JPanel) getContentPane();
- pane.setLayout(new BorderLayout(10, 10));
- pane.add(statusPanel, BorderLayout.CENTER);
- pane.add(ButtonBarFactory.buildRightAlignedBar(hideButton, exitButton), BorderLayout.SOUTH);
-
- pane.setBorder(Borders.DIALOG_BORDER);
- }
-
- private void addBehaviour() {
- hideButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- setActive(false);
- }
- });
- exitButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- System.exit(0);
- }
- });
- }
-
-} \ No newline at end of file