pax_global_header00006660000000000000000000000064145051564710014522gustar00rootroot0000000000000052 comment=041df3dadd4e1e532c55833a4d42b3be71425abe ivyplusplus-1.42/000077500000000000000000000000001450515647100140675ustar00rootroot00000000000000ivyplusplus-1.42/.gitignore000066400000000000000000000001141450515647100160530ustar00rootroot00000000000000.classpath .project .settings escudo-upload.key bin build dist lib ivyCache ivyplusplus-1.42/LICENSE000066400000000000000000000020641450515647100150760ustar00rootroot00000000000000Copyright (C) 2009-2017 The Project Lombok Authors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ivyplusplus-1.42/README.markdown000066400000000000000000000302461450515647100165750ustar00rootroot00000000000000# com.zwitserloot.ivyplusplus `com.zwitserloot.ivyplusplus` is a jar containing [Apache Ivy](https://ant.apache.org/ivy/) as well as a few useful constructs built on top of it. Aside from ivy itself, you get a few extra tasks and a command line tool that creates a new project by filling out a skeleton build.xml and ivy configuration. ## How to use Run `java -jar ivyplusplus.jar --help` for more information on how to create a skeleton project. _Supported since ipp 1.5_ For a more thorough example, just like at the build file of this very project (com.zwitserloot.ivyplusplus eats its own dog food). ## Developing com.zwitserloot.ivyplusplus in eclipse Run `ant eclipse` first, then just load the main directory of the project as eclipse project. ## Developing com.zwitserloot.ivyplusplus in intellij Run `ant intellij` first, then just load the main directory of the project as intellij project. ## Extra Tasks ### `` - creates intellij project files from your ivy configuration. Specify your preferred target/source JVM as attribute named 'source'. Specify the target directory as attribute named 'todir' (default: project dir, which is what you should leave it at unless you know what you are doing or want to test). First specify all the configurations you need with inner `` constructs. Each such configuration will be turned into a library set. 'sources' is optional, of course. All artifacts that would be downloaded when resolving _build_ will be added to this library set, and all artifacts that would be downloaded when resolving _contrib_ are added to this library set as sources. Finally, create intellij modules with inner `` entries. These modules will be dependent on the listed library sets (which you just made using ``). The `` tag should include nested `` entries. To enable annotation processing, include `` inside your `` task. intellijgen will also generate the project settings (warnings, errors, source and target compatibility, formatters, styles, etcetera) if you want, by including the `` element. Put ant resource elements inside. To write your own file, configure a project the way you want it, then mix together all the various `` elements in the files in your `.idea` directory. `intellijgen` knows how to sort each element back into the appropriate file. Note that intellij won't itself actually download any of the files, so it would be a good idea to run `` on the needed confs first. Example: _Supported since ipp 1.4_ ### `` - creates eclipse project files from your ivy configuration. Specify your preferred target/source JVM as attribute named 'source'. Specify the target directory as attribute named 'todir' (default: project dir, which is what you should leave it at unless you know what you are doing or want to test). Then, specify each source dir with an inner `` element, with an optional attribute named `optional="true"` for optional sources. For annotation processing, `.apt_generated` is automatically added as optional source dir for you. Specify ivy configuration using inner elements like so: `` - this will add all artifacts that would be downloaded when resolving _build_ to the eclipse classpath, and if a certain dependency would also download some files for the _contrib_ configuration, attaches those as sources. You can specify multiple configurations, and if a certain artifact is in multiple configurations, only the one from the highest listed 'conf' element is used. `sources` is of course optional. If you have apt processors, specify them with ``. If you have separate jar files, you can specify these with ``. To set up the eclipse project so that sibling/child projects also under active development are registered as project dependencies instead of dependencies on the ivy artifacts, use ``; this will look for `../your.org.projname/.project` relative to the current directory, and, _only if that file exists_, it will replace any ivy dependency on the stated org/name pair (of any version!) with that project. If that file does not exist, no warning or error is generated and the normal dependency is inserted. This way, a 'fresh' clone from a source repo compiles cleanly, but you can replace any dependency with tandem development on that project by just checking it out into the same workspace and rerunning 'ant eclipse'. eclipsegen will also generate the project settings (warnings, errors, source and target compatibility, formatters, styles, etcetera) if you want, by including the `` element. Put eclipse settings properties inside as plain text, as well as ant resource elements. If any of the following keys aren't defined, they will be added based on the `source` attribute of eclipsegen: * `org.eclipse.jdt.core.compiler.processAnnotations` - disabled for 1.5, enabled for anything above that. * `org.eclipse.jdt.core.compiler.source` - set to 'source' value. * `org.eclipse.jdt.core.compiler.compliance` - set to 'source' value. * `org.eclipse.jdt.core.compiler.codegen.targetPlatform` - set to 'source' value. To write your own file, configure a project the way you want it, then mix together all the various files in the `.settings` directory. `eclipsegen` knows how to sort each key back into the appropriate file. Note that eclipsegen won't itself actually download any of the files, so it would be a good idea to run `` on the needed confs first. Example: org.eclipse.jdt.core.formatter.lineSplit=100 _Supported since ipp 1.0_ ### `` - Error out or set a property if available version of ivyplusplus is not sufficient. Ivy takes care of version control, but who will take care of Ivy's own version control? With this task you can error out (or set a property) if the cached ivyplusplus.jar is a version that's not equal to/higher than what you need. Example: `` the `property` set in the attribute will be set if the version available is equal to or higher than the version put in the mandatory `version` attribute. Alternative usage is to omit `property`. In that case, a build error will occur if `version` is higher than what's available. _Supported since ipp 1.4_ ### `` - just like ``, but this task will also copy any non-java, non-class files to the destination directory. The defaults are also different: debug = on source = 1.8 target = 1.8 encoding = UTF-8 includeAntRuntime = false The _destdir_ directory is also created automatically, so you don't have to `` it first. (since ipp 1.22: You can also set ecj="true" to use ecj instead. Useful if you want to compile with old source/target). (since ipp 1.40: You can include a `` element, which is required to run APs in ecj). _Supported since ipp 1.0_ ### `` - similar to unjar, except will not unpack jars that don't need to be unpacked. While `cachedunjar` is similar to `unjar`, it supports only file resources, either via a `source` attribute or nested `` elements. You must specify a `dest` attribute just like with `unjar`. In addition, you must specify a file via the `marker` attribute. This file is used to track the state of the unpacked jars; a 'savefile' of sorts. Example: _Supported since ipp 1.7_ ### `` - creates a dependency report, and then opens your browser to show it. The last executed `` serves as the configuration for which a dependency report will be generated. By default `build/report` is used as target dir for both temporary files needed to create and view the report as well as the report itself. Change it with the `todir` attribute. _Supported since ipp 1.0_ ### `` - loads version info from a text file. Set the file containing the version name in the `file` attribute. The property will be read from it by stripping linebreaks and treating the rest as the version. This version will then be loaded into a property named `version`. You can change the property by setting the `property` attribute. _Supported since ipp 1.3_ ### `` - runs git. Only works if git is locally installed (for windows users, you'd have to be running ant inside cygwin/msys). Set the git command, such as _pull_ in the `command` attribute. The command will run in the project dir, unless you override this by specifying the optional `dir` attribute. You can add more arguments via a nested `args` element containing `` elements. Fails with a helpful error message if git doesn't exist. _Supported since ipp 1.0_ ### `` - runs git clone. Required attributes: `repository` listing the repository URL and `dest` listing the directory to place the git repository. _Supported since ipp 1.0_ ### `` - convenience for `` _Supported since ipp 1.0_ ### `` - creates/updates maven-compatible repositories Attributes: * `url` - list the base URL where the repository is located. Example: `https://projectlombok.org/mavenrepo` * `group` - group name. Example: `org.projectlombok` * `artifact` - artifact name. Example: `lombok` * `version` - this version. make-maven-repo won't work if this version name is already available from the repository. * `outfile` - a bzip2 tarball will be produced that must be unpacked in the existing mavenrepo to update it. This describes where to build it. * `tmpdir` (optional) - where to put the files that will end up being bzip2 tarballed. By default `build/maven`. * `artifactfile` - Location of the artifact (e.g. jar file). This will be uploaded along with the logistics to be a maven repository. * `pomfile` - Location of the pom file describing this project. `@VERSION@` will be replaced with the version. artifact and group IDs and the like must match. Inner elements: * `sources` - should contain filesets pointing at source files. Will be used to create a source artifact. _Supported since ipp 1.3_ NB: make-maven-repo is no longer under active development since sonatype changed their policy on how maven artifacts are to be added to maven central. ### `` - creates hardlinks instead of copying files Attributes: * `from` - File to hardlink from (only individual files are supported). * `to` - New file to create which will be a hardlink copy of `from`. This task will use `fsutil hardlink create` on windows, and `ln` on other systems. ### `` and `` - Uploads files / runs scripts via SSH Attributes * `server` - IP or domain of the SSH server to talk to * `port` - Port to use (optional, defaults to 22) * `username` - Username to connect as. * `keyFile` - The only supported connection mechanism is key files, not password protected (many formats supported. ed25519 recommended). * `knownHosts` - A file listing known hosts; defaults to `ssh.knownHosts`. If you fail to list the host, the command fails put prints what you'd have to add to this file to make it work. For scpUpload: * `from` - File to upload. * `to` - Where to upload to. For sshExec: * `cmd` - Command to execute. ivyplusplus-1.42/build.xml000066400000000000000000000251721450515647100157170ustar00rootroot00000000000000 com.zwitserloot.ivyplusplus version: ${ivyplusplus.version} ${sha256.pack} Aborted. ${allDeps} <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="src/"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-${jre.version}"/> <classpathentry kind="output" path="bin"/> </classpath> ivyplusplus-1.42/buildScripts/000077500000000000000000000000001450515647100165365ustar00rootroot00000000000000ivyplusplus-1.42/buildScripts/ivy-repo/000077500000000000000000000000001450515647100203105ustar00rootroot00000000000000ivyplusplus-1.42/buildScripts/ivy-repo/org.projectlombok-jsch-ant-fixed-0.1.42.xml000066400000000000000000000007341450515647100300200ustar00rootroot00000000000000 ivyplusplus-1.42/buildScripts/ivy.xml000066400000000000000000000024621450515647100200730ustar00rootroot00000000000000 ivyplusplus-1.42/buildScripts/ivysettings.xml000066400000000000000000000006631450515647100216550ustar00rootroot00000000000000 ivyplusplus-1.42/buildScripts/maven-pom.xml000066400000000000000000000017201450515647100211570ustar00rootroot00000000000000 4.0.0 com.zwitserloot ivyplusplus jar @VERSION@ IvyPlusPlus https://zwitserloot.com/ivyplusplus Adds some useful features to ant based on ivy, such as building an eclipse project based on your dependencies. The MIT License https://www.opensource.org/licenses/mit-license.php repo scm:git:git://github.com/rzwitserloot/ivyplusplus.git scm:git:git://github.com/rzwitserloot/ivyplusplus.git ivyplusplus-1.42/src/000077500000000000000000000000001450515647100146565ustar00rootroot00000000000000ivyplusplus-1.42/src/com/000077500000000000000000000000001450515647100154345ustar00rootroot00000000000000ivyplusplus-1.42/src/com/zwitserloot/000077500000000000000000000000001450515647100200415ustar00rootroot00000000000000ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/000077500000000000000000000000001450515647100224605ustar00rootroot00000000000000ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/AnnotationProcessorEntry.java000066400000000000000000000006041450515647100303570ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus; import java.io.File; public class AnnotationProcessorEntry { private String processorClass; private File jar; public void setProcessor(String proc) { this.processorClass = proc; } public void setJar(File jar) { this.jar = jar; } public String getProcessor() { return processorClass; } public File getJar() { return jar; } }ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/CachedUnjar.java000066400000000000000000000173771450515647100255110ustar00rootroot00000000000000/** * Copyright © 2011 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Delete; import org.apache.tools.ant.taskdefs.Expand; import org.apache.tools.ant.taskdefs.MatchingTask; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.resources.FileResource; public class CachedUnjar extends MatchingTask { private File dest; private File source; private File marker; private List fileSets = new ArrayList(); private List paths = new ArrayList(); public void addFileset(FileSet set) { this.fileSets.add(set); } public void addPath(Path path) { this.paths.add(path); } public void setSource(File file) { this.source = file; } public void setMarker(File file) { this.marker = file; } public void setDest(File file) { this.dest = file; } public void execute() throws BuildException { if (source == null && fileSets.isEmpty() && paths.isEmpty()) { throw new BuildException("Specify either 'source' or include a fileset or path.", getLocation()); } if (marker == null) throw new BuildException("Specify 'marker' which is a file that carries caching info.", getLocation()); if (dest == null) throw new BuildException("Specify 'dest' which is the directory the jars are unpacked to.", getLocation()); if (!dest.exists()) if (!dest.mkdirs()) throw new BuildException("'dest' does not exist and cannot be created as directory: " + dest, getLocation()); if (!dest.isDirectory()) throw new BuildException("'dest' must be a directory: " + dest, getLocation()); if (source != null && (!fileSets.isEmpty() || !paths.isEmpty())) { throw new BuildException("Specify either 'source' or include filesets/paths, not both.", getLocation()); } Set caches; try { caches = readCaches(marker); } catch (IOException e) { throw new BuildException("Can't read marker file", e, getLocation()); } Set newCache = new LinkedHashSet(); Set toUnpack = new LinkedHashSet(); List toUnpackRes = new ArrayList(); List allRes = new ArrayList(); if (source != null) { FileSet fs = new FileSet(); fs.setFile(source); fileSets.add(fs); } if (!fileSets.isEmpty()) { Path fsPath = new Path(getProject()); for (FileSet fs : fileSets) fsPath.addFileset(fs); paths.add(fsPath); } try { for (Path path : paths) { Iterator it = path.iterator(); while (it.hasNext()) { Resource res = (Resource) it.next(); if (!(res instanceof FileResource)) { throw new BuildException("Only file resources supported: " + res.getName(), getLocation()); } File jarFile = ((FileResource)res).getFile(); allRes.add(jarFile); CacheRecord cr = new CacheRecord(jarFile.getCanonicalPath(), res.getLastModified(), res.getSize()); if (caches.contains(cr)) { this.log(String.format("Skipping %s due to cache", jarFile.getCanonicalPath()), Project.MSG_VERBOSE); newCache.add(cr); } else { newCache.add(cr); toUnpack.add(cr); toUnpackRes.add(jarFile); } } } if (newCache.size() - toUnpack.size() == caches.size()) { // We just need to unpack toUnpack. unpack(toUnpackRes); } else { // At least one unpack library is no longer in the set, so we delete and unpack all. this.log(String.format("Deleting %s because previously present jar is no longer there.", dest), Project.MSG_INFO); clearDest(); unpack(allRes); } } catch (IOException e) { throw new BuildException(e, getLocation()); } try { saveCache(newCache); } catch (IOException e) { throw new BuildException("Can't write marker file", e, getLocation()); } } private void clearDest() { Delete d = new Delete(); d.setDir(dest); d.execute(); } private void unpack(Collection ress) { for (File res : ress) { Expand ex = new Expand(); ex.setDest(dest); ex.setSrc(res); ex.setTaskName("cachingunjar"); ex.setTaskType("unjar"); ex.execute(); } } private void saveCache(Collection crs) throws IOException { FileOutputStream fos = new FileOutputStream(marker); try { for (CacheRecord cr : crs) fos.write(cr.write().getBytes("UTF-8")); } finally { fos.close(); } } private static Set readCaches(File marker) throws IOException { Set out = new LinkedHashSet(); try ( FileInputStream fis = new FileInputStream(marker); BufferedReader br = new BufferedReader(new InputStreamReader(fis, "UTF-8")) ) { for (String line = br.readLine(); line != null; line = br.readLine()) { line = line.trim(); if (line.startsWith("#")) continue; if (line.length() == 0) continue; out.add(CacheRecord.read(line)); } } catch (FileNotFoundException e) {} return out; } private static class CacheRecord { private final String name; private final long lastMod, len; public CacheRecord(String name, long lastMod, long len) { this.name = name; this.lastMod = lastMod; this.len = len; } @Override public String toString() { return name + "[lastMod = " + lastMod + ", len = " + len + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) (lastMod ^ (lastMod >>> 32)); result = prime * result + (int) (len ^ (len >>> 32)); result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; CacheRecord other = (CacheRecord) obj; if (lastMod != other.lastMod) return false; if (len != other.len) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } static CacheRecord read(String line) { String[] elems = line.split(" ::: ", 3); return new CacheRecord(elems[0], Long.parseLong(elems[1]), Long.parseLong(elems[2])); } String write() { return String.format("%s ::: %d ::: %d\n", name, lastMod, len); } } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/Compile.java000066400000000000000000000266441450515647100247270ustar00rootroot00000000000000/** * Copyright © 2010-2017 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus; import static java.util.Collections.unmodifiableMap; import java.io.File; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DynamicAttribute; import org.apache.tools.ant.Project; import org.apache.tools.ant.RuntimeConfigurable; import org.apache.tools.ant.UnknownElement; import org.apache.tools.ant.taskdefs.Copy; import org.apache.tools.ant.taskdefs.Javac; import org.apache.tools.ant.taskdefs.MatchingTask; import org.apache.tools.ant.taskdefs.Mkdir; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.util.facade.FacadeTaskHelper; import org.apache.tools.ant.util.facade.ImplementationSpecificArgument; import com.zwitserloot.ivyplusplus.ecj.EcjAdapter; public class Compile extends MatchingTask implements DynamicAttribute { private UnknownElement javac, copy, mkdir; private Path src; private boolean doCopy = true; private boolean ecj; private boolean includeSystemBootclasspath; private String copyExcludes; private String destdirLoc; public void setIncludeSystemBootclasspath(boolean includeSystemBootclasspath) { this.includeSystemBootclasspath = includeSystemBootclasspath; } public void setEcj(boolean ecj) { this.ecj = ecj; } public void setCopyExcludes(String copyExcludes) { this.copyExcludes = copyExcludes; } public void setCopy(boolean copy) { this.doCopy = copy; } public void init() { javac = new UnknownElement("javac"); copy = new UnknownElement("copy"); mkdir = new UnknownElement("mkdir"); javac.setTaskName("compile:javac"); copy.setTaskName("compile:copy"); mkdir.setTaskName("compile:mkdir"); new RuntimeConfigurable(javac, javac.getTaskName()); new RuntimeConfigurable(copy, copy.getTaskName()); new RuntimeConfigurable(mkdir, mkdir.getTaskName()); javac.setProject(getProject()); copy.setProject(getProject()); mkdir.setProject(getProject()); } private static final Map JAVAC_ATTR_MAP, COPY_ATTR_MAP, MKDIR_ATTR_MAP, JAVAC_DEFAULTS, COPY_DEFAULTS; static { Map m; m = new HashMap(); m.put("destdir", "dir"); MKDIR_ATTR_MAP = unmodifiableMap(m); m = new HashMap(); m.put("destdir", "destdir"); m.put("classpath", "classpath"); m.put("sourcepath", "sourcepath"); m.put("bootclasspath", "bootclasspath"); m.put("classpathref", "classpathref"); m.put("sourcepathref", "sourcepathref"); m.put("bootclasspathref", "bootclasspathref"); m.put("extdirs", "extdirs"); m.put("encoding", "encoding"); m.put("nowarn", "nowarn"); m.put("debug", "debug"); m.put("debuglevel", "debuglevel"); m.put("deprecation", "deprecation"); m.put("target", "target"); m.put("source", "source"); m.put("release", "release"); m.put("verbose", "verbose"); m.put("depend", "depend"); m.put("includeantruntime", "includeantruntime"); m.put("includejavaruntime", "includejavaruntime"); m.put("fork", "fork"); m.put("executable", "executable"); m.put("memoryinitialsize", "memoryinitialsize"); m.put("memorymaximumsize", "memorymaximumsize"); m.put("failonerror", "failonerror"); m.put("errorproperty", "errorproperty"); m.put("compiler", "compiler"); m.put("listfiles", "listfiles"); m.put("tempdir", "tempdir"); m.put("updatedproperty", "updatedproperty"); m.put("includedestclasses", "includedestclasses"); JAVAC_ATTR_MAP = unmodifiableMap(m); m = new HashMap(); m.put("encoding", "UTF-8"); m.put("debug", "on"); m.put("target", "1.8"); m.put("source", "1.8"); m.put("includeantruntime", "false"); JAVAC_DEFAULTS = unmodifiableMap(m); m = new HashMap(); m.put("destdir", "todir"); m.put("preservelastmodified", "preservelastmodified"); m.put("includeemptydirs", "includeemptydirs"); m.put("failonerror", "failonerror"); m.put("verbose", "verbose"); COPY_ATTR_MAP = unmodifiableMap(m); m = new HashMap(); m.put("includeemptydirs", "false"); COPY_DEFAULTS = unmodifiableMap(m); } private boolean setWithKey(UnknownElement elem, Map map, String name, String value) { String key = map.get(name); if (key == null) return false; elem.getWrapper().setAttribute(key, value); return true; } public void setDynamicAttribute(String name, String value) throws BuildException { boolean matched = false; matched |= setWithKey(mkdir, MKDIR_ATTR_MAP, name, value); matched |= setWithKey(javac, JAVAC_ATTR_MAP, name, value); matched |= setWithKey(copy, COPY_ATTR_MAP, name, value); if (!matched) throw new BuildException("Unknown property of compile task: " + name, getLocation()); if ("destdir".equals(name)) destdirLoc = value; } public void setSrcdir(Path srcDir) { if (src == null) src = srcDir; else src.append(srcDir); } public Path createSrc() { if (src == null) { src = new Path(getProject()); } return src.createPath(); } private Path compileClasspath, compileSourcepath, bootclasspath, extdirs; public Path createSourcepath() { if (compileSourcepath == null) compileSourcepath = new Path(getProject()); return compileSourcepath.createPath(); } public Path createClasspath() { if (compileClasspath == null) compileClasspath = new Path(getProject()); return compileClasspath.createPath(); } public Path createBootclasspath() { if (bootclasspath == null) bootclasspath = new Path(getProject()); return bootclasspath.createPath(); } public Path createExtdirs() { if (extdirs == null) extdirs = new Path(getProject()); return extdirs.createPath(); } private List compilerArgs = new ArrayList(); private List annotationProcessorEntries = new ArrayList(); public ImplementationSpecificArgument createCompilerArg() { ImplementationSpecificArgument arg = new ImplementationSpecificArgument(); compilerArgs.add(arg); return arg; } public AnnotationProcessorEntry createAnnotationProcessor() { AnnotationProcessorEntry entry = new AnnotationProcessorEntry(); annotationProcessorEntries.add(entry); return entry; } public void execute() { if (destdirLoc == null) throw new BuildException("mandatory property 'destdir' not set."); log(getLocation().toString() + "compiling to " + destdirLoc, Project.MSG_VERBOSE); if (src == null) src = new Path(getProject()); Map attributeMap = javac.getWrapper().getAttributeMap(); boolean hasRelease = attributeMap.containsKey("release"); for (Map.Entry e : JAVAC_DEFAULTS.entrySet()) { if (!(hasRelease && (e.getKey().equals("source") || e.getKey().equals("target"))) && !attributeMap.containsKey(e.getKey())) { javac.getWrapper().setAttribute(e.getKey(), e.getValue()); } } attributeMap = copy.getWrapper().getAttributeMap(); for (Map.Entry e : COPY_DEFAULTS.entrySet()) { if (!attributeMap.containsKey(e.getKey())) copy.getWrapper().setAttribute(e.getKey(), e.getValue()); } mkdir.maybeConfigure(); Mkdir mkdirTask = (Mkdir) mkdir.getRealThing(); mkdirTask.execute(); javac.maybeConfigure(); Javac javacTask = (Javac) javac.getRealThing(); javacTask.setSrcdir(src); javacTask.createCompilerArg().setValue("-Xlint:unchecked"); if (bootclasspath != null) javacTask.setBootclasspath(bootclasspath); if (compileClasspath != null) javacTask.setClasspath(compileClasspath); if (compileSourcepath != null) javacTask.setSourcepath(compileSourcepath); if (extdirs != null) javacTask.setExtdirs(extdirs); Set procClasses = new LinkedHashSet(); Set procJars = new LinkedHashSet(); try { for (AnnotationProcessorEntry entry : annotationProcessorEntries) { procClasses.add(entry.getProcessor()); procJars.add(entry.getJar()); } Field f = MatchingTask.class.getDeclaredField("fileset"); f.setAccessible(true); f.set(javacTask, getImplicitFileSet().clone()); f = Javac.class.getDeclaredField("facade"); f.setAccessible(true); FacadeTaskHelper facade = (FacadeTaskHelper) f.get(javacTask); for (ImplementationSpecificArgument isa : compilerArgs) facade.addImplementationArgument(isa); if (!procJars.isEmpty()) { ImplementationSpecificArgument arg = new ImplementationSpecificArgument(); arg.setValue("-processorpath"); facade.addImplementationArgument(arg); StringBuilder sb = new StringBuilder(); for (File procJar : procJars) { if (sb.length() > 0) sb.append(File.pathSeparator); sb.append(procJar.getAbsolutePath()); } arg = new ImplementationSpecificArgument(); arg.setValue(sb.toString()); facade.addImplementationArgument(arg); } if (!procClasses.isEmpty()) { ImplementationSpecificArgument arg = new ImplementationSpecificArgument(); arg.setValue("-processor"); facade.addImplementationArgument(arg); StringBuilder sb = new StringBuilder(); for (String procClass : procClasses) { if (sb.length() > 0) sb.append(","); sb.append(procClass); } arg = new ImplementationSpecificArgument(); arg.setValue(sb.toString()); facade.addImplementationArgument(arg); } } catch (Exception e) { throw new BuildException(e, getLocation()); } if (ecj) { if (!compilerArgs.isEmpty()) throw new BuildException("compilerArg is not supported for ecj=\"true\""); EcjAdapter ecjAdapter = new EcjAdapter(); ecjAdapter.setAnnotationProcessorEntries(procClasses, procJars); if (includeSystemBootclasspath) ecjAdapter.setIncludeSystemBootclasspath(true); javacTask.add(ecjAdapter); } else { if (includeSystemBootclasspath) throw new BuildException("includeSystemBootclasspath only supported in combination with ecj=\"true\""); } javacTask.execute(); if (doCopy) { copy.maybeConfigure(); Copy copyTask = (Copy) copy.getRealThing(); for (String pathElem : src.list()) { File srcPath = getProject().resolveFile(pathElem); FileSet fs = (FileSet) getImplicitFileSet().clone(); fs.setDir(srcPath); fs.createExclude().setName("**/*.java"); if (copyExcludes != null) fs.createExclude().setName(copyExcludes); copyTask.addFileset(fs); } copyTask.execute(); } } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/EnsureVersion.java000066400000000000000000000111701450515647100261320ustar00rootroot00000000000000/** * Copyright © 2010 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; public class EnsureVersion extends Task { private String version; private String property; public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } public String getProperty() { return property; } public void setProperty(String property) { this.property = property; } @Override public void execute() throws BuildException { if (version == null || version.isEmpty()) throw new BuildException("Must specify mandatory attribute 'version'", getLocation()); List want = toVersion(version); List have = toVersion(Version.getVersion()); if (!isEqualOrHigher(have, want)) { if (property == null) throw new BuildException("ivyplusplus version not sufficient; delete ivyplusplus.jar and run this script again. You have: " + Version.getVersion() + " but need: " + version); } else { if (property != null) getProject().setProperty(property, "true"); } } public static List toVersion(String version) { String[] parts = version.split("[-.]"); List ret = new ArrayList(); for (String part : parts) { ret.add(VersionPart.of(part)); } return Collections.unmodifiableList(ret); } /** * Returns {@code true} if {@code have} is a version equal to or higher than {@code want}. */ public static boolean isEqualOrHigher(List have, List want) { int largest = Math.max(have.size(), want.size()); for (int i = 0; i < largest; i++) { VersionPart a = i < have.size() ? have.get(i) : VersionPart.zero(); VersionPart b = i < want.size() ? want.get(i) : VersionPart.zero(); int res = a.compareTo(b); if (res < 0) return false; if (res > 0) return true; } return true; } private static class VersionPart implements Comparable { private final int number; private final String name; public VersionPart(int number, String name) { this.number = number; this.name = name; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + number; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; VersionPart other = (VersionPart) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (number != other.number) return false; return true; } public int compareTo(VersionPart o) { if (o.name == null) { if (name != null) return -1; if (number < o.number) return -1; if (number > o.number) return +1; return 0; } if (name == null) return +1; return name.compareTo(o.name); } public static VersionPart zero() { return new VersionPart(0, null); } public static VersionPart of(String part) { int v = 0; String name = null; for (char c : part.toCharArray()) { if (c >= '0' && c <= '9') { v = (v * 10) + (c - '0'); } else { v = 0; name = part.trim(); break; } } if (name != null && name.isEmpty()) name = null; if (name == null) return new VersionPart(v, null); else return new VersionPart(0, name); } } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/Hardlink.java000066400000000000000000000053241450515647100250630ustar00rootroot00000000000000/** * Copyright © 2017 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus; import java.io.File; import java.io.IOException; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; public class Hardlink extends Task { private File from; private File to; public void setFrom(File from) { this.from = from; } public void setTo(File to) { this.to = to; } public void execute() throws BuildException { if (from == null) throw new BuildException("Specify 'from'"); if (to == null) throw new BuildException("Specify 'to'"); File lnExe = new File("/bin/ln"); if (lnExe.isFile()) executePosix(); else executeWindows(); } private void executeWindows() { if (to.isFile()) to.delete(); String w = System.getenv().get("windir"); if (w == null || w.isEmpty()) w = "C:\\Windows"; ProcessBuilder pb = new ProcessBuilder(w + "\\System32\\fsutil.exe", "hardlink", "create", to.getAbsolutePath(), from.getAbsolutePath()); int errCode; try { errCode = pb.start().waitFor(); } catch (InterruptedException e) { throw new BuildException("interrupted"); } catch (IOException e) { throw new BuildException(e); } if (0 != errCode) throw new BuildException("Hardlinking failed: " + errCode); } private void executePosix() { ProcessBuilder pb = new ProcessBuilder("/bin/ln", "-f", from.getAbsolutePath(), to.getAbsolutePath()); int errCode; try { errCode = pb.start().waitFor(); } catch (InterruptedException e) { throw new BuildException("interrupted"); } catch (IOException e) { throw new BuildException(e); } if (0 != errCode) throw new BuildException("Hardlinking failed: " + errCode); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/Version.java000066400000000000000000000032151450515647100247510ustar00rootroot00000000000000/** * Copyright © 2010-2020 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus; public class Version { // ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries). private static final String VERSION = "1.42"; private Version() { //Prevent instantiation } /** * Prints the version followed by a newline, and exits. */ public static void main(String[] args) { System.out.println(VERSION); } /** * Get the current ivyplusplus version. */ public static String getVersion() { return VERSION; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/antlib.xml000066400000000000000000000255321450515647100244620ustar00rootroot00000000000000 public class ShowHtml { public static void main(String[] args) { try { java.awt.Desktop.getDesktop().browse(new java.io.File(args[0]).toURI()); } catch (Throwable t) { t.printStackTrace(); System.err.println("To see the file, browse to: " + new java.io.File(args[0]).toURI()); } } } public class ShowDependencyReport { public static void main(String[] args) { try { java.awt.Desktop.getDesktop().browse(new java.io.File(args[0]).toURI()); } catch (Throwable t) { t.printStackTrace(); System.err.println("To see the dependency report, browse to: " + new java.io.File(args[0]).toURI()); } } } [GIT NOT FOUND] You don't appear to have git installed. If you're on windows, try running this in your git shell. Otherwise, install git. git is a free and open source version control system. You can download it from: http://git-scm.com/ @{group} <version>@{version}</version> ${mvn.bin.md5.@{group}.@{artifact}} ${mvn.bin.sha1.@{group}.@{artifact}} ${mvn.src.md5.@{group}.@{artifact}} ${mvn.src.sha1.@{group}.@{artifact}} ${mvn.pom.md5.@{group}.@{artifact}} ${mvn.pom.sha1.@{group}.@{artifact}} <?xml version="1.0" encoding="UTF-8"?> <metadata> <groupId>@{group}</groupId> <artifactId>@{artifact}</artifactId> <version>@{version}</version> <versioning> <versions> <version>@{version}</version> ${mvn.oldversions.@{group}.@{artifact}} </versions> <lastUpdated>${now.millis.@{group}.@{artifact}}</lastUpdated> </versioning> </metadata> ${mvn.manifest.md5.@{group}.@{artifact}} ${mvn.manifest.sha1.@{group}.@{artifact}} ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/createProject/000077500000000000000000000000001450515647100252525ustar00rootroot00000000000000ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/createProject/CreateProject.java000066400000000000000000000245311450515647100306540ustar00rootroot00000000000000/** * Copyright © 2011-2020 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.createProject; import java.io.Console; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.security.Security; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Scanner; import com.zwitserloot.cmdreader.CmdReader; import com.zwitserloot.cmdreader.Description; import com.zwitserloot.cmdreader.Excludes; import com.zwitserloot.cmdreader.FullName; import com.zwitserloot.cmdreader.InvalidCommandLineException; import com.zwitserloot.cmdreader.Mandatory; import com.zwitserloot.cmdreader.Sequential; import com.zwitserloot.cmdreader.Shorthand; import com.zwitserloot.ivyplusplus.Version; import com.zwitserloot.ivyplusplus.mavencentral.CreateSigningKey; import com.zwitserloot.ivyplusplus.mavencentral.InitializeBouncyCastle; import com.zwitserloot.ivyplusplus.mavencentral.SigningException; import com.zwitserloot.ivyplusplus.template.TemplateApplier; public class CreateProject { private static class CmdArgs { @Shorthand("h") @Description("Show this command line help") boolean help; @Sequential @Mandatory(onlyIfNot={"help", "generate-key", "version"}) @Description("The name of your project. Example: com.zwitserloot.cmdreader") String projectName; @Shorthand("j") @Description("If present, a jUnit test framework will be generated.") boolean junit; @Shorthand("d") @Description("If present, javadoc ant targets will be produced.") boolean javadoc; @FullName("sonatype-forge") @Description("Creates a 'maven-build' and 'maven-upload' task that creates (and uploads) this project to Sonatype Forge. Run --generate-key to make a signing pair first if you need one.") boolean sonatypeForge; @Shorthand("f") @Description("Overwrite files if they already exist.") boolean force; @Shorthand("l") @Description("This project is not an app - do not generate a main class and dont include Main-Class in the manifest.") boolean library; @Description("Add a simple bsd-like license to the top of generated sources, using the supplied name as copyright holder.") String freeware; @Description("Generates a key pair for signing artifacts so that i.e. Sonatype Forge, which is one way to get your libraries into maven central, accepts them.") @FullName("generate-key") @Excludes({"freeware", "library", "junit", "projectName", "sonatype-forge"}) boolean generateMavenRepoSigningKey; @Description("Shows version number and exits") boolean version; } public static void main(String[] rawArgs) throws IOException { CmdReader reader = CmdReader.of(CmdArgs.class); CmdArgs args; try { args = reader.make(rawArgs); } catch (InvalidCommandLineException e) { System.err.println(e.getMessage()); System.err.println(reader.generateCommandLineHelp("java -jar ivyplusplus.jar")); System.exit(1); return; } if (args.help) { System.out.println(reader.generateCommandLineHelp("java -jar ivyplusplus.jar")); System.exit(0); return; } if (args.version) { System.out.println("ivyplusplus v" + Version.getVersion()); System.exit(0); return; } if (args.generateMavenRepoSigningKey) { System.exit(runGenerateMavenSigningKey()); return; } TemplateApplier template = new TemplateApplier(); template.put("PROJECTNAME", args.projectName); template.put("MIN_IPP_VERSION", Version.getVersion()); if (args.javadoc) template.put("JAVADOC", "true"); if (args.sonatypeForge) { template.put("JAVADOC", "true"); template.put("MAVEN", "true"); } if (args.junit) template.put("JUNIT", "true"); if (args.freeware != null) { handleAndAddFreewareCopyright(template, args.freeware, args.force); template.put("MIT_LICENSE_SET", "true"); } else { template.put("MIT_LICENSE_UNSET", "true"); } if (!args.library) template.put("APP", "true"); String organization, simpleName; { int idx = args.projectName.lastIndexOf('.'); if (idx == -1) { organization = args.projectName; simpleName = args.projectName; } else { organization = reverseOnDots(args.projectName.substring(0, idx)); simpleName = args.projectName.substring(idx + 1); } } template.put("ORGANIZATION", organization); template.put("SIMPLENAME", simpleName); template.put("PATH_TO_VERSIONJAVA", reverseOnDots(args.projectName).replace(".", "/") + "/Version.java"); new File("buildScripts").mkdir(); new File("buildScripts/ivy-repo").mkdir(); writeFile(template.applyResource(CreateProject.class, "build.xml.template"), "build.xml", args.force); writeFile(template.applyResource(CreateProject.class, "ivy.xml.template"), "buildScripts/ivy.xml", args.force); writeFile(template.applyResource(CreateProject.class, "ivysettings.xml.template"), "buildScripts/ivysettings.xml", args.force); new File("src").mkdir(); new File("src/main").mkdir(); if (args.junit) new File("src/test").mkdir(); File srcDir = new File("src/main"); File testDir = new File("src/test"); for (String pkgElem : reverseOnDots(args.projectName).split("\\.")) { srcDir = new File(srcDir, pkgElem); srcDir.mkdir(); testDir = new File(testDir, pkgElem); if (args.junit) testDir.mkdir(); } if (!args.library) { writeFile(template.applyResource(CreateProject.class, "Main.java.template"), new File(srcDir, "Main.java").getPath(), args.force); } if (args.sonatypeForge) { File docDir = new File("doc"); docDir.mkdir(); writeFile(template.applyResource(CreateProject.class, "maven-pom.xml.template"), new File(docDir, "maven-pom.xml").getPath(), args.force); System.out.println("doc/maven-pom.xml is a pom skeleton.\nYou'll need to edit it and replace all the stuff between the exclamation marks with appropriate strings."); } writeFile(template.applyResource(CreateProject.class, "Version.java.template"), new File(srcDir, "Version.java").getPath(), args.force); } private static int runGenerateMavenSigningKey() { try { InitializeBouncyCastle.init(); } catch (SigningException e) { System.err.println(e.getMessage()); return 12; } System.out.println(java.util.Arrays.toString(Security.getProviders())); System.out.println("Generating a new key pair. The generated key pair will be used by the task."); System.out.print("What is the full name of the owner of this key: "); @SuppressWarnings("resource") Scanner s = new Scanner(System.in); String fullName = s.nextLine(); System.out.print("What is the email of the owner of this key: " ); String email = s.nextLine(); String identity = fullName + " <" + email + ">"; System.out.println("Key's identity: " + identity); System.out.println(); System.out.println("Hit enter to set a blank passphrase.\n" + "This means anyone with the key ring file can sign as you,\n" + "so don't do this unless you know what you're doing!"); Console console = System.console(); String passphrase, verify; if (console == null) { System.out.print("Passphrase for this key: "); passphrase = s.nextLine(); System.out.print("Repeat passphrase: "); verify = s.nextLine(); } else { System.out.print("Passphrase for this key: "); passphrase = new String(console.readPassword()); System.out.print("Repeat passphrase: "); verify = new String(console.readPassword()); } if (!passphrase.equals(verify)) { System.err.println("Passwords do not match - key creation aborted."); return 5; } try { new CreateSigningKey().createSigningKey(identity, passphrase, System.out); } catch (IOException e) { System.err.println("Problem creating passkey files. Is the current directory writable?"); System.err.println(e); return 1; } catch (SigningException e) { System.err.println("Problem creating keys: " + e.getMessage()); return 1; } System.out.println("Key files created. You don't need mavenrepo-signing-key-public.bpr, but its there if you want others to be able to encrypt things so only you can read them."); return 0; } private static String reverseOnDots(String in) { StringBuilder sb = new StringBuilder(); for (String elem : in.split("\\.")) { if (sb.length() > 0) sb.append("."); sb.append(elem); } return sb.toString(); } private static void writeFile(String content, String fileName, boolean force) throws IOException { File f = new File(fileName); if (f.exists() && !force) { throw new IllegalStateException(String.format("File %s already exists. Delete it first if you want me to overwrite it, or use --force", f)); } FileOutputStream fos = new FileOutputStream(fileName); try { fos.write(content.getBytes("UTF-8")); } finally { fos.close(); } } private static void handleAndAddFreewareCopyright(TemplateApplier template, String holder, boolean force) throws IOException { template.put("YEAR", String.valueOf(new GregorianCalendar().get(Calendar.YEAR))); template.put("HOLDER", holder); String copyright = template.applyResource(CreateProject.class, "simpleLicense.txt.template"); template.put("COPYRIGHT", copyright); String sourceCopyright = " * " + copyright.replace("\n", "\n * "); if (sourceCopyright.endsWith(" * ")) sourceCopyright = sourceCopyright.substring(0, sourceCopyright.length() - 3) + "\n"; template.put("SOURCE_COPYRIGHT",sourceCopyright); writeFile(copyright, "LICENSE", force); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/createProject/Main.java.template000066400000000000000000000003471450515647100306170ustar00rootroot00000000000000{{if SOURCE_COPYRIGHT}} /** {{@SOURCE_COPYRIGHT}} */ {{end SOURCE_COPYRIGHT}} package {{@PROJECTNAME}}; public class Main { public static void main(String[] args) { System.out.println("Hello, world! - {{@PROJECTNAME}}"); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/createProject/Version.java.template000066400000000000000000000011501450515647100313510ustar00rootroot00000000000000{{if SOURCE_COPYRIGHT}} /** {{@SOURCE_COPYRIGHT}} */ {{end SOURCE_COPYRIGHT}} package {{@PROJECTNAME}}; public class Version { // ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries). private static final String VERSION = "0.1"; private Version() { //Prevent instantiation } /** * Prints the version followed by a newline, and exits. */ public static void main(String[] args) { System.out.println(VERSION); } /** * Get the current {{@PROJECTNAME}} version. */ public static String getVersion() { return VERSION; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/createProject/build.xml.template000066400000000000000000000220311450515647100307030ustar00rootroot00000000000000{{if COPYRIGHT}} {{end COPYRIGHT}} {{if DESCRIPTION}} {{@DESCRIPTION}} {{end DESCRIPTION}} {{if JUNIT}} {{end JUNIT}} ivyplusplus has been updated to a new version. Restart the script to continue. {{@PROJECTNAME}} version: ${app.version} {{if JUNIT}} {{end JUNIT}} {{if JAVADOC}} {{end JAVADOC}} {{if JUNIT}} {{end JUNIT}} {{if APP}} {{end APP}} {{if JAVADOC}} {{end JAVADOC}} {{if JUNIT}} All tests successful. {{end JUNIT}} {{if JAVADOC}} {{end JAVADOC}} {{if JUNIT}} {{end JUNIT}} {{if JUNIT}} {{end JUNIT}} {{if JUNIT}} {{end JUNIT}} {{if JUNIT}} {{end JUNIT}} {{if MAVEN}} {{end MAVEN}} ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/createProject/ivy.xml.template000066400000000000000000000014411450515647100304150ustar00rootroot00000000000000 {{if JUNIT}} {{end JUNIT}} {{if JUNIT}} {{end JUNIT}} ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/createProject/ivysettings.xml.template000066400000000000000000000010171450515647100321750ustar00rootroot00000000000000 ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/createProject/maven-pom.xml.template000066400000000000000000000027061450515647100315120ustar00rootroot00000000000000 4.0.0 {{@ORGANIZATION}} {{@SIMPLENAME}} jar @VERSION@ {{@PROJECTNAME}} !! FILL IN URL TO PROJECT SITE HERE !! !! FILL IN DESCRIPTION HERE !! {{if MIT_LICENSE_SET}} The MIT License !! URL TO PROJECT SITE HERE !!/LICENSE {{end MIT_LICENSE_SET}} {{if MIT_LICENSE_UNSET}} !! FILL IN LICENSE NAME HERE !! !! URL TO LICENSE HERE !! {{end MIT_LICENSE_UNSET}} repo scm:git:git://github.com/!!git username here!!/!!gitname here!!.git scm:git:git://github.com/!!git username here!!/!!gitname here!!.git GitHub https://github.com/!!username!!/!!projectname!!/issues !!your name!! !!your full name!! !!your mail!! !!your site!! !!your timestamp!! ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/createProject/simpleLicense.txt.template000066400000000000000000000020441450515647100324210ustar00rootroot00000000000000Copyright © {{@YEAR}} {{@HOLDER}}. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/000077500000000000000000000000001450515647100232215ustar00rootroot00000000000000ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/Assure.java000066400000000000000000000141421450515647100253300ustar00rootroot00000000000000/********************************************************************** * Copyright (c) 2005-2009 ant4eclipse project team. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich **********************************************************************/ package com.zwitserloot.ivyplusplus.ecj; import java.io.File; /** * Implements utility methods to support design-by-contract. If a condition is * evaluated to false, a RuntimeException will be thrown. * * @author Gerd Wütherich (gerd@gerd-wuetherich.de) * @author Daniel Kasmeroglu (daniel.kasmeroglu@kasisoft.net) */ public class Assure { /** * Assert that the specified object is not null. * * @param parameterName The name of the parameter that is checked * @param object The object that must be set. */ public static final void notNull(String parameterName, Object object) { if (object == null) throw new NullPointerException(parameterName); } /** * Asserts that the specified array is neither {@code null} nor empty. * * @param parametername The name of the parameter that has to be tested. * @param object The object that has to be tested. */ public static final void nonEmpty(String parameterName, byte[] object) { notNull(parameterName, object); if (object.length == 0) throw new IllegalArgumentException("empty " + parameterName); } /** * Asserts that the specified array is neither {@code null} nor empty. * * @param parametername The name of the parameter that has to be tested. * @param object The object that has to be tested. */ public static final void nonEmpty(String parameterName, boolean[] object) { notNull(parameterName, object); if (object.length == 0) throw new IllegalArgumentException("empty " + parameterName); } /** * Asserts that the specified array is neither {@code null} nor empty. * * @param parametername The name of the parameter that has to be tested. * @param object The object that has to be tested. */ public static final void nonEmpty(String parameterName, char[] object) { notNull(parameterName, object); if (object.length == 0) throw new IllegalArgumentException("empty " + parameterName); } /** * Asserts that the specified array is neither {@code null} nor empty. * * @param parametername The name of the parameter that has to be tested. * @param object The object that has to be tested. */ public static final void nonEmpty(String parameterName, short[] object) { notNull(parameterName, object); if (object.length == 0) throw new IllegalArgumentException("empty " + parameterName); } /** * Asserts that the specified array is neither null nor empty. * Asserts that the specified array is neither {@code null} nor empty. * * @param parametername The name of the parameter that has to be tested. * @param object The object that has to be tested. */ public static final void nonEmpty(String parameterName, int[] object) { notNull(parameterName, object); if (object.length == 0) throw new IllegalArgumentException("empty " + parameterName); } /** * Asserts that the specified array is neither {@code null} nor empty. * * @param parametername The name of the parameter that has to be tested. * @param object The object that has to be tested. */ public static final void nonEmpty(String parameterName, long[] object) { notNull(parameterName, object); if (object.length == 0) throw new IllegalArgumentException("empty " + parameterName); } /** * Asserts that the given parameter is an instance of the given type. * * @param parameterName The name of the parameter that is checked. * @param parameter The actual parameter value. * @param expectedType The type the parameter should be an instance of. */ public static final void instanceOf(String parameterName, Object parameter, Class expectedType) { notNull(parameterName, parameter); if (!expectedType.isInstance(parameter)) throw new IllegalArgumentException("Expected type " + expectedType.getSimpleName() + " for " + parameterName); } /** * Assert that the supplied string isn't empty. * * @param string The string that must not be empty. */ public static final void nonEmpty(String parameterName, String string) { notNull(parameterName, string); if (string.length() == 0) throw new IllegalArgumentException("empty " + parameterName); } /** * Assert that the specified file is not null and exists. * * @param file The file that must exist. */ public static final void exists(String parameterName, File file) { notNull(parameterName, file); if (!file.exists()) throw new IllegalArgumentException(parameterName + " does not exist"); } /** * Assert that the specified file is not null, exists and is a file. * * @param file The file that must be a file. */ public static final void isFile(String parameterName, File file) { Assure.exists(parameterName, file); if (!file.isFile()) throw new IllegalArgumentException(parameterName + " not a file"); } /** * Assert that the specified file is not null, exists and is a directory. * * @param file The file that must be a directory. */ public static final void isDirectory(String parameterName, File file) { Assure.exists(parameterName, file); if (!file.isDirectory()) throw new IllegalArgumentException(parameterName + " not a directory"); } public static final void assertTrue(boolean condition, String msg) { if (!condition) throw new IllegalStateException("precondition not met: " + msg); } /** * Checks whether a value is in a specific range or not. * * @param value The value that shall be tested. * @param from The lower bound inclusive. * @param to The upper bound inclusive. */ public static final void inRange(int value, int from, int to) { if ((value < from) || (value > to)) throw new IllegalStateException("Value expected to be in range [" + from + ", " + to + "], not " + value); } }ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/ClassName.java000066400000000000000000000070021450515647100257310ustar00rootroot00000000000000/********************************************************************** * Copyright (c) 2005-2009 ant4eclipse project team. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich **********************************************************************/ package com.zwitserloot.ivyplusplus.ecj; /** * Represents a qualified class name. * * @author Nils Hartmann (nils@nilshartmann.net) */ public final class ClassName { private String _packageName; private String _className; private String _qualifiedName; private ClassName(String qualifiedClassName) { this._qualifiedName = qualifiedClassName; this._packageName = ""; this._className = qualifiedClassName; int v = qualifiedClassName.lastIndexOf('.'); if (v != -1) { this._packageName = qualifiedClassName.substring(0, v); this._className = qualifiedClassName.substring(v + 1); } } /** * Returns the qualified name of this class as a java type identifier (e.g. * {@code foo.bar.Bazz}). * * @return The qualified class name. Neither {@code null} nor empty. */ public String getQualifiedClassName() { return this._qualifiedName; } /** * Returns the name of this class without package (e.g. {@code Bazz}). * * @return Name of this class. Never null. */ public String getClassName() { return this._className; } /** * Returns the package name of this class (e.g. {@code foo.bar}). * * @return Package name of this class. Never null. */ public String getPackageName() { return this._packageName; } /** * Returns this package as a directory name (e.g. {@code foo/bar}). * * @return this package as a directory name. Never null. */ public String getPackageAsDirectoryName() { return getPackageName().replace('.', '/'); } /** * Returns this class name as a classname including the package directory * structure and the ".class" postfix. (e.g. * {@code foo/bar/Bazz.class}). * * @return this class name as a file name. */ public String asClassFileName() { String fileName = getQualifiedClassName().replace('.', '/'); return fileName + ".class"; } /** * Returns this class name as a classname including the package directory * structure and the ".java" ending (e.g. {@code foo/bar/Bazz.java}). * * @return this class name as a file name. */ public String asSourceFileName() { String fileName = getQualifiedClassName().replace('.', '/'); return fileName + ".java"; } @Override public String toString() { return this._qualifiedName; } @Override public int hashCode() { return this._qualifiedName.hashCode(); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; ClassName other = (ClassName) obj; return this._qualifiedName.equals(other._qualifiedName); } /** * Returns a new instance of type {@link ClassName} representing the given * qualified class name. * * @param qualifiedClassName The qualified class name * @return a ClassName instance representing this qualified class name */ public static final ClassName fromQualifiedClassName(String qualifiedClassName) { Assure.nonEmpty("qualifiedClassName", qualifiedClassName); return new ClassName(qualifiedClassName); } }ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/CompilationUnitImpl.java000066400000000000000000000073531450515647100300340ustar00rootroot00000000000000/********************************************************************** * Copyright (c) 2005-2009 ant4eclipse project team. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich **********************************************************************/ package com.zwitserloot.ivyplusplus.ecj; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.StringTokenizer; import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; /** *

* Adapter class for providing java source files to the eclipse java compiler. *

* * @author Nils Hartmann (nils@nilshartmann.net) * @author Gerd Wütherich (gerd@gerd-wuetherich.de) */ public class CompilationUnitImpl implements ICompilationUnit { private static final String JAVA_FILE_POSTFIX = ".java"; private SourceFile _sourceFile; /** the file name, relative to the source folder */ private char[] _fileName; /** the name of the top level public type, e.g. {Hashtable} */ private char[] _mainTypeName; /** the name of the package , e.g. {java, lang} */ private char[][] _packageName; public CompilationUnitImpl(SourceFile sourceFile) { Assure.notNull("sourceFile", sourceFile); this._sourceFile = sourceFile; this._fileName = this._sourceFile.getSourceFileName().toCharArray(); // compute qualified name String qualifiedTypeName = getQualifiedTypeName(this._sourceFile.getSourceFileName()); // compute package and main type name int v = qualifiedTypeName.lastIndexOf('.'); this._mainTypeName = qualifiedTypeName.substring(v + 1).toCharArray(); if ((v > 0) && (v < qualifiedTypeName.length())) { String packageName = qualifiedTypeName.substring(0, v); StringTokenizer packages = new StringTokenizer(packageName, "."); this._packageName = new char[packages.countTokens()][]; for (int i = 0; i < this._packageName.length; i++) { this._packageName[i] = packages.nextToken().toCharArray(); } } else { this._packageName = new char[0][]; } } public final char[] getMainTypeName() { return this._mainTypeName; } public final char[][] getPackageName() { return this._packageName; } public final char[] getFileName() { return this._fileName; } public final char[] getContents() { String filename = new String(this._fileName); File sourceFile = new File(this._sourceFile.getSourceFolder(), filename); StringBuffer result = new StringBuffer(); try ( FileInputStream rawIn = new FileInputStream(sourceFile); BufferedReader in = new BufferedReader(new InputStreamReader(rawIn, this._sourceFile.getEncoding())); ) { String str; while ((str = in.readLine()) != null) { result.append(str); result.append("\n"); } } catch (UnsupportedEncodingException e) { throw new IllegalStateException("Unable to read compilation content (encoding)", e); } catch (IOException e) { throw new IllegalStateException("Unable to read compilation content (I/O)", e); } return result.toString().toCharArray(); } public SourceFile getSourceFile() { return this._sourceFile; } private String getQualifiedTypeName(String fileName) { if (fileName.toLowerCase().endsWith(JAVA_FILE_POSTFIX)) { return fileName.substring(0, fileName.length() - 5).replace(File.separatorChar, '.'); } else { return fileName.replace(File.separatorChar, '.'); } } public boolean ignoreOptionalProblems() { return false; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/CompileJobDescription.java000066400000000000000000000022751450515647100303210ustar00rootroot00000000000000/********************************************************************** * Copyright (c) 2005-2009 ant4eclipse project team. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich **********************************************************************/ package com.zwitserloot.ivyplusplus.ecj; import java.util.Map; import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath; /** * A {@link CompileJobDescription} describes a compile job that can be executed * with the eclipse java compiler. * * @author Gerd Wütherich (gerd@gerd-wuetherich.de) */ public interface CompileJobDescription { Map getCompilerOptions(); /** * Returns an array of directories that contains the source files that * should be compiled. * * @return an array of directories that contains the source files that * should be compiled. */ SourceFile[] getSourceFiles(); Classpath[] getClasspaths(); } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/CompileJobDescriptionImpl.java000066400000000000000000000066451450515647100311500ustar00rootroot00000000000000/********************************************************************** * Copyright (c) 2005-2009 ant4eclipse project team. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich **********************************************************************/ package com.zwitserloot.ivyplusplus.ecj; import java.util.Arrays; import java.util.Iterator; import java.util.Map; import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath; /** * Default implementation of a {@link CompileJobDescription}. * * @author Gerd Wütherich (gerd@gerd-wuetherich.de) */ public class CompileJobDescriptionImpl implements CompileJobDescription { private Classpath[] _classpaths; private Map _compilerOptions; private SourceFile[] _sourceFiles; public CompileJobDescriptionImpl() {} public CompileJobDescriptionImpl(Classpath[] classpaths, Map compilerOptions, SourceFile[] sourceFiles) { Assure.notNull("classpaths", classpaths); Assure.notNull("compilerOptions", compilerOptions); Assure.notNull("sourceFiles", sourceFiles); this._classpaths = classpaths; this._compilerOptions = compilerOptions; this._sourceFiles = sourceFiles; } public Classpath[] getClasspaths() { return this._classpaths; } public Map getCompilerOptions() { return this._compilerOptions; } public SourceFile[] getSourceFiles() { return this._sourceFiles; } public void setClasspaths(Classpath[] classpaths) { Assure.notNull("classpaths", classpaths); this._classpaths = classpaths; } public void setCompilerOptions(Map compilerOptions) { Assure.notNull("compilerOptions", compilerOptions); this._compilerOptions = compilerOptions; } public void setSourceFiles(SourceFile[] sourceFiles) { Assure.notNull("sourceFiles", sourceFiles); this._sourceFiles = sourceFiles; } @Override public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("[DefaultCompileJobDescription:"); buffer.append(" _classpaths: "); buffer.append(Arrays.toString(this._classpaths)); buffer.append(", _compilerOptions: {"); if ((this._compilerOptions != null) && (this._compilerOptions.size() > 0)) { Iterator> iterator = this._compilerOptions.entrySet().iterator(); Map.Entry current = iterator.next(); buffer.append("("); buffer.append(current.getKey()); buffer.append(","); buffer.append(current.getValue()); buffer.append(")"); while (iterator.hasNext()) { buffer.append(","); current = iterator.next(); buffer.append("("); buffer.append(current.getKey()); buffer.append(","); buffer.append(current.getValue()); buffer.append(")"); } } buffer.append(this._compilerOptions); buffer.append("}"); buffer.append(", _sourceFiles: {"); if ((this._sourceFiles != null) && (this._sourceFiles.length > 0)) { buffer.append(this._sourceFiles[0]); for (int i = 1; i < this._sourceFiles.length; i++) { buffer.append(", "); buffer.append(this._sourceFiles[i]); } } buffer.append(Arrays.toString(this._sourceFiles)); buffer.append("}"); buffer.append("]"); return buffer.toString(); } }ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/CompileJobResult.java000066400000000000000000000016731450515647100273150ustar00rootroot00000000000000/********************************************************************** * Copyright (c) 2005-2009 ant4eclipse project team. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich **********************************************************************/ package com.zwitserloot.ivyplusplus.ecj; import org.eclipse.jdt.core.compiler.CategorizedProblem; import java.io.File; import java.util.Map; /** * The {@link CompileJobResult} represents a compile job result. * * @author Gerd Wütherich (gerd@gerd-wuetherich.de) */ public interface CompileJobResult { boolean succeeded(); CategorizedProblem[] getCategorizedProblems(); Map getCompiledClassFiles(); } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/CompileJobResultImpl.java000066400000000000000000000037441450515647100301400ustar00rootroot00000000000000/********************************************************************** * Copyright (c) 2005-2009 ant4eclipse project team. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich **********************************************************************/ package com.zwitserloot.ivyplusplus.ecj; import org.eclipse.jdt.core.compiler.CategorizedProblem; import java.io.File; import java.util.Arrays; import java.util.Collections; import java.util.Map; public class CompileJobResultImpl implements CompileJobResult { private boolean _succeeded; private CategorizedProblem[] _categorizedProblems; private Map _compiledClassFiles; public boolean succeeded() { return this._succeeded; } public CategorizedProblem[] getCategorizedProblems() { return this._categorizedProblems == null ? new CategorizedProblem[0] : this._categorizedProblems; } public void setSucceeded(boolean succeeded) { this._succeeded = succeeded; } public void setCategorizedProblems(CategorizedProblem[] categorizedProblems) { this._categorizedProblems = categorizedProblems; } public Map getCompiledClassFiles() { return this._compiledClassFiles == null ? Collections.emptyMap() : this._compiledClassFiles; } /** * Changes the map which contains the compiled class files. * * @param compiledclasses A map for the class files. Maybe {@code null}. */ public void setCompiledClassFiles(Map compiledClasses) { this._compiledClassFiles = compiledClasses; } @Override public String toString() { return "CompileJobResultImpl [succeeded=" + _succeeded + ", categorizedProblems=" + Arrays.toString(_categorizedProblems) + ", compiledClassFiles=" + _compiledClassFiles + "]"; } }ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/CompilerOptionsProvider.java000066400000000000000000000356021450515647100307330ustar00rootroot00000000000000/********************************************************************** * Copyright (c) 2005-2009 ant4eclipse project team. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich **********************************************************************/ package com.zwitserloot.ivyplusplus.ecj; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.taskdefs.Javac; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.util.Util; /** * The {@link CompilerOptionsProvider} is a utility class that computes compiler * options based on ant's javac task as well as an (optional) project specific * and an (optional) global compiler options file. * * @author Gerd Wütherich (gerd@gerd-wuetherich.de) */ public class CompilerOptionsProvider { /** * This property enables the javadoc parsing in ECJ (same as -enableJavadoc on the command line) */ public static final String ENABLE_JAVADOC_SUPPORT = "org.eclipse.jdt.core.compiler.doc.comment.support"; public static final String FORBIDDEN_REFERENCE = "org.eclipse.jdt.core.compiler.problem.forbiddenReference"; /** prefix used for the exported preferences */ private static final String PREFS_INSTANCE = "/instance/"; /** we're only interested in jdt settings */ private static final String PREFS_JDTTYPE = "org.eclipse.jdt.core/"; private static final String VERSION_1_9 = "9"; /** * Creates the compiler options for the JDT compiler. * * The compiler options are defined here: * * * @param javac The javac task. * @param projectCompilerOptionsFile The project specific compiler options file. * @param globalCompilerOptionsFile The global compiler options file. * @return the map with the merged compiler options. */ public static final Map getCompilerOptions(Javac javac, String projectCompilerOptionsFile, String globalCompilerOptionsFile) { Assure.notNull("javac", javac); // get the project options Map projectOptions = getFileCompilerOptions(projectCompilerOptionsFile); // get the default options Map defaultOptions = getFileCompilerOptions(globalCompilerOptionsFile); // get the javac options Map javacOptions = getJavacCompilerOptions(javac); // merge the map Map mergedMap = mergeCompilerOptions(projectOptions, defaultOptions, javacOptions); // [AE-201] If not enabled/disabled explicitly, enable ECJ javadoc parsing support to find references inside javadoc if (!mergedMap.containsKey(ENABLE_JAVADOC_SUPPORT)) mergedMap.put(ENABLE_JAVADOC_SUPPORT, "enabled"); // If not enabled/disabled explicitly, set ECJ forbidden reference to 'error' if (!mergedMap.containsKey(FORBIDDEN_REFERENCE)) mergedMap.put(FORBIDDEN_REFERENCE, "error"); CompilerOptions compilerOptions = new CompilerOptions(mergedMap); compilerOptions.verbose = javac.getVerbose(); compilerOptions.complianceLevel = compilerOptions.sourceLevel; long v16 = CompilerOptions.versionToJdkLevel(CompilerOptions.VERSION_1_6); if (v16 > compilerOptions.sourceLevel) compilerOptions.complianceLevel = v16; if (javac.getNowarn()) { compilerOptions.suppressWarnings = true; compilerOptions.suppressOptionalErrors = true; } // return the compiler options Map result = new HashMap(); result.putAll(compilerOptions.getMap()); return result; } /** * Returns the compiler options specified in the javac task. * * @param javac the javac task * @return the compiler options specified in the javac task. */ @SuppressWarnings("unchecked") private static final Map getJavacCompilerOptions(Javac javac) { Map result = new HashMap(); if (javac.getSource() != null && !javac.getSource().isEmpty()) { String source = javac.getSource(); if (source.equals("1.3")) { result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3); } else if (source.equals("1.4")) { result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4); } else if (source.equals("1.5") || source.equals("5") || source.equals("5.0")) { result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5); } else if (source.equals("1.6") || source.equals("6") || source.equals("6.0")) { result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6); } else if (source.equals("1.7") || source.equals("7") || source.equals("7.0")) { result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7); } else if (source.equals("1.8") || source.equals("8") || source.equals("8.0")) { result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8); } else if (source.equals("9") || source.equals("9.0")) { result.put(CompilerOptions.OPTION_Source, VERSION_1_9); } else { throw new BuildException("Unknown java source: " + source); } } if (javac.getTarget() != null && !javac.getTarget().isEmpty()) { String target = javac.getTarget(); if (target.equals("1.3")) { result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_3); result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_3); } else if (target.equals("1.4")) { result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4); } else if (target.equals("1.5") || target.equals("5") || target.equals("5.0")) { result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5); result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5); } else if (target.equals("1.6") || target.equals("6") || target.equals("6.0")) { result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6); } else if (target.equals("1.7") || target.equals("7") || target.equals("7.0")) { result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7); result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7); } else if (target.equals("1.8") || target.equals("8") || target.equals("8.0")) { result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8); result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8); } else if (target.equals("9") || target.equals("9.0")) { result.put(CompilerOptions.OPTION_TargetPlatform, VERSION_1_9); result.put(CompilerOptions.OPTION_Compliance, VERSION_1_9); } else { throw new BuildException("Unknown java target: " + target); } } if (javac.getRelease() != null && !javac.getRelease().isEmpty()) { String release = javac.getRelease(); if (release.equals("9")) { result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_9); result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9); result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_9); } else if (release.equals("10")) { result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_10); result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10); result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_10); } else if (release.equals("11")) { result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_11); result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11); result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11); } else if (release.equals("12")) { result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); } else if (release.equals("13")) { result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13); result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13); result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13); } else { throw new BuildException("unknown java release: " + release); } } if (javac.getDebug()) { String debugLevel = javac.getDebugLevel(); if (debugLevel != null) { result.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE); result.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE); result.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.DO_NOT_GENERATE); if (debugLevel.length() != 0) { if (debugLevel.indexOf("vars") != -1) { result.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE); } if (debugLevel.indexOf("lines") != -1) { result.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE); } if (debugLevel.indexOf("source") != -1) { result.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.GENERATE); } } } else { result.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE); result.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE); result.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.GENERATE); } } else { result.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE); result.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE); result.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.DO_NOT_GENERATE); } /* * Handle the nowarn option. If none, then we generate all warnings. */ if (javac.getNowarn()) { // disable all warnings Map.Entry[] entries = result.entrySet().toArray(new Map.Entry[result.size()]); for (Entry entrie : entries) { Map.Entry entry = entrie; if (entry.getValue().equals(CompilerOptions.WARNING)) { result.put(entry.getKey(), CompilerOptions.IGNORE); } } result.put(CompilerOptions.OPTION_TaskTags, Util.EMPTY_STRING); if (javac.getDeprecation()) { result.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING); result.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.ENABLED); result.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.ENABLED); } } else if (javac.getDeprecation()) { result.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING); result.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.ENABLED); result.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.ENABLED); } else { result.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE); result.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.DISABLED); result.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.DISABLED); } if (javac.getEncoding() != null) result.put(CompilerOptions.OPTION_Encoding, javac.getEncoding()); return result; } /** * Returns the compiler options for the given compiler options file. * * If fileName is null or empty no file is read. * * @param fileName The compiler options file. Might be null or empty string. * @return the map with the compiler options. */ private static final Map getFileCompilerOptions(String fileName) { if (fileName != null && !fileName.isEmpty()) { try { File compilerOptionsFile = new File(fileName); if (compilerOptionsFile.exists() && compilerOptionsFile.isFile()) { Map compilerOptionsMap = propertiesAsMap(compilerOptionsFile); compilerOptionsMap = convertPreferences(compilerOptionsMap); return compilerOptionsMap; } } catch (Exception e) { throw new BuildException(String.format("Could not read compiler options file '%s'.\nReason: '%s'", fileName, e.getMessage())); } } return null; } private static Map propertiesAsMap(File propertiesFile) { Map result = new HashMap(); try { try (FileInputStream fis = new FileInputStream(propertiesFile)) { Properties properties = new Properties(); properties.load(fis); for (Map.Entry entry : properties.entrySet()) { result.put((String) entry.getKey(), (String) entry.getValue()); } return result; } } catch (IOException e) { throw new BuildException(e); } } /** * This function alters the supplied options so exported preferences * containing jdt compiler settings will be altered while removing the * preference related prefix. * * @param options * The options currently used. Maybe an exported preferences * file. Not null. * * @return The altered settings. Not null. */ private static final Map convertPreferences(Map options) { Map result = new HashMap(); for (Map.Entry entry : options.entrySet()) { if (entry.getKey().startsWith(PREFS_INSTANCE)) { // this is an exported preferences key String key = entry.getKey().substring(PREFS_INSTANCE.length()); if (key.startsWith(PREFS_JDTTYPE)) { // we've got a jdt related setting, so use it key = key.substring(PREFS_JDTTYPE.length()); result.put(key, entry.getValue()); } } else { // not recognized as a preferences key result.put(entry.getKey(), entry.getValue()); } } return result; } private static final Map mergeCompilerOptions(Map a, Map b, Map c) { Map result = new HashMap(); if (c != null) result.putAll(c); if (b != null) result.putAll(b); if (a != null) result.putAll(a); return result; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/CompilerRequestorImpl.java000066400000000000000000000100221450515647100303650ustar00rootroot00000000000000/********************************************************************** * Copyright (c) 2005-2009 ant4eclipse project team. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich **********************************************************************/ package com.zwitserloot.ivyplusplus.ecj; import org.eclipse.jdt.core.compiler.CategorizedProblem; import org.eclipse.jdt.internal.compiler.ClassFile; import org.eclipse.jdt.internal.compiler.CompilationResult; import org.eclipse.jdt.internal.compiler.ICompilerRequestor; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; import java.util.Collections; import java.util.Hashtable; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * Implements the call-back interface {@link ICompilerRequestor} for receiving compilation results. The * {@link CompilerRequestorImpl} writes the compiled class files to disc or reports the errors in case the compilation * was not successful. * * @author Nils Hartmann (nils@nilshartmann.net) */ public class CompilerRequestorImpl implements ICompilerRequestor { /** Indicates whether the compilation was successful or not. */ protected boolean _compilationSuccessful; /** The list of categorized problems. */ protected List _categorizedProblems; /** Collection of class files which have been compiled */ private Map _compiledClassFiles; public CompilerRequestorImpl() { this._compilationSuccessful = true; this._categorizedProblems = new LinkedList(); this._compiledClassFiles = new Hashtable(); } public Map getCompiledClassFiles() { return Collections.unmodifiableMap(this._compiledClassFiles); } public void acceptResult(CompilationResult result) { CompilationUnitImpl compilationUnitImpl = (CompilationUnitImpl) result.getCompilationUnit(); SourceFile sourceFile = compilationUnitImpl.getSourceFile(); File destinationDirectory = sourceFile.getDestinationFolder(); this._compilationSuccessful = false; if (!result.hasErrors()) { this._compilationSuccessful = true; ClassFile[] classFiles = result.getClassFiles(); for (ClassFile classFile2 : classFiles) { char[][] compoundName = classFile2.getCompoundName(); StringBuffer classFileName = new StringBuffer(); for (int j = 0; j < compoundName.length; j++) { classFileName.append(compoundName[j]); if (j < compoundName.length - 1) classFileName.append('/'); } classFileName.append(".class"); File classFile = new File(destinationDirectory, classFileName.toString()); File classDir = classFile.getParentFile(); if (!classDir.exists()) classDir.mkdirs(); writeFile(classFile, classFile2.getBytes()); this._compiledClassFiles.put(classFileName.toString(), classFile); } } if (result.getAllProblems() != null) this._categorizedProblems.addAll(Arrays.asList(result.getAllProblems())); } public boolean isCompilationSuccessful() { return this._compilationSuccessful; } public CategorizedProblem[] getCategorizedProblems() { return this._categorizedProblems.toArray(new CategorizedProblem[0]); } /** * This function stores a file under a specified location using a chosen encoding. * * @param destination The destination where the file has to be written to. Not {@code null}. * @param content The content that has to be written. Not {@code null}. */ public static final void writeFile(File destination, byte[] content) { Assure.notNull("destination", destination); Assure.notNull("content", content); try (OutputStream output = new FileOutputStream(destination)) { output.write(content); } catch (IOException ex) { throw new RuntimeException(ex); } } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/DefaultReferableType.java000066400000000000000000000034661450515647100301330ustar00rootroot00000000000000/********************************************************************** * Copyright (c) 2005-2008 ant4eclipse project team. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich **********************************************************************/ package com.zwitserloot.ivyplusplus.ecj; import org.eclipse.jdt.internal.compiler.env.AccessRestriction; /** * {@link DefaultReferableType} is the base class of all referable types. * * @author Gerd Wuetherich (gerd@gerd-wuetherich.de) */ public class DefaultReferableType implements ReferableType { private String _libraryLocation; private byte _libraryType; private AccessRestriction _accessRestriction; public DefaultReferableType() {} protected DefaultReferableType(String libraryLocation, byte libraryType) { Assure.notNull("libraryLocation", libraryLocation); this._libraryLocation = libraryLocation; this._libraryType = libraryType; } public String getLibraryLocation() { return this._libraryLocation; } public byte getLibraryType() { return this._libraryType; } public final AccessRestriction getAccessRestriction() { return this._accessRestriction; } public final boolean hasAccessRestriction() { return this._accessRestriction != null; } public final void setAccessRestriction(AccessRestriction accessRestriction) { this._accessRestriction = accessRestriction; } public void setLibraryLocation(String libraryLocation) { this._libraryLocation = libraryLocation; } public void setLibraryType(byte libraryType) { this._libraryType = libraryType; } }ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/EcjAdapter.java000066400000000000000000000424271450515647100260770ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.ecj; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.lang.reflect.Field; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import javax.tools.StandardLocation; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Javac; import org.apache.tools.ant.taskdefs.compilers.CompilerAdapter; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.resources.FileResource; import org.eclipse.jdt.core.compiler.CategorizedProblem; import org.eclipse.jdt.internal.compiler.Compiler; import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy; import org.eclipse.jdt.internal.compiler.IProblemFactory; import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseAnnotationProcessorManager; import org.eclipse.jdt.internal.compiler.apt.dispatch.BatchAnnotationProcessorManager; import org.eclipse.jdt.internal.compiler.apt.dispatch.BatchProcessingEnvImpl; import org.eclipse.jdt.internal.compiler.apt.util.EclipseFileManager; import org.eclipse.jdt.internal.compiler.batch.FileSystem; import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath; import org.eclipse.jdt.internal.compiler.batch.Main; import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; import org.eclipse.jdt.internal.compiler.env.IModuleAwareNameEnvironment; import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; import org.eclipse.jdt.internal.compiler.util.Util; public class EcjAdapter implements CompilerAdapter { static final byte PROJECT = 1; static final byte LIBRARY = 2; private static final String COMPILER_OPTIONS_FILE = "compiler.options.file"; private static final String COMPILER_ARGS_SEPARATOR = "="; private static final String DEFAULT_COMPILER_OPTIONS_FILE = "default.compiler.options.file"; private static final String COMPILE_PROBLEM_MESSAGE = "----------\n%s. %s in %s (at line %s)\n%s\n%s\n%s\n"; private Javac javac; private boolean includeSystemBootclasspath; private Set procClasses; private Set procJars; public void setJavac(Javac javac) { this.javac = javac; } public boolean execute() throws BuildException { CompileJobDescriptionImpl description = new CompileJobDescriptionImpl(); SourceFile[] sourceFiles = getSourceFilesToCompile(); description.setSourceFiles(sourceFiles); description.setClasspaths(createClasspaths()); String compilerOptionsFileName = extractJavacCompilerArg(COMPILER_OPTIONS_FILE, null); String defaultCompilerOptionsFileName = extractJavacCompilerArg(DEFAULT_COMPILER_OPTIONS_FILE, null); Map compilerOptions = CompilerOptionsProvider.getCompilerOptions(javac, compilerOptionsFileName, defaultCompilerOptionsFileName); description.setCompilerOptions(compilerOptions); CompileJobResult compileJobResult = compile(description); CategorizedProblem[] categorizedProblems = compileJobResult.getCategorizedProblems(); // Buffer for messages StringBuilder builder = new StringBuilder(); boolean hasErrors = false; for (int i = 0; i < categorizedProblems.length; i++) { CategorizedProblem categorizedProblem = categorizedProblems[i]; if (categorizedProblem.isError() || (categorizedProblem.isWarning() && !javac.getNowarn())) { String fileName = String.valueOf(categorizedProblem.getOriginatingFileName()); for (SourceFile sourceFile : sourceFiles) { if (fileName.equals(sourceFile.getSourceFileName())) { Object[] args = new Object[7]; args[0] = Integer.valueOf(i + 1); args[1] = categorizedProblem.isError() ? "ERROR" : "WARNING"; args[2] = sourceFile.getSourceFile().getAbsolutePath(); args[3] = Integer.valueOf(categorizedProblem.getSourceLineNumber()); String[] problematicLine = readProblematicLine(sourceFile, categorizedProblem); args[4] = problematicLine[0]; args[5] = problematicLine[1]; args[6] = categorizedProblem.getMessage(); builder.append(String.format(COMPILE_PROBLEM_MESSAGE, args)); if (i + 1 == categorizedProblems.length) builder.append("----------\n"); if (categorizedProblem.isError()) hasErrors = true; } } } } if (builder.length() > 0) { if (hasErrors) { javac.getProject().log("Compile errors: \n" + builder.toString(), Project.MSG_ERR); } else { if (!javac.getNowarn()) { javac.getProject().log("Compile warnings: \n" + builder.toString(), Project.MSG_WARN); } } } // if the destination directory has been specified for the javac task we might need // to copy the generated class files if (compileJobResult.succeeded() && (javac.getDestdir() != null)) { File destdir = getCanonicalFile(javac.getDestdir()); try { cloneClasses(destdir, compileJobResult.getCompiledClassFiles()); } catch (IOException e) { throw new BuildException(e); } } // throw Exception if compilation was not successful if (!compileJobResult.succeeded() || hasErrors) throw new BuildException("Compilation not successful"); return true; } private void cloneClasses(File destDir, Map compiledClasses) throws IOException { if (!destDir.isAbsolute()) destDir = destDir.getAbsoluteFile(); for (Map.Entry entry : compiledClasses.entrySet()) { File destFile = getCanonicalFile(new File(destDir, entry.getKey())); destFile.getParentFile().mkdirs(); if (!destFile.equals(entry.getValue())) copy(entry.getValue(), destFile); } } public static final void copy(File source, File dest) throws IOException { Assure.isFile("source", source); Assure.notNull("to", dest); FileInputStream in = null; FileOutputStream out = null; FileChannel inC = null; FileChannel outC = null; in = new FileInputStream(source); out = new FileOutputStream(dest); inC = in.getChannel(); outC = out.getChannel(); inC.transferTo(0, inC.size(), outC); inC.close(); outC.close(); in.close(); out.close(); } private static final File getCanonicalFile(File file) { Assure.notNull("file", file); try { return file.getCanonicalFile(); } catch (IOException ex) { return file.getAbsoluteFile(); } } private String[] readProblematicLine(SourceFile sourceFile, CategorizedProblem categorizedProblem) { Assure.notNull("sourceFile", sourceFile); Assure.notNull("categorizedProblem", categorizedProblem); int lineNumber = categorizedProblem.getSourceLineNumber(); int sourceStart = categorizedProblem.getSourceStart(); int sourceEnd = categorizedProblem.getSourceEnd(); try { // Open the file that is the first command line parameter FileInputStream fstream = new FileInputStream(sourceFile.getSourceFile()); DataInputStream in = new DataInputStream(fstream); BufferedReader br = new BufferedReader(new InputStreamReader(in)); int lineStart = 0; String strLine = ""; // Read File Line By Line for (int i = 0; i < lineNumber; i++) { String newLine = br.readLine(); lineStart = lineStart + strLine.length(); if (i + 1 != lineNumber) lineStart = lineStart + 1; strLine = newLine; } in.close(); StringBuilder underscoreLine = new StringBuilder(); for (int i = lineStart; i < sourceStart; i++) { if (strLine.charAt(i - lineStart) == '\t') underscoreLine.append('\t'); else underscoreLine.append(' '); } for (int i = sourceStart; i <= sourceEnd; i++) underscoreLine.append('^'); return new String[] {strLine, underscoreLine.toString()}; } catch (Exception e) {// Catch exception if any return new String[] {"", ""}; } } private String extractJavacCompilerArg(String argumentName, String defaultValue) { Assure.notNull("argumentName", argumentName); // Step 1: Get all compilerArguments String[] currentCompilerArgs = javac.getCurrentCompilerArgs(); // Step 2: Find the 'right' one for (String compilerArg : currentCompilerArgs) { // split the argument String[] args = compilerArg.split(COMPILER_ARGS_SEPARATOR); // requested one? if (args.length > 1 && argumentName.equalsIgnoreCase(args[0])) { return args[1]; } } return defaultValue; } private SourceFile[] getSourceFilesToCompile() throws BuildException { File defaultDestinationFolder = javac.getDestdir(); List sourceFiles = new ArrayList(); File[] fileList = javac.getFileList(); for (File file : fileList) { if (!hasSourceFolder(file)) { // the user has restricted the source folders for the compilation. // f.e. the project has two source folders while the user only compiles one at a time. continue; } File sourceFolder = getSourceFolder(file); String sourceFileName = file.getAbsolutePath().substring(sourceFolder.getAbsolutePath().length() + File.separator.length()); File destinationFolder = defaultDestinationFolder; if (destinationFolder == null) throw new BuildException("dest path not set"); // compile package-info.java first if (sourceFileName.endsWith("package-info.java")) { sourceFiles.add(0, SourceFileFactory.createSourceFile(sourceFolder, sourceFileName, destinationFolder, getDefaultEncoding())); } else { sourceFiles.add(SourceFileFactory.createSourceFile(sourceFolder, sourceFileName, destinationFolder, getDefaultEncoding())); } } return sourceFiles.toArray(new SourceFile[sourceFiles.size()]); } private Classpath[] createClasspaths() { List classpathList = new ArrayList(); boolean includeSystem = includeSystemBootclasspath || javac.getBootclasspath() == null; if (javac.getBootclasspath() != null) { createBootClasspath(classpathList); } if (includeSystem) { String defaultBc = System.getProperty("sun.boot.class.path"); if (defaultBc != null) { for (String x : defaultBc.split(File.pathSeparator)) { File f = new File(x); if (f.exists()) classpathList.add(FileSystem.getClasspath(x, "UTF-8", null)); } } else { org.eclipse.jdt.internal.compiler.util.Util.collectVMBootclasspath(classpathList, Util.getJavaHome()); } } if (javac.getClasspath() != null) { Iterator iterator = javac.getClasspath().iterator(); while (iterator.hasNext()) { FileResource fileResource = iterator.next().as(FileResource.class); if (fileResource == null) continue; File classesFile = fileResource.getFile(); if (classesFile.exists()) classpathList.add(FileSystem.getClasspath(classesFile.toString(), "UTF-8", null)); } } return classpathList.toArray(new Classpath[0]); } private void createBootClasspath(List classpaths) { // Step 1: get the boot class path as specified in the javac task Path bootClasspath = javac.getBootclasspath(); // Step 2: iterate over the boot class path entries as specified in the ant path for (Iterator iterator = bootClasspath.iterator(); iterator.hasNext();) { FileResource fileResource = iterator.next().as(FileResource.class); if (fileResource == null) continue; if (fileResource.getFile().exists()) classpaths.add(FileSystem.getClasspath(fileResource.getFile().toString(), "UTF-8", null)); } } private String getDefaultEncoding() { String encoding = javac.getEncoding(); if (encoding != null) return encoding; return "UTF-8"; } private boolean hasSourceFolder(File sourceFile) { String absolutePath = sourceFile.getAbsolutePath(); // get the list of all source directories String[] srcDirs = javac.getSrcdir().list(); // find the 'right' source directory for (String srcDir : srcDirs) { if (absolutePath.startsWith(srcDir) && absolutePath.charAt(srcDir.length()) == File.separatorChar) return true; } return false; } private File getSourceFolder(File sourceFile) throws BuildException { String absolutePath = sourceFile.getAbsolutePath(); String[] srcDirs = javac.getSrcdir().list(); for (String srcDir : srcDirs) { if (absolutePath.startsWith(srcDir) && absolutePath.charAt(srcDir.length()) == File.separatorChar) return new File(srcDir); } throw new BuildException("Source folder for source file does not exist: " + sourceFile.getAbsolutePath()); } static class MyFileSystem extends FileSystem { protected MyFileSystem(Classpath[] paths) { super(paths, new String[0], false); } @Override public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, char[] moduleName) { return super.findType(typeName, packageName, moduleName); } @Override public NameEnvironmentAnswer findType(char[][] compoundName, char[] moduleName) { return super.findType(compoundName, moduleName); } } public CompileJobResult compile(CompileJobDescription description) { IModuleAwareNameEnvironment nameEnvironment = new MyFileSystem(description.getClasspaths()); Map compilerOptionsMap = description.getCompilerOptions(); ICompilationUnit[] sources = getCompilationUnits(description.getSourceFiles()); IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.proceedWithAllProblems(); IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault()); CompilerRequestorImpl requestor = new CompilerRequestorImpl(); CompilerOptions compilerOptions = new CompilerOptions(compilerOptionsMap); compilerOptions.storeAnnotations = true; Compiler compiler = new Compiler(nameEnvironment, policy, compilerOptions, requestor, problemFactory); if (Boolean.getBoolean("ecj.useMultiThreading")) compiler.useSingleThread = false; BatchAnnotationProcessorManager aptManager = new BatchAnnotationProcessorManager(); Main m = makeDummyMain(); m.batchCompiler = compiler; List aptArgs = new ArrayList(); if (!procJars.isEmpty()) { aptArgs.add("-processorpath"); StringBuilder sb = new StringBuilder(); for (File procJar : procJars) { if (sb.length() > 0) sb.append(File.pathSeparator); sb.append(procJar.getAbsolutePath()); } aptArgs.add(sb.toString()); } if (!procClasses.isEmpty()) { aptArgs.add("-processor"); StringBuilder sb = new StringBuilder(); for (String procClass : procClasses) { if (sb.length() > 0) sb.append(","); sb.append(procClass); } aptArgs.add(sb.toString()); } aptManager.configure(m, aptArgs.toArray(new String[0])); compiler.annotationProcessorManager = aptManager; EclipseFileManager filer = null; try { Field f = BaseAnnotationProcessorManager.class.getDeclaredField("_processingEnv"); f.setAccessible(true); BatchProcessingEnvImpl procEnv = (BatchProcessingEnvImpl) f.get(aptManager); filer = (EclipseFileManager) procEnv.getFileManager(); } catch (NoSuchFieldException e) { // we tried - maybe it's different infra. } catch (IllegalAccessException e) { // we tried - maybe it's different infra. } if (filer != null) { Set sourcePath = new HashSet(); Set destinationPath = new HashSet(); for (SourceFile sf : description.getSourceFiles()) { sourcePath.add(sf.getSourceFolder()); destinationPath.add(sf.getDestinationFolder()); } try { filer.setLocation(StandardLocation.SOURCE_PATH, sourcePath); filer.setLocation(StandardLocation.CLASS_OUTPUT, destinationPath); } catch (IOException e) { throw new BuildException("Can't set annotation processor filer paths", e); } } compiler.compile(sources); CompileJobResultImpl result = new CompileJobResultImpl(); result.setSucceeded(requestor.isCompilationSuccessful()); result.setCategorizedProblems(requestor.getCategorizedProblems()); result.setCompiledClassFiles(requestor.getCompiledClassFiles()); return result; } private Main makeDummyMain() { // Make a dummy 'Main', because the ecj code is hard-linked to it existing. This is all hackery to get around // an utterly unusable API. This API has been replaced, but the replacement cannot process annotations, // unless you rewrite a ton of infrastructure. PrintWriter outWriter = new PrintWriter(new OutputStream() { @Override public void write(int b) throws IOException { // just ignore it silently. } }); return new Main(outWriter, outWriter, false, new HashMap(), null); } private ICompilationUnit[] getCompilationUnits(SourceFile[] sourceFiles) { List result = new ArrayList(); for (SourceFile sourceFile : sourceFiles) { CompilationUnitImpl compilationUnitImpl = new CompilationUnitImpl(sourceFile); if (!result.contains(compilationUnitImpl)) result.add(compilationUnitImpl); } return result.toArray(new ICompilationUnit[result.size()]); } public void setIncludeSystemBootclasspath(boolean includeSystemBootclasspath) { this.includeSystemBootclasspath = includeSystemBootclasspath; } public void setAnnotationProcessorEntries(Set procClasses, Set procJars) { this.procClasses = procClasses; this.procJars = procJars; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/ReferableType.java000066400000000000000000000034711450515647100266220ustar00rootroot00000000000000/********************************************************************** * Copyright (c) 2005-2009 ant4eclipse project team. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich **********************************************************************/ package com.zwitserloot.ivyplusplus.ecj; import org.eclipse.jdt.internal.compiler.env.AccessRestriction; /** * A {@link ReferableType} is a class file or a source file that can be referred * from a project that should be build. * * @author Gerd Wütherich (gerd@gerd-wuetherich.de) */ public interface ReferableType { /** * Returns the type of the bundle this {@link ReferableType} was loaded * from. Possible values are {@link EcjAdapter#LIBRARY} and * {@link EcjAdapter#PROJECT}. * * @return the type of the bundle this class file was loaded from. */ byte getLibraryType(); /** * Returns of location of the bundle this {@link ReferableType} was loaded * from. * * @return the location of the bundle this {@link ReferableType} was loaded from. */ String getLibraryLocation(); /** * Returns whether there exists an access restriction for this class file or * not. * * @return whether there exists an access restriction for this class file or not. */ boolean hasAccessRestriction(); /** * Returns the access restriction for this class file or {@code null} * if no access restriction exists. * * @return the access restriction for this class file or {@code null} * if no access restriction exists. */ AccessRestriction getAccessRestriction(); }ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/SourceFile.java000066400000000000000000000015501450515647100261250ustar00rootroot00000000000000/********************************************************************** * Copyright (c) 2005-2009 ant4eclipse project team. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich **********************************************************************/ package com.zwitserloot.ivyplusplus.ecj; import java.io.File; /** * Describes a source file that should be compiled. * * @author Gerd Wütherich (gerd@gerd-wuetherich.de) */ public interface SourceFile { File getSourceFolder(); String getSourceFileName(); File getSourceFile(); File getDestinationFolder(); String getEncoding(); } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/SourceFileFactory.java000066400000000000000000000011721450515647100274550ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.ecj; import java.io.File; /** * Factory to create {@link SourceFile SourceFiles}. * * @author Gerd Wütherich (gerd@gerd-wuetherich.de) */ public class SourceFileFactory { public static SourceFile createSourceFile(File sourceFolder, String sourceFileName, File destinationFolder, String encoding) { return new SourceFileImpl(sourceFolder, sourceFileName, destinationFolder, encoding); } public static SourceFile createSourceFile(File sourceFolder, String sourceFileName, File destinationFolder) { return new SourceFileImpl(sourceFolder, sourceFileName, destinationFolder); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ecj/SourceFileImpl.java000066400000000000000000000045161450515647100267540ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.ecj; import java.io.File; /** * Describes a source file that should be compiled. * * @author Gerd Wütherich (gerd@gerd-wuetherich.de) */ public class SourceFileImpl implements SourceFile { private static final String FILE_ENCODING_SYSTEM_PROPERTY = "file.encoding"; private File _sourceFolder; private String _sourceFileName; private File _destinationFolder; private String _encoding; public SourceFileImpl(File sourceFolder, String sourceFileName, File destinationFolder, String encoding) { Assure.isDirectory("sourceFolder", sourceFolder); Assure.nonEmpty("sourceFileName", sourceFileName); Assure.isDirectory("destinationFolder", destinationFolder); Assure.nonEmpty("encoding", encoding); this._destinationFolder = destinationFolder; this._encoding = encoding; this._sourceFileName = sourceFileName; this._sourceFolder = sourceFolder; } public SourceFileImpl(File sourceFolder, String sourceFileName, File destinationFolder) { this(sourceFolder, sourceFileName, destinationFolder, System.getProperty(FILE_ENCODING_SYSTEM_PROPERTY)); } protected SourceFileImpl(File sourceFolder, String sourceFileName) { Assure.isDirectory("sourceFolder", sourceFolder); Assure.nonEmpty("sourceFileName", sourceFileName); this._sourceFileName = sourceFileName; this._sourceFolder = sourceFolder; this._encoding = System.getProperty(FILE_ENCODING_SYSTEM_PROPERTY); } public File getSourceFolder() { return this._sourceFolder; } public String getSourceFileName() { return this._sourceFileName; } public File getSourceFile() { return new File(this._sourceFolder, this._sourceFileName); } public File getDestinationFolder() { return this._destinationFolder; } public boolean hasDestinationFolder() { return this._destinationFolder != null; } public String getEncoding() { return this._encoding; } @Override public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("[SourceFile:"); buffer.append(" _sourceFolder: "); buffer.append(this._sourceFolder); buffer.append(" _sourceFileName: "); buffer.append(this._sourceFileName); buffer.append(" _destinationFolder: "); buffer.append(this._destinationFolder); buffer.append(" _encoding: "); buffer.append(this._encoding); buffer.append("]"); return buffer.toString(); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/eclipse/000077500000000000000000000000001450515647100241045ustar00rootroot00000000000000ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/eclipse/Apt.java000066400000000000000000000036421450515647100255000ustar00rootroot00000000000000/** * Copyright © 2010 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.eclipse; public class Apt { private String location; public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } @Override public String toString() { return "Apt [location=" + location + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((location == null) ? 0 : location.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Apt other = (Apt) obj; if (location == null) { if (other.location != null) return false; } else if (!location.equals(other.location)) return false; return true; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/eclipse/BuildEclipseProject.java000066400000000000000000000456531450515647100306570ustar00rootroot00000000000000/** * Copyright © 2010-2020 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.eclipse; import static java.util.Collections.unmodifiableMap; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.ivy.ant.IvyPostResolveTask; import org.apache.ivy.core.IvyPatternHelper; import org.apache.ivy.core.module.descriptor.Artifact; import org.apache.ivy.core.module.descriptor.ModuleDescriptor; import org.apache.ivy.core.module.id.ArtifactRevisionId; import org.apache.ivy.core.resolve.IvyNode; import org.apache.ivy.core.resolve.ResolveOptions; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; public class BuildEclipseProject extends IvyPostResolveTask { private File todir = null; private String projectname; private List srcdirs = new ArrayList(); private List confs = new ArrayList(); private List apts = new ArrayList(); private List locals = new ArrayList(); private List projectdeps = new ArrayList(); private List exports = new ArrayList(); private List libs = new ArrayList(); private String source = "1.8"; private String srcout = "bin"; private Settings settings; private boolean pde = false; public void setTodir(File todir) { this.todir = todir; } public void setProjectname(String projectname) { this.projectname = projectname; } public void setSrcout(String srcout) { this.srcout = srcout; } public void setSource(String source) { this.source = source; } public void setSettings(Settings settings) { this.settings = settings; } public void setPde(boolean pde) { this.pde = pde; } private void generateDotProject() throws IOException { File f = new File(todir, ".project"); f.delete(); FileOutputStream fos = new FileOutputStream(f); try { InputStream in = BuildEclipseProject.class.getResourceAsStream(pde ? "pde_project.template" : "project.template"); try { byte[] b = new byte[4096]; for (int r = in.read(b); r != -1; r = in.read(b)) { for (int i = 0; i < r; i++) { if (b[i] == '%') { fos.write(b, 0, i); fos.write(projectname.getBytes("UTF-8")); if (i < r - 1) fos.write(b, i + 1, r - i - 1); break; } else if (i == r - 1) { fos.write(b, 0, r); } } } } finally { in.close(); } } finally { fos.close(); } } private void generateDotFactorypath() throws IOException { if (apts.isEmpty()) return; File f = new File(todir, ".factorypath"); f.delete(); FileOutputStream fos = new FileOutputStream(f); try { Writer out = new OutputStreamWriter(fos, "UTF-8"); try { out.write("\n"); for (Apt apt : apts) { EclipsePath ep = eclipsify(todir, apt.getLocation(), true); if (ep == null) throw new BuildException("'location' attribute is required on ", getLocation()); out.write("\t\n"); } out.write("\n"); } finally { out.close(); } } finally { fos.close(); } } private static final class EclipsePath { private final boolean external; private final String path; public EclipsePath(boolean external, String path) { this.external = external; this.path = path; } @Override public String toString() { return path; } public String getPath() { return path; } public boolean isExternal() { return external; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (external ? 1231 : 1237); result = prime * result + ((path == null) ? 0 : path.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; EclipsePath other = (EclipsePath) obj; if (external != other.external) return false; if (path == null) { if (other.path != null) return false; } else if (!path.equals(other.path)) return false; return true; } } private EclipsePath eclipsify(File base, String loc, boolean forceProject) { if (loc == null) return null; return eclipsify(base, new File(loc), forceProject); } private EclipsePath eclipsify(File base, File loc, boolean forceProject) { if (loc == null) return null; /* Check if the folder shared by baseUri and locUri is the direct parent AND the next dir for locUri is an eclipse project. * If that is the case, go project relative (assume that project is also in the workspace). */ { int lastSlash = -1; String b = canonical(base); String c = canonical(loc); int min = Math.min(b.length(), c.length()); int i = 0; for (; i < min; i++) { char bc = b.charAt(i); char cc = c.charAt(i); if (bc != cc) break; if (bc == '/') lastSlash = i; } if (i == b.length() && c.length() > i && c.charAt(i) == '/') { return new EclipsePath(false, (forceProject ? ("/" + projectname + "/") : "") + c.substring(i + 1)); } int lastSlashInBase = b.indexOf('/', lastSlash + 1); if (lastSlashInBase == -1 || lastSlashInBase == b.length() - 1) { // This means the shared root is indeed the direct parent of base. // Next requirement: the first subdir after this in 'loc' must be an eclipse project. String siblingProjectName = fetchSiblingProjectName(c, lastSlash); if (siblingProjectName != null) { int nextSlashInLoc = c.indexOf('/', lastSlash + 1); if (nextSlashInLoc != -1) { return new EclipsePath(false, "/" + siblingProjectName + "/" + c.substring(nextSlashInLoc + 1)); } } } } /* Give up, going with an absolute path. */ { return new EclipsePath(true, canonical(loc)); } } private String fetchSiblingProjectName(String resourcePath, int workspaceRootPos) { int nextSlashInLoc = resourcePath.indexOf('/', workspaceRootPos + 1); if (nextSlashInLoc == -1) return null; File siblingProj = new File(resourcePath.substring(0, nextSlashInLoc), ".project"); if (!siblingProj.isFile()) return null; try { return readProjName(siblingProj, true); } catch (IOException e) { warnAboutEclipseProjectReadFailure(false, siblingProj); return null; } } private final List alreadyWarnedForEclipseProjectReadFailure = new ArrayList(); private String warnAboutEclipseProjectReadFailure(boolean error, File resourceFile) { String resourcePath = canonical(resourceFile); if (error) throw new BuildException("Cannot parse eclipse project file: " + resourcePath); if (alreadyWarnedForEclipseProjectReadFailure.contains(resourcePath)) return null; alreadyWarnedForEclipseProjectReadFailure.add(resourcePath); getProject().log("Can't read eclispe project file: " + resourcePath, Project.MSG_WARN); return null; } private String canonical(File f) { try { return f.getCanonicalPath(); } catch (IOException e) { return f.getAbsolutePath(); } } private void generateDotClasspath(String content) throws IOException { File f = new File(todir, ".classpath"); f.delete(); FileOutputStream fos = new FileOutputStream(f); try { Writer out = new OutputStreamWriter(fos, "UTF-8"); try { out.write(content); } finally { out.close(); } } finally { fos.close(); } } public void addSrcdir(Srcdir srcdir) { srcdirs.add(srcdir); } public void addConf(Conf conf) { confs.add(conf); } public void addApt(Apt apt) { apts.add(apt); } public void addLocal(Local local) { locals.add(local); } public void addProjectdep(Projectdep projectdep) { projectdeps.add(projectdep); } public void addExport(Export export) { exports.add(export); } public void addLib(Lib lib) { libs.add(lib); } public void addSettings(Settings settings) { if (this.settings != null) throw new BuildException("Only one allowed.", getLocation()); this.settings = settings; } private static final Map SOURCE_TO_CON; static { Map map = new LinkedHashMap(); map.put("25", "JavaSE-25"); map.put("24", "JavaSE-24"); map.put("23", "JavaSE-23"); map.put("22", "JavaSE-22"); map.put("21", "JavaSE-21"); map.put("20", "JavaSE-20"); map.put("19", "JavaSE-19"); map.put("18", "JavaSE-18"); map.put("17", "JavaSE-17"); map.put("16", "JavaSE-16"); map.put("15", "JavaSE-15"); map.put("14", "JavaSE-14"); map.put("13", "JavaSE-13"); map.put("12", "JavaSE-12"); map.put("11", "JavaSE-11"); map.put("10", "JavaSE-10"); map.put("9", "JavaSE-9"); map.put("1.8", "JavaSE-1.8"); map.put("1.7", "JavaSE-1.7"); map.put("1.6", "JavaSE-1.6"); map.put("1.5", "J2SE-1.5"); map.put("1.4", "J2SE-1.4"); map.put("1.3", "J2SE-1.3"); map.put("1.2", "J2SE-1.2"); map.put("1.1", "JRE-1.1"); SOURCE_TO_CON = unmodifiableMap(map); } private List calculateConfsWithSources() { List out = new ArrayList(); for (Conf conf : confs) { String confName = conf.getName(); if (confName == null) throw new BuildException(" requires a 'name' attribute naming an ivy configuration.", getLocation()); if (!out.contains(confName)) out.add(confName); String sourcesName = conf.getSources(); if (sourcesName != null && !out.contains(sourcesName)) out.add(sourcesName); } return out; } private String readProjName(File in, boolean error) throws IOException { try ( FileInputStream fis = new FileInputStream(in); BufferedReader br = new BufferedReader(new InputStreamReader(fis, "UTF-8")); ) { List stack = new ArrayList(); while (true) { String line = br.readLine(); if (line == null) return null; line = line.trim(); if (!line.startsWith("<")) return warnAboutEclipseProjectReadFailure(error, in); int idx = line.indexOf('>'); if (idx == -1) return warnAboutEclipseProjectReadFailure(error, in); if (line.length() > 4 && line.charAt(1) == '?' && line.charAt(line.length() - 2) == '?' && line.charAt(line.length() -1) == '>') continue; String tag = line.substring(1, idx); if (tag.startsWith("/")) { if (stack.size() == 0) return warnAboutEclipseProjectReadFailure(error, in); if (!stack.get(stack.size() - 1).equals(tag)) return warnAboutEclipseProjectReadFailure(error, in); stack.remove(stack.size() - 1); continue; } if (idx == line.length() - 1) { stack.add(tag); continue; } if (line.endsWith("")) { String text = line.substring(idx + 1, line.length() - 3 - tag.length()); if (text.indexOf('<') != -1 || text.indexOf('>') != -1) return warnAboutEclipseProjectReadFailure(error, in); if (!tag.equals("name")) continue; if (stack.size() == 1 && stack.get(0).equals("projectDescription")) return text; continue; } return warnAboutEclipseProjectReadFailure(error, in); } } } @Override public void doExecute() throws BuildException { if (todir == null) todir = getProject().getBaseDir(); for (Srcdir dir : srcdirs) { if (dir.getDir() == null) throw new BuildException(" requires a 'src' attribute with the source dir you'd like to include.", getLocation()); } Map localsToConsider = new HashMap(); List toExport = new ArrayList(); for (Local local : locals) { if (local.getName() == null) throw new BuildException(" requires a 'name' attribute with a name like an ivy dependency's 'name' attribute.", getLocation()); if (local.getOrg() == null) throw new BuildException(" requires an 'org' attribute with a name like an ivy dependency's 'org' attribute.", getLocation()); String dir = local.getDir(); if (dir == null) { dir = "../" + local.getOrg() + "." + local.getName(); } if (new File(dir, ".project").isFile()) { localsToConsider.put(local.getOrg() + "." + local.getName(), dir); } } for (Export export : exports) { if (export.getName() == null) throw new BuildException(" requires a 'name' attribute with a name like an ivy dependency's 'name' attribute.", getLocation()); if (export.getOrg() == null) throw new BuildException(" requires an 'org' attribute with a name like an ivy dependency's 'org' attribute.", getLocation()); toExport.add(export.getOrg() + "." + export.getName()); } List confsWithSources = calculateConfsWithSources(); if (!SOURCE_TO_CON.containsKey(source)) throw new BuildException("Invalid value for 'source'. Valid values: " + SOURCE_TO_CON.keySet(), getLocation()); if (projectname == null) projectname = getProject().getName(); prepareAndCheck(); if (settings != null) settings.execute(todir, getLocation(), source); StringBuilder elements = new StringBuilder(); String retrievePattern = getProject().getProperty("ivy.retrieve.pattern"); assert retrievePattern != null; retrievePattern = IvyPatternHelper.substituteVariables(retrievePattern, getIvyInstance().getSettings().getVariables()); elements.append("\n"); elements.append("\n"); for (Srcdir dir : srcdirs) { String path = todir.toURI().relativize(dir.getDir().toURI()).toString(); elements.append("\t\n\t\t\n\t\t\t\n\t\t\n\t\n"); } else { elements.append("/>\n"); } } if (pde) { elements.append("\t\n"); } elements.append("\t\n"); elements.append("\t\t\n\t\t\t\n\t\t\n"); elements.append("\t\n"); for (Projectdep pd : projectdeps) { elements.append("\t\n"); } ModuleDescriptor md = getResolveId() != null ? (ModuleDescriptor) getResolvedDescriptor(getResolveId()) : (ModuleDescriptor) getResolvedDescriptor(getOrganisation(), getModule(), false); IvyNode[] deps = getIvyInstance().getResolveEngine().getDependencies(md, new ResolveOptions() .setConfs(confsWithSources.toArray(new String[0])).setResolveId(getResolveId()).setValidate(doValidate(getSettings())), null); List handledArtifacts = new ArrayList(); for (IvyNode dep : deps) { if (dep.isCompletelyEvicted()) continue; boolean export = toExport.contains(dep.getId().getOrganisation() + "." + dep.getId().getName()); String exportString = export ? "exported=\"true\" " : ""; String localDir = localsToConsider.get(dep.getId().getOrganisation() + "." + dep.getId().getName()); if (localDir != null) { String projName; try { projName = readProjName(new File(localDir, ".project"), true); } catch (IOException e) { throw new BuildException(e.getMessage()); } elements.append("\t\n"); } else for (Conf conf : confs) { for (Artifact artifact : dep.getArtifacts(conf.getName())) { if (handledArtifacts.contains(artifact.getId())) continue; handledArtifacts.add(artifact.getId()); if (!"jar".equals(artifact.getType()) && !"bundle".equals(artifact.getType())) continue; String destFileName = IvyPatternHelper.substitute(retrievePattern, artifact.getModuleRevisionId(), artifact, conf.getName(), null); String sourceConf = conf.getSources(); String sourceAttachment = null; if (sourceConf != null) for (Artifact sourceArtifact : dep.getArtifacts(sourceConf)) { sourceAttachment = IvyPatternHelper.substitute(retrievePattern, sourceArtifact.getModuleRevisionId(), sourceArtifact, sourceConf, null); break; } EclipsePath libPath = eclipsify(todir, destFileName, false); EclipsePath relSrcAtt = eclipsify(todir, sourceAttachment, false); elements.append("\t\n"); } } } for (Lib lib : libs) { if (lib.getLocation() == null) throw new BuildException(" requires 'src' attribute pointing to a jar file.", getLocation()); String exportString = lib.export ? "exported=\"true\" " : ""; EclipsePath path = eclipsify(todir, lib.getLocation(), false); elements.append("\t\n"); } elements.append("\t\n"); elements.append("\t\n"); elements.append("\n"); try { generateDotProject(); generateDotClasspath(elements.toString()); generateDotFactorypath(); } catch (IOException e) { throw new BuildException(e, getLocation()); } } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/eclipse/Conf.java000066400000000000000000000043441450515647100256410ustar00rootroot00000000000000/** * Copyright © 2010 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.eclipse; public class Conf { private String name; private String sources; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSources() { return sources; } public void setSources(String sources) { this.sources = sources; } @Override public String toString() { return "Conf [name=" + name + ", sources=" + sources + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((sources == null) ? 0 : sources.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Conf other = (Conf) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (sources == null) { if (other.sources != null) return false; } else if (!sources.equals(other.sources)) return false; return true; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/eclipse/Export.java000066400000000000000000000021101450515647100262220ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.eclipse; public class Export { private String org; private String name; public String getOrg() { return org; } public void setOrg(String org) { this.org = org; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Export [org=" + org + ", name=" + name + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((org == null) ? 0 : org.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Export other = (Export) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (org == null) { if (other.org != null) return false; } else if (!org.equals(other.org)) return false; return true; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/eclipse/Lib.java000066400000000000000000000021121450515647100254510ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.eclipse; import java.io.File; public class Lib { File location; boolean export = false; public File getLocation() { return location; } public void setLocation(File location) { this.location = location; } public boolean isExport() { return export; } public void setExport(boolean export) { this.export = export; } @Override public String toString() { return "Lib [location=" + location + ", export=" + export + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (export ? 1231 : 1237); result = prime * result + ((location == null) ? 0 : location.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Lib other = (Lib) obj; if (export != other.export) return false; if (location == null) { if (other.location != null) return false; } else if (!location.equals(other.location)) return false; return true; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/eclipse/Local.java000066400000000000000000000026021450515647100260010ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.eclipse; public class Local { private String org; private String name; private String dir; public String getOrg() { return org; } public void setOrg(String org) { this.org = org; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDir() { return dir; } public void setDir(String dir) { this.dir = dir; } @Override public String toString() { return "Local [org=" + org + ", name=" + name + ", dir=" + dir + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((dir == null) ? 0 : dir.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((org == null) ? 0 : org.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Local other = (Local) obj; if (dir == null) { if (other.dir != null) return false; } else if (!dir.equals(other.dir)) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (org == null) { if (other.org != null) return false; } else if (!org.equals(other.org)) return false; return true; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/eclipse/Projectdep.java000066400000000000000000000014321450515647100270460ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.eclipse; public class Projectdep { private String name; @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Projectdep other = (Projectdep) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } @Override public String toString() { return "Projectdep [name=" + name + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/eclipse/Settings.java000066400000000000000000000202731450515647100265530ustar00rootroot00000000000000/** * Copyright © 2010 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.eclipse; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.TreeMap; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Location; import org.apache.tools.ant.types.Resource; public class Settings { private TreeMap properties = new TreeMap(String.CASE_INSENSITIVE_ORDER); private List inputs = new ArrayList(); public void addText(String text) { inputs.add(text); } private void loadProps(InputStream in, boolean overwrite) throws IOException { Properties p = new Properties(); p.load(in); for (Map.Entry e : p.entrySet()) { String key = (String) e.getKey(); String value = (String) e.getValue(); if (overwrite || !properties.containsKey(key)) properties.put(key, value); } } public void add(Resource resource) { inputs.add(resource); } private static final Map PROPERTY_NAME_MAP; static { Map map = new HashMap(); map.put("eclipse.preferences.version", null); map.put("cleanup.", "org.eclipse.jdt.ui"); map.put("cleanup_", "org.eclipse.jdt.ui"); map.put("sp_cleanup.", "org.eclipse.jdt.ui"); map.put("formatter_", "org.eclipse.jdt.ui"); map.put("editor_save_participant_org.eclipse.jdt.ui.", "org.eclipse.jdt.ui"); map.put("org.eclipse.jdt.ui.", "org.eclipse.jdt.ui"); map.put("encoding/", "org.eclipse.core.resources"); map.put("org.eclipse.jdt.core.", "org.eclipse.jdt.core"); map.put("line.separator", "org.eclipse.core.runtime"); map.put("org.eclipse.jdt.launching.", "org.eclipse.jdt.launching"); map.put("org.eclipse.jdt.apt.", "org.eclipse.jdt.apt.core"); map.put("org.eclipse.ltk.core.refactoring.", "org.eclipse.ltk.core.refactoring"); map.put("org.eclipse.jdt.apt.", "org.eclipse.jdt.apt.core"); PROPERTY_NAME_MAP = Collections.unmodifiableMap(map); } public void execute(File todir, Location location, String source) { int v; if ("1.5".equals(source)) v = 5; else if ("1.6".equals(source)) v = 6; else if ("1.7".equals(source)) v = 7; else if ("1.8".equals(source)) v = 8; else try { v = Integer.parseInt(source); if (v < 8 || v > 9999) throw new IllegalArgumentException("source: " + source); } catch (NumberFormatException e) { v = 4; } todir = new File(todir, ".settings"); boolean normalExit = false; for (Object input : inputs) { if (input == null) continue; if (input instanceof String) { try { InputStream in = new ByteArrayInputStream(((String) input).getBytes("ISO-8859-1")); loadProps(in, true); } catch (IOException e) { throw new BuildException(e, location); } } else if (input instanceof Resource) { try { InputStream in = ((Resource) input).getInputStream(); try { loadProps(in, false); } finally { if (in != null) in.close(); } } catch (IOException e) { throw new BuildException(e, location); } } else { assert false: "A non-string, non-resource showed up"; } } if (!properties.containsKey("org.eclipse.jdt.core.compiler.processAnnotations")) { if (v < 6) properties.put("org.eclipse.jdt.core.compiler.processAnnotations", "disabled"); if (v > 5) properties.put("org.eclipse.jdt.core.compiler.processAnnotations", "enabled"); } if (!properties.containsKey("org.eclipse.jdt.core.compiler.source")) { if (v > 4) properties.put("org.eclipse.jdt.core.compiler.source", source); } if (!properties.containsKey("org.eclipse.jdt.core.compiler.compliance")) { if (v > 4) properties.put("org.eclipse.jdt.core.compiler.compliance", source); } if (!properties.containsKey("org.eclipse.jdt.core.compiler.codegen.targetPlatform")) { if (v > 4) properties.put("org.eclipse.jdt.core.compiler.codegen.targetPlatform", source); } try { for (Map.Entry e : properties.entrySet()) { String key = e.getKey(); String value = e.getValue(); boolean handled = false; for (Map.Entry f : PROPERTY_NAME_MAP.entrySet()) { if (key.startsWith(f.getKey())) { handled = true; addToFile(f.getValue(), key, value, todir, location); break; } } if (!handled) { throw new BuildException("Unknown eclipse property: " + key, location); } } normalExit = true; } catch (IOException e) { throw new BuildException(e); } finally { Throwable stored = null; for (FileOutputStream out : createdFiles.values()) { try { out.close(); } catch (Throwable t) { if (stored != null) stored = t; } } if (normalExit && stored != null) { if (stored instanceof BuildException) throw (BuildException) stored; throw new BuildException(stored, location); } } } private Map createdFiles = new HashMap(); private void addToFile(String fileName, String key, String value, File todir, Location location) throws IOException { if (!todir.exists()) { if (!todir.mkdirs()) throw new BuildException("Can't create directory: " + todir.getAbsolutePath(), location); } if (!todir.isDirectory()) throw new BuildException("Not a directory: " + todir.getAbsolutePath(), location); FileOutputStream out; if (!createdFiles.containsKey(fileName)) { File f = new File(todir, fileName + ".prefs"); if (f.exists()) f.delete(); createdFiles.put(fileName, out = new FileOutputStream(f)); writePreamble(out); } else { out = createdFiles.get(fileName); } out.write(escapeKey(key).getBytes("ISO-8859-1")); out.write('='); out.write(escapeValue(value).getBytes("ISO-8859-1")); out.write(System.getProperty("line.separator", "\n").getBytes("ISO-8859-1")); } private String escapeKey(String key) { StringBuilder sb = new StringBuilder(); for (char c : escapeValue(key).toCharArray()) { if (c == ':' || c == '=' || c == ' ') { sb.append('\\'); sb.append(c); } else sb.append(c); } return sb.toString(); } private String escapeValue(String key) { StringBuilder sb = new StringBuilder(); for (char c : key.toCharArray()) { if (c == '\n') sb.append("\\n"); else if (c == '\r') sb.append("\\r"); else if (c == '\t') sb.append("\\t"); else if (c == '\f') sb.append("\\f"); else if (c == '\\') sb.append("\\\\"); else if (c < 32 || c > 126) { sb.append('\\').append('u').append(String.format("%04X", (int)c)); } else { sb.append(c); } } return sb.toString(); } private void writePreamble(OutputStream out) throws IOException { out.write(("#" + new Date().toString()).getBytes("ISO-8859-1")); out.write(System.getProperty("line.separator", "\n").getBytes("ISO-8859-1")); out.write("eclipse.preferences.version=1".getBytes("ISO-8859-1")); out.write(System.getProperty("line.separator", "\n").getBytes("ISO-8859-1")); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/eclipse/Srcdir.java000066400000000000000000000053321450515647100262000ustar00rootroot00000000000000/** * Copyright © 2010-2020 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.eclipse; import java.io.File; public class Srcdir { private File dir; private boolean optional = false; private boolean test = false; private String srcout = ""; public File getDir() { return dir; } public void setDir(File dir) { this.dir = dir; } public String getSrcout() { return srcout; } public void setSrcout(String srcout) { this.srcout = srcout; } public boolean isOptional() { return optional; } public void setOptional(boolean optional) { this.optional = optional; } public boolean isTest() { return test; } public void setTest(boolean test) { this.test = test; } @Override public String toString() { String out = "Srcdir [dir=" + dir + ", optional=" + optional + ", test=" + test; if (!srcout.isEmpty()) out += ", srcout=" + srcout; return out + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((dir == null) ? 0 : dir.hashCode()); result = prime * result + (optional ? 1231 : 1237); result = prime * result + (test ? 1231 : 1237); result = prime * result + srcout.hashCode(); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Srcdir other = (Srcdir) obj; if (dir == null) { if (other.dir != null) return false; } else if (!dir.equals(other.dir)) return false; if (optional != other.optional) return false; if (test != other.test) return false; if (!srcout.equals(other.srcout)) return false; return true; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/eclipse/pde_project.template000066400000000000000000000011721450515647100301400ustar00rootroot00000000000000 % org.eclipse.jdt.core.javabuilder org.eclipse.pde.ManifestBuilder org.eclipse.pde.SchemaBuilder org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/eclipse/project.template000066400000000000000000000005501450515647100273070ustar00rootroot00000000000000 % org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/intellij/000077500000000000000000000000001450515647100242725ustar00rootroot00000000000000ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/intellij/Apt.java000066400000000000000000000025051450515647100256630ustar00rootroot00000000000000/** * Copyright © 2010 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.intellij; public class Apt { private boolean enabled; public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/intellij/BuildIntellijProject.java000066400000000000000000000223361450515647100312240ustar00rootroot00000000000000/** * Copyright © 2010-2020 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.intellij; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.ivy.ant.IvyPostResolveTask; import org.apache.ivy.core.IvyPatternHelper; import org.apache.ivy.core.module.descriptor.Artifact; import org.apache.ivy.core.module.descriptor.ModuleDescriptor; import org.apache.ivy.core.module.id.ArtifactRevisionId; import org.apache.ivy.core.resolve.IvyNode; import org.apache.ivy.core.resolve.ResolveOptions; import org.apache.tools.ant.BuildException; public class BuildIntellijProject extends IvyPostResolveTask { private File todir = null; private List modules = new ArrayList(); private List confs = new ArrayList(); private Apt apt; private String source = "1.8"; private Settings settings; public void setTodir(File todir) { this.todir = todir; } public void setSource(String source) { this.source = source; } public void setSettings(Settings settings) { this.settings = settings; } public void addConf(Conf conf) { confs.add(conf); } public void addApt(Apt apt) { if (this.apt != null) throw new BuildException("Only one allowed.", getLocation()); this.apt = apt; } public void addSettings(Settings settings) { if (this.settings != null) throw new BuildException("Only one allowed.", getLocation()); this.settings = settings; } public void addModule(Module module) { modules.add(module); } @Override public void doExecute() throws BuildException { if (todir == null) todir = getProject().getBaseDir(); for (Module m : modules) m.validate(getLocation()); try { generateAntXml(todir); generateCompilerXml(todir, apt != null && apt.isEnabled()); generateLibraryXml(todir); generateModulesXml(todir); for (Module m : modules) { generateModuleXml(todir, m); } } catch (IOException e) { throw new BuildException(e, getLocation()); } } private void generateAntXml(File toDir) throws IOException { applyTemplate("ant.xml.template", new File(toDir, ".idea/ant.xml")); } private void generateCompilerXml(File toDir, boolean isAptEnabled) throws IOException { applyTemplate("compiler.xml.template", new File(toDir, ".idea/compiler.xml"), isAptEnabled ? "true" : "false"); } private void generateModulesXml(File toDir) throws IOException { StringBuilder moduleLines = new StringBuilder(); for (Module m : modules) { moduleLines.append(" \n"); } applyTemplate("modules.xml.template", new File(toDir, ".idea/modules.xml"), moduleLines.toString()); } private List calculateConfsWithSources() { List out = new ArrayList(); for (Conf conf : confs) { String confName = conf.getName(); if (confName == null) throw new BuildException(" requires a 'name' attribute naming an ivy configuration.", getLocation()); if (!out.contains(confName)) out.add(confName); String sourcesName = conf.getSources(); if (sourcesName != null && !out.contains(sourcesName)) out.add(sourcesName); } return out; } private void generateLibraryXml(File toDir) throws IOException { ModuleDescriptor md = getResolveId() != null ? (ModuleDescriptor) getResolvedDescriptor(getResolveId()) : (ModuleDescriptor) getResolvedDescriptor(getOrganisation(), getModule(), false); prepareAndCheck(); if (settings != null) settings.execute(todir, getLocation(), source); List confsWithSources = calculateConfsWithSources(); String retrievePattern = getProject().getProperty("ivy.retrieve.pattern"); assert retrievePattern != null; IvyNode[] deps = getIvyInstance().getResolveEngine().getDependencies(md, new ResolveOptions() .setConfs(confsWithSources.toArray(new String[0])).setResolveId(getResolveId()).setValidate(doValidate(getSettings())), null); List handledArtifacts = new ArrayList(); Map depLines = new HashMap(); Map sourceLines = new HashMap(); for (IvyNode dep : deps) { if (dep.isCompletelyEvicted()) continue; for (Conf conf : confs) { for (Artifact artifact : dep.getArtifacts(conf.getName())) { if (handledArtifacts.contains(artifact.getId())) continue; handledArtifacts.add(artifact.getId()); if (!"jar".equals(artifact.getType()) && !"bundle".equals(artifact.getType())) continue; String destFileName = IvyPatternHelper.substitute(retrievePattern, artifact.getModuleRevisionId(), artifact, conf.getName(), null); String sourceConf = conf.getSources(); String sourceAttachment = null; if (sourceConf != null) for (Artifact sourceArtifact : dep.getArtifacts(sourceConf)) { sourceAttachment = IvyPatternHelper.substitute(retrievePattern, sourceArtifact.getModuleRevisionId(), sourceArtifact, sourceConf, null); break; } StringBuilder sb = depLines.get(conf); if (sb == null) { sb = new StringBuilder(); depLines.put(conf, sb); } sb.append(" \n"); if (sourceAttachment != null) { sb = sourceLines.get(conf); if (sb == null) { sb = new StringBuilder(); sourceLines.put(conf, sb); } sb.append(" \n"); } } } } for (Conf conf : confs) { String depLine = depLines.get(conf) == null ? "" : depLines.get(conf).toString(); String sourceLine = sourceLines.get(conf) == null ? "" : sourceLines.get(conf).toString(); applyTemplate("librarySet.xml.template", new File(toDir, ".idea/libraries/" + conf.getName() + "_libs.xml"), conf.getName() + " libs", depLine, sourceLine); } } private void generateModuleXml(File toDir, Module m) throws IOException { // // StringBuilder sourceDirs = new StringBuilder(); StringBuilder libSets = new StringBuilder(); for (Srcdir dir : m.getSrcdirs()) { String path = getProject().getBaseDir().toURI().relativize(dir.getDir().toURI()).toString(); sourceDirs.append(" \n"); } String deps = m.getDepends(); if (deps == null) deps = ""; for (String dep : deps.split(",")) { dep = dep.trim(); libSets.append(" \n"); } applyTemplate("module.xml.template", new File(toDir, m.getName() + ".iml"), sourceDirs.toString(), source, libSets.toString()); } private static final String MARKER = "%%"; private static void applyTemplate(String resource, File out, String... replacements) throws IOException { out.delete(); out.getParentFile().mkdirs(); FileOutputStream fos = new FileOutputStream(out); try { InputStream in = BuildIntellijProject.class.getResourceAsStream(resource); try { byte[] b = new byte[4096]; int state = 0; for (int r = in.read(b); r != -1; r = in.read(b)) { int start = 0; for (int i = 0; i < r; i++) { if (b[i] == '%') { if (state == 0) { fos.write(b, start, i - start); start = i; } if (++state > MARKER.length()) { state--; start++; fos.write('%'); } } else if (state == MARKER.length() && Character.isDigit(b[i])) { start = i + 1; fos.write(replacements[b[i] - '1'].getBytes("UTF-8")); state = 0; } else if (state > 0) { state = 0; fos.write(b, start, i - start); start = i; } } if (start < r) { fos.write(b, start, r - start); } } } finally { in.close(); } } finally { fos.close(); } } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/intellij/Conf.java000066400000000000000000000043451450515647100260300ustar00rootroot00000000000000/** * Copyright © 2010 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.intellij; public class Conf { private String name; private String sources; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSources() { return sources; } public void setSources(String sources) { this.sources = sources; } @Override public String toString() { return "Conf [name=" + name + ", sources=" + sources + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((sources == null) ? 0 : sources.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Conf other = (Conf) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (sources == null) { if (other.sources != null) return false; } else if (!sources.equals(other.sources)) return false; return true; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/intellij/Module.java000066400000000000000000000041221450515647100263610ustar00rootroot00000000000000/** * Copyright © 2010 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.intellij; import java.util.ArrayList; import java.util.List; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Location; public class Module { private List srcdirs = new ArrayList(); private String name; private String depends; List getSrcdirs() { return srcdirs; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDepends() { return depends; } public void setDepends(String depends) { this.depends = depends; } public void addSrcdir(Srcdir srcdir) { srcdirs.add(srcdir); } void validate(Location location) { for (Srcdir dir : srcdirs) { if (dir.getDir() == null) throw new BuildException(" requires a 'src' attribute with the source dir you'd like to include.", location); } if (name == null || name.isEmpty()) throw new BuildException(" requires a 'name' attribute.", location); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/intellij/Settings.java000066400000000000000000000155771450515647100267540ustar00rootroot00000000000000/** * Copyright © 2010 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.intellij; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Location; import org.apache.tools.ant.types.Resource; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class Settings { private TreeMap components = new TreeMap(String.CASE_INSENSITIVE_ORDER); private List inputs = new ArrayList(); private DocumentBuilderFactory factory; public void addText(String text) { inputs.add(text); } public static void main(String[] args) throws Exception { new Settings().loadXML(new FileInputStream(args[0]), true); } private void loadXML(InputStream in, boolean overwrite) throws IOException { try { DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(in); List components = new ArrayList(); gatherComponents(doc.getDocumentElement(), components); for (Element component : components) { String name = component.getAttribute("name"); if (overwrite || !this.components.containsKey(name)) this.components.put(name, component); } } catch (ParserConfigurationException e) { throw new IOException(e); } catch (SAXException e) { throw new IOException(e); } } private void gatherComponents(Element element, List list) { if ("component".equals(element.getNodeName())) { list.add(element); return; } NodeList nodeList = element.getChildNodes(); for (int i = 0; i < nodeList.getLength(); i++) { Node n = nodeList.item(i); if (n instanceof Element) gatherComponents((Element) nodeList.item(i), list); } } public void add(Resource resource) { inputs.add(resource); } private static final Map COMPONENT_NAME_MAP; static { Map map = new HashMap(); map.put("CompilerConfiguration", ".idea/compiler.xml"); map.put("CodeStyleSettingsManager", ".idea/projectCodeStyle.xml"); map.put("Encoding", ".idea/encodings.xml"); map.put("Palette2", ".idea/uiDesigner.xml"); map.put("VcsDirectoryMappings", ".idea/vcs.xml"); map.put("ProjectModuleManager", ".idea/modules.xml"); map.put("", ".idea/misc.xml"); COMPONENT_NAME_MAP = Collections.unmodifiableMap(map); } public void execute(File todir, Location location, String source) { this.factory = DocumentBuilderFactory.newInstance(); for (Object input : inputs) { if (input == null) continue; if (input instanceof String) { if (!((String)input).trim().isEmpty()) { try { InputStream in = new ByteArrayInputStream(((String) input).getBytes("ISO-8859-1")); loadXML(in, true); } catch (IOException e) { throw new BuildException(e, location); } } } else if (input instanceof Resource) { try { InputStream in = ((Resource) input).getInputStream(); try { loadXML(in, false); } finally { if (in != null) in.close(); } } catch (IOException e) { throw new BuildException(e, location); } } else { assert false: "A non-string, non-resource showed up"; } } Map> fileToComponents = new HashMap>(); for (Map.Entry e : components.entrySet()) { String key = e.getKey(); Element value = e.getValue(); File file = null; for (Map.Entry f : COMPONENT_NAME_MAP.entrySet()) { if (key.equalsIgnoreCase(f.getKey())) { file = new File(todir, f.getValue()); break; } } if (file == null) file = new File(todir, COMPONENT_NAME_MAP.get("")); List elemList = fileToComponents.get(file); if (elemList == null) { elemList = new ArrayList(); fileToComponents.put(file, elemList); } elemList.add(value); } try { for (Map.Entry> e : fileToComponents.entrySet()) { File key = e.getKey(); List elemList = e.getValue(); createFile(key, elemList, location); } } catch (IOException e) { throw new BuildException(e, location); } } private void createFile(File file, List elemList, Location location) throws IOException { try { file.getParentFile().mkdirs(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.newDocument(); Element top = doc.createElement("project"); top.setAttribute("version", "4"); for (Element elem : elemList) { top.appendChild(doc.importNode(elem, true)); } doc.appendChild(top); DOMSource src = new DOMSource(doc); Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.transform(src, new StreamResult(file)); } catch (ParserConfigurationException e) { throw new IOException(e); } catch (TransformerConfigurationException e) { throw new IOException(e); } catch (TransformerFactoryConfigurationError e) { throw new IOException(e); } catch (TransformerException e) { throw new IOException(e); } } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/intellij/Srcdir.java000066400000000000000000000041551450515647100263700ustar00rootroot00000000000000/** * Copyright © 2010 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.intellij; import java.io.File; public class Srcdir { private File dir; private boolean test = false; public File getDir() { return dir; } public void setDir(File dir) { this.dir = dir; } public boolean isTest() { return test; } public void setTest(boolean test) { this.test = test; } @Override public String toString() { return "Srcdir [dir=" + dir + ", test=" + test + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((dir == null) ? 0 : dir.hashCode()); result = prime * result + (test ? 1231 : 1237); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Srcdir other = (Srcdir) obj; if (dir == null) { if (other.dir != null) return false; } else if (!dir.equals(other.dir)) return false; if (test != other.test) return false; return true; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/intellij/ant.xml.template000066400000000000000000000006641450515647100274160ustar00rootroot00000000000000 ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/intellij/compiler.xml.template000066400000000000000000000017301450515647100304410ustar00rootroot00000000000000 ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/intellij/librarySet.xml.template000066400000000000000000000003071450515647100307460ustar00rootroot00000000000000 %%2 %%3 ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/intellij/module.xml.template000066400000000000000000000005731450515647100301200ustar00rootroot00000000000000 %%1 %%3 ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/intellij/modules.xml.template000066400000000000000000000002411450515647100302730ustar00rootroot00000000000000 %%1 ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/mavencentral/000077500000000000000000000000001450515647100251375ustar00rootroot00000000000000ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/mavencentral/CreateArtifactBundle.java000066400000000000000000000213601450515647100320170ustar00rootroot00000000000000/** * Copyright © 2011 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.mavencentral; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; public class CreateArtifactBundle extends Task { private File src, bin, javadoc, pom, key, out; private String version, artifactId, passphrase; private boolean noSourceOrJavadocNeeded; public void setSrc(File src) { this.src = src; } public void setBin(File bin) { this.bin = bin; } public void setJavadoc(File javadoc) { this.javadoc = javadoc; } public void setPom(File pom) { this.pom = pom; } public void setKey(File key) { this.key = key; } public void setOut(File out) { this.out = out; } public void setVersion(String version) { this.version = version; } public void setArtifactId(String artifactId) { this.artifactId = artifactId; } public void setPassphrase(String passphrase) { this.passphrase = passphrase; } public void setNoSourceOrJavadocNeeded(boolean noSourceOrJavadocNeeded) { this.noSourceOrJavadocNeeded = noSourceOrJavadocNeeded; } @Override public void execute() throws BuildException { try { InitializeBouncyCastle.init(); } catch (SigningException e) { throw new BuildException(e.getMessage(), e.getCause(), getLocation()); } if (bin == null) throw new BuildException("Must specify mandatory attribute 'bin' (points at the jar with class files in it)", getLocation()); if (pom == null) throw new BuildException("Must specify mandatory attribute 'pom' (points at your maven pom file)", getLocation()); if (out == null) throw new BuildException("Must specify mandatory attribute 'out' (this is where the artifact bundle will be written to)", getLocation()); if (key == null) throw new BuildException("Must specify mandatory attribute 'key' (file containing your signing key. Created by running ivyplusplus.jar with java -jar)", getLocation()); if (version == null) throw new BuildException("Must specify mandatory attribute 'version'", getLocation()); if (artifactId == null) throw new BuildException("Must specify mandatory attribute 'artifactId'", getLocation()); if (passphrase == null) passphrase = ""; if (!noSourceOrJavadocNeeded && src == null) throw new BuildException("Must specify mandatory attribute 'src' unless 'noSourceOrJavadocNeeded' is true (points at the jar with sources in it)", getLocation()); if (!noSourceOrJavadocNeeded && javadoc == null) throw new BuildException("Must specify mandatory attribute 'javadoc' unless 'noSourceOrJavadocNeeded' is true (points at the jar with javadocs in it)", getLocation()); if (bin != null && !bin.getName().toLowerCase().endsWith(".jar")) throw new BuildException("Only jar files are supported by create-artifact-bundle; 'bin' attribute isn't one.", getLocation()); if (src != null && !src.getName().toLowerCase().endsWith(".jar")) throw new BuildException("Only jar files are supported by create-artifact-bundle; 'src' attribute isn't one.", getLocation()); if (javadoc != null && !javadoc.getName().toLowerCase().endsWith(".jar")) throw new BuildException("Only jar files are supported by create-artifact-bundle; 'javadoc' attribute isn't one.", getLocation()); byte[] pomData; try { InputStream pomStream = new FileInputStream(pom); try { pomData = readStream(pomStream); } finally { pomStream.close(); } } catch (FileNotFoundException e) { throw new BuildException("Missing pom file", e, getLocation()); } catch (IOException e) { throw new BuildException("Can't read pom file", e, getLocation()); } if (version != null && !version.isEmpty()) { pomData = replaceVersion(pomData, "@VERSION@", version); } CreateDetachedSignatures signer = new CreateDetachedSignatures(); try { FileOutputStream outStream = new FileOutputStream(out); try { JarOutputStream zipOut = new JarOutputStream(outStream); zipOut.putNextEntry(new JarEntry("pom.xml")); zipOut.write(pomData); ByteArrayOutputStream signature = new ByteArrayOutputStream(); signer.signFile(new ByteArrayInputStream(pomData), signature, key, passphrase); zipOut.putNextEntry(new JarEntry("pom.xml.asc")); zipOut.write(signature.toByteArray()); writeToJar(zipOut, artifactId + "-" + version + ".jar", bin); if (src != null) writeToJar(zipOut, artifactId + "-" + version + "-sources.jar", src); if (src != null) writeToJar(zipOut, artifactId + "-" + version + "-javadoc.jar", javadoc); zipOut.closeEntry(); zipOut.close(); } finally { outStream.close(); } } catch (FileNotFoundException e) { throw new BuildException("File not found: " + e.getMessage(), e, getLocation()); } catch (IOException e) { throw new BuildException("I/O problem writing out file or reading in files", e, getLocation()); } catch (SigningException e) { throw new BuildException("Problem signing files", e, getLocation()); } } private void writeToJar(JarOutputStream zipOut, String filename, File data) throws IOException, SigningException { ByteArrayOutputStream signature = new ByteArrayOutputStream(); zipOut.putNextEntry(new JarEntry(filename)); FileInputStream fis = new FileInputStream(data); try { CreateDetachedSignatures signer = new CreateDetachedSignatures(); signer.signFile(new DuplicatingInputStream(fis, zipOut), signature, key, passphrase); zipOut.putNextEntry(new JarEntry(filename + ".asc")); zipOut.write(signature.toByteArray()); zipOut.closeEntry(); } finally { fis.close(); } } private static class DuplicatingInputStream extends InputStream { private final InputStream wrapped; private final OutputStream pipe; DuplicatingInputStream(InputStream wrapped, OutputStream pipe) { this.wrapped = wrapped; this.pipe = pipe; } @Override public int read() throws IOException { int c = wrapped.read(); if (c != -1) pipe.write(c); return c; } @Override public int read(byte[] b) throws IOException { int r = wrapped.read(b); if (r != -1) pipe.write(b, 0, r); return r; } @Override public int read(byte[] b, int off, int len) throws IOException { int r = wrapped.read(b, off, len); if (r != -1) pipe.write(b, off, r); return r; } } private static byte[] readStream(InputStream in) throws IOException { byte[] b = new byte[4096]; ByteArrayOutputStream out = new ByteArrayOutputStream(); while (true) { int r = in.read(b); if (r == -1) return out.toByteArray(); out.write(b, 0, r); } } private static byte[] replaceVersion(byte[] in, String token_, String replacement_) { try { int start = 0; ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] token = token_.getBytes("US-ASCII"); byte[] replacement = replacement_.getBytes("US-ASCII"); while (true) { int idx = find(in, token, start); if (idx == -1) break; out.write(in, start, idx - start); start = idx + token.length; out.write(replacement); } if (start < in.length) { out.write(in, start, in.length - start); } return out.toByteArray(); } catch (IOException e) { throw new RuntimeException("IOException on mem-only operations", e); } } private static int find(byte[] haystack, byte[] needle, int start) { int pos = 0; for (int i = start; i < haystack.length; i++) { if (pos == needle.length) return i; if (haystack[i] == needle[pos]) pos++; else pos = 0; } return -1; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/mavencentral/CreateDetachedSignatures.java000066400000000000000000000016001450515647100326710ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.mavencentral; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; public class CreateDetachedSignatures { public void signFile(File file, File keyFile, String passphrase) throws IOException, SigningException { InitializeBouncyCastle.call(getClass().getName() + "_", "signFile", Arrays.>asList(File.class, File.class, String.class), Arrays.asList(file, keyFile, passphrase)); } public void signFile(InputStream dataIn, OutputStream signOut, File keyFile, String passphrase) throws SigningException, IOException { InitializeBouncyCastle.call(getClass().getName() + "_", "signFile", Arrays.>asList(InputStream.class, OutputStream.class, File.class, String.class), Arrays.asList(dataIn, signOut, keyFile, passphrase)); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/mavencentral/CreateDetachedSignatures_.java000066400000000000000000000137321450515647100330410ustar00rootroot00000000000000/** * Copyright © 2011 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.mavencentral; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SignatureException; import java.util.Iterator; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider; import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; public class CreateDetachedSignatures_ { public void signFile(File file, File keyFile, String passphrase) throws IOException, SigningException { try { PGPSecretKey key; { FileInputStream keyIn = new FileInputStream(keyFile); try { key = getSigningKey(keyIn, keyFile.getName()); } finally { keyIn.close(); } } { OutputStream outStream = new FileOutputStream(file.getAbsolutePath() + ".asc"); try { InputStream fileIn = new FileInputStream(file); try { signFile(fileIn, key, passphrase, outStream); } finally { fileIn.close(); } } finally { outStream.close(); } } } catch (NoSuchProviderException e) { throw new SigningException("Bouncycastle provider not loaded", e); } catch (NoSuchAlgorithmException e) { throw new SigningException("Signature key uses an algorithm that is not compatible with ivyplusplus", e); } catch (PGPException e) { throw new SigningException("Unknown signing problem: " + e.getMessage(), e); } catch (SignatureException e) { throw new SigningException("Problem with signature: " + e.getMessage(), e); } } public void signFile(InputStream dataIn, OutputStream signOut, File keyFile, String passphrase) throws IOException, SigningException { try { PGPSecretKey key; { FileInputStream keyIn = new FileInputStream(keyFile); try { key = getSigningKey(keyIn, keyFile.getName()); } finally { keyIn.close(); } } { signFile(dataIn, key, passphrase, signOut); } } catch (NoSuchProviderException e) { throw new SigningException("Bouncycastle provider not loaded", e); } catch (NoSuchAlgorithmException e) { throw new SigningException("Signature key uses an algorithm that is not compatible with ivyplusplus", e); } catch (PGPException e) { throw new SigningException("Unknown signing problem: " + e.getMessage(), e); } catch (SignatureException e) { throw new SigningException("Problem with signature: " + e.getMessage(), e); } } void signFile(InputStream fileData, PGPSecretKey signingKey, String passphrase, OutputStream out) throws IOException, NoSuchProviderException, PGPException, NoSuchAlgorithmException, SignatureException { PGPDigestCalculatorProvider provider = new BcPGPDigestCalculatorProvider(); PBESecretKeyDecryptor decryptor = new BcPBESecretKeyDecryptorBuilder(provider).build(passphrase.toCharArray()); PGPPrivateKey privKey = signingKey.extractPrivateKey(decryptor); PGPSignatureGenerator sigGen = new PGPSignatureGenerator( new BcPGPContentSignerBuilder(signingKey.getPublicKey().getAlgorithm(), PGPUtil.SHA1)); sigGen.init(PGPSignature.BINARY_DOCUMENT, privKey); out = new ArmoredOutputStream(out); BCPGOutputStream bOut = new BCPGOutputStream(out); byte[] b = new byte[4096]; while (true) { int r = fileData.read(b); if (r == -1) break; sigGen.update(b, 0, r); } sigGen.generate().encode(bOut); bOut.close(); out.close(); } PGPSecretKey getSigningKey(InputStream keyData, String streamName) throws IOException, PGPException, SigningException { PGPSecretKeyRingCollection keyrings_ = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyData), new BcKeyFingerprintCalculator()); Iterator keyrings = keyrings_.getKeyRings(); while (keyrings.hasNext()) { PGPSecretKeyRing keys_ = (PGPSecretKeyRing) keyrings.next(); Iterator keys = keys_.getSecretKeys(); while (keys.hasNext()) { PGPSecretKey key = (PGPSecretKey) keys.next(); if (key.isSigningKey()) return key; } } throw new SigningException("No signing key found in keyring: " + streamName); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/mavencentral/CreateSigningKey.java000066400000000000000000000007651450515647100312050ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.mavencentral; import java.io.IOException; import java.io.PrintStream; import java.util.Arrays; public class CreateSigningKey { public void createSigningKey(String identity, String passphrase, PrintStream log) throws IOException, SigningException { InitializeBouncyCastle.call(getClass().getName() + "_", "createSigningKey", Arrays.>asList(String.class, String.class, PrintStream.class), Arrays.asList(identity, passphrase, log)); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/mavencentral/CreateSigningKey_.java000066400000000000000000000123101450515647100313310ustar00rootroot00000000000000/** * Copyright © 2011-2017 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.mavencentral; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.math.BigInteger; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.util.Date; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.generators.DSAKeyPairGenerator; import org.bouncycastle.crypto.generators.ElGamalKeyPairGenerator; import org.bouncycastle.crypto.params.ElGamalKeyGenerationParameters; import org.bouncycastle.crypto.params.ElGamalParameters; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPKeyRingGenerator; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder; public class CreateSigningKey_ { public void createSigningKey(String identity, String passphrase, PrintStream log) throws IOException, SigningException { if (passphrase == null) passphrase = ""; SecureRandom sr = new SecureRandom(); try { DSAKeyPairGenerator gen = new DSAKeyPairGenerator(); gen.init(new KeyGenerationParameters(sr, 1024)); log.printf("Please hold on, a 1024 bit key is being generated. This takes a while and requires a lot of random data, so try moving the mouse at random.\n"); AsymmetricCipherKeyPair privPair = gen.generateKeyPair(); ElGamalKeyPairGenerator elgamal = new ElGamalKeyPairGenerator(); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); elgamal.init(new ElGamalKeyGenerationParameters(sr, new ElGamalParameters(p, g))); AsymmetricCipherKeyPair signPair = elgamal.generateKeyPair(); OutputStream privOut = new FileOutputStream("mavenrepo-signing-key-secret.bpr"); try { OutputStream pubOut = new FileOutputStream("mavenrepo-signing-key-public.bpr"); try { export(privOut,pubOut, privPair, signPair, identity, passphrase); } finally { pubOut.close(); } } finally { privOut.close(); } } catch (NoSuchProviderException e) { throw new SigningException("Bouncycastle provider not loaded", e); } catch (PGPException e) { e.printStackTrace(); throw new SigningException("Unknown signing problem: " + e.getMessage(), e); } } void export(OutputStream privOut, OutputStream pubOut, AsymmetricCipherKeyPair privPair_, AsymmetricCipherKeyPair signPair_, String identity, String passphrase) throws PGPException, NoSuchProviderException, IOException { PGPKeyPair privPair = new BcPGPKeyPair(PGPPublicKey.DSA, privPair_, new Date()); PGPKeyPair signPair = new BcPGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, signPair_, new Date()); PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1); PGPKeyRingGenerator ringGen = new PGPKeyRingGenerator( PGPSignature.POSITIVE_CERTIFICATION, privPair, identity, sha1Calc, null, null, new JcaPGPContentSignerBuilder(privPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1), new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha1Calc).setProvider("BC").build(passphrase.toCharArray())); ringGen.addSubKey(signPair); ringGen.generateSecretKeyRing().encode(privOut); privOut.close(); ringGen.generatePublicKeyRing().encode(pubOut); pubOut.close(); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/mavencentral/InitializeBouncyCastle.java000066400000000000000000000102051450515647100324150ustar00rootroot00000000000000/** * Copyright © 2011 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.mavencentral; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.net.URL; import java.net.URLClassLoader; import java.security.Provider; import java.security.Security; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; public class InitializeBouncyCastle { private static AtomicBoolean initialized = new AtomicBoolean(false); private static ClassLoader loader; public static void init() throws SigningException { if (initialized.getAndSet(true)) return; URL[] urls = new URL[3]; urls[0] = writeToTemp("bcprov-jdk16"); urls[1] = writeToTemp("bcpg-jdk16"); urls[2] = writeToTemp("ipp-bc-bridges"); try { loader = new URLClassLoader(urls, InitializeBouncyCastle.class.getClassLoader()); Class provider = loader.loadClass("org.bouncycastle.jce.provider.BouncyCastleProvider"); Security.addProvider((Provider) provider.newInstance()); } catch (ClassNotFoundException e) { throw new SigningException("Included bouncycastle provider jar is corrupted", e); } catch (IllegalAccessException e) { throw new SigningException("Included bouncycastle provider jar is corrupted", e); } catch (InstantiationException e) { throw new SigningException("Included bouncycastle provider jar is corrupted", e); } } private static URL writeToTemp(String resourceKey) throws SigningException { try { File file = File.createTempFile(resourceKey, "jar"); file.deleteOnExit(); FileOutputStream out = new FileOutputStream(file); try { InputStream in = InitializeBouncyCastle.class.getResourceAsStream("/" + resourceKey + ".jar"); try { byte[] b = new byte[4096]; while (true) { int r = in.read(b); if (r == -1) break; out.write(b, 0, r); } } finally { if (in != null) in.close(); } } finally { out.close(); } return file.toURI().toURL(); } catch (IOException e) { throw new SigningException("Can't unpack bouncycastle crypto provider to temp dir: " + e, e); } } public static Object call(String fqn, String methodName, List> types, List params) throws SigningException { Throwable t; try { Class c = loader.loadClass(fqn); return c.getMethod(methodName, types.toArray(new Class[0])).invoke(c.newInstance(), params.toArray(new Object[0])); } catch (ClassNotFoundException e) { t = e; } catch (IllegalAccessException e) { t = e; } catch (InstantiationException e) { t = e; } catch (InvocationTargetException e) { Throwable c = e.getCause(); if (c instanceof RuntimeException) throw (RuntimeException) c; if (c instanceof Error) throw (Error) c; if (c instanceof SigningException) throw (SigningException) c; if (c == null) throw new RuntimeException(); throw new RuntimeException(c); } catch (NoSuchMethodException e) { t = e; } t.printStackTrace(); throw new SigningException("bouncycastle corrupted", t); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/mavencentral/SigningException.java000066400000000000000000000025511450515647100312620ustar00rootroot00000000000000/** * Copyright © 2011 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.mavencentral; public class SigningException extends Exception { public SigningException(String message) { super(message); } public SigningException(String message, Throwable cause) { super(message, cause); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ssh/000077500000000000000000000000001450515647100232555ustar00rootroot00000000000000ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ssh/JarUnpacker.java000066400000000000000000000114071450515647100263300ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.ssh; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLDecoder; import java.nio.charset.Charset; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.regex.Matcher; import java.util.regex.Pattern; public class JarUnpacker { private static final Pattern classSpec = Pattern.compile("^.*com/zwitserloot/ivyplusplus/ssh/internal/.*\\.class$"); private static String getPackHash() throws IOException { InputStream ph = JarUnpacker.class.getResourceAsStream("/packhash"); if (ph == null) throw new IOException("Missing packhash"); try { BufferedReader br = new BufferedReader(new InputStreamReader(ph, "UTF-8")); return br.readLine(); } finally { try { ph.close(); } catch (Exception ignore) {} } } public static void unpack(File tgtDir, String hashGuard) throws IOException { String homeOfClass = findClasspathRoot(JarUnpacker.class); String packHash = getPackHash(); if (packHash.equals(hashGuard)) return; try (JarFile jf = new JarFile(homeOfClass)) { new File(tgtDir, "HASH").delete(); deleteAll(tgtDir, 0); Enumeration en = jf.entries(); if (hashGuard != null) { } while (en.hasMoreElements()) { JarEntry entry = en.nextElement(); if (entry.getName().endsWith(".jar")) { File out = new File(tgtDir, "lib"); out.mkdirs(); out = new File(out, entry.getName()); InputStream in = jf.getInputStream(entry); transfer(in, out); } else { Matcher m = classSpec.matcher(entry.getName()); if (!m.matches()) continue; File out = new File(tgtDir, "classes"); out.mkdirs(); String[] parts = entry.getName().split("/"); for (String part : parts) { out.mkdirs(); out = new File(out, part); } InputStream in = jf.getInputStream(entry); transfer(in, out); } } } File f = new File(tgtDir, "HASH"); OutputStream hashOut = new FileOutputStream(f); try { byte[] phb = packHash.getBytes("UTF-8"); byte[] phb2 = new byte[phb.length + 1]; System.arraycopy(phb, 0, phb2, 0, phb.length); phb2[phb.length] = '\n'; hashOut.write(phb2); } finally { hashOut.close(); } } private static void deleteAll(File tgtDir, int lp) { if (lp > 50) return; for (File f : tgtDir.listFiles()) { if (f.isFile()) f.delete(); if (f.isDirectory()) deleteAll(f, lp+1); } if (lp > 0) tgtDir.delete(); } private static void transfer(InputStream in, File out) throws IOException { OutputStream stream = null; try { byte[] b = new byte[65536]; stream = new FileOutputStream(out); while (true) { int r = in.read(b); if (r == -1) return; stream.write(b, 0, r); } } finally { try { in.close(); } catch (Throwable ignore) {} if (stream != null) stream.close(); } } private static String urlDecode(String in) { try { return URLDecoder.decode(in, Charset.defaultCharset().name()); } catch (UnsupportedEncodingException e) { try { return URLDecoder.decode(in, "UTF-8"); } catch (UnsupportedEncodingException e1) { return in; } } } private static String findClasspathRoot(Class context) { URL selfURL = context.getResource(context.getSimpleName() + ".class"); String self = selfURL.toString(); if (self.startsWith("file:/")) { self = urlDecode(self.substring(5)); Package p = context.getPackage(); String pName = p == null ? "" : (p.getName().replace(".", "/") + "/"); String suffix = "/" + pName + context.getSimpleName() + ".class"; if (self.endsWith(suffix)) self = self.substring(0, self.length() - suffix.length()); else throw new IllegalArgumentException("Unknown path structure: " + self); } else if (self.startsWith("jar:")) { int sep = self.indexOf('!'); if (sep == -1) throw new IllegalArgumentException("No separator in jar protocol: " + self); String jarLoc = self.substring(4, sep); if (jarLoc.startsWith("file:/")) { jarLoc = urlDecode(jarLoc.substring(5)); self = jarLoc; } else throw new IllegalArgumentException("Unknown path structure: " + self); } else { throw new IllegalArgumentException("Unknown protocol: " + self); } if (self.endsWith("/bin")) self = self.substring(0, self.length() - 4); else if (self.endsWith("/build")) self = self.substring(0, self.length() - 6); if (self.isEmpty()) self = "/"; if (self.length() >= 3 && self.charAt(0) == '/' && self.charAt(2) == ':') { // Handling for windows paths including drive letter. self = self.substring(1); } return self; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ssh/ScpUpload.java000066400000000000000000000034301450515647100260120ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.ssh; import java.io.File; import java.io.IOException; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; public class ScpUpload extends Task { private String to; private File from; private String server; private int port; private String username; private File keyFile; private File knownHosts; public void setTo(String to) { this.to = to; } public void setFrom(File from) { this.from = from; } public void setServer(String server) { this.server = server; } public void setPort(int port) { this.port = port; } public void setUsername(String username) { this.username = username; } public void setKeyFile(File keyFile) { this.keyFile = keyFile; } public void setKnownHosts(File knownHosts) { this.knownHosts = knownHosts; } @Override public void execute() throws BuildException { if (to == null) throw new BuildException("'to' is mandatory."); if (from == null) throw new BuildException("'from' is mandatory."); if (server == null) throw new BuildException("'server' is mandatory."); if (username == null) throw new BuildException("'username' is mandatory."); if (keyFile == null) throw new BuildException("'keyFile' is mandatory."); if (port == 0) port = 22; if (knownHosts == null) knownHosts = new File(getProject().getBaseDir(), "ssh.knownHosts"); File loc = new File(getProject().getBaseDir(), "build/ssh"); try { SshSubsystem.unpack(loc); } catch (IOException e) { log(e, Project.MSG_ERR); throw new BuildException("Can't unpack ssh subsystem into build/ssh"); } SshSubsystem.call(loc, getProject(), this, "com.zwitserloot.ivyplusplus.ssh.internal.ScpUpload", from, to, server, port, username, keyFile, knownHosts); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ssh/SshExec.java000066400000000000000000000032011450515647100254560ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.ssh; import java.io.File; import java.io.IOException; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; public class SshExec extends Task { private String cmd; private String server; private int port; private String username; private File keyFile; private File knownHosts; public void setCmd(String cmd) { this.cmd = cmd; } public void setServer(String server) { this.server = server; } public void setPort(int port) { this.port = port; } public void setUsername(String username) { this.username = username; } public void setKeyFile(File keyFile) { this.keyFile = keyFile; } public void setKnownHosts(File knownHosts) { this.knownHosts = knownHosts; } @Override public void execute() throws BuildException { if (cmd == null) throw new BuildException("'cmd' is mandatory."); if (server == null) throw new BuildException("'server' is mandatory."); if (username == null) throw new BuildException("'username' is mandatory."); if (keyFile == null) throw new BuildException("'keyFile' is mandatory."); if (port == 0) port = 22; if (knownHosts == null) knownHosts = new File(getProject().getBaseDir(), "ssh.knownHosts"); File loc = new File(getProject().getBaseDir(), "build/ssh"); try { SshSubsystem.unpack(loc); } catch (IOException e) { log(e, Project.MSG_ERR); throw new BuildException("Can't unpack ssh subsystem into build/ssh"); } SshSubsystem.call(loc, getProject(), this, "com.zwitserloot.ivyplusplus.ssh.internal.SshExec", cmd, server, port, username, keyFile, knownHosts); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ssh/SshSubsystem.java000066400000000000000000000071201450515647100265740ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.ssh; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; import org.apache.tools.ant.taskdefs.Java; import org.apache.tools.ant.taskdefs.Redirector; import org.apache.tools.ant.types.Path; public class SshSubsystem { public static void unpack(File loc) throws IOException { loc.mkdirs(); File f = new File(loc, "HASH"); String existingHash = null; if (f.exists()) existingHash = fetchHash(f); JarUnpacker.unpack(loc, existingHash); } private static String fetchHash(File f) throws IOException { try (InputStream in = new FileInputStream(f)) { return new BufferedReader(new InputStreamReader(in, "UTF-8")).readLine(); } } private static final class DummyInputStream extends InputStream { @Override public int read() throws IOException { return -1; } @Override public int read(byte[] b) throws IOException { return -1; } @Override public int read(byte[] b, int off, int len) throws IOException { return -1; } } private static final class CmdHandlerStream extends OutputStream { private final StringBuilder line = new StringBuilder(); private final Project p; private final Task t; CmdHandlerStream(Project p, Task t) { this.p = p; this.t = t; } @Override public void write(int b) throws IOException { if (b == '\n') { if (line.length() > 0 && line.charAt(line.length() - 1) == '\r') line.setLength(line.length() - 1); String txt = line.toString(); line.setLength(0); if (txt.startsWith("T:")) { p.log(t, txt.substring(2), Project.MSG_ERR); } else if (txt.startsWith("V:")) { p.log(t, txt.substring(2), Project.MSG_VERBOSE); } else if (txt.startsWith("C:")) { p.log(t, txt.substring(2), Project.MSG_INFO); } else if (txt.trim().length() > 0) { p.log(t, txt, Project.MSG_INFO); } } else { line.append((char) b); } } } public static void call(File loc, final Project p, final Task t, String classSpec, Object... args) { final Java task = new Java() { @Override protected void setupRedirector() { this.redirector = new Redirector(this) { private CmdHandlerStream out, err; private InputStream in; @Override public void createStreams() { out = new CmdHandlerStream(p, t); err = new CmdHandlerStream(p, t); in = new DummyInputStream(); } @Override public OutputStream getOutputStream() { return out; } @Override public OutputStream getErrorStream() { return err; } @Override public InputStream getInputStream() { return in; } @Override public void complete() throws IOException { out.write('\n'); err.write('\n'); } }; super.setupRedirector(); } }; task.setProject(p); task.setFork(true); task.setTaskName("ssh"); task.createJvmarg().setValue("-Dorg.slf4j.simpleLogger.defaultLogLevel=warn"); Path cp = task.createClasspath(); cp.add(new Path(p, new File(loc, "classes").getAbsolutePath())); for (File jar : new File(loc, "lib").listFiles()) { if (jar.isFile() && jar.getName().endsWith(".jar")) cp.add(new Path(p, new File(new File(loc, "lib"), jar.getName()).getAbsolutePath())); } for (Object a : args) { if (a instanceof File) task.createArg().setValue(((File) a).getAbsolutePath()); else task.createArg().setValue(a.toString()); } task.setClassname(classSpec); task.execute(); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ssh/internal/000077500000000000000000000000001450515647100250715ustar00rootroot00000000000000ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ssh/internal/ScpUpload.java000066400000000000000000000023071450515647100276300ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.ssh.internal; import java.io.File; import java.io.IOException; import net.schmizz.sshj.SSHClient; import net.schmizz.sshj.xfer.FileSystemFile; public class ScpUpload { public static void main(String[] args) { File from = new File(args[0]); String to = args[1]; String server = args[2]; int port = Integer.parseInt(args[3]); String username = args[4]; File keyFile = new File(args[5]); File knownHosts = new File(args[6]); try { execute(from, to, server, port, username, keyFile, knownHosts); } catch (IOException e) { System.out.println("T: " + e.getMessage()); System.exit(1); } } public static void execute(File from, String to, String server, int port, String username, File keyFile, final File knownHosts) throws IOException { SSHClient ssh = new SSHClient(); SshUtil.handleKnownHosts(ssh, knownHosts); System.out.println("V:connecting to " + username + "@" + server + ":" + port + " with key file " + keyFile.getAbsolutePath()); ssh.connect(server, port); if (!SshUtil.handleKeyFile(ssh, username, keyFile)) { System.exit(0); return; } ssh.newSCPFileTransfer().upload(new FileSystemFile(from), to); System.exit(0); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ssh/internal/SshExec.java000066400000000000000000000034551450515647100273050ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.ssh.internal; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.concurrent.TimeUnit; import net.schmizz.sshj.SSHClient; import net.schmizz.sshj.connection.channel.direct.Session; import net.schmizz.sshj.connection.channel.direct.Session.Command; public class SshExec { public static void main(String[] args) { String cmd = args[0]; String server = args[1]; int port = Integer.parseInt(args[2]); String username = args[3]; File keyFile = new File(args[4]); File knownHosts = new File(args[5]); try { execute(cmd, server, port, username, keyFile, knownHosts); } catch (IOException e) { System.out.println("T: " + e.getMessage()); System.exit(1); } } public static void execute(String cmd, String server, int port, String username, File keyFile, final File knownHosts) throws IOException { SSHClient ssh = new SSHClient(); SshUtil.handleKnownHosts(ssh, knownHosts); ssh.connect(server, port); if (!SshUtil.handleKeyFile(ssh, username, keyFile)) { System.exit(0); return; } Session session = ssh.startSession(); System.out.println("V:Starting session to run cmd \"" + cmd + "\""); Command command = session.exec(cmd); InputStream in = command.getInputStream(); try { BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8")); for (String line = br.readLine(); line != null; line = br.readLine()) { System.out.println("C:" + line); } } finally { in.close(); } command.join(5, TimeUnit.SECONDS); Integer i = command.getExitStatus(); if (i == null) System.exit(0); if (i.intValue() != 0) System.out.println("T:Remote process exited with error code " + i.intValue()); System.exit(0); } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/ssh/internal/SshUtil.java000066400000000000000000000071501450515647100273320ustar00rootroot00000000000000package com.zwitserloot.ivyplusplus.ssh.internal; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.security.PublicKey; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.bouncycastle.util.encoders.Base64; import com.hierynomus.sshj.userauth.keyprovider.OpenSSHKeyV1KeyFile; import net.schmizz.sshj.SSHClient; import net.schmizz.sshj.transport.verification.HostKeyVerifier; import net.schmizz.sshj.userauth.keyprovider.KeyFormat; import net.schmizz.sshj.userauth.keyprovider.KeyProvider; import net.schmizz.sshj.userauth.keyprovider.KeyProviderUtil; import net.schmizz.sshj.userauth.keyprovider.OpenSSHKeyFile; import net.schmizz.sshj.userauth.keyprovider.PKCS5KeyFile; import net.schmizz.sshj.userauth.keyprovider.PKCS8KeyFile; import net.schmizz.sshj.userauth.keyprovider.PuTTYKeyFile; class SshUtil { static class KnownHost { String hostName; int port; String algorithm; String format; String base64; } static List readKnownHosts(File f) throws IOException { if (!f.exists()) return Collections.emptyList(); List out = new ArrayList(); try ( InputStream raw = new FileInputStream(f); BufferedReader br = new BufferedReader(new InputStreamReader(raw, "UTF-8")); ) { for (String line = br.readLine(); line != null; line = br.readLine()) { line = line.trim(); if (line.isEmpty() || line.startsWith("#")) continue; String[] p = line.split(":", 5); KnownHost kn = new KnownHost(); kn.hostName = p[0]; kn.port = Integer.parseInt(p[1]); kn.algorithm = p[2]; kn.format = p[3]; kn.base64 = p[4]; out.add(kn); } } return out; } public static void handleKnownHosts(SSHClient ssh, final File knownHosts) throws IOException { final List knownHostsList = readKnownHosts(knownHosts); ssh.addHostKeyVerifier(new HostKeyVerifier() { @Override public boolean verify(String hostName, int port, PublicKey key) { String b64 = Base64.toBase64String(key.getEncoded()); for (KnownHost kn : knownHostsList) { if (kn.hostName.equals(hostName) && kn.port == port && kn.algorithm.equals(key.getAlgorithm()) && kn.format.equals(key.getFormat()) && kn.base64.equals(b64)) { System.out.println("V:host signature matched in known hosts file " + knownHosts.getAbsolutePath()); return true; } } System.out.println("T:Known hosts file does not list this server. Edit " + knownHosts.getAbsolutePath() + " and add this line:"); System.out.println("T:" + hostName + ":" + port + ":" + key.getAlgorithm() + ":" + key.getFormat() + ":" + b64); return false; } }); } public static boolean handleKeyFile(SSHClient ssh, String username, File keyFile) throws IOException { KeyFormat format = KeyProviderUtil.detectKeyFileFormat(keyFile); KeyProvider kp; switch (format) { default: case Unknown: System.out.println("T:Not a recognized key file format: " + keyFile + " (" + format + ")"); return false; case OpenSSHv1: kp = new OpenSSHKeyV1KeyFile(); ((OpenSSHKeyV1KeyFile) kp).init(keyFile); break; case OpenSSH: kp = new OpenSSHKeyFile(); ((OpenSSHKeyFile) kp).init(keyFile); break; case PuTTY: kp = new PuTTYKeyFile(); ((PuTTYKeyFile) kp).init(keyFile); break; case PKCS8: kp = new PKCS8KeyFile(); ((PKCS8KeyFile) kp).init(keyFile); break; case PKCS5: kp = new PKCS5KeyFile(); ((PKCS5KeyFile) kp).init(keyFile); break; } ssh.authPublickey(username, kp); return true; } } ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/template/000077500000000000000000000000001450515647100242735ustar00rootroot00000000000000ivyplusplus-1.42/src/com/zwitserloot/ivyplusplus/template/TemplateApplier.java000066400000000000000000000146521450515647100302360ustar00rootroot00000000000000/** * Copyright © 2011 Reinier Zwitserloot. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.zwitserloot.ivyplusplus.template; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayDeque; import java.util.Deque; import java.util.HashMap; import java.util.Map; public class TemplateApplier { private static final class IfStackEntry { final String key; final boolean value; final int pos; IfStackEntry(String key, int pos, boolean value) { this.key = key; this.value = value; this.pos = pos; } } @Override public String toString() { return map.toString(); } private final Map map = new HashMap(); public String applyStream(InputStream in) throws IOException { return applyStream(in, "UTF-8"); } public String applyStream(InputStream in, String charset) throws IOException { byte[] data; try { data = read(in); } finally { in.close(); } return applyTemplate(new String(data, charset)); } public String applyFile(File in) throws IOException { return applyFile(in, "UTF-8"); } public String applyFile(File in, String charset) throws IOException { FileInputStream fis = new FileInputStream(in); byte[] data; try { data = read(fis); } finally { fis.close(); } return applyTemplate(new String(data, charset)); } public String applyResource(Class context, String resource) throws IOException { return applyResource(context, resource, "UTF-8"); } public String applyResource(Class context, String resource, String charset) throws IOException { InputStream is = context.getResourceAsStream(resource); byte[] data; try { data = read(is); } finally { is.close(); } return applyTemplate(new String(data, charset)); } public void put(String key, String value) { this.map.put(key, value); } public String applyTemplate(String template) { StringBuilder sb = new StringBuilder(); int pos = 0; Deque ifStack = new ArrayDeque(); boolean suppress = false; while (pos < template.length()) { int idx = template.indexOf("{{", pos); if (idx == -1) { if (!suppress) sb.append(template.substring(pos)); break; } if (!suppress) sb.append(template.substring(pos, idx)); int braceCount = 2; while (idx + braceCount < template.length()) { if (template.charAt(idx + braceCount) != '{') break; braceCount++; } if (braceCount > 2) { pos = idx + braceCount; while (braceCount > 1) { if (!suppress) sb.append("{"); braceCount--; } continue; } int endIdx = template.indexOf("}}", idx); if (endIdx == -1) { if (!suppress) sb.append(template.substring(idx)); break; } String command = template.substring(idx + 2, endIdx); boolean removePrefixWhitespace = false; pos = endIdx + 2; if (template.length() == endIdx + 2) { removePrefixWhitespace = true; } else if (template.length() > endIdx + 2 && template.charAt(endIdx + 2) == '\n') { removePrefixWhitespace = true; pos = endIdx + 3; } else if (template.length() > endIdx + 3 && template.charAt(endIdx + 2) == '\r' && template.charAt(endIdx + 2) == '\n') { removePrefixWhitespace = true; pos = endIdx + 4; } StringBuilder prefixWhitespace = new StringBuilder(); if (removePrefixWhitespace) while (sb.length() > 0) { char ws = sb.charAt(sb.length() - 1); if (ws != ' ' && ws != '\t') break; prefixWhitespace.insert(0, ws); sb.setLength(sb.length() - 1); } if (command.startsWith("@")) { String key = command.substring(1).trim(); if (!suppress) sb.append(map.containsKey(key) ? addWhitespacePrefix(prefixWhitespace.toString(), map.get(key)) : ""); } else if (command.startsWith("if ")) { String key = command.substring(3).trim(); boolean val = map.containsKey(key); ifStack.push(new IfStackEntry(key, idx, val)); suppress |= !val; } else if (command.startsWith("end ")) { String key = command.substring(4).trim(); if (ifStack.isEmpty()) throw new IllegalArgumentException(String.format("%s floating {{end %s}}", toLinePos(template, idx), key)); ifStack.pop(); suppress = false; for (IfStackEntry v : ifStack) suppress |= !v.value; } else { throw new IllegalArgumentException(String.format("%s Unknown command: %s", toLinePos(template, idx), command)); } } if (!ifStack.isEmpty()) throw new IllegalArgumentException(String.format("%s {{if %s}} not closed", toLinePos(template, ifStack.peek().pos), ifStack.peek().key)); return sb.toString(); } private String addWhitespacePrefix(String prefix, String text) { String t = text.replace("\n", "\n" + prefix).trim(); return prefix + t + (prefix.length() > 0 ? "\n" : ""); } private static final byte[] read(InputStream in) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] b = new byte[4096]; while (true) { int r = in.read(b); if (r == -1) break; baos.write(b, 0, r); } return baos.toByteArray(); } public static String toLinePos(String template, int idx) { int line = 0; int col = 0; for (int i = 0; i < idx; i++) { char c = template.charAt(i); col += c == '\t' ? 4 : 1; if (c == '\n') { line++; col = 0; } } return String.format("[%d, %d]", line + 1, col + 1); } } ivyplusplus-1.42/ssh.configuration000066400000000000000000000001431450515647100174530ustar00rootroot00000000000000#Tue, 01 Jul 2014 23:14:14 +0200 ssh.username=reinier ssh.keyfile=/Users/rzwitserloot/.ssh/id_rsa