chiark / gitweb /
Initial commit of Yarrg code
[jarrg-owen.git] / src / com / tedpearson / ypp / market / Installer.java
diff --git a/src/com/tedpearson/ypp/market/Installer.java b/src/com/tedpearson/ypp/market/Installer.java
new file mode 100644 (file)
index 0000000..a7621b8
--- /dev/null
@@ -0,0 +1,345 @@
+package com.tedpearson.ypp.market;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.border.*;
+import java.io.*;
+import com.tedpearson.util.update.*;
+import java.util.Properties;
+import java.net.URLDecoder;
+
+/*
+       allow adding islands/oceans
+       implement uploads to YAARG
+*/
+
+/**
+*      An Installer for PCTB Java Client.
+*/
+public class Installer extends JFrame {
+       public final static int VERSION = 8; 
+       private JLabel label;
+       private JProgressBar progress;
+       private JButton install, uninstall;
+       private static String os = System.getProperty("os.name");
+       private static String home = System.getProperty("java.home");
+       private static String user_home = System.getProperty("user.home");
+       private boolean installed = false;
+       private boolean uninstalled = false;
+       private static PrintWriter pw;
+       
+       public static void debug(String str) {
+               try {
+                       pw.println(str);
+                       pw.flush();
+               }catch(Exception e) {
+                       
+               }
+       }
+       
+       public static void main(String[] args) {
+               /*
+               try{
+                       pw = new PrintWriter("C:/Users/Public/ERRORS");
+               }catch(Exception e) {
+                       
+               }
+               */
+               new Installer(args);
+       }
+       
+       /**
+       *       Checks if we have permission to write to the Java Home folder
+       *       that runs YPP. Pops up an error message and exits if we don't have access,
+       *       or on Mac OS X, re-runs the installer using applescript to authenticate.
+       */
+       private void checkPermission(String[] args) {
+               File a11y = null;
+               a11y = new File(getJavaHome(),"lib");
+               if(os.equals("Mac OS X")) {
+                       if(!a11y.canWrite()) {
+                               JOptionPane.showMessageDialog(null,"Please authenticate as an Administrator, when prompted, to continue installation.");
+                               try {
+                                       String installer = URLDecoder.decode(getClass().getProtectionDomain().getCodeSource().getLocation()
+                                               .getPath(), "URT-8");
+                                       Runtime.getRuntime().exec(new String[]{"osascript","-e","do shell script \"java -jar " +
+                                               installer + "\" with administrator privileges"});
+                               } catch(Exception e) {
+                                       e.printStackTrace();
+                               }
+                               System.exit(0);
+                       }
+               } else {
+                       // clean up after myself
+                       if(os.contains("Vista")) {
+                               File tempDir = new File(System.getProperty("java.io.tmpdir"));
+                               for(File f : tempDir.listFiles()) {
+                                       if(f.getName().startsWith("PCTB-lib")) {
+                                               for(File g : f.listFiles()) {
+                                                       g.delete();
+                                               }
+                                               f.delete();
+                                       }
+                               }
+                       }
+                       // first check for YPP java
+                       boolean canWrite = true;
+                       File test = new File(a11y, "test_pctb");
+                       try {
+                               test.createNewFile();
+                               test.delete();
+                       } catch(IOException e) {
+                               canWrite = false;
+                       }
+                       if(!canWrite || !a11y.canWrite()) {
+                               if(os.contains("Vista")) {
+                                       if(args.length == 1 && args[0].equals("--elevate")) {
+                                               JOptionPane.showMessageDialog(null,"Please run this installer while logged in as an Administrator.");
+                                               System.exit(0);
+                                       }
+                                       try {
+                                               String installer = URLDecoder.decode(getClass().getProtectionDomain().getCodeSource().getLocation()
+                                                       .getPath(), "UTF-8").replaceFirst("/","");
+                                               ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/C", "elevate javaw -jar \"" + installer +
+                                                       "\" --elevate");
+                                               // create temp lib directory
+                                               File temp = File.createTempFile("PCTB-lib",null);
+                                               temp.delete();
+                                               temp.mkdir();
+                                               File elevate = new File(temp, "elevate.cmd");
+                                               OutputStream out = new FileOutputStream(elevate);
+                                               InputStream in = getClass().getResourceAsStream("/lib/elevate.cmd");
+                                               Updater.copyFile(in, out);
+                                               
+                                               elevate = new File(temp, "elevate.vbs");
+                                               out = new FileOutputStream(elevate);
+                                               in = getClass().getResourceAsStream("/lib/elevate.vbs");
+                                               Updater.copyFile(in, out);
+                                               
+                                               pb.directory(temp);
+                                               Process p = pb.start();
+                                       } catch(Exception e) {
+                                               e.printStackTrace();
+                                       }
+                                       System.exit(0);
+                               } else {
+                                       JOptionPane.showMessageDialog(null,"Please run this installer while logged in as an Administrator.");
+                                       System.exit(0);
+                               }
+                       }
+               }
+       }
+       
+       /**
+       *       Create the installer GUI
+       */
+       public Installer(String[] args) {
+               super("PCTB Installer");
+               
+               Updater.getUpdater().checkAndUpdate(null, "http://tedpearson.com/market/version",
+                       "the PCTB Uploader client", VERSION, true,
+                       getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
+               
+               // gui: simple window with status area and progress bar
+               checkPermission(args);
+               label = new JLabel("Ready to install!");
+               add(label,BorderLayout.NORTH);
+               progress = new JProgressBar();
+               progress.setBorder(new EmptyBorder(10,0,10,0));
+               add(progress,BorderLayout.CENTER);
+               String buttonText = "Install";
+               install = new JButton(buttonText);
+               JPanel buttons = new JPanel();
+               add(buttons,BorderLayout.SOUTH);
+               install.addActionListener(new ActionListener() {
+                       public void actionPerformed(ActionEvent e) {
+                               if(installed) {
+                                       System.exit(0);
+                               }
+                               try {
+                                       install.setEnabled(false);
+                                       uninstall.setEnabled(false);
+                                       install();
+                               } catch(IOException err) {
+                                       err.printStackTrace();
+                                       JOptionPane.showMessageDialog(Installer.this, "Error during installation.");
+                                       setButtonStatus(false,false);
+                                       label.setText("Install failed!");
+                               }
+                       }
+               });
+               uninstall = new JButton("Uninstall");
+               buttons.add(uninstall);
+               buttons.add(install);
+               uninstall.addActionListener(new ActionListener() {
+                       public void actionPerformed(ActionEvent e) {
+                               if(uninstalled) {
+                                       System.exit(0);
+                               }
+                               try {
+                                       install.setEnabled(false);
+                                       uninstall.setEnabled(false);
+                                       uninstall();
+                               } catch(IOException err) {
+                                       err.printStackTrace();
+                                       JOptionPane.showMessageDialog(Installer.this, "Error during installation.");
+                                       setButtonStatus(false,false);
+                                       label.setText("Uninstall failed!");
+                               }
+                       }
+               });
+               getRootPane().setBorder(new EmptyBorder(10,10,10,10));
+               getRootPane().setDefaultButton(install);
+               pack();
+               setSize(300,getHeight());
+               setLocationRelativeTo(null);
+               setDefaultCloseOperation(EXIT_ON_CLOSE);
+               setVisible(true);
+       }
+       
+       /**
+       *       Uninstalls the client. Throws an IOException ir errors occur.
+       *       (removes the PCTB class from assistive tech, deletes the jar)
+       */
+       private void uninstall() throws IOException {
+               label.setText("Uninstalling...");
+               progress.setIndeterminate(true);
+               // remove from assistive tech
+               File java_home = getJavaHome();
+               File a11y = new File(java_home,"lib/accessibility.properties");
+               if(a11y.exists()) {
+                       Properties p = new Properties();
+                       p.load(new FileInputStream(a11y));
+                       String tech = p.getProperty("assistive_technologies");
+                       tech = tech.replace("com.tedpearson.ypp.market.MarketUploader", "");
+                       p.setProperty("assistive_technologies", tech);
+                       p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer");
+               }
+               // remove jar
+               File jar = new File(java_home, "lib/ext/PCTB-Uploader.jar");
+               jar.delete();
+               setButtonStatus(false,true);
+       }
+       
+       /**
+       *       Utility method to find the Java Home folder that runs YPP. On Windows, it could be
+       *       inside the YPP folder.
+       */
+       private File getJavaHome() {
+               File java_home = new File(home);
+               if(os.contains("Windows")) {
+                       File defaultLocation = null;
+                       // check for javavm inside YPP folder, otherwise default location
+                       if(os.contains("Vista")) {
+                               String user = System.getProperty("user.name");
+                               defaultLocation = new File("C:\\Users\\" + user + "\\AppData\\Roaming\\Three Rings Design\\Puzzle Pirates\\");
+                       } else if(os.contains("XP")) {
+                               defaultLocation = new File("C:\\Program Files\\Three Rings Design\\Puzzle Pirates\\");
+                       }
+                       if(defaultLocation != null && defaultLocation.exists()) {
+                               File java_vm = new File(defaultLocation, "java_vm");
+                               if(java_vm.exists()) {
+                                       // this is where we want to install instead
+                                       java_home = new File(defaultLocation, "java_vm");
+                               }
+                       }
+               }
+               return java_home;
+       }
+       
+       /**
+       *       Installs the client.
+       */
+       private void install() throws IOException {
+               label.setText("Installing...");
+               progress.setIndeterminate(true);
+               File java_home = getJavaHome();
+               File controlPanel = new File(user_home);
+               JFileChooser chooser = new JFileChooser(controlPanel);
+               chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+               chooser.setDialogTitle("Choose location for Control Panel");
+               chooser.setApproveButtonText("Install Control Panel here");
+               int state = chooser.showOpenDialog(this);
+               if(state == JFileChooser.APPROVE_OPTION) {
+                       controlPanel = chooser.getSelectedFile();
+               } else {
+                       setButtonStatus(false,false);
+                       label.setText("Install failed!");
+                       return;
+               }
+               InputStream in = getClass().getResourceAsStream("/PCTB-ControlPanel.jar");
+               File newFile = new File(controlPanel, "PCTB-ControlPanel.jar");
+               newFile.createNewFile();
+               OutputStream out = new FileOutputStream(newFile);
+               Updater.copyFile(in, out);
+               String search = "assistive_technologies";
+               String value = "com.tedpearson.ypp.market.MarketUploader";
+               File a11y = new File(java_home,"lib/accessibility.properties");
+               boolean skipA11y = false;
+               Properties p = new Properties();
+               if(a11y.exists()) {
+                       // if already contains our modification, ignore
+                       // else add our modification
+                       p.load(new FileInputStream(a11y));
+                       String tech = p.getProperty(search);
+                       if(tech == null || tech.trim().equals("")) {
+                               // add it!
+                               p.setProperty(search, value);
+                               p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer");
+                       } else if(!tech.contains(value)) {
+                               p.setProperty(search, tech+","+value);
+                               p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer");
+                       }
+               } else {
+                       // create file with our modification
+                       a11y.createNewFile();
+                       p.setProperty(search, value);
+                       p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer");
+               }
+               
+               // install program
+               // copy jar from resource to new file in ext
+               //String installer = getClass().getProtectionDomain().getCodeSource().getLocation()
+               //      .getPath().replaceAll("%20"," ");
+               //new FileInputStream(installer);
+               in = getClass().getResourceAsStream("/PCTB-Uploader.jar");
+               newFile = new File(java_home, "lib/ext/PCTB-Uploader.jar");
+               newFile.createNewFile();
+               out = new FileOutputStream(newFile);
+               Updater.copyFile(in, out);
+               JOptionPane.showMessageDialog(this, "Install successful!\n\nWhen you open a new YPP client, you'll see\n" +
+                       "the upload client window alongside YPP.\n\n" +
+                       "To stop the window from appearing, use\n" +
+                       "the Control Panel to disable it, or uninstall.", "Success!", JOptionPane.INFORMATION_MESSAGE);
+               setButtonStatus(true,false);
+       }
+       
+       /**
+       *       Cleanup after an install, uninstall, or error. Buttons, statuses, and such
+       */
+       private void setButtonStatus(boolean installQ, boolean uninstallQ) {
+               progress.setIndeterminate(false);
+               progress.setValue(100);
+               install.setEnabled(true);
+               uninstall.setEnabled(true);
+               String q = "Quit";
+               if(installQ) {
+                       install.setText(q);
+                       installed = true;
+                       label.setText("Install complete!");
+               } else {
+                       install.setText("Install");
+                       installed = false;
+               }
+               
+               if(uninstallQ) {
+                       uninstall.setText(q);
+                       uninstalled = true;
+                       label.setText("Uninstall successful.");
+               } else {
+                       uninstall.setText("Uninstall");
+                       uninstalled = false;
+               }
+       }
+}
\ No newline at end of file