package lombok.eclipseCreate; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.LinkedHashMap; import java.util.Map; import java.util.regex.Pattern; public class CreateEclipseDebugTarget { private Map args; private StringBuilder launchContent = new StringBuilder(); private static class InvalidCommandLineException extends Exception { InvalidCommandLineException(String msg) { super(msg); } InvalidCommandLineException(String msg, Throwable cause) { super(msg, cause); } } public static void main(String[] args) throws Exception { CreateEclipseDebugTarget instance = new CreateEclipseDebugTarget(); try { instance.args = parseArgs(args); if (instance.args.isEmpty()) throw new InvalidCommandLineException(""); instance.go(); } catch (InvalidCommandLineException e) { String msg = e.getMessage(); if (!msg.isEmpty()) System.err.println("ERROR: " + msg); if (e.getCause() != null) { e.getCause().printStackTrace(); } printCommandLineHelp(); System.exit(1); } catch (IOException e) { e.printStackTrace(); System.exit(1); } } private void go() throws InvalidCommandLineException, IOException { prologue(); classpath(); epilogue(); String n = getArgString("name"); File f = new File(n + ".launch").getCanonicalFile(); OutputStream out = new FileOutputStream(f); try { out.write(launchContent.toString().getBytes("UTF-8")); } finally { out.close(); } System.out.println("Debug target created: " + f); } private void prologue() throws InvalidCommandLineException { String type = getArgString("testType"); launchContent.append("\n"); launchContent.append("\n"); launchContent.append("\t\n"); launchContent.append("\t\t\n"); launchContent.append("\t\n"); launchContent.append("\t\n"); launchContent.append("\t\t\n"); launchContent.append("\t\n"); if (getArgBoolean("favorite")) { launchContent.append("\t\n"); launchContent.append("\t\t\n"); launchContent.append("\t\n"); } launchContent.append("\t\n"); launchContent.append("\t\n"); launchContent.append("\t\n"); launchContent.append("\t\n"); launchContent.append("\t\n"); } private void classpath() throws InvalidCommandLineException { launchContent.append("\t\n"); String self; try { self = new File("..").getCanonicalPath(); } catch (IOException e) { throw new InvalidCommandLineException("Cannot obtain canonical path to parent directory", e); } String bootpath = getBootPath(); launchContent.append("\t\t\n"); for (Map.Entry entry : args.entrySet()) { if (!entry.getKey().startsWith("conf.")) continue; String v = entry.getValue(); if (v.equals("NONE")) continue; String[] files = v.split(Pattern.quote(File.pathSeparator)); for (String file : files) { String n; try { n = new File(file).getCanonicalPath(); } catch (IOException e) { throw new InvalidCommandLineException("Cannot obtain canonical path to dependency " + file, e); } if (n.startsWith(self)) { launchContent.append("\t\t\n"); } } } if (bootpath != null) launchContent.append("\t\t\n"); launchContent.append("\t\n"); } private void epilogue() throws InvalidCommandLineException { String type = getArgString("testType"); launchContent.append("\t\n"); String jvmTarget = getArgString("jvmTarget"); String bootpath = getBootPath(); launchContent.append("\t\n"); launchContent.append("\t\n"); launchContent.append("\t\n"); launchContent.append("\t\n"); if (getArgBoolean("shadowLoaderBased")) { launchContent.append(" entry : args.entrySet()) { if (!entry.getKey().startsWith("conf.")) continue; launchContent.append(File.pathSeparator).append(entry.getValue()); } if (bootpath != null) launchContent.append(" -Ddelombok.bootclasspath=" + bootpath); } launchContent.append("\"/>\n\n"); } private String getBootPath() { String bp = args.get("bootpath"); if (bp == null || bp.isEmpty() || bp.equals("0")) return null; File f = new File(bp); if (!f.isAbsolute()) return bp; String r = new File(".").getAbsolutePath(); if (r.endsWith(".")) r = r.substring(0, r.length() - 1); if (bp.startsWith(r)) return bp.substring(r.length()); throw new IllegalStateException("Cannot reconstruct relative path; base: " + r + " is not a parent of " + bp); } private String getArgString(String key) throws InvalidCommandLineException { String v = args.get(key); if (v == null) throw new InvalidCommandLineException("mandatory argument '" + key + "' missing"); return v; } private boolean getArgBoolean(String key) throws InvalidCommandLineException { String v = args.get(key); if (v == null) return false; if (v.equalsIgnoreCase("false") || v.equalsIgnoreCase("f")) return false; return true; } private static void printCommandLineHelp() { System.err.println("CreateEclipseDebugTarget\n" + " name=Lombok-test BaseJavac 11 # Sets the name of the debug target to make\n" + " testType=lombok.RunJavacAndBaseTests # The test class file that this debug target should run\n" + " shadowLoaderBased # Add the VM options to use lombok as an agent and pass the classpath to the shadow loader. Needed for ECJ/Eclipse.\n" + " conf.test=foo:bar:baz # Where 'test' is an ivy conf name, and 'foo' is a path to a jar, relativized vs. current directory.\n" + " favorite # Should the debug target be marked as favourite?\n" + ""); } private static Map parseArgs(String[] args) throws IllegalArgumentException { Map map = new LinkedHashMap(); for (String arg : args) { int idx = arg.indexOf('='); String key = (idx == -1 ? arg : arg.substring(0, idx)).trim(); String value = (idx == -1 ? "" : arg.substring(idx + 1)).trim(); String existing = map.get(key); if (existing != null) { if (key.startsWith("conf.")) { value = existing + File.pathSeparator + value; } else { throw new IllegalArgumentException("Duplicate argument not allowed: " + key); } } map.put(key, value); } return map; } }