diff --git a/src/de/tobifleig/lxc/LXC.java b/src/de/tobifleig/lxc/LXC.java index b548b03..a498cd5 100644 --- a/src/de/tobifleig/lxc/LXC.java +++ b/src/de/tobifleig/lxc/LXC.java @@ -31,7 +31,7 @@ import de.tobifleig.lxc.net.NetworkManager; import de.tobifleig.lxc.net.NetworkManagerListener; import de.tobifleig.lxc.net.TransFileList; -import de.tobifleig.lxc.plaf.GuiInterface; +import de.tobifleig.lxc.plaf.impl.ui.UserInterface; import de.tobifleig.lxc.plaf.GuiListener; import de.tobifleig.lxc.plaf.Platform; @@ -59,7 +59,7 @@ public class LXC { /** * Our GUI. */ - private GuiInterface gui; + private final UserInterface gui; /** * The networkmanager. */ diff --git a/src/de/tobifleig/lxc/data/LXCFile.java b/src/de/tobifleig/lxc/data/LXCFile.java index 487f5f4..b115c5e 100644 --- a/src/de/tobifleig/lxc/data/LXCFile.java +++ b/src/de/tobifleig/lxc/data/LXCFile.java @@ -241,6 +241,15 @@ public String getShownName() { return shownName; } + /** + * Return a String with exactly 30 chars containing the name. The name is cut or suffixed with extra spaces to fill the 30 chars. + * + * @return + */ + public String getFormattedName() { + return String.format("%-30.30s", getShownName()); + } + /** * Returns the type. * diff --git a/src/de/tobifleig/lxc/main/LxcDaemonController.java b/src/de/tobifleig/lxc/main/LxcDaemonController.java new file mode 100644 index 0000000..c407abe --- /dev/null +++ b/src/de/tobifleig/lxc/main/LxcDaemonController.java @@ -0,0 +1,164 @@ +/* + * Copyright 2009, 2010, 2011, 2012, 2013, 2014 Tobias Fleig (tobifleig gmail com) + * + * All rights reserved. + * + * This file is part of LanXchange. + * + * LanXchange is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LanXchange is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LanXchange. If not, see . + */ +package de.tobifleig.lxc.main; + +import de.tobifleig.lxc.plaf.impl.textbased.LxcDaemon; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.Arrays; + +/** + * Control the Lxc-Daemon. Sends start, stop, file-upload etc. commands to the + * daemon + * + * @author Michael + */ +public class LxcDaemonController { + + /** + * The socket used to communicate to the Lxc-Daemon + */ + private Socket socket; + /** + * The reader to read from the sockets inputstream. + */ + private BufferedReader reader; + + public LxcDaemonController(String args[]) { + + if (Arrays.asList(args).contains("status")) { + if (tryConnectSocket()) { + System.out.println("LxcDaemon is running."); + try { + socket.close(); + } catch (Exception ex) { + }; + } else { + System.out.println("LxcDaemon is NOT running."); + } + } else if (Arrays.asList(args).contains("start")) { + if (startDaemon()) { + System.out.println("LxcDaemon started successfully."); + } else { + System.out.println("Error starting LxcDaemon."); + } + } else if (Arrays.asList(args).contains("daemonize")) { + LxcDaemon daemon = new LxcDaemon(); + } else if (Arrays.asList(args).contains("stop")) { + if (tryConnectSocket()) { + try { + socket.getOutputStream().write("stop\n".getBytes()); + String answer = reader.readLine(); + if (answer.equals("stopping...")) { + System.out.println("LxcDaemon shutting down."); + } else { + System.out.println("Error stopping LxcDaemon."); + } + socket.close(); + } catch (IOException ex) { + System.out.println("Error stopping LxcDaemon."); + } + } else { + System.out.println("LxcDaemon is not running."); + } + } else if (Arrays.asList(args).contains("help") || Arrays.asList(args).contains("halp") || Arrays.asList(args).contains("hlep")) { + System.out.println("Usage:"); + System.out.println("Show status: lxc -nogui status"); + System.out.println("Start daemon: lxc -nogui start"); + System.out.println("Stop daemon: lxc -nogui stop"); + System.out.println("List available files: lxc -nogui list"); + System.out.println("Download file: lxc -nogui download [number]"); + System.out.println("Upload file: lxc -nogui upload-file [file]"); + System.out.println("Stop Uploading file: lxc -nogui stop-uploading-file [file]"); + } else { + // Its a command to the deamon, send it and print the answer: + if (!tryConnectSocket()) { + if (startDaemon()) { + System.out.println("LxcDaemon started."); + } else { + System.out.println("Cant start LxcDaemon!"); + tryCloseSocket(); + return; + } + } + String command = ""; + boolean daemonargs = false; + for (int i = 0; i < args.length; i++) { + if (daemonargs) { + command += " " + args[i]; + } else if (args[i].equals("-nogui")) { + daemonargs = true; + } + } + command = command.substring(1); + try { + socket.getOutputStream().write(command.getBytes()); + socket.getOutputStream().write("\n".getBytes()); + String answer; + do { + answer = reader.readLine(); + System.out.println(answer); + } while (!answer.isEmpty()); + socket.close(); + } catch (IOException ex) { + System.out.println("Cant connect to LXCDaemon."); + } + } + tryCloseSocket(); + } + + private boolean startDaemon() { + try { + ProcessBuilder builder = new ProcessBuilder(); + builder.environment().putAll(System.getenv()); +// builder.command("java", "-jar", "LXC.jar", "-nogui", "daemonize"); + builder.command("lxc", "-nogui", "daemonize"); + builder.start(); + return tryConnectSocket(); + } catch (IOException ex) { + ex.printStackTrace(); + return false; + } + } + + private boolean tryConnectSocket() { + try { + socket = new Socket(); + socket.connect(new InetSocketAddress("localhost", LxcDaemon.LXC_DAEMON_PORT)); + reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); + return true; + } catch (IOException ex) { + return false; + } + } + + private void tryCloseSocket() { + try { + reader.close(); + socket.close(); + } catch (Exception ex) { + + } + } +} diff --git a/src/de/tobifleig/lxc/main/Main.java b/src/de/tobifleig/lxc/main/Main.java new file mode 100644 index 0000000..72aa0b7 --- /dev/null +++ b/src/de/tobifleig/lxc/main/Main.java @@ -0,0 +1,46 @@ +/* + * Copyright 2009, 2010, 2011, 2012, 2013, 2014 Tobias Fleig (tobifleig gmail com) + * + * All rights reserved. + * + * This file is part of LanXchange. + * + * LanXchange is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LanXchange is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LanXchange. If not, see . + */ +package de.tobifleig.lxc.main; + +import java.util.Arrays; + +/** + * Application entry point. Every project should have a main class. + * + * @author Michael + */ +public class Main { + + /** + * Entry point Launch Swing-GUI unless -nogui was given as argument + * + * @param args the command line arguments + */ + public static void main(String args[]) { + if (Arrays.asList(args).contains("-nogui")) { + new LxcDaemonController(args); + } else { + new SwingGUILauncher(args); + } + + } + +} diff --git a/src/de/tobifleig/lxc/plaf/impl/WinPlatform.java b/src/de/tobifleig/lxc/main/SwingGUILauncher.java similarity index 71% rename from src/de/tobifleig/lxc/plaf/impl/WinPlatform.java rename to src/de/tobifleig/lxc/main/SwingGUILauncher.java index 9896b1f..126afe4 100644 --- a/src/de/tobifleig/lxc/plaf/impl/WinPlatform.java +++ b/src/de/tobifleig/lxc/main/SwingGUILauncher.java @@ -18,13 +18,21 @@ * You should have received a copy of the GNU General Public License * along with LanXchange. If not, see . */ -package de.tobifleig.lxc.plaf.impl; + +package de.tobifleig.lxc.main; + +import de.tobifleig.lxc.plaf.impl.GenericPCPlatform; +import de.tobifleig.lxc.plaf.impl.swing.SwingGui; /** - * Windows-specific behaviors/settings. + * Start LXC with a swing GUI. * - * @author Tobias Fleig + * @author Michael */ -public class WinPlatform extends GenericPCPlatform { - // Room for future enhancements +public class SwingGUILauncher { + + public SwingGUILauncher(String args[]) { + GenericPCPlatform.startLXC(new SwingGui(), args); + } + } diff --git a/src/de/tobifleig/lxc/plaf/Platform.java b/src/de/tobifleig/lxc/plaf/Platform.java index a4d7d0f..5cdc026 100644 --- a/src/de/tobifleig/lxc/plaf/Platform.java +++ b/src/de/tobifleig/lxc/plaf/Platform.java @@ -20,6 +20,9 @@ */ package de.tobifleig.lxc.plaf; +import de.tobifleig.lxc.plaf.impl.ui.UserInterface; +import java.io.File; +import de.tobifleig.lxc.data.LXCFile; import java.io.File; import de.tobifleig.lxc.data.LXCFile; @@ -52,7 +55,7 @@ public interface Platform { * @param args the start-parameters * @return the platform-specific user interface */ - public GuiInterface getGui(String[] args); + public UserInterface getGui(String[] args); /** * Reads and returns the configuration. diff --git a/src/de/tobifleig/lxc/plaf/impl/GenericPCPlatform.java b/src/de/tobifleig/lxc/plaf/impl/GenericPCPlatform.java index 057b889..4c58236 100644 --- a/src/de/tobifleig/lxc/plaf/impl/GenericPCPlatform.java +++ b/src/de/tobifleig/lxc/plaf/impl/GenericPCPlatform.java @@ -23,7 +23,7 @@ import de.tobifleig.lxc.Configuration; import de.tobifleig.lxc.LXC; import de.tobifleig.lxc.data.LXCFile; -import de.tobifleig.lxc.plaf.GuiInterface; +import de.tobifleig.lxc.plaf.impl.ui.UserInterface; import de.tobifleig.lxc.plaf.Platform; import de.tobifleig.lxc.plaf.impl.swing.LXCUpdater; import de.tobifleig.lxc.plaf.impl.swing.SwingGui; @@ -52,7 +52,16 @@ public class GenericPCPlatform implements Platform { /** * the swing-gui. */ - private static SwingGui gui = new SwingGui(); + private static UserInterface userInterface; + + /** + * Create a new GenericPCPlatform and use the given UserInterface to talk to the user. + * + * @param userInterface + */ + public GenericPCPlatform(UserInterface userInterface) { + this.userInterface = userInterface; + } @Override public boolean hasAutoUpdates() { @@ -104,8 +113,7 @@ public void checkAndPerformUpdates(String[] args) { @Override public void run() { try { - LXCUpdater.checkAndPerformUpdate(gui, force, - noVerification, managed); + LXCUpdater.checkAndPerformUpdate(userInterface, force, noVerification, managed); } catch (Exception ex) { ex.printStackTrace(); } @@ -123,8 +131,8 @@ public void run() { } @Override - public GuiInterface getGui(String[] args) { - return gui; + public UserInterface getGui(String[] args) { + return userInterface; } @Override @@ -217,10 +225,10 @@ public String getDefaultDownloadTarget() { /** * Starts LanXchange on PC plaforms. * - * @param args - * any arguments you want to pass to LanXchange + * @param userInterface the interface (graphical or text) to talk to the user + * @param args any arguments you want to pass to LanXchange */ - public static void main(String[] args) { + public static void startLXC(UserInterface userInterface, String[] args) { // check permission for own folder try { File.createTempFile("testacl", null, new File(".")).delete(); @@ -230,10 +238,10 @@ public static void main(String[] args) { System.out.println("ERROR: Cannot write to my directory (" + new File(".").getAbsolutePath() + "). Try running LXC in your home directory."); - gui.showError("LXC is not allowed to create/modify files in the folder it is located. Please move to your home directory or start as administrator."); + userInterface.showError("LXC is not allowed to create/modify files in the folder it is located. Please move to your home directory or start as administrator."); System.exit(1); } - LXC lxc = new LXC(new GenericPCPlatform(), args); + LXC lxc = new LXC(new GenericPCPlatform(userInterface), args); } @Override diff --git a/src/de/tobifleig/lxc/plaf/impl/android/service/LXCService.java b/src/de/tobifleig/lxc/plaf/impl/android/service/LXCService.java index d146d7a..7ceed3a 100644 --- a/src/de/tobifleig/lxc/plaf/impl/android/service/LXCService.java +++ b/src/de/tobifleig/lxc/plaf/impl/android/service/LXCService.java @@ -39,7 +39,7 @@ import de.tobifleig.lxc.R; import de.tobifleig.lxc.data.LXCFile; import de.tobifleig.lxc.data.VirtualFile; -import de.tobifleig.lxc.plaf.GuiInterface; +import de.tobifleig.lxc.plaf.impl.ui.UserInterface; import de.tobifleig.lxc.plaf.GuiListener; import de.tobifleig.lxc.plaf.Platform; import de.tobifleig.lxc.plaf.impl.AndroidPlatform; @@ -122,8 +122,8 @@ public void checkAndPerformUpdates(String[] args) { } @Override - public GuiInterface getGui(String[] args) { - return new GuiInterface() { + public UserInterface getGui(String[] args) { + return new UserInterface() { @Override public void update() { diff --git a/src/de/tobifleig/lxc/plaf/impl/swing/LXCUpdater.java b/src/de/tobifleig/lxc/plaf/impl/swing/LXCUpdater.java index c62b0c0..b33740b 100644 --- a/src/de/tobifleig/lxc/plaf/impl/swing/LXCUpdater.java +++ b/src/de/tobifleig/lxc/plaf/impl/swing/LXCUpdater.java @@ -20,7 +20,9 @@ */ package de.tobifleig.lxc.plaf.impl.swing; +import de.tobifleig.lxc.plaf.impl.ui.UpdateDialog; import de.tobifleig.lxc.LXC; +import de.tobifleig.lxc.plaf.impl.ui.UserInterface; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; @@ -74,7 +76,7 @@ public final class LXCUpdater { * @param restartable if true, whoever started LXC is aware of this updatesystem and wants to be notifiyed when LXC should be restarted rather than regularely terminated (this is done by returning exit code 6 rather than 0) * @throws Exception may throw a bunch of exceptions, this class requires, working internet, github, signature checks etc. */ - public static void checkAndPerformUpdate(SwingGui gui, boolean forceUpdate, boolean overrideVerification, boolean restartable) throws Exception { + public static void checkAndPerformUpdate(UserInterface userInterface, boolean forceUpdate, boolean overrideVerification, boolean restartable) throws Exception { if (forceUpdate) { System.out.println("Info: Forcing update..."); } @@ -87,10 +89,11 @@ public static void checkAndPerformUpdate(SwingGui gui, boolean forceUpdate, bool // compare version number if (gotver > LXC.versionId || forceUpdate) { System.out.println("Newer Version available!"); - UpdateDialog updateGui = new UpdateDialog(gui, true, title); + UpdateDialog updateDialog = userInterface.getUpdateDialog(); + updateDialog.setTitle(title); // prompt user - if (updateGui.isUpdate()) { - updateGui.toProgressView(); + if (updateDialog.isUpdate()) { + updateDialog.toProgressView(); // download update URL url = new URL("https://raw.github.com/tfg13/LanXchange/master/update/update_master.zip"); FileOutputStream os = new FileOutputStream(new File("update_dl.zip")); @@ -109,7 +112,7 @@ public static void checkAndPerformUpdate(SwingGui gui, boolean forceUpdate, bool } os.close(); // verify signature - updateGui.setStatusToVerify(); + updateDialog.setStatusToVerify(); // extract update & signature file File psource = new File("update_dl.zip"); ZipFile masterZip = new ZipFile(psource); @@ -160,7 +163,7 @@ public static void checkAndPerformUpdate(SwingGui gui, boolean forceUpdate, bool inss.close(); // signature ok? if (sign.verify(bs) || overrideVerification) { - updateGui.setStatusToInstall(); + updateDialog.setStatusToInstall(); // extract update File source = new File("temp_update.zip"); File target = new File("."); @@ -210,30 +213,30 @@ public static void checkAndPerformUpdate(SwingGui gui, boolean forceUpdate, bool } //done - updateGui.setStatusToRestart(); - updateGui.setRestartTime(5, !restartable); + updateDialog.setStatusToRestart(); + updateDialog.setRestartTime(5, !restartable); Thread.sleep(1000); - updateGui.setRestartTime(4, !restartable); + updateDialog.setRestartTime(4, !restartable); Thread.sleep(1000); - updateGui.setRestartTime(3, !restartable); + updateDialog.setRestartTime(3, !restartable); Thread.sleep(1000); - updateGui.setRestartTime(2, !restartable); + updateDialog.setRestartTime(2, !restartable); Thread.sleep(1000); - updateGui.setRestartTime(1, !restartable); + updateDialog.setRestartTime(1, !restartable); Thread.sleep(1000); - updateGui.setRestartTime(0, !restartable); + updateDialog.setRestartTime(0, !restartable); System.exit(6); } else { System.out.println("ERROR: Bad signature! File corrupted (OR MANIPULATED!!!). Will not update!"); - updateGui.setStatusToError(); + updateDialog.setStatusToError(); return; } } else { System.out.println("Update rejected by user"); } - updateGui.setVisible(false); - updateGui.dispose(); + updateDialog.setVisible(false); + updateDialog.dispose(); } else { System.out.println("You have the latest version"); } diff --git a/src/de/tobifleig/lxc/plaf/impl/swing/SwingGui.java b/src/de/tobifleig/lxc/plaf/impl/swing/SwingGui.java index 7999f32..2ba21f7 100644 --- a/src/de/tobifleig/lxc/plaf/impl/swing/SwingGui.java +++ b/src/de/tobifleig/lxc/plaf/impl/swing/SwingGui.java @@ -20,8 +20,9 @@ */ package de.tobifleig.lxc.plaf.impl.swing; +import de.tobifleig.lxc.plaf.impl.ui.UpdateDialog; import de.tobifleig.lxc.data.LXCFile; -import de.tobifleig.lxc.plaf.GuiInterface; +import de.tobifleig.lxc.plaf.impl.ui.UserInterface; import de.tobifleig.lxc.plaf.GuiListener; import java.awt.Font; import java.awt.FontFormatException; @@ -30,6 +31,7 @@ import java.awt.event.WindowStateListener; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.util.Timer; import java.util.TimerTask; import javax.imageio.ImageIO; @@ -46,7 +48,7 @@ * * @author Tobias Fleig */ -public class SwingGui extends javax.swing.JFrame implements GuiInterface { +public class SwingGui extends javax.swing.JFrame implements UserInterface { private static final long serialVersionUID = 1L; /** @@ -263,4 +265,9 @@ public File getFileTarget(LXCFile file) { public boolean confirmCloseWithTransfersRunning() { return (JOptionPane.showConfirmDialog(rootPane, "Exiting now will kill all running transfers. Quit anyway?", "Transfers running", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION); } + + @Override + public UpdateDialog getUpdateDialog() { + return new SwingUpdateDialog(this); + } } diff --git a/src/de/tobifleig/lxc/plaf/impl/swing/UpdateDialog.form b/src/de/tobifleig/lxc/plaf/impl/swing/SwingUpdateDialog.form similarity index 94% rename from src/de/tobifleig/lxc/plaf/impl/swing/UpdateDialog.form rename to src/de/tobifleig/lxc/plaf/impl/swing/SwingUpdateDialog.form index 0a02276..e16a0a2 100644 --- a/src/de/tobifleig/lxc/plaf/impl/swing/UpdateDialog.form +++ b/src/de/tobifleig/lxc/plaf/impl/swing/SwingUpdateDialog.form @@ -106,25 +106,10 @@ - - - - - - - - - - - - - - - @@ -188,7 +173,7 @@ - + diff --git a/src/de/tobifleig/lxc/plaf/impl/swing/UpdateDialog.java b/src/de/tobifleig/lxc/plaf/impl/swing/SwingUpdateDialog.java similarity index 93% rename from src/de/tobifleig/lxc/plaf/impl/swing/UpdateDialog.java rename to src/de/tobifleig/lxc/plaf/impl/swing/SwingUpdateDialog.java index bc0060b..ad83f0f 100644 --- a/src/de/tobifleig/lxc/plaf/impl/swing/UpdateDialog.java +++ b/src/de/tobifleig/lxc/plaf/impl/swing/SwingUpdateDialog.java @@ -20,16 +20,16 @@ */ package de.tobifleig.lxc.plaf.impl.swing; +import de.tobifleig.lxc.plaf.impl.ui.UpdateDialog; import java.awt.Color; import javax.swing.ImageIcon; /** - * Update-Dialog. - * Created by the NetBeans-GuiBuilder + * Update-Dialog. Created by the NetBeans-GuiBuilder * * @author Tobias Fleig */ -public class UpdateDialog extends javax.swing.JDialog { +public class SwingUpdateDialog extends javax.swing.JDialog implements UpdateDialog { private static final long serialVersionUID = 1L; private boolean update = false; @@ -39,10 +39,9 @@ public class UpdateDialog extends javax.swing.JDialog { * Creates new form LXCUpdateDialog * * @param parent - * @param modal * @param nextVersion */ - public UpdateDialog(java.awt.Frame parent, boolean modal, String nextVersion) { + public SwingUpdateDialog(java.awt.Frame parent) { super(parent, false); initComponents(); jLabel1.setIcon(new ImageIcon("img/update.png")); @@ -50,7 +49,6 @@ public UpdateDialog(java.awt.Frame parent, boolean modal, String nextVersion) { jLabel14.setIcon(jLabel13.getIcon()); jLabel16.setIcon(jLabel13.getIcon()); jPanel3.setVisible(false); - jLabel3.setText(nextVersion); setSize(getWidth(), jPanel2.getSize().height + 130); setLocationRelativeTo(parent); addWindowListener(new java.awt.event.WindowAdapter() { @@ -71,11 +69,15 @@ public void windowClosing(java.awt.event.WindowEvent e) { } } + + @Override + public void setTitle(String title){ + jLabel3.setText(title); + } /** - * This method is called from within the constructor to - * initialize the form. - * WARNING: Do NOT modify this code. The content of this method is - * always regenerated by the Form Editor. + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents @@ -118,12 +120,6 @@ private void initComponents() { jLabel12.setText("Step 4: restart LXC..."); - jLabel13.setIcon(new javax.swing.ImageIcon("/home/tfg/NetBeansProjects/lanXchange2/img/done.png")); // NOI18N - - jLabel14.setIcon(new javax.swing.ImageIcon("/home/tfg/NetBeansProjects/lanXchange2/img/done.png")); // NOI18N - - jLabel16.setIcon(new javax.swing.ImageIcon("/home/tfg/NetBeansProjects/lanXchange2/img/done.png")); // NOI18N - javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( @@ -179,7 +175,7 @@ private void initComponents() { setResizable(false); jLabel1.setFont(new java.awt.Font("Ubuntu", 1, 12)); // NOI18N - jLabel1.setIcon(new javax.swing.ImageIcon("/home/tfg/NetBeansProjects/lanXchange2/img/update.png")); // NOI18N + jLabel1.setIcon(new javax.swing.ImageIcon("/home/tfg/NetBeansProjects/LanXchange/img/update.png")); // NOI18N jLabel2.setFont(new java.awt.Font("Dialog", 1, 24)); // NOI18N jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); @@ -225,7 +221,7 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addComponent(jButton1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 143, Short.MAX_VALUE) .addComponent(jButton2)) - .addComponent(jLabel7, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 309, Short.MAX_VALUE) + .addComponent(jLabel7, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 309, Short.MAX_VALUE) .addComponent(jLabel6, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel5, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 309, Short.MAX_VALUE) .addComponent(jLabel4, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 309, Short.MAX_VALUE)) @@ -322,11 +318,13 @@ private void buttonKlicked(boolean update) { private javax.swing.JSeparator jSeparator2; // End of variables declaration//GEN-END:variables - boolean isUpdate() { + @Override + public boolean isUpdate() { return update; } - void toProgressView() { + @Override + public void toProgressView() { jPanel2.removeAll(); jPanel2.setLayout(null); jPanel2.add(jPanel3); @@ -341,22 +339,26 @@ void toProgressView() { repaint(); } - void setStatusToVerify() { + @Override + public void setStatusToVerify() { jLabel10.setVisible(true); jLabel13.setVisible(true); } - void setStatusToInstall() { + @Override + public void setStatusToInstall() { jLabel11.setVisible(true); jLabel14.setVisible(true); } - void setStatusToRestart() { + @Override + public void setStatusToRestart() { jLabel12.setVisible(true); jLabel16.setVisible(true); } - void setRestartTime(int i, boolean manual) { + @Override + public void setRestartTime(int i, boolean manual) { if (manual) { jLabel12.setText("OK! Please restart LXC. Terminating in: " + i); } else { @@ -364,7 +366,8 @@ void setRestartTime(int i, boolean manual) { } } - void setStatusToError() { + @Override + public void setStatusToError() { jLabel10.setForeground(Color.RED); jLabel11.setText("ERROR. Update corrupted or manipulated!"); jLabel12.setText("For your security, will not be installed"); diff --git a/src/de/tobifleig/lxc/plaf/impl/textbased/FileNumberTranslator.java b/src/de/tobifleig/lxc/plaf/impl/textbased/FileNumberTranslator.java new file mode 100644 index 0000000..e056b72 --- /dev/null +++ b/src/de/tobifleig/lxc/plaf/impl/textbased/FileNumberTranslator.java @@ -0,0 +1,61 @@ +/* + * Copyright 2009, 2010, 2011, 2012, 2013, 2014 Tobias Fleig (tobifleig gmail com) + * + * All rights reserved. + * + * This file is part of LanXchange. + * + * LanXchange is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LanXchange is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LanXchange. If not, see . + */ + +package de.tobifleig.lxc.plaf.impl.textbased; + +import de.tobifleig.lxc.data.LXCFile; +import java.util.HashMap; + +/** + * Provides a convinient number for LXCFiles and resolves that number back to the file. + * + * @author Michael + */ +public class FileNumberTranslator { + + private HashMap files; + private HashMap numbers; + private int currentNumber = 0; + + public FileNumberTranslator() { + files = new HashMap(); + numbers = new HashMap(); + } + + public LXCFile getFileForNumber(int number) { + if (files.containsKey(number)) { + return files.get(number); + } else { + return null; + } + + } + + public int getNumberForFile(LXCFile file) { + if (numbers.containsKey(file)) { + return numbers.get(file); + } else { + numbers.put(file, currentNumber); + files.put(currentNumber, file); + return currentNumber++; + } + } +} diff --git a/src/de/tobifleig/lxc/plaf/impl/textbased/LXCDaemonUserInterface.java b/src/de/tobifleig/lxc/plaf/impl/textbased/LXCDaemonUserInterface.java new file mode 100644 index 0000000..09bc042 --- /dev/null +++ b/src/de/tobifleig/lxc/plaf/impl/textbased/LXCDaemonUserInterface.java @@ -0,0 +1,167 @@ +/* + * Copyright 2009, 2010, 2011, 2012, 2013, 2014 Tobias Fleig (tobifleig gmail com) + * + * All rights reserved. + * + * This file is part of LanXchange. + * + * LanXchange is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LanXchange is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LanXchange. If not, see . + */ +package de.tobifleig.lxc.plaf.impl.textbased; + +import de.tobifleig.lxc.data.LXCFile; +import de.tobifleig.lxc.data.LXCJob; +import de.tobifleig.lxc.plaf.GuiListener; +import de.tobifleig.lxc.plaf.impl.ui.UpdateDialog; +import de.tobifleig.lxc.plaf.impl.ui.UserInterface; +import java.io.File; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +/** + * The UnserInterface that lets the daemon communicate with lxc. + * + * @author Michael + */ +public class LXCDaemonUserInterface implements UserInterface { + + private GuiListener guiListener; + private List lxcFileList; + FileNumberTranslator translator = new FileNumberTranslator(); + private File downloadFolder; + + public String getStatus() { + String status = "ID NAME DESCRIPTION\n"; + for (LXCFile file : lxcFileList) { + status += translator.getNumberForFile(file) + " "; + status += file.getFormattedName() + " "; + if (file.isLocal()) { + if (file.getJobs().isEmpty()) { + status += "Offered by this machine\n"; + } else { + Iterator iter = file.getJobs().iterator(); + while (iter.hasNext()) { + LXCJob job = iter.next(); + status += "Sending to " + job.getRemote().getName() + " at " + job.getTrans().getCurrentSpeed() + ", " + job.getTrans().getProgress() + "% complete.\n"; + if (iter.hasNext()) { + status += " "; + } + } + } + // TODO show downloaders and their progress + } else { + if (file.getJobs().isEmpty()) { + status += "Offered from " + file.getInstance().getName(); + } else { + LXCJob job = file.getJobs().get(0); + status += "Downloading from " + file.getInstance().getName() + " at " + job.getTrans().getCurrentSpeed() + ", " + job.getTrans().getProgress() + "% complete.\n"; + } + + } + status += "\n"; + } + return status; + } + + @Override + public void init(String[] args) { + } + + @Override + public void display() { + lxcFileList = guiListener.getFileList(); + } + + @Override + public void showError(String error) { + LxcDaemon.errorBuffer.add(error); + } + + @Override + public void setGuiListener(GuiListener guiListener) { + this.guiListener = guiListener; + } + + @Override + public void update() { + // lxcd is not interactive, so we ignore updates + } + + @Override + public File getFileTarget(LXCFile file) { + return downloadFolder; + } + + @Override + public boolean confirmCloseWithTransfersRunning() { + return true; + } + + @Override + public UpdateDialog getUpdateDialog() { + return new TextBasedUpdateDialog(); + } + + public String uploadFile(String filename) { + File file = new File(filename); + if (!file.exists()) { + return "File not found"; + } + List files = new LinkedList(); + files.add(file); + LXCFile lxcFile = new LXCFile(LXCFile.convertToVirtual(files), file.getName()); + guiListener.offerFile(lxcFile); + return "File uploaded as " + translator.getNumberForFile(lxcFile); + } + + public String stopUploadFile(int number) { + LXCFile file = translator.getFileForNumber(number); + if (file == null || !lxcFileList.contains(file)) { + return "No such file."; + } else if (!file.isLocal()) { + return "File is uploaded from another system."; + } else { + guiListener.removeFile(file); + return "Stopped uploading " + file.getShownName(); + } + } + + String downloadFile(int number, String target) { + LXCFile file = translator.getFileForNumber(number); + if (file == null || !lxcFileList.contains(file)) { + return "No such file."; + } else if (!file.isLocal()) { + if (!target.isEmpty()) { + downloadFolder = new File(target); + } + if (downloadFolder == null) { + return "Set defaulttarget in lxc.cfg or supply the download target as argument."; + } else if (!downloadFolder.canWrite()) { + return "Cant write to " + downloadFolder.getAbsolutePath(); + } else { + guiListener.downloadFile(file, true); + return "Downloading " + file.getFormattedName(); + } + } else { + return "Cant download files offered from this machine." + file.getShownName(); + } + } + + public void setDefaultDownloadTarget(String defaultDownloadTarget) { + if (defaultDownloadTarget != null) { + downloadFolder = new File(defaultDownloadTarget); + } + } +} diff --git a/src/de/tobifleig/lxc/plaf/impl/textbased/LxcDaemon.java b/src/de/tobifleig/lxc/plaf/impl/textbased/LxcDaemon.java new file mode 100644 index 0000000..f731309 --- /dev/null +++ b/src/de/tobifleig/lxc/plaf/impl/textbased/LxcDaemon.java @@ -0,0 +1,123 @@ +/* + * Copyright 2009, 2010, 2011, 2012, 2013, 2014 Tobias Fleig (tobifleig gmail com) + * + * All rights reserved. + * + * This file is part of LanXchange. + * + * LanXchange is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LanXchange is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LanXchange. If not, see . + */ +package de.tobifleig.lxc.plaf.impl.textbased; + +import de.tobifleig.lxc.LXC; +import de.tobifleig.lxc.plaf.Platform; +import de.tobifleig.lxc.plaf.impl.GenericPCPlatform; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; + +/** + * The LXC Daemon runs LXC in the backgroud and talks to the LxcDaemonController + * over a socket. + * + * @author Michael + */ +public class LxcDaemon implements Runnable { + + public static int LXC_DAEMON_PORT = 27718; + + private ServerSocket serverSocket; + private Thread serverThread; + private LXCDaemonUserInterface lxcInterface; + + public static ArrayList errorBuffer = new ArrayList(); + + public LxcDaemon() { + try { + lxcInterface = new LXCDaemonUserInterface(); + Platform plattform = new GenericPCPlatform(lxcInterface); + lxcInterface.setDefaultDownloadTarget(plattform.getDefaultDownloadTarget()); + new LXC(plattform, new String[0]); + serverSocket = new ServerSocket(LXC_DAEMON_PORT); + serverThread = new Thread(this); + serverThread.setName("LxcDaemonThread"); + serverThread.start(); + System.out.println("LxcDaemon started successfully."); + } catch (IOException ex) { + System.out.println("Error starting socket on port " + LXC_DAEMON_PORT); + System.exit(1); + } + } + + @Override + public void run() { + boolean run = true; + while (run) { + try { + Socket socket = serverSocket.accept(); + BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); + + // print the errors that have occured since the last call to LxcDaemon: + printErrors(socket.getOutputStream()); + + String[] commands = reader.readLine().split(" "); + + if (commands[0].equals("stop")) { + socket.getOutputStream().write("stopping...\n".getBytes()); + socket.close(); + run = false; + System.exit(0); + } else if (commands[0].equals("list")) { + socket.getOutputStream().write((lxcInterface.getStatus()).getBytes()); + } else if (commands[0].equals("upload-file")) { + socket.getOutputStream().write((lxcInterface.uploadFile(commands[1])).getBytes()); + } else if (commands[0].equals("stop-uploading-file")) { + socket.getOutputStream().write((lxcInterface.stopUploadFile(Integer.parseInt(commands[1]))).getBytes()); + } else if (commands[0].equals("download")) { + String target = ""; + if (commands.length > 2) { + target = commands[2]; + } + socket.getOutputStream().write((lxcInterface.downloadFile(Integer.parseInt(commands[1]), target)).getBytes()); + } else { + socket.getOutputStream().write(("unknown command: " + commands[0]).getBytes()); + } + + // print the errors that have occured during command execution: + printErrors(socket.getOutputStream()); + + socket.getOutputStream().write("\n\n".getBytes()); + socket.close(); + } catch (Exception ex) { + // Connection closed before a command was sent + // lets just ignore this and go on with the next request + } + } + } + + private void printErrors(OutputStream stream) { + while (!errorBuffer.isEmpty()) { + try { + stream.write((errorBuffer.remove(0) + "\n").getBytes()); + } catch (IOException ex) { + // connection error, abort + } + } + } + +} diff --git a/src/de/tobifleig/lxc/plaf/impl/textbased/TextBasedUpdateDialog.java b/src/de/tobifleig/lxc/plaf/impl/textbased/TextBasedUpdateDialog.java new file mode 100644 index 0000000..a05d62d --- /dev/null +++ b/src/de/tobifleig/lxc/plaf/impl/textbased/TextBasedUpdateDialog.java @@ -0,0 +1,75 @@ +/* + * Copyright 2009, 2010, 2011, 2012, 2013, 2014 Tobias Fleig (tobifleig gmail com) + * + * All rights reserved. + * + * This file is part of LanXchange. + * + * LanXchange is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LanXchange is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LanXchange. If not, see . + */ +package de.tobifleig.lxc.plaf.impl.textbased; + +import de.tobifleig.lxc.plaf.impl.ui.UpdateDialog; + +/** + * A surrogate update dialog. Does nothing since textbased lxc does not do updates (yet). + * @author Michael + */ +class TextBasedUpdateDialog implements UpdateDialog { + + public TextBasedUpdateDialog() { + } + + @Override + public boolean isUpdate() { + return false; // dont update. + } + + @Override + public void toProgressView() { + } + + @Override + public void setStatusToVerify() { + } + + @Override + public void setStatusToInstall() { + } + + @Override + public void setStatusToRestart() { + } + + @Override + public void setRestartTime(int i, boolean manual) { + } + + @Override + public void setStatusToError() { + } + + @Override + public void setVisible(boolean visible) { + } + + @Override + public void dispose() { + } + + @Override + public void setTitle(String title) { + } + +} diff --git a/src/de/tobifleig/lxc/plaf/impl/ui/UpdateDialog.java b/src/de/tobifleig/lxc/plaf/impl/ui/UpdateDialog.java new file mode 100644 index 0000000..53edf38 --- /dev/null +++ b/src/de/tobifleig/lxc/plaf/impl/ui/UpdateDialog.java @@ -0,0 +1,88 @@ +/* + * Copyright 2009, 2010, 2011, 2012, 2013, 2014 Tobias Fleig (tobifleig gmail com) + * + * All rights reserved. + * + * This file is part of LanXchange. + * + * LanXchange is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LanXchange is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LanXchange. If not, see . + */ +package de.tobifleig.lxc.plaf.impl.ui; + +/** + * Generic Dialog to inform the user of the update progress. + * + * @author Michael + */ +public interface UpdateDialog { + + /** + * + * @return + */ + public boolean isUpdate(); + + /** + * + * @return + */ + public void toProgressView(); + + /** + * + * @return + */ + public void setStatusToVerify(); + + /** + * + * @return + */ + public void setStatusToInstall(); + + /** + * + * @return + */ + public void setStatusToRestart(); + + /** + * + * @return + */ + public void setRestartTime(int i, boolean manual); + + /** + * + * @return + */ + public void setStatusToError(); + + /** + * + * @param visible + */ + public void setVisible(boolean visible); + + /** + * + */ + public void dispose(); + + /** + * + * @param title + */ + public void setTitle(String title); +} diff --git a/src/de/tobifleig/lxc/plaf/GuiInterface.java b/src/de/tobifleig/lxc/plaf/impl/ui/UserInterface.java similarity index 83% rename from src/de/tobifleig/lxc/plaf/GuiInterface.java rename to src/de/tobifleig/lxc/plaf/impl/ui/UserInterface.java index 8724cc0..5953eff 100644 --- a/src/de/tobifleig/lxc/plaf/GuiInterface.java +++ b/src/de/tobifleig/lxc/plaf/impl/ui/UserInterface.java @@ -18,19 +18,21 @@ * You should have received a copy of the GNU General Public License * along with LanXchange. If not, see . */ -package de.tobifleig.lxc.plaf; +package de.tobifleig.lxc.plaf.impl.ui; import de.tobifleig.lxc.data.LXCFile; +import de.tobifleig.lxc.plaf.GuiListener; +import de.tobifleig.lxc.plaf.impl.ui.UpdateDialog; import java.io.File; /** - * Defines a LXC-GUI. + * Defines a LXC-UI. * - * Enables the same codebase to use Swing or the Android-UI + * Enables the same codebase to use Swing or the Android-UI or a textbased interface * * @author Tobias Fleig */ -public interface GuiInterface { +public interface UserInterface { /** * Initialize the user-inferface. @@ -82,4 +84,11 @@ public interface GuiInterface { * @return true, if user really wants to quit and cancel all running transfers */ public boolean confirmCloseWithTransfersRunning(); + + /** + * Return a dialog that can be used to inform the user of the update process. + * + * @return + */ + public UpdateDialog getUpdateDialog(); }