Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package ca.weblite.jdeploy; import com.codename1.io.JSONParser; import com.codename1.processing.Result; import com.codename1.xml.Element; import com.codename1.xml.XMLParser; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.net.URL; import java.net.URLClassLoader; import java.nio.file.PathMatcher; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.Set; import java.util.Timer; import java.util.TimerTask; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.commons.io.FileUtils; /** * * @author shannah */ public class JDeploy { private final File directory; private File packageJsonFile; private Map packageJsonMap; private Result packageJsonResult; public class CopyRule { String dir; List<String> includes; List<String> excludes; public CopyRule(String dir, List<String> includes, List<String> excludes) { this.dir = dir; this.includes = includes; this.excludes = excludes; } public CopyRule(String dir, String includes, String excludes) { this.dir = dir; this.includes = includes == null ? null : Arrays.asList(includes.split(",")); this.excludes = excludes == null ? null : Arrays.asList(excludes.split(",")); } public String toString() { return "CopyRule{dir=" + dir + ", includes=" + includes + ", excludes=" + excludes + "}"; } public void copyTo(File destDirectory) throws IOException { System.out.println("Executing copy rule " + this); final File srcDir = new File(dir); if (!srcDir.exists()) { throw new IOException("Source directory of copy rule does not exist: " + srcDir); } if (!destDirectory.exists()) { throw new IOException("Destination directory of copy rule does not exist: " + destDirectory); } if (srcDir.equals(destDirectory)) { System.err.println("Copy rule has same srcDir and destDir. Not copying: " + srcDir); return; } final Set<String> includedDirectories = new HashSet<String>(); FileUtils.copyDirectory(srcDir, destDirectory, new FileFilter() { @Override public boolean accept(File pathname) { if (pathname.isDirectory()) { for (File child : pathname.listFiles()) { if (this.accept(child)) { return true; } } } File parent = pathname.getParentFile(); if (parent != null && includedDirectories.contains(parent.getPath())) { if (pathname.isDirectory()) { includedDirectories.add(pathname.getPath()); } return true; } if (excludes != null) { for (String pattern : excludes) { PathMatcher matcher = srcDir.toPath().getFileSystem() .getPathMatcher("glob:" + dir + "/" + pattern.replace("\\", "/")); if (matcher.matches(pathname.toPath())) { return false; } } } if (includes != null) { for (String pattern : includes) { PathMatcher matcher = srcDir.toPath().getFileSystem() .getPathMatcher("glob:" + dir + "/" + pattern.replace("\\", "/")); if (matcher.matches(pathname.toPath())) { if (pathname.isDirectory()) { includedDirectories.add(pathname.getPath()); } return true; } } System.out.println(pathname + " does not match any patterns."); return false; } else { if (pathname.isDirectory()) { includedDirectories.add(pathname.getPath()); } return true; } } }); } } public JDeploy(File directory) { this.directory = directory; } public File getDirectory() { return directory; } public File getPackageJsonFile() { if (packageJsonFile == null) { packageJsonFile = new File(directory, "package.json"); } return packageJsonFile; } private File f() { return getPackageJsonFile(); } public Map getPackageJsonMap() { if (packageJsonMap == null) { try { JSONParser p = new JSONParser(); packageJsonMap = (Map) p .parseJSON(new StringReader(FileUtils.readFileToString(getPackageJsonFile(), "UTF-8"))); } catch (IOException ex) { Logger.getLogger(JDeploy.class.getName()).log(Level.SEVERE, null, ex); throw new RuntimeException(ex); } } return packageJsonMap; } private Map m() { return getPackageJsonMap(); } private Map mj() { if (!m().containsKey("jdeploy")) { m().put("jdeploy", new HashMap()); } return (Map) m().get("jdeploy"); } private Result rj() { return Result.fromContent(mj()); } public Result getPackageJsonResult() { if (packageJsonResult == null) { packageJsonResult = Result.fromContent(getPackageJsonMap()); } return packageJsonResult; } private Result r() { return getPackageJsonResult(); } public void savePackageJson() throws IOException { FileUtils.writeStringToFile(getPackageJsonFile(), getPackageJsonResult().toString(), "UTF-8"); packageJsonMap = null; packageJsonResult = null; } public void set(String property, String value) { mj().put(property, value); } public void set(String property, int value) { mj().put(property, value); } public void set(String property, List value) { mj().put(property, value); } public String getString(String property, String defaultValue) { if (mj().containsKey(property)) { return r().getAsString("jdeploy/" + property); } return defaultValue; } public int getInt(String property, int defaultValue) { if (mj().containsKey(property)) { return r().getAsInteger("jdeploy/" + property); } return defaultValue; } public List getList(String property, boolean defaultEmptyList) { if (mj().containsKey(property)) { return r().getAsArray("jdeploy/" + property); } return defaultEmptyList ? new ArrayList() : null; } public int getPort(int defaultValue) { return getInt("port", defaultValue); } public void setPort(int port) { set("port", port); } public String getWar(String defaultVal) { return getString("war", defaultVal); } public void setWar(String war) { set("war", war); } public String getJar(String defaultVal) { return getString("jar", defaultVal); } public void setJar(String jar) { set("jar", jar); } public String getClassPath(String defaultVal) { return getString("classPath", defaultVal); } public void setClassPath(String cp) { set("classPath", cp); } public String getMainClass(String defaultVal) { return getString("mainClass", defaultVal); } public void setMainClass(String mainClass) { set("mainClass", mainClass); } public List<CopyRule> getFiles() { List files = getList("files", true); List<CopyRule> out = new ArrayList<CopyRule>(); for (Object o : files) { if (o instanceof Map) { Map m = (Map) o; String dir = (String) m.get("dir"); ArrayList<String> incs = null; if (m.containsKey("includes")) { Object i = m.get("includes"); incs = new ArrayList<String>(); if (i instanceof List) { incs.addAll((List<String>) i); } else if (i instanceof String) { incs.addAll(Arrays.asList(((String) i).split(","))); } } ArrayList<String> excs = null; if (m.containsKey("excludes")) { Object i = m.get("excludes"); excs = new ArrayList<String>(); if (i instanceof List) { excs.addAll((List<String>) i); } else if (i instanceof String) { excs.addAll(Arrays.asList(((String) i).split(","))); } } out.add(new CopyRule(dir, incs, excs)); } else if (o instanceof String) { out.add(new CopyRule((String) o, (String) null, (String) null)); } } return out; } public void setPreCopyScript(String preScript) { set("preCopyScript", preScript); } public String getPreCopyScript(String defaultValue) { return getString("preCopyScript", defaultValue); } public void setPostCopyScript(String postScript) { set("postCopyScript", postScript); } public String getPostCopyScript(String defaultValue) { return getString("postCopyScript", defaultValue); } public void setPreCopyTarget(String preScript) { set("preCopyTarget", preScript); } public String getPreCopyTarget(String defaultValue) { return getString("preCopyTarget", defaultValue); } public void setPostCopyTarget(String postScript) { set("postCopyTarget", postScript); } public String getPostCopyTarget(String defaultValue) { return getString("postCopyTarget", defaultValue); } public void setAntFile(String antFile) { set("antFile", antFile); } public String getAntFile(String defaultVal) { return getString("antFile", defaultVal); } public String getBinDir() { return "jdeploy-bundle"; } public String getBinName() { if (m().containsKey("bin")) { Map<String, String> bins = (Map<String, String>) m().get("bin"); for (String binName : bins.keySet()) { if ((getBinDir() + "/jdeploy.js").equals(bins.get(binName))) { return binName; } } } return null; } private int runScript(String script) throws IOException { try { ProcessBuilder pb = new ProcessBuilder(); pb.command(script); Process p = pb.start(); return p.waitFor(); } catch (InterruptedException ex) { Logger.getLogger(JDeploy.class.getName()).log(Level.SEVERE, null, ex); return 1; } } private int runAntTask(String antFile, String target) throws IOException { try { ProcessBuilder pb = new ProcessBuilder(); pb.command("ant", "-f", antFile, target); Process p = pb.start(); return p.waitFor(); } catch (InterruptedException ex) { Logger.getLogger(JDeploy.class.getName()).log(Level.SEVERE, null, ex); return 1; } } static String convertStreamToString(java.io.InputStream is) { java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A"); return s.hasNext() ? s.next() : ""; } public File findJarFile() { if (getJar(null) != null) { File jarFile = new File(getJar(null)); if (!jarFile.exists() && jarFile.getParentFile().exists()) { // Jar file might be a glob try { PathMatcher matcher = jarFile.getParentFile().toPath().getFileSystem() .getPathMatcher(jarFile.getName()); for (File f : jarFile.getParentFile().listFiles()) { if (matcher.matches(f.toPath())) { jarFile = f; break; } } } catch (IllegalArgumentException ex) { // just eat this } if (!jarFile.exists()) { return null; } } return jarFile; } return null; } public File findWarFile() { if (getWar(null) != null) { File warFile = new File(getWar(null)); if (!warFile.exists() && warFile.getParentFile().exists()) { // Jar file might be a glob PathMatcher matcher = warFile.getParentFile().toPath().getFileSystem() .getPathMatcher(warFile.getName()); for (File f : warFile.getParentFile().listFiles()) { if (matcher.matches(f.toPath())) { warFile = f; break; } } if (!warFile.exists()) { return null; } } return warFile; } return null; } private String[] findClassPath(File jarFile) throws IOException { Manifest m = new JarFile(jarFile).getManifest(); //System.out.println(m.getEntries()); String cp = m.getMainAttributes().getValue(Attributes.Name.CLASS_PATH); //System.out.println("Class path is "+cp); if (cp != null) { return cp.split(" "); } else { return new String[0]; } } public void loadDefaults() throws IOException { } private File[] findJarCandidates() throws IOException { File[] jars = findCandidates(directory.toPath().getFileSystem().getPathMatcher("glob:**/*.jar")); List<File> out = new ArrayList<File>(); // We only want executable jars for (File f : jars) { Manifest m = new JarFile(f).getManifest(); //System.out.println(m.getEntries()); if (m != null) { Attributes atts = m.getMainAttributes(); if (atts.containsKey(Attributes.Name.MAIN_CLASS)) { //executable jar out.add(f); } } } return out.toArray(new File[out.size()]); } private File findBestCandidate() throws IOException { File[] jars = findJarCandidates(); File[] wars = findWarCandidates(); File[] webApps = findWebAppCandidates(); List<File> combined = new ArrayList<File>(); combined.addAll(Arrays.asList(jars)); combined.addAll(Arrays.asList(wars)); combined.addAll(Arrays.asList(webApps)); return shallowest(combined.toArray(new File[combined.size()])); } private File[] findWarCandidates() { return findCandidates(directory.toPath().getFileSystem().getPathMatcher("glob:**.war")); } private File[] findWebAppCandidates() { List<File> out = new ArrayList<File>(); findWebAppCandidates(directory, out); return out.toArray(new File[out.size()]); } private void findWebAppCandidates(File root, List<File> matches) { if (".".equals(root.getName()) && root.getParentFile() != null) { root = root.getParentFile(); } if ("WEB-INF".equals(root.getName()) && root.isDirectory() && root.getParentFile() != null) { matches.add(root.getParentFile()); } else if (root.isDirectory()) { if (root.getName().startsWith(".") || excludedDirectoriesForJarAndWarSearches.contains(root.getName())) { return; } for (File f : root.listFiles()) { findWebAppCandidates(f, matches); } } } private File[] findCandidates(PathMatcher matcher) { List<File> out = new ArrayList<File>(); //PathMatcher matcher = directory.toPath().getFileSystem().getPathMatcher("glob:**.jar"); findCandidates(directory, matcher, out); return out.toArray(new File[out.size()]); } private static final List<String> excludedDirectoriesForJarAndWarSearches = new ArrayList<String>(); static { final String[] l = new String[] { "src", "jdeploy-bundle", "node_modules" }; excludedDirectoriesForJarAndWarSearches.addAll(Arrays.asList(l)); } private File shallowest(File[] files) { File out = null; int depth = -1; for (File f : files) { int fDepth = f.getPath().split(Pattern.quote("\\") + "|" + Pattern.quote("/")).length; if (out == null || fDepth < depth) { depth = fDepth; out = f; } } return out; } private void findCandidates(File root, PathMatcher matcher, List<File> matches) { if (".".equals(root.getName()) && root.getParentFile() != null) { root = root.getParentFile(); } //System.out.println("Checking "+root+" for "+matcher); if (matcher.matches(root.toPath())) { matches.add(root); } if (root.isDirectory()) { if (root.getName().startsWith(".") || excludedDirectoriesForJarAndWarSearches.contains(root.getName())) { return; } for (File f : root.listFiles()) { findCandidates(f, matcher, matches); } } } public void copyToBin() throws IOException { loadDefaults(); if (getPreCopyScript(null) != null) { int code = 0; if ((code = runScript(getPreCopyScript(null))) != 0) { System.err.println("Pre-copy script failed."); System.exit(code); } } File antFile = new File(getAntFile("build.xml")); if (antFile.exists() && getPreCopyTarget(null) != null) { int code = runAntTask(getAntFile("build.xml"), getPreCopyTarget(null)); if (code != 0) { System.err.println("Pre-copy ant task failed"); System.exit(code); } } // Actually copy the files List<CopyRule> includes = getFiles(); /* if (includes.isEmpty()) { File distDir = new File("dist"); if (distDir.exists()) { File distLib = new File(distDir, "lib"); includes.add(new CopyRule("dist", "*.jar", null)); if (distLib.exists()) { includes.add(new CopyRule("dist", "lib/*.jar", null)); } } File targetDir = new File("target"); if (targetDir.exists()) { includes.add(new CopyRule("target", "*.jar", null)); } }*/ File bin = new File(getBinDir()); bin.mkdir(); if (getJar(null) == null && getWar(null) == null) { // no jar or war explicitly specified... need to scan System.out.println( "No jar, war, or web app explicitly specified. Scanning directory to find best candidate."); File best = findBestCandidate(); System.out.println("Found " + best); System.out.println( "To explicitly set the jar, war, or web app to build, use the \"war\" or \"jar\" property of the \"jdeploy\" section of the package.json file."); if (best == null) { } else if (best.getName().endsWith(".jar")) { setJar(best.getPath()); } else { setWar(best.getPath()); } } if (getJar(null) != null) { // We need to include the jar at least File jarFile = findJarFile(); if (jarFile == null) { throw new IOException("Could not find jar file: " + getJar(null)); } String parentPath = jarFile.getParentFile() != null ? jarFile.getParentFile().getPath() : "."; includes.add(new CopyRule(parentPath, jarFile.getName(), null)); for (String path : findClassPath(jarFile)) { includes.add(new CopyRule(parentPath, path, null)); } } else if (getWar(null) != null) { File warFile = findWarFile(); if (warFile == null) { throw new IOException("Could not find war file: " + getWar(null)); } String parentPath = warFile.getParentFile() != null ? warFile.getParentFile().getPath() : "."; includes.add(new CopyRule(parentPath, warFile.getName(), null)); //if (warFile.isDirectory()) { // includes.add(new CopyRule(parentPath, warFile.getName()+"/**", null)); //} } else { throw new RuntimeException("No jar, war, or web app was found to build in this directory."); } if (includes.isEmpty()) { throw new RuntimeException("No files were found to include in the bundle"); } // Now actually copy the files for (CopyRule r : includes) { try { r.copyTo(bin); } catch (Exception ex) { System.err.println("Failed to copy to " + bin + " with rule " + r); System.err.println("Files: " + includes); throw ex; } } if (getWar(null) != null) { bundleJetty(); } bundleJdeploy(); if (getPostCopyScript(null) != null) { int code = 0; if ((code = runScript(getPostCopyScript(null))) != 0) { System.err.println("Post-copy script failed."); System.exit(code); } } if (antFile.exists() && getPostCopyTarget(null) != null) { int code = runAntTask(getAntFile("build.xml"), getPostCopyTarget(null)); if (code != 0) { System.err.println("Post-copy ant task failed"); System.exit(code); } } } public void bundleJetty() throws IOException { // Now we need to create the stub. File bin = new File(getBinDir()); //File pkgPath = new File(bin, "ca"+File.separator+"weblite"+File.separator+"jdeploy"); //pkgPath.mkdirs(); //File stubFile = new File(bin, "WarRunner.jar"); InputStream warRunnerInput = getClass().getResourceAsStream("WarRunner.jar"); //FileUtils.copyInputStreamToFile(warRunnerInput, stubFile); //String stubFileSrc = FileUtils.readFileToString(stubFile, "UTF-8"); //stubFileSrc = stubFileSrc.replace("{{PORT}}", String.valueOf(getPort(0))); //stubFileSrc = stubFileSrc.replace("{{WAR_PATH}}", new File(getWar(null)).getName()); //FileUtils.writeStringToFile(stubFile, stubFileSrc, "UTF-8"); InputStream jettyRunnerJarInput = getClass().getResourceAsStream("jetty-runner.jar"); File libDir = new File(bin, "lib"); libDir.mkdir(); File jettyRunnerDest = new File(libDir, "jetty-runner.jar"); File warRunnerDest = new File(libDir, "WarRunner.jar"); FileUtils.copyInputStreamToFile(jettyRunnerJarInput, jettyRunnerDest); FileUtils.copyInputStreamToFile(warRunnerInput, warRunnerDest); /* ProcessBuilder javac = new ProcessBuilder(); javac.inheritIO(); javac.directory(bin); javac.command("javac", "-cp", "lib/jetty-runner.jar", "ca" + File.separator + "weblite" + File.separator + "jdeploy" + File.separator + "WarRunner.java"); Process javacP = javac.start(); int javacResult=0; try { javacResult = javacP.waitFor(); } catch (InterruptedException ex) { Logger.getLogger(JDeploy.class.getName()).log(Level.SEVERE, null, ex); throw new IOException(ex); } if (javacResult != 0) { System.exit(javacResult); } */ setMainClass("ca.weblite.jdeploy.WarRunner"); setClassPath("." + File.pathSeparator + "lib/jetty-runner.jar" + File.pathSeparator + "lib/WarRunner.jar"); } public void bundleJdeploy() throws IOException { File bin = new File(getBinDir()); InputStream jdeployJs = this.getClass().getResourceAsStream("jdeploy.js"); File jDeployFile = new File(bin, "jdeploy.js"); FileUtils.copyInputStreamToFile(jdeployJs, jDeployFile); String jdeployContents = FileUtils.readFileToString(jDeployFile, "UTF-8"); jdeployContents = processJdeployTemplate(jdeployContents); FileUtils.writeStringToFile(jDeployFile, jdeployContents, "UTF-8"); } public String processJdeployTemplate(String jdeployContents) { jdeployContents = jdeployContents.replace("{{PORT}}", String.valueOf(getPort(0))); if (getWar(null) != null) { jdeployContents = jdeployContents.replace("{{WAR_PATH}}", new File(getWar(null)).getName()); } else { jdeployContents = jdeployContents.replace("{{WAR_PATH}}", ""); } if (getJar(null) != null) { File jarFile = findJarFile(); if (jarFile == null) { throw new RuntimeException("Could not find jar file: " + getJar(null)); } jdeployContents = jdeployContents.replace("{{JAR_NAME}}", findJarFile().getName()); } else if (getMainClass(null) != null) { jdeployContents = jdeployContents.replace("{{CLASSPATH}}", getClassPath(".")); jdeployContents = jdeployContents.replace("{{MAIN_CLASS}}", getMainClass(null)); } else { throw new RuntimeException("No main class or jar specified. Cannot fill template"); } return jdeployContents; } public void initPackageJson() { } public void updatePackageJson() { } public static boolean isAlive(Process p) { try { p.exitValue(); return false; } catch (IllegalThreadStateException e) { return true; } } private String getRelativePath(File f) { return directory.toURI().relativize(f.toURI()).getPath(); } private void updatePackageJson(String commandName) throws IOException { File candidate = findBestCandidate(); if (commandName == null) { if (candidate == null) { } else if (candidate.getName().endsWith(".jar") || candidate.getName().endsWith(".war")) { commandName = candidate.getName().substring(0, candidate.getName().lastIndexOf(".")).toLowerCase(); } else { commandName = candidate.getName().toLowerCase(); } } File packageJson = new File(directory, "package.json"); System.err.println("A package.json file already exists. Updating mandatory fields..."); JSONParser p = new JSONParser(); String str = FileUtils.readFileToString(packageJson, "UTF-8"); Map pj = (Map) p.parseJSON(new StringReader(str)); if (!pj.containsKey("bin")) { pj.put("bin", new HashMap()); } Map bin = (Map) pj.get("bin"); if (bin.isEmpty()) { bin.put(commandName, getBinDir() + "/jdeploy.js"); } if (!pj.containsKey("dependencies")) { pj.put("dependencies", new HashMap()); } Map deps = (Map) pj.get("dependencies"); deps.put("shelljs", "^0.7.5"); if (!pj.containsKey("jdeploy")) { pj.put("jdeploy", new HashMap()); } Map jdeploy = (Map) pj.get("jdeploy"); if (candidate != null && !jdeploy.containsKey("war") && !jdeploy.containsKey("jar")) { if (candidate.getName().endsWith(".jar")) { jdeploy.put("jar", getRelativePath(candidate)); } else { jdeploy.put("war", getRelativePath(candidate)); } } String jsonStr = Result.fromContent(pj).toString(); System.out.println("Updating your package.json file as follows:\n "); System.out.println(jsonStr); System.out.println(""); System.out.print("Proceed? (y/N)"); Scanner reader = new Scanner(System.in); String response = reader.next(); if ("y".equals(response.toLowerCase())) { System.out.println("Writing package.json..."); FileUtils.writeStringToFile(packageJson, jsonStr, "UTF-8"); System.out.println("Complete!"); } else { System.out.println("Cancelled"); } } private void init(String commandName) throws IOException { commandName = directory.getAbsoluteFile().getName().toLowerCase(); if (".".equals(commandName)) { commandName = directory.getAbsoluteFile().getParentFile().getName().toLowerCase(); } File packageJson = new File(directory, "package.json"); if (packageJson.exists()) { updatePackageJson(commandName); } else { File candidate = findBestCandidate(); if (commandName == null) { /* if (candidate == null) { commandName = directory.getAbsoluteFile().getName().toLowerCase(); if (".".equals(commandName)) { commandName = directory.getAbsoluteFile().getParentFile().getName().toLowerCase(); } } else if (candidate.getName().endsWith(".jar") || candidate.getName().endsWith(".war")) { commandName = candidate.getName().substring(0, candidate.getName().lastIndexOf(".")).toLowerCase(); } else { commandName = candidate.getName().toLowerCase(); }*/ } Map m = new HashMap(); // for package.json m.put("name", commandName); m.put("version", "1.0.0"); m.put("repository", ""); m.put("description", ""); m.put("main", "index.js"); Map bin = new HashMap(); bin.put(commandName, getBinDir() + "/jdeploy.js"); m.put("bin", bin); m.put("preferGlobal", true); m.put("author", ""); Map scripts = new HashMap(); scripts.put("test", "echo \"Error: no test specified\" && exit 1"); m.put("scripts", scripts); m.put("license", "ISC"); Map dependencies = new HashMap(); dependencies.put("shelljs", "^0.7.5"); m.put("dependencies", dependencies); List files = new ArrayList(); files.add("jdeploy-bundle"); m.put("files", files); Map jdeploy = new HashMap(); if (candidate == null) { } else if (candidate.getName().endsWith(".jar")) { jdeploy.put("jar", getRelativePath(candidate)); } else { jdeploy.put("war", getRelativePath(candidate)); } m.put("jdeploy", jdeploy); Result res = Result.fromContent(m); String jsonStr = res.toString(); System.out.println("Creating your package.json file with following content:\n "); System.out.println(jsonStr); System.out.println(""); System.out.print("Proceed? (y/N)"); Scanner reader = new Scanner(System.in); String response = reader.next(); if ("y".equals(response.toLowerCase().trim())) { System.out.println("Writing package.json..."); FileUtils.writeStringToFile(packageJson, jsonStr, "UTF-8"); System.out.println("Complete!"); } else { System.out.println("Cancelled"); } } } static boolean isWindows() { return System.getProperty("os.name").toLowerCase().contains("win"); } static String npm = isWindows() ? "npm.cmd" : "npm"; private void init_old(String commandName) throws IOException { try { File packageJson = new File(directory, "package.json"); if (!packageJson.exists()) { ProcessBuilder pb = new ProcessBuilder(); pb.command(npm, "init"); pb.inheritIO(); final Process p = pb.start(); Timer t = new Timer(); TimerTask tt = new TimerTask() { @Override public void run() { if (packageJson.exists()) { p.destroy(); cancel(); } } }; t.schedule(tt, new Date(System.currentTimeMillis() + 1000), 1000); int code = p.waitFor(); if (!packageJson.exists() && code != 0) { System.err.println("Stopped init because npm init failed"); System.exit(code); } } String pkgJsonStr = FileUtils.readFileToString(packageJson, "UTF-8"); if (!pkgJsonStr.contains("shelljs")) { System.out.println("Installing shelljs"); ProcessBuilder pb = new ProcessBuilder(); pb.inheritIO(); pb.command(npm, "install", "shelljs", "--save"); Process p = pb.start(); int result = p.waitFor(); if (result != 0) { System.err.println("Failed to install shelljs"); System.exit(result); } } // For some reason it never sticks in the package.json file the first time pkgJsonStr = FileUtils.readFileToString(packageJson, "UTF-8"); if (!pkgJsonStr.contains("shelljs")) { System.out.println("Installing shelljs"); ProcessBuilder pb = new ProcessBuilder(); pb.inheritIO(); pb.command(npm, "install", "shelljs", "--save"); Process p = pb.start(); int result = p.waitFor(); if (result != 0) { System.err.println("Failed to install shelljs"); System.exit(result); } } JSONParser parser = new JSONParser(); Map contents = parser.parseJSON(new StringReader(pkgJsonStr)); if (commandName == null) { commandName = (String) contents.get("name"); } if (!contents.containsKey("bin")) { contents.put("bin", new HashMap()); } Map bins = (Map) contents.get("bin"); if (!bins.values().contains(getBinDir() + "/jdeploy.js")) { contents.put("preferGlobal", true); bins.put(commandName, getBinDir() + "/jdeploy.js"); Result res = Result.fromContent(contents); FileUtils.writeStringToFile(packageJson, res.toString(), "UTF-8"); } if (!contents.containsKey("files")) { contents.put("files", new ArrayList()); } List files = (List) contents.get("files"); if (!files.contains(getBinDir())) { files.add(getBinDir()); Result res = Result.fromContent(contents); FileUtils.writeStringToFile(packageJson, res.toString(), "UTF-8"); } } catch (InterruptedException ex) { throw new RuntimeException(ex); } } private void _package() throws IOException { copyToBin(); } private void install() throws IOException { _package(); try { ProcessBuilder pb = new ProcessBuilder(); pb.inheritIO(); pb.command(npm, "link"); Process p = pb.start(); int result = p.waitFor(); if (result != 0) { System.exit(result); } } catch (InterruptedException ex) { Logger.getLogger(JDeploy.class.getName()).log(Level.SEVERE, null, ex); throw new RuntimeException(ex); } } private void publish() throws IOException { try { ProcessBuilder pb = new ProcessBuilder(); pb.inheritIO(); pb.command(npm, "publish"); Process p = pb.start(); int result = p.waitFor(); if (result != 0) { System.exit(result); } } catch (InterruptedException ex) { Logger.getLogger(JDeploy.class.getName()).log(Level.SEVERE, null, ex); throw new RuntimeException(ex); } } private void scan() throws IOException { System.out.println("Scanning directory for executable jars, wars, and webapps..."); File[] jars = findJarCandidates(); System.out.println("Found " + jars.length + " jars: " + Arrays.toString(jars)); System.out.println("Best candidate: " + shallowest(jars)); File[] wars = findWarCandidates(); System.out.println("Found " + wars.length + " wars: " + Arrays.toString(wars)); System.out.println("Best candidate: " + shallowest(jars)); File[] webApps = findWebAppCandidates(); System.out.println("Found " + webApps.length + " web apps: " + Arrays.toString(webApps)); System.out.println("Best candidate: " + shallowest(jars)); List<File> combined = new ArrayList<File>(); combined.addAll(Arrays.asList(jars)); combined.addAll(Arrays.asList(wars)); combined.addAll(Arrays.asList(webApps)); System.out.println( "If jdeploy were to run on this directory without specifying the jar or war in the package.json, it would choose " + shallowest(combined.toArray(new File[combined.size()]))); } private void help(Options opts) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("jdeploy [init|package|install|publish] [commandName]\n" + "\n" + "Commands:\n" + " init : Initialize the project\n" + " package : Prepare for install. This copies necessary files into bin directory.\n" + " install : Installs the app locally (links to PATH)\n" + " publish : Publishes to NPM\n", opts); } private void _run() { System.out.println("run not implemented yet"); } /** * @param args the command line arguments */ public static void main(String[] args) { try { JDeploy prog = new JDeploy(new File(".").getAbsoluteFile()); CommandLineParser parser = new DefaultParser(); Options opts = new Options(); CommandLine line = parser.parse(opts, args); args = line.getArgs(); if (args.length == 0) { prog.help(opts); System.exit(1); } if ("package".equals(args[0])) { prog._package(); } else if ("init".equals(args[0])) { String commandName = null; if (args.length > 1) { commandName = args[1]; } prog.init(commandName); } else if ("install".equals(args[0])) { prog.install(); } else if ("publish".equals(args[0])) { prog.publish(); } else if ("scan".equals(args[0])) { prog.scan(); } else if ("run".equals(args[0])) { prog._run(); } else { prog.help(opts); System.exit(1); } } catch (Exception ex) { throw new RuntimeException(ex); } } }