Package jsynoptic.installer

Source Code of jsynoptic.installer.PackagesPanel$TipListener

/*
* Created on 7 mai 2004
*
* To change the template for this generated file go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
package jsynoptic.installer;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import jsynoptic.installer.resources.InstallerResources;
import simtools.ui.CustomizedLocale;

/**
* @author nicolas
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
class PackagesPanel extends InstallerPanel {

  /**
   * A looger to dump error or warning messages in a soket, an output stream, a file...
   */
  static Logger _logger = simtools.util.LogConfigurator.getLogger(PackagesPanel.class.getName());

 
  protected ArrayList boxes;
  protected int numPackages;
  protected File location;
  protected JTextField tfLoc;
  protected JButton btnLoc;
  protected JEditorPane tipPane;
  protected JScrollPane tipScroll;
  protected JProgressBar progress;
  // fields protected by mutex => why can't we synchronize a field on the = current Object?
  protected boolean installFinished;
  protected Thread installThread;
  protected String os;
 
  public PackagesPanel(Installer installer) {
    super(installer);

    setLayout(new BorderLayout());
   
    boxes = new ArrayList();
   
    numPackages = Long.decode(Installer.resources.getString("numPackages")).intValue();

    // Simple OS detection => enough for our purpose to get default location
    if (File.separatorChar == '/') os = "Unix";
    else if (File.separatorChar == '\\') os = "Windows";
    else os = "Other";
   
    JPanel packSection = new JPanel(new BorderLayout());
   
    JPanel boxPanel = new JPanel(new GridLayout(numPackages, 1));
    JPanel scrollableBoxPanel = new JPanel(new BorderLayout());
   
    // Add all packages
    for (int i=1; i<=numPackages; ++i) {
      // 0 => unckecked, 1 => checked, 2 => mandatory (and thus checked)
      int defaultState = Long.decode(Installer.resources.getString("packageDefaultState"+i)).intValue();
      String name;
      try {
        name = Installer.resources.getString("packageName"+i+os);
      } catch (MissingResourceException e1) {
        name = Installer.resources.getString("packageName"+i);
      }
      JCheckBox cb = new JCheckBox(name, defaultState>=1);
      cb.addMouseListener(new TipListener("packageTip"+i));
      if (defaultState==2) cb.setEnabled(false);
      boxes.add(cb);
      cb.setAlignmentX(Component.LEFT_ALIGNMENT);
      boxPanel.add(cb);
    }
    scrollableBoxPanel.add(boxPanel, BorderLayout.NORTH);
    packSection.add(new JScrollPane(scrollableBoxPanel),BorderLayout.WEST);

    tipPane = new JEditorPane();
        tipPane.setEditable(false);
        tipPane.setAutoscrolls(false);
        tipPane.setContentType("text/html");
    tipPane.setText(Installer.resources.getString("pointPackageForDescription"));
        packSection.add(tipScroll = new JScrollPane(tipPane),BorderLayout.CENTER);

        packSection.add(progress = new JProgressBar(), BorderLayout.SOUTH);
       
    add(packSection,BorderLayout.CENTER);
   
    Box hbox = Box.createHorizontalBox();
    hbox.add(new JLabel(Installer.resources.getString("location")));
   
    location = new File(Installer.resources.getString("defaultLocation"+os));
   
    hbox.add(tfLoc = new JTextField());
    updateLoc();
    Dimension d = tfLoc.getPreferredSize();
    d.width = getWidth();
    tfLoc.setMaximumSize(d);
    hbox.add(btnLoc = new JButton(Installer.resources.getString("chooseLocation")));

    add(hbox,BorderLayout.SOUTH);
   
    btnLoc.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        JFileChooser fc = new JFileChooser(location);
        fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        int res = fc.showOpenDialog(PackagesPanel.this.installer);
        if (res==JFileChooser.APPROVE_OPTION) {
          // first choose selection
          location = fc.getSelectedFile();
          // if user entered directory but no selection, choose it instead
          if (location==null) location = fc.getCurrentDirectory();
          updateLoc();
        }
      }
    });

    installFinished = false;
    installThread = null;
   
  }
 
  /* (non-Javadoc)
   * @see jsynoptic.installer.InstallerPanel#process()
   */
  public boolean process() {
    boolean run = false;
    synchronized(this) {
      if (installFinished) run = true;
      else {
        if (installThread!=null) return false;
        installThread = new Thread() {
          public void run() {
            install();
          }
        };
      }
    }
    if (run) {
      runJSynoptic();
      return true;
    }
    installThread.start();
    return false;
  }
 
  protected void runJSynoptic() {
    new Thread() {
      public void run() {
        installer.writeProperties();
        location.getAbsolutePath();
       
        File jsynoptic;
        if (os.equals("Unix")) jsynoptic = new File(location,"jsynoptic.sh");
        else if (os.equals("Windows")) jsynoptic = new File(location,"jsynoptic.exe");
        else jsynoptic = null;
       
        if ((jsynoptic!=null) && jsynoptic.exists()) {
          try {
            Runtime.getRuntime().exec(jsynoptic.getAbsolutePath());
            // terminate this JVM, the other process should run in parallel
            System.exit(0);
          } catch (IOException e1) {
            // see below
          }
        }

        ResourceBundle runRes = ResourceBundle.getBundle("jsynoptic.ui.resources.RunResources",CustomizedLocale.get());
       
        // try manually run the jar file from this JVM
        // of course, this supposes the jar file is present
        File jsynJar = new File(location,"jsynoptic-" + runRes.getString("productVersion") + ".jar");
        if (!jsynJar.exists()) {
          JOptionPane.showMessageDialog(
              installer,
              Installer.resources.getString("cantFindJSynoptic"),
              Installer.resources.getString("errorInInstall"),
              JOptionPane.ERROR_MESSAGE
          );
          return;
        }
       
        // remove this installer
        installer.dispose();
       
        // Now the fun part => run jsynoptic
        // first add the jsynoptic jar file to the classpath
        URLClassLoader sysloader = (URLClassLoader)ClassLoader.getSystemClassLoader();
        Method method;
        try {
          method = URLClassLoader.class.getDeclaredMethod("addURL",new Class[]{URL.class});
          method.setAccessible(true);
          method.invoke(sysloader,new Object[]{ jsynJar.toURL() });

          // So, jsynoptic jar should be added in the class path now
          method = Class.forName("jsynoptic.ui.Run").getDeclaredMethod("main",new Class[]{String[].class});
          // invoke the main function
          method.invoke(null,new Object[]{new String[]{}});

          // Main exited but JSynoptic main window sould be present
          // since the installer window is out, JSynoptic should be in charge now
         
        } catch (Exception e) {
          // window already destroyed => use err channel
          System.err.println(Installer.resources.getString("installErrorIs")+e.getLocalizedMessage());
          System.err.println(Installer.resources.getString("errorInInstall"));
          System.exit(1); // bad luck :-(
        }
       
       
      }
    }.start();
  }

  public void install() {

    location = new File(tfLoc.getText());
   
    if (!location.exists()) {
      location.mkdirs();
    }
   
    if (!location.isDirectory())
      location = new File(location.getParentFile(), "jsynoptic");


    tfLoc.setText(location.getAbsolutePath());

    boolean overwriteAll = false;
    byte[] data = new byte[4096]; // small array allows progress bar to move
   
    installer.previous.setEnabled(false);
    installer.next.setEnabled(false);
    tfLoc.setEnabled(false);
    btnLoc.setEnabled(false);

    try {
      // Install all checked packages
      for (int i=1; i<=numPackages; ++i) {
        JCheckBox cb = (JCheckBox)boxes.get(i-1);
        if (!cb.isSelected()) continue;
       
        cb.setBackground(Color.red);
       
        String zipName;
        try {
            if (installer.jre==null) {
                try {
                    zipName = Installer.resources.getString("packageZip"+i+os+"NoJRE");
                } catch (MissingResourceException e) {
                    zipName = Installer.resources.getString("packageZip"+i+os);
                }
            } else {
                zipName = Installer.resources.getString("packageZip"+i+os);
            }
       
        } catch (MissingResourceException e1) {
          zipName = Installer.resources.getString("packageZip"+i);
        }
        InputStream is = InstallerResources.class.getResourceAsStream(zipName);
        if (is==null) throw new IOException();
        ZipInputStream zip = new ZipInputStream(is);
        ZipEntry entry;
        while ((entry = zip.getNextEntry()) != null) {

          File f = new File(location, entry.getName());
          if (entry.isDirectory()) {
            f.mkdirs(); // TODO: handle installation failed
            continue;
          }
          if (f.exists() && (!overwriteAll)) {
            Object[] options = new Object[] {
              Installer.resources.getString("yes"),
              Installer.resources.getString("yesAll"),
              Installer.resources.getString("no"),
              Installer.resources.getString("cancel"),
            };
            int res = JOptionPane.showOptionDialog(
                installer,
                Installer.resources.getString("overwriteFile")+f.getAbsolutePath(),
                Installer.resources.getString("overwriteTitle"),
                JOptionPane.DEFAULT_OPTION,
                JOptionPane.QUESTION_MESSAGE,
                null,
                options,
                options[0]);

            if (res==2) continue;
            if ((res==JOptionPane.CLOSED_OPTION) || (res == 3)) break; // TODO: handle installation failed
            if (res==1) overwriteAll = true;
          }
          long size = entry.getSize();
          if (size!=-1) {
            progress.setIndeterminate(false);
            progress.setMinimum(0);     
            progress.setMaximum((int)size);
            progress.setValue(0);
          }
          else progress.setIndeterminate(true);
          progress.setString(f.getAbsolutePath());
          progress.setStringPainted(true);

          FileOutputStream fos = new FileOutputStream(f);
          int nread;
          while ((nread = zip.read(data)) !=-1) {
            fos.write(data,0,nread);
            try {
              SwingUtilities.invokeAndWait(new BarUpdater(nread));
            } catch (InterruptedException e1) {
            } catch (InvocationTargetException e1) {
            }
          }
          fos.flush();
          fos.close();
        }
       
        cb.setBackground(Color.green);
      }
     
      // Extract JRE from installer's ZIP if present => gives feedback
      if (installer.zip!=null) {
        ZipFile zip = new ZipFile(installer.zip);
        ZipEntry entry = zip.getEntry("jre");
       
        // Overkill: entry exists and was checked by the installer main function
        if (entry==null) throw new IOException("Internal Error!");
       
        Enumeration enumEntries = zip.entries();
        while (enumEntries.hasMoreElements()) {
         
          entry = (ZipEntry)enumEntries.nextElement();
          if (!entry.getName().startsWith("jre")) continue;

          File f = new File(location, entry.getName());
          if (entry.isDirectory()) {
            f.mkdirs(); // TODO: handle installation failed
            continue;
          }
          if (f.exists() && (!overwriteAll)) {
            Object[] options = new Object[] {
              Installer.resources.getString("yes"),
              Installer.resources.getString("yesAll"),
              Installer.resources.getString("no"),
              Installer.resources.getString("cancel"),
            };
            int res = JOptionPane.showOptionDialog(
                installer,
                Installer.resources.getString("overwriteFile")+f.getAbsolutePath(),
                Installer.resources.getString("overwriteTitle"),
                JOptionPane.DEFAULT_OPTION,
                JOptionPane.QUESTION_MESSAGE,
                null,
                options,
                options[0]);

            if (res==2) continue;
            if ((res==JOptionPane.CLOSED_OPTION) || (res == 3)) break; // TODO: handle installation failed
            if (res==1) overwriteAll = true;
          }
          long size = entry.getSize();
          if (size!=-1) {
            progress.setIndeterminate(false);
            progress.setMinimum(0);     
            progress.setMaximum((int)size);
            progress.setValue(0);
          }
          else progress.setIndeterminate(true);
          progress.setString(Installer.resources.getString("installingJRE")+" : "+f.getAbsolutePath());
          progress.setStringPainted(true);

          FileOutputStream fos = new FileOutputStream(f);
          InputStream zipStream = zip.getInputStream(entry);
          int nread;
          while ((nread = zipStream.read(data)) !=-1) {
            fos.write(data,0,nread);
            try {
              SwingUtilities.invokeAndWait(new BarUpdater(nread));
            } catch (InterruptedException e1) {
            } catch (InvocationTargetException e1) {
            }
          }
          fos.flush();
          fos.close();
        }
        zip.close();
      }
     
      // Else copy file by file the JRE directory
      else if (installer.jre!=null) {
        progress.setMinimum(0);     
        progress.setMaximum(1);     
        progress.setValue(0);
        try {
          SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
              progress.setIndeterminate(true);
              progress.setString(Installer.resources.getString("installingJRE"));
            }
          });
        } catch (InterruptedException e1) {
        } catch (InvocationTargetException e1) {
        }
        copy(installer.jre, location);
        try {
          SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
              progress.setIndeterminate(false);
              progress.setValue(1);
            }
          });
        } catch (InterruptedException e1) {
        } catch (InvocationTargetException e1) {
        }
      }

      // Unix permissions for executable files
      if (os.equals("Unix")) {
       
        File chmod = new File("/usr/bin/chmod");
        if (!chmod.exists()) chmod = new File("/bin/chmod");
        if (!chmod.exists()) chmod = new File("/usr/local/bin/chmod");
        if (!chmod.exists()) chmod = new File("/sbin/chmod");
        if (!chmod.exists()) chmod = new File("/usr/sbin/chmod");
        if (!chmod.exists()) chmod = new File("/usr/local/sbin/chmod");

        if (chmod.exists()) {
          String cmd = chmod.getAbsolutePath() + " +x ";

          // Permission for launch script => mandatory package, always present
          File jsynoptic = new File(location,"jsynoptic.sh");
          if (jsynoptic.exists()) Runtime.getRuntime().exec(cmd + jsynoptic.getAbsolutePath());
         
          File jreBinDir = new File(new File(location, "jre"),"bin");
          if (jreBinDir.exists()) {
            File[] binaries = jreBinDir.listFiles();
            for (int i=0; i<binaries.length; ++i) {
              Runtime.getRuntime().exec(cmd + binaries[i].getAbsolutePath());
            }
          }
         
          // Also make the JSynoptic run script executable
          Runtime.getRuntime().exec(cmd + "jsynoptic.sh");
        }
       
      }
     
     
    } catch (IOException e) {
      installer.previous.setEnabled(true);
      installer.next.setEnabled(true);
      tfLoc.setEnabled(true);
      btnLoc.setEnabled(true);

      JOptionPane.showMessageDialog(
          installer,
          Installer.resources.getString("installErrorIs")+e.getLocalizedMessage(),
          Installer.resources.getString("errorInInstall"),
          JOptionPane.ERROR_MESSAGE
      );
      synchronized(this) {
        installFinished = false;
        installThread = null;
      }
      return;
    }
   
    synchronized(this) {
      installFinished = true;
      progress.setString(Installer.resources.getString("installComplete"));
      installer.next.setText(Installer.resources.getString("run"));
      installer.cancel.setText(Installer.resources.getString("dontRun"));
      ActionListener[] listeners = installer.cancel.getActionListeners();
      for (int i=0; i<listeners.length; ++i) installer.cancel.removeActionListener(listeners[i]);
      installer.cancel.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          installer.writeProperties();
          System.exit(0);
        }
      });
      installer.next.setEnabled(true);
    }
  }
 
  /**
   * Recursive copy of file1 to file2, including subdirectories
   * @param src A file or directory to copy recursively
   * @param dest The name of the destination file if src is actually a file. In case dest is a directory, src will be copied in this directory with the same name.
   * @throws IOException if an error occurs, and in particular if src or dest refers to a non existent file or directory
   */
  protected void copy(File src, File dest) throws IOException {
    if (src.isDirectory() && dest.isFile()) throw new IOException("Cannot copy a directory to a file");
    if (src.isDirectory()) {
      // so, location is a direcory too
      // Create an empty dir
      File newDir = new File(dest, src.getName());
      if (!newDir.mkdirs()) throw new IOException("Cannot create a new Directory");
      // recursively copy all entries in the new dir
      File[] entries = src.listFiles();
      for (int i=0; i<entries.length; ++i) copy(entries[i],newDir);
      return;
    }
    // So, f is a file
    if (dest.isDirectory()) {
      // Create a new file of that name in the empty directory
      File newFile = new File(dest, src.getName());
      newFile.createNewFile();
      // Use copy in the last case : file to file
      copy(src,newFile);
      return;
    }
    try {
      // file to file transfer
      if (src.length()==0) {
        dest.createNewFile();
        return;
      }
      // transfering >0 bytes
      FileChannel fc = new FileInputStream(src).getChannel();
      FileChannel dstChannel = new FileOutputStream(dest).getChannel();
      long transfered = 0;
      long totalLength = src.length();
      while (transfered < totalLength) {
        long num = fc.transferTo(transfered,totalLength-transfered,dstChannel);
        if (num==0) throw new IOException("Error while copying");
        transfered += num;
      }
      dstChannel.close();
      fc.close();
    } catch (IOException e) {
      if (os.equals("Unix")) {
       
        _logger.fine("Trying to use cp to copy file...");
       
        File cp = new File("/usr/bin/cp");
        if (!cp.exists()) cp = new File("/bin/cp");
        if (!cp.exists()) cp = new File("/usr/local/bin/cp");
        if (!cp.exists()) cp = new File("/sbin/cp");
        if (!cp.exists()) cp = new File("/usr/sbin/cp");
        if (!cp.exists()) cp = new File("/usr/local/sbin/cp");

        if (cp.exists()) {
          Process cpProcess = Runtime.getRuntime().exec(cp.getAbsolutePath() + " '" + src.getAbsolutePath() + "' '"+dest.getAbsolutePath()+"'");
          int errCode;
          try {
            errCode = cpProcess.waitFor();
          } catch (java.lang.InterruptedException ie) {
            throw e;
          }
          return;
        }
      }
      throw e;
    }
  }

  protected class BarUpdater implements Runnable {
    int delta;
    public BarUpdater(int delta) {
      this.delta = delta;
    }
    public void run() {
      progress.setValue(progress.getValue()+delta);
    }
  }
 
  protected void updateLoc() {
    try {
      tfLoc.setText(location.getCanonicalPath());
    } catch (IOException e) {
      tfLoc.setText(location.getAbsolutePath());
    }
  }

  public void update() {
    synchronized(this) {
      if (installFinished) {
        installer.next.setText(Installer.resources.getString("run"));
        installer.cancel.setText(Installer.resources.getString("dontRun"));
        installer.previous.setEnabled(false);
      }
      else {
        installer.next.setText(Installer.resources.getString("install"));
        installer.cancel.setText(Installer.resources.getString("cancel"));
      }
    }
    setBorder(BorderFactory.createTitledBorder(Installer.resources.getString("selectPackages")));
    // update all packages with current lang
    for (int i=1; i<=numPackages; ++i) {
      JCheckBox cb = (JCheckBox)boxes.get(i-1);
      String name;
      try {
        name = Installer.resources.getString("packageName"+i+os);
      } catch (MissingResourceException e1) {
        name = Installer.resources.getString("packageName"+i);
      }
      cb.setText(name);
    }
    tipPane.setText(Installer.resources.getString("pointPackageForDescription"));
    progress.setMinimum(0);     
    progress.setMaximum(1);     
    progress.setValue(0);
    progress.setStringPainted(false);
  }
 
  protected class TipListener extends MouseAdapter {
    protected String key;
   
    // store key, not text, because lang may change => force get text from resources each time
    public TipListener(String resourceKey) {
      key = resourceKey;
    }
   
    public void mouseEntered(MouseEvent e) {
      String text;
      try {
        text = Installer.resources.getString(key+os);
      } catch (MissingResourceException e1) {
        text = Installer.resources.getString(key);
      }
      tipPane.setText(text);
      JScrollBar sb = tipScroll.getVerticalScrollBar();
      if (sb!=null) sb.setValue(sb.getMinimum());
    }
  }
}


TOP

Related Classes of jsynoptic.installer.PackagesPanel$TipListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.