diff --git a/jps/.idea/modules.xml b/jps/.idea/modules.xml index d8e1dbbd8f97..ae879f386b29 100644 --- a/jps/.idea/modules.xml +++ b/jps/.idea/modules.xml @@ -4,6 +4,7 @@ + diff --git a/jps/antLayout/antlayout.iml b/jps/antLayout/antlayout.iml new file mode 100644 index 000000000000..c053808175a3 --- /dev/null +++ b/jps/antLayout/antlayout.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/jps/antLayout/src/jetbrains/antlayout/antlib.xml b/jps/antLayout/src/jetbrains/antlayout/antlib.xml new file mode 100755 index 000000000000..e1100dea26af --- /dev/null +++ b/jps/antLayout/src/jetbrains/antlayout/antlib.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/jps/antLayout/src/jetbrains/antlayout/datatypes/Container.java b/jps/antLayout/src/jetbrains/antlayout/datatypes/Container.java new file mode 100755 index 000000000000..e87c1c8e0e43 --- /dev/null +++ b/jps/antLayout/src/jetbrains/antlayout/datatypes/Container.java @@ -0,0 +1,118 @@ +package jetbrains.antlayout.datatypes; + +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.types.ZipFileSet; +import org.apache.tools.ant.BuildException; + +import java.util.List; +import java.util.ArrayList; +import java.util.Set; +import java.util.HashSet; + +import jetbrains.antlayout.util.TempFileFactory; +import jetbrains.antlayout.util.LayoutFileSet; + +/** + * @author max + */ +public abstract class Container extends Content { + private List filesets = new ArrayList(); + private List children = new ArrayList(); + + private String excludes = null; + private String includes = null; + + public void addFileset(FileSet set) { + filesets.add(set); + } + + public void addZipfileset(ZipFileSet set) { + filesets.add(set); + } + + public void addDir(DirContainer container) { + children.add(container); + } + + public void addJar(JarContainer container) { + children.add(container); + } + + public void addZip(ZipContainer container) { + children.add(container); + } + + public void addContainer(Container container) { + children.add(container); + } + + public void addModule(IdeaModule module) { + filesets.add(module); + } + + public List getFilesets() { + return filesets; + } + + public List getChildren() { + return children; + } + + + public void setExcludes(String excludes) { + this.excludes = excludes; + } + + public void setIncludes(String includes) { + this.includes = includes; + } + + public List build(TempFileFactory temp) { + Set result = new HashSet(); + for (FileSet set : filesets) { + result.add(createCopy(set)); + } + + for (Container child : children) { + for (LayoutFileSet set : child.build(temp)) { + result.add(createCopy(set)); + } + } + + ArrayList list = new ArrayList(result); + for (LayoutFileSet set : list) { + if (includes != null) { + set.setIncludes(includes); + } + + if (excludes != null) { + set.setExcludes(excludes); + } + } + + return list; + } + + protected LayoutFileSet createCopy(FileSet set) { + if (set instanceof IdeaModule) { + return new IdeaModule((IdeaModule) set); + } + if (set instanceof ZipFileSet) { + return new LayoutFileSet((ZipFileSet) set.clone()); + } else { + return new LayoutFileSet((FileSet) set.clone()); + } + } + + public void validateArguments() throws BuildException { + for (Container child : children) { + child.validateArguments(); + } + + for (FileSet set : filesets) { + if (set instanceof IdeaModule) { + ((IdeaModule) set).validateArguments(); + } + } + } +} diff --git a/jps/antLayout/src/jetbrains/antlayout/datatypes/Content.java b/jps/antLayout/src/jetbrains/antlayout/datatypes/Content.java new file mode 100755 index 000000000000..f306200d25a0 --- /dev/null +++ b/jps/antLayout/src/jetbrains/antlayout/datatypes/Content.java @@ -0,0 +1,18 @@ +package jetbrains.antlayout.datatypes; + +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.BuildException; + +import java.util.List; + +import jetbrains.antlayout.util.TempFileFactory; +import jetbrains.antlayout.util.LayoutFileSet; + +/** + * @author max + */ +public abstract class Content extends DataType { + public abstract List build(TempFileFactory temp); + + public abstract void validateArguments() throws BuildException; +} diff --git a/jps/antLayout/src/jetbrains/antlayout/datatypes/DirContainer.java b/jps/antLayout/src/jetbrains/antlayout/datatypes/DirContainer.java new file mode 100755 index 000000000000..c5f334543e4c --- /dev/null +++ b/jps/antLayout/src/jetbrains/antlayout/datatypes/DirContainer.java @@ -0,0 +1,41 @@ +package jetbrains.antlayout.datatypes; + +import jetbrains.antlayout.util.TempFileFactory; +import jetbrains.antlayout.util.LayoutFileSet; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tools.ant.BuildException; + +/** + * @author max + */ +public class DirContainer extends Container { + private String dirName; + + public void setName(String name) { + dirName = name; + } + + public List build(TempFileFactory temp) { + List unprefixed = super.build(temp); + List prefixed = new ArrayList(); + + for (LayoutFileSet set : unprefixed) { + LayoutFileSet copy = createCopy(set); + copy.setPrefix(dirName + "/" + set.getPrefix(getProject())); + prefixed.add(copy); + } + + return prefixed; + } + + + public void validateArguments() throws BuildException { + super.validateArguments(); + if (dirName == null) { + throw new BuildException("dirname attribute must be specified for direntry"); + } + } +} diff --git a/jps/antLayout/src/jetbrains/antlayout/datatypes/IdeaModule.java b/jps/antLayout/src/jetbrains/antlayout/datatypes/IdeaModule.java new file mode 100755 index 000000000000..7435db1053d7 --- /dev/null +++ b/jps/antLayout/src/jetbrains/antlayout/datatypes/IdeaModule.java @@ -0,0 +1,65 @@ +package jetbrains.antlayout.datatypes; + +import jetbrains.antlayout.util.LayoutFileSet; +import org.apache.tools.ant.BuildException; + +import java.io.File; + +/** + * @author max + */ +public class IdeaModule extends LayoutFileSet { + private String name; + + public IdeaModule() { + } + + public IdeaModule(IdeaModule fileset) { + super(fileset); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + setDir(getMainOutput()); + } + + private File getMainOutput() { + String common = getProject().getProperty("modules.output"); + if (common != null) { + return new File(new File(common), "production/" + name); + } + + String adhoc = getProject().getProperty("module." + name +".output.main"); + return adhoc != null ? new File(adhoc) : null; + } + + public void validateArguments() throws BuildException { + if (name == null) { + throw new BuildException("name attribute must be specified for moduleentry"); + } + + File main = getMainOutput(); + + if (main == null || !main.exists()) { + throw new BuildException("No production output found for module " + name + + ". Either modules.output property references project output that doesn't contain this module or " + + "module." + name +".output.main is not defined or references non-existing directory."); + } + } + + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IdeaModule that = (IdeaModule) o; + return getDir(getProject()).equals(that.getDir(getProject())); + } + + public int hashCode() { + return getDir(getProject()).hashCode(); + } +} diff --git a/jps/antLayout/src/jetbrains/antlayout/datatypes/JarContainer.java b/jps/antLayout/src/jetbrains/antlayout/datatypes/JarContainer.java new file mode 100755 index 000000000000..d27918cd69d6 --- /dev/null +++ b/jps/antLayout/src/jetbrains/antlayout/datatypes/JarContainer.java @@ -0,0 +1,45 @@ +package jetbrains.antlayout.datatypes; + +import org.apache.tools.ant.taskdefs.Zip; +import org.apache.tools.ant.taskdefs.Jar; +import org.apache.tools.ant.taskdefs.Manifest; +import org.apache.tools.ant.taskdefs.ManifestException; +import org.apache.tools.ant.types.ZipFileSet; +import org.apache.tools.ant.types.Path; + +import java.io.File; + +/** + * @author max + */ +public class JarContainer extends ZipContainer { + protected Zip createTask() { + Jar task = new Jar(); + task.setTaskName("jar"); + return task; + } + + public void setIndex(boolean flag) { + ((Jar) task).setIndex(flag); + } + + public void setManifestEncoding(String manifestEncoding) { + ((Jar) task).setManifestEncoding(manifestEncoding); + } + + public void setManifest(File manifestFile) { + ((Jar) task).setManifest(manifestFile); + } + + public void setFilesetmanifest(Jar.FilesetManifestConfig config) { + ((Jar) task).setFilesetmanifest(config); + } + + public void addConfiguredManifest(Manifest newManifest) throws ManifestException { + ((Jar) task).addConfiguredManifest(newManifest); + } + + public void addMetainf(ZipFileSet fs) { + ((Jar) task).addMetainf(fs); + } +} diff --git a/jps/antLayout/src/jetbrains/antlayout/datatypes/RootContainer.java b/jps/antLayout/src/jetbrains/antlayout/datatypes/RootContainer.java new file mode 100755 index 000000000000..e619e48b233b --- /dev/null +++ b/jps/antLayout/src/jetbrains/antlayout/datatypes/RootContainer.java @@ -0,0 +1,53 @@ +package jetbrains.antlayout.datatypes; + +import jetbrains.antlayout.util.TempFileFactory; +import jetbrains.antlayout.util.LayoutFileSet; + +import java.io.File; +import java.util.List; +import java.util.Collections; + +import org.apache.tools.ant.taskdefs.Copy; +import org.apache.tools.ant.BuildException; + +/** + * @author max + */ +public class RootContainer extends Container { + private File destDirectory; + + public RootContainer(File destDirectory) { + this.destDirectory = destDirectory; + } + + + public List build(TempFileFactory temp) { + List built = super.build(temp); + for (LayoutFileSet set : built) { + copySet(set); + } + + return Collections.emptyList(); + } + + private void copySet(LayoutFileSet set) { + Copy task = new Copy(); + task.setTaskName("copy"); + task.setProject(getProject()); + String prefix = set.getPrefix(getProject()); + File target = prefix.length() > 0 ? new File(destDirectory, prefix + "/") : destDirectory; + + target.mkdirs(); + + task.setTodir(target); + LayoutFileSet unprefixed = (LayoutFileSet) set.clone(); + unprefixed.setPrefix(""); + + task.addFileset(unprefixed); + task.perform(); + } + + public void validateArguments() throws BuildException { + super.validateArguments(); + } +} diff --git a/jps/antLayout/src/jetbrains/antlayout/datatypes/ZipContainer.java b/jps/antLayout/src/jetbrains/antlayout/datatypes/ZipContainer.java new file mode 100755 index 000000000000..f00fd01fad32 --- /dev/null +++ b/jps/antLayout/src/jetbrains/antlayout/datatypes/ZipContainer.java @@ -0,0 +1,84 @@ +package jetbrains.antlayout.datatypes; + +import jetbrains.antlayout.util.TempFileFactory; +import jetbrains.antlayout.util.LayoutFileSet; +import org.apache.tools.ant.taskdefs.Zip; +import org.apache.tools.ant.BuildException; + +import java.io.File; +import java.util.Arrays; +import java.util.List; + +/** + * @author max + */ +public class ZipContainer extends Container { + private String name; + protected Zip task; + + public ZipContainer() { + task = createTask(); + task.setCompress(true); // Default compress is false + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List build(TempFileFactory temp) { + List built = super.build(temp); + File dest = temp.allocateTempFile(name); + + task.setProject(getProject()); + task.setDestFile(dest); + + for (LayoutFileSet set : built) { + task.addZipfileset(set); + } + + LayoutFileSet result = new LayoutFileSet(); + result.setFile(dest); + + task.perform(); + + return Arrays.asList(result); + } + + protected Zip createTask() { + Zip task = new Zip(); + task.setTaskName("zip"); + return task; + } + + public void setCompress(boolean compress) { + task.setCompress(compress); + } + + public void setFilesonly(boolean f) { + task.setFilesonly(f); + } + + public void setDuplicate(Zip.Duplicate df) { + task.setDuplicate(df); + } + + public void setEncoding(String encoding) { + task.setEncoding(encoding); + } + + public void setBasedir(File baseDir) { + task.setBasedir(baseDir); + } + + public void validateArguments() throws BuildException { + super.validateArguments(); + + if (name == null) { + throw new BuildException("name attribute must be specified for zipentry or jarentry"); + } + } +} diff --git a/jps/antLayout/src/jetbrains/antlayout/tasks/LayoutTask.java b/jps/antLayout/src/jetbrains/antlayout/tasks/LayoutTask.java new file mode 100755 index 000000000000..09ac536fee64 --- /dev/null +++ b/jps/antLayout/src/jetbrains/antlayout/tasks/LayoutTask.java @@ -0,0 +1,85 @@ +package jetbrains.antlayout.tasks; + +import org.apache.tools.ant.Task; +import org.apache.tools.ant.BuildException; +import jetbrains.antlayout.datatypes.*; +import jetbrains.antlayout.util.TempFileFactory; + +import java.util.List; +import java.util.ArrayList; +import java.io.File; + +/** + * @author max + */ +public class LayoutTask extends Task { + private List containers = new ArrayList(); + private File destDir; + + public void addDir(DirContainer container) { + containers.add(container); + } + + public void addJar(JarContainer container) { + containers.add(container); + } + + public void addZip(ZipContainer container) { + containers.add(container); + } + + public void setTodir(File dir) { + destDir = dir; + } + + public File getDestDir() { + return destDir; + } + + public void execute() throws BuildException { + validateArguments(); + + RootContainer root = new RootContainer(destDir); + root.setProject(getProject()); + for (Container container : containers) { + root.addContainer(container); + } + + final File tempDir = new File(destDir, "___tmp___"); + tempDir.mkdirs(); + + root.build(new TempFileFactory() { + int counter = 0; + public File allocateTempFile(String name) { + File localTmp = new File(tempDir, "_" + counter + "/"); + counter++; + localTmp.mkdirs(); + return new File(localTmp, name); + } + }); + + deleteRecursively(tempDir); + } + + protected void deleteRecursively(File d) { + if (d.isDirectory()) { + for (File file : d.listFiles()) { + deleteRecursively(file); + } + } + + if (!d.delete()) { + throw new BuildException("Unable to delete file " + d.getAbsolutePath()); + } + } + + private void validateArguments() throws BuildException { + if (destDir == null) { + throw new BuildException("todir attribute must be specified"); + } + + for (Container container : containers) { + container.validateArguments(); + } + } +} diff --git a/jps/antLayout/src/jetbrains/antlayout/util/LayoutFileSet.java b/jps/antLayout/src/jetbrains/antlayout/util/LayoutFileSet.java new file mode 100755 index 000000000000..178d08bfa5d0 --- /dev/null +++ b/jps/antLayout/src/jetbrains/antlayout/util/LayoutFileSet.java @@ -0,0 +1,20 @@ +package jetbrains.antlayout.util; + +import org.apache.tools.ant.types.ZipFileSet; +import org.apache.tools.ant.types.FileSet; + +/** + * @author max + */ +public class LayoutFileSet extends ZipFileSet { + public LayoutFileSet() { + } + + public LayoutFileSet(FileSet fileset) { + super(fileset); + } + + public LayoutFileSet(ZipFileSet fileset) { + super(fileset); + } +} diff --git a/jps/antLayout/src/jetbrains/antlayout/util/TempFileFactory.java b/jps/antLayout/src/jetbrains/antlayout/util/TempFileFactory.java new file mode 100755 index 000000000000..26b22013b619 --- /dev/null +++ b/jps/antLayout/src/jetbrains/antlayout/util/TempFileFactory.java @@ -0,0 +1,10 @@ +package jetbrains.antlayout.util; + +import java.io.File; + +/** + * @author max + */ +public interface TempFileFactory { + File allocateTempFile(String name); +} diff --git a/jps/build.gant b/jps/build.gant index 641d30b11a2b..8f7505938be4 100644 --- a/jps/build.gant +++ b/jps/build.gant @@ -3,13 +3,30 @@ import org.jetbrains.jps.* includeTool << Jps def projectHome = "." +def libs = "$projectHome/lib/" project.targetFolder = "${projectHome}/build" -module("jps") { + +library("ANT") { + new File(libs).eachFile{ jar -> + def path = jar.absolutePath + def name = jar.name + if (name.startsWith("ant")) { + classpath path + } + } +} + +module("JPS") { src "${projectHome}/src" } +module("antlayout") { + classpath ANT + src "${projectHome}/antLayout/src" +} + target('default' : 'Default target') { project.clean() long start = System.currentTimeMillis() @@ -17,9 +34,11 @@ target('default' : 'Default target') { layout("${project.targetFolder}/deploy") { jar("jps.jar") { - module("jps") - zipfileset(src: "${projectHome}/lib/javac2.jar") - zipfileset(src: "${projectHome}/lib/antlayout.jar") + module("JPS") + module("antlayout") + zipfileset(src: "${projectHome}/lib/javac2.jar") { + exclude (name: "JDOM*.class") + } } } diff --git a/jps/lib/ant-1.7.1.jar b/jps/lib/ant-1.7.1.jar new file mode 100644 index 000000000000..704717779f6d Binary files /dev/null and b/jps/lib/ant-1.7.1.jar differ