Newer
Older
KisoJikkenNWP / src / main / java / istlab / KisoJikken / App.java
@motoki miura motoki miura on 12 Sep 2023 8 KB d
package istlab.KisoJikken;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.CodeSource;
import java.security.ProtectionDomain;

import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;

/**
 * Hello world!
 */
public class App {
    public static String userhome;
    public static String userhome_escaped;
    public static String nwp = File.separator + "NWP";
    public static String nwpsrc = File.separator + "NWP" + File.separator + "src";
    public static String gitrepos = "https://git.istlab.info/git/miura250/NWP.git";
    public static String latestVersion;
    public static Path execPath;
    public static String downloadurl = "https://cit.istlab.info/KisoJikkenNWP/target/";

    public static boolean isWindows;

    static {
        userhome = System.getProperty("user.home");
        userhome_escaped = App.userhome.replaceAll("\\\\", "\\\\\\\\"); // なんじゃこの意味不明なエスケープは
                                                                        // https://stackoverflow.com/questions/1701839/string-replaceall-single-backslashes-with-double-backslashes
        String os = System.getProperty("os.name").toLowerCase();
        isWindows = os.contains("windows");
    }

    // public App() {
    // }

    public static void main(String[] args) {
        
        try {
            App.execPath = getApplicationPath(new App().getClass());
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }

        // 最新版かどうかチェック
        if (!isLatest()) {
            System.out.println("Different! " + latestVersion + " from " + execPath.getFileName().toString());
            String pathfile = download();
            if (pathfile != null) {
                int res = JOptionPane.showConfirmDialog(null, "最新版をダウンロードしました。最新版を起動しますか?", "アプリ更新",
                        JOptionPane.YES_NO_OPTION);
                if (res == JOptionPane.YES_OPTION) {
                    reboot(pathfile);
                }
            }
        }

        // ファイルがあるかチェック
        getNWPifnotexist(false);

        SwingUtilities.invokeLater(() -> {
            try {
                String laf = UIManager.getSystemLookAndFeelClassName();
                // System.out.println(laf);
                // Linuxの場合
                if (laf.endsWith("GTKLookAndFeel"))
                    laf = "javax.swing.plaf.metal.MetalLookAndFeel";
                UIManager.setLookAndFeel(laf);
            } catch (Exception e) {
                /* Never happens */ }
            new Launcher(args).setVisible(true);
        });

    }

    public static Path getApplicationPath(Class<?> cls) throws URISyntaxException {
        ProtectionDomain pd = cls.getProtectionDomain();
        CodeSource cs = pd.getCodeSource();
        URL location = cs.getLocation();
        URI uri = location.toURI();
        Path path = Paths.get(uri);
        return path;
    }

    public static boolean isLatest() {
        // 最初に、ダウンロードサイトから最新版の情報を得る
        // 更新があれば、ダウンロードし、ファイルを表示する。
        StringBuilder sb = new StringBuilder();
        latestVersion = null;
        try {
            URL url = new URL(downloadurl);
            InputStream is = url.openConnection().getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            String line = null;
            while ((line = reader.readLine()) != null) {
                if (latestVersion == null) {
                    latestVersion = line.trim();
                    System.out.println(line);
                }
                sb.append(line + "\n");
            }
            reader.close();
        } catch (Exception ex) {
        }
        // System.out.println(sb.toString());
        // 同じかどうかチェック
        // System.out.println("[" + latestVersion + "]");
        // System.out.println("=" + execPath.getFileName() + "=");
        if (execPath.getFileName().toString().equals("classes"))
            return true;
        return latestVersion.equals(execPath.getFileName().toString());
    }

    // ダウンロードして実行パーミッションをつける
    public static String download() {
        try {
            URL url = new URL(downloadurl + "/" + latestVersion);
            ReadableByteChannel readableByteChannel = Channels.newChannel(url.openStream());
            FileOutputStream fileOutputStream = new FileOutputStream(latestVersion);
            FileChannel fileChannel = fileOutputStream.getChannel();
            fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
            fileChannel.close();
            fileOutputStream.close();

            File execjar = new File(execPath.getParent().toString() + File.separator + latestVersion);
            execjar.setExecutable(true);
            return execjar.getAbsolutePath();
        } catch (Exception ex) {
        } finally {
        }
        return null;
    }

    public static void reboot(String pathfile) {
        String com;
        ProcessBuilder processBuilder;
        if (App.isWindows) {
            pathfile = pathfile.replaceAll("\\\\", "\\\\\\\\");
            com = "java -jar " + new File(pathfile).getName();
            processBuilder = new ProcessBuilder("cmd", "/c", com);
        } else {
            com = "sleep 1 ; java -jar " + pathfile;
            processBuilder = new ProcessBuilder("bash", "-c", com);
        }
        System.out.println(com);
        try {
            processBuilder.start();
        } catch (Exception ex) {
        }
        Thread t = new Thread(Launcher.theapp);
        t.start();
    }

    // public static void reboot(String pathfile) {
    // String com = "sleep 2 ; java -jar " + pathfile;
    // System.out.println(com);
    // ProcessBuilder processBuilder = new ProcessBuilder("bash", "-c", com);
    // try {
    // processBuilder.start();
    // System.exit(0);
    // } catch (Exception ex) {

    // }
    // }

    public static void getNWPifnotexist(boolean showMessageIfExist) {
        if (Files.notExists(Paths.get(userhome + nwpsrc))) {
            int res = JOptionPane.showConfirmDialog(Launcher.theapp,
                    "NWP実験用のファイルが " + userhome + nwpsrc + " にありません。ダウンロードしますか?");
            if (res == JOptionPane.YES_OPTION) {
                // JGitをもちいる
                try {
                    Git git = Git.cloneRepository()
                            .setURI(gitrepos)
                            .setDirectory(new File(userhome + nwp))
                            .call();
                } catch (GitAPIException e) {
                    JOptionPane.showMessageDialog(Launcher.theapp, "NWP実験用ファイルのダウンロード失敗しました。\n\n講義中であれば、教員を呼んでください。");
                    e.printStackTrace();
                }
                // System.out.println("cd ; git clone " + gitrepos + " を実行。");
                // ProcessBuilder processBuilder = new ProcessBuilder("git", "clone", gitrepos);
                // processBuilder.directory(new File(userhome));
                // processBuilder.inheritIO();
                // try {
                // Process process;
                // process = processBuilder.start();
                // process.waitFor();
                // } catch (IOException | InterruptedException e1) {
                // e1.printStackTrace();
                // }
            } else {
                System.out.println("cd ; git clone " + gitrepos + " を実行してください。");
                System.exit(0);
            }
        } else {
            if (showMessageIfExist)
                JOptionPane.showMessageDialog(Launcher.theapp,
                        "NWP実験用のファイルが " + userhome + nwpsrc + " にすでにあるため、ダウンロードをキャンセルしました。");
        }
    }
}