diff --git a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsGlobalSerializationTest.java b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsGlobalSerializationTest.java index 780253e2565d..58c3532e00e0 100644 --- a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsGlobalSerializationTest.java +++ b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsGlobalSerializationTest.java @@ -1,6 +1,5 @@ package org.jetbrains.jps.model.serialization; -import com.intellij.openapi.util.JDOMUtil; import com.intellij.testFramework.PlatformTestUtil; import org.jdom.Element; import org.jdom.JDOMException; @@ -34,7 +33,8 @@ public class JpsGlobalSerializationTest extends JpsSerializationTestCase { Element actual = new Element("component").setAttribute("name", "ProjectJdkTable"); JpsSdkTableSerializer.saveSdks(myModel.getGlobal().getLibraryCollection(), actual); File jdkTableFile = new File(getTestDataFileAbsolutePath(OPTIONS_DIR), "jdk.table.xml"); - Element expected = JDomSerializationUtil.findComponent(JDOMUtil.loadDocument(jdkTableFile).getRootElement(), "ProjectJdkTable"); + JpsMacroExpander expander = new JpsMacroExpander(getPathVariables()); + Element expected = JDomSerializationUtil.findComponent(JpsLoaderBase.loadRootElement(jdkTableFile, expander), "ProjectJdkTable"); PlatformTestUtil.assertElementsEqual(expected, actual); } diff --git a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsSerializationTestCase.java b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsSerializationTestCase.java index 723cd7738a70..b25721007c21 100644 --- a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsSerializationTestCase.java +++ b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsSerializationTestCase.java @@ -1,15 +1,19 @@ package org.jetbrains.jps.model.serialization; +import com.intellij.application.options.PathMacrosImpl; import com.intellij.openapi.application.ex.PathManagerEx; import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.util.PathUtil; +import com.intellij.util.SystemProperties; import org.jdom.Element; import org.jetbrains.jps.model.JpsModelTestCase; import java.io.File; import java.io.IOException; import java.util.Collections; +import java.util.HashMap; +import java.util.Map; /** * @author nik @@ -27,7 +31,7 @@ public abstract class JpsSerializationTestCase extends JpsModelTestCase { myProjectHomePath = PathUtil.getParentPath(myProjectHomePath); } try { - JpsProjectLoader.loadProject(myProject, Collections.emptyMap(), path); + JpsProjectLoader.loadProject(myProject, getPathVariables(), path); } catch (IOException e) { throw new RuntimeException(e); @@ -35,19 +39,31 @@ public abstract class JpsSerializationTestCase extends JpsModelTestCase { } protected String getUrl(String relativePath) { - return VfsUtilCore.pathToUrl(myProjectHomePath + "/" + relativePath); + return VfsUtilCore.pathToUrl(getAbsolutePath(relativePath)); + } + + protected String getAbsolutePath(String relativePath) { + return myProjectHomePath + "/" + relativePath; } protected void loadGlobalSettings(final String optionsDir) { try { String optionsPath = getTestDataFileAbsolutePath(optionsDir); - JpsGlobalLoader.loadGlobalSettings(myModel.getGlobal(), Collections.emptyMap(), optionsPath); + Map pathVariables = getPathVariables(); + JpsGlobalLoader.loadGlobalSettings(myModel.getGlobal(), pathVariables, optionsPath); } catch (IOException e) { throw new RuntimeException(e); } } + protected Map getPathVariables() { + Map variables = new HashMap(); + variables.put(PathMacrosImpl.APPLICATION_HOME_MACRO_NAME, PathManagerEx.getHomePath(getClass())); + variables.put(PathMacrosImpl.USER_HOME_MACRO_NAME, SystemProperties.getUserHome()); + return variables; + } + protected String getTestDataFileAbsolutePath(String relativePath) { return PathManagerEx.findFileUnderProjectHome(relativePath, getClass()).getAbsolutePath(); } diff --git a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/build/AntArtifactBuildTaskProvider.java b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/build/AntArtifactBuildTaskProvider.java index d4a40b2c6734..b9f712887cfc 100644 --- a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/build/AntArtifactBuildTaskProvider.java +++ b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/build/AntArtifactBuildTaskProvider.java @@ -26,12 +26,14 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.rt.ant.execution.AntMain2; +import com.intellij.util.SystemProperties; import com.intellij.util.execution.ParametersListUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.ant.model.JpsAntBuildFileOptions; import org.jetbrains.jps.ant.model.JpsAntExtensionService; import org.jetbrains.jps.ant.model.JpsAntInstallation; import org.jetbrains.jps.ant.model.artifacts.JpsAntArtifactExtension; +import org.jetbrains.jps.ant.model.impl.JpsAntInstallationImpl; import org.jetbrains.jps.builders.artifacts.ArtifactBuildTaskProvider; import org.jetbrains.jps.incremental.BuildTask; import org.jetbrains.jps.incremental.CompileContext; @@ -114,7 +116,8 @@ public class AntArtifactBuildTaskProvider extends ArtifactBuildTaskProvider { } JpsSdk jdk = jdkLibrary.getProperties(); - JpsAntInstallation antInstallation = JpsAntExtensionService.getBundledAntHome(context.getProjectDescriptor().getModel().getGlobal()); + JpsAntInstallation antInstallation = JpsAntExtensionService.getAntInstallationForBuildFile(context.getProjectDescriptor().getModel(), + myExtension.getFileUrl()); if (antInstallation == null) { reportError(context, "Ant installation is not configured"); throw new ProjectBuildException(); @@ -127,7 +130,9 @@ public class AntArtifactBuildTaskProvider extends ArtifactBuildTaskProvider { classpath.add(file.getAbsolutePath()); } } + classpath.addAll(options.getAdditionalClasspath()); classpath.addAll(antInstallation.getClasspath()); + JpsAntInstallationImpl.addAllJarsFromDirectory(classpath, new File(SystemProperties.getUserHome(), ".ant/lib")); classpath.add(PathManager.getJarPathForClass(AntMain2.class)); List vmParams = new ArrayList(); diff --git a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntBuildFileOptions.java b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntBuildFileOptions.java index 693eb2c1d9c7..a6d3f265db3a 100644 --- a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntBuildFileOptions.java +++ b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntBuildFileOptions.java @@ -15,6 +15,10 @@ */ package org.jetbrains.jps.ant.model; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + /** * @author nik */ @@ -24,4 +28,13 @@ public interface JpsAntBuildFileOptions { String getCustomJdkName(); String getAntCommandLineParameters(); + + void setAntCommandLineParameters(String antCommandLineParameters); + + @Nullable + String getAntInstallationName(); + + boolean isUseProjectDefaultAnt(); + + List getAdditionalClasspath(); } diff --git a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntConfiguration.java b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntConfiguration.java index 603d307e4853..6c58f95429e6 100644 --- a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntConfiguration.java +++ b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntConfiguration.java @@ -16,6 +16,7 @@ package org.jetbrains.jps.ant.model; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.JpsElement; /** @@ -24,4 +25,7 @@ import org.jetbrains.jps.model.JpsElement; public interface JpsAntConfiguration extends JpsElement { @NotNull JpsAntBuildFileOptions getOptions(@NotNull String buildFileUrl); + + @Nullable + String getProjectDefaultAntName(); } diff --git a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntExtensionService.java b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntExtensionService.java index d8a911fdebe8..22668a1c6bc0 100644 --- a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntExtensionService.java +++ b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntExtensionService.java @@ -21,14 +21,18 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.ant.model.artifacts.JpsAntArtifactExtension; import org.jetbrains.jps.ant.model.impl.JpsAntBuildFileOptionsImpl; import org.jetbrains.jps.ant.model.impl.JpsAntConfigurationImpl; +import org.jetbrains.jps.ant.model.impl.JpsAntInstallationImpl; import org.jetbrains.jps.ant.model.impl.artifacts.JpsAntArtifactExtensionImpl; +import org.jetbrains.jps.model.JpsElementCollection; import org.jetbrains.jps.model.JpsGlobal; +import org.jetbrains.jps.model.JpsModel; import org.jetbrains.jps.model.JpsProject; import org.jetbrains.jps.model.artifact.JpsArtifact; import org.jetbrains.jps.model.serialization.JpsGlobalLoader; import org.jetbrains.jps.model.serialization.PathMacroUtil; import java.io.File; +import java.util.Collections; /** * @author nik @@ -46,9 +50,13 @@ public class JpsAntExtensionService { return artifact.getContainer().getChild(JpsAntArtifactExtensionImpl.POSTPROCESSING_ROLE); } + public static void addAntInstallation(JpsGlobal global, JpsAntInstallation antInstallation) { + global.getContainer().getOrSetChild(JpsAntInstallationImpl.COLLECTION_ROLE).addChild(antInstallation); + } + @NotNull public static JpsAntBuildFileOptions getOptions(@NotNull JpsProject project, @NotNull String buildFileUrl) { - JpsAntConfiguration configuration = project.getContainer().getChild(JpsAntConfigurationImpl.ROLE); + JpsAntConfiguration configuration = getAntConfiguration(project); if (configuration != null) { return configuration.getOptions(buildFileUrl); } @@ -56,7 +64,12 @@ public class JpsAntExtensionService { } @Nullable - public static JpsAntInstallation getBundledAntHome(@NotNull JpsGlobal global) { + private static JpsAntConfiguration getAntConfiguration(JpsProject project) { + return project.getContainer().getChild(JpsAntConfigurationImpl.ROLE); + } + + @Nullable + private static JpsAntInstallation getBundledAntInstallation(@NotNull JpsGlobal global) { String appHome = JpsGlobalLoader.getPathVariable(global, PathMacroUtil.APPLICATION_HOME_DIR); if (appHome == null) { LOG.debug(PathMacroUtil.APPLICATION_HOME_DIR + " path variable not found, bundled Ant won't be configured"); @@ -75,6 +88,41 @@ public class JpsAntExtensionService { return null; } - return new JpsAntInstallation(antHome); + String antLib = new File(antHome, "lib").getAbsolutePath(); + return new JpsAntInstallationImpl(antHome, "Bundled Ant", Collections.emptyList(), Collections.singletonList(antLib)); + } + + @Nullable + public static JpsAntInstallation getAntInstallationForBuildFile(@NotNull JpsModel model, @NotNull String buildFileUrl) { + JpsAntBuildFileOptions options = getOptions(model.getProject(), buildFileUrl); + String antInstallationName; + if (options.isUseProjectDefaultAnt()) { + JpsAntConfiguration antConfiguration = getAntConfiguration(model.getProject()); + antInstallationName = antConfiguration != null ? antConfiguration.getProjectDefaultAntName() : null; + } + else { + antInstallationName = options.getAntInstallationName(); + } + + if (antInstallationName == null) return getBundledAntInstallation(model.getGlobal()); + + return findAntInstallation(model, antInstallationName); + } + + @Nullable + public static JpsAntInstallation findAntInstallation(@NotNull JpsModel model, @NotNull String antInstallationName) { + JpsElementCollection antInstallations = model.getGlobal().getContainer().getChild(JpsAntInstallationImpl.COLLECTION_ROLE); + if (antInstallations != null) { + for (JpsAntInstallation installation : antInstallations.getElements()) { + if (antInstallationName.equals(installation.getName())) { + return installation; + } + } + LOG.debug("Ant installation '" + antInstallationName + "' not found"); + } + else { + LOG.debug("Ant installations weren't loaded"); + } + return null; } } diff --git a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntInstallation.java b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntInstallation.java index 0af1ed0840d1..c0fd00dfe4b7 100644 --- a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntInstallation.java +++ b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/JpsAntInstallation.java @@ -15,37 +15,18 @@ */ package org.jetbrains.jps.ant.model; -import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.jps.model.JpsElement; import java.io.File; -import java.util.ArrayList; import java.util.List; /** * @author nik */ -public class JpsAntInstallation { - private File myAntHome; +public interface JpsAntInstallation extends JpsElement { + File getAntHome(); - public JpsAntInstallation(File antHome) { - myAntHome = antHome; - } + List getClasspath(); - public File getAntHome() { - return myAntHome; - } - - public List getClasspath() { - File lib = new File(myAntHome, "lib"); - List result = new ArrayList(); - File[] files = lib.listFiles(); - if (files != null) { - for (File file : files) { - if (StringUtil.endsWithIgnoreCase(file.getName(), ".jar")) { - result.add(file.getAbsolutePath()); - } - } - } - return result; - } + String getName(); } diff --git a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/impl/JpsAntBuildFileOptionsImpl.java b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/impl/JpsAntBuildFileOptionsImpl.java index 5950eaac6527..ddce091d278b 100644 --- a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/impl/JpsAntBuildFileOptionsImpl.java +++ b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/impl/JpsAntBuildFileOptionsImpl.java @@ -17,6 +17,9 @@ package org.jetbrains.jps.ant.model.impl; import org.jetbrains.jps.ant.model.JpsAntBuildFileOptions; +import java.util.ArrayList; +import java.util.List; + /** * @author nik */ @@ -25,15 +28,41 @@ public class JpsAntBuildFileOptionsImpl implements JpsAntBuildFileOptions { private String myAntCommandLineParameters = ""; private int myMaxHeapSize = 128; private String myCustomJdkName = ""; + private boolean myUseProjectDefaultAnt = true; + private String myAntInstallationName; + private List myClasspath = new ArrayList(); + private List myJarDirectories = new ArrayList(); public void setMaxStackSize(int maxStackSize) { myMaxStackSize = maxStackSize; } + @Override public void setAntCommandLineParameters(String antCommandLineParameters) { myAntCommandLineParameters = antCommandLineParameters; } + public void setUseProjectDefaultAnt(boolean useProjectDefaultAnt) { + myUseProjectDefaultAnt = useProjectDefaultAnt; + } + + @Override + public String getAntInstallationName() { + return myAntInstallationName; + } + + public void setAntInstallationName(String antInstallationName) { + myAntInstallationName = antInstallationName; + } + + public void addJarPath(String path) { + myClasspath.add(path); + } + + public void addJarDirectory(String directoryPath) { + myJarDirectories.add(directoryPath); + } + public void setMaxHeapSize(int maxHeapSize) { myMaxHeapSize = maxHeapSize; } @@ -61,4 +90,14 @@ public class JpsAntBuildFileOptionsImpl implements JpsAntBuildFileOptions { public String getAntCommandLineParameters() { return myAntCommandLineParameters; } + + @Override + public boolean isUseProjectDefaultAnt() { + return myUseProjectDefaultAnt; + } + + @Override + public List getAdditionalClasspath() { + return JpsAntInstallationImpl.getClasspath(myClasspath, myJarDirectories); + } } diff --git a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/impl/JpsAntConfigurationImpl.java b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/impl/JpsAntConfigurationImpl.java index 6af0618ef214..eb1c0c13b2b5 100644 --- a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/impl/JpsAntConfigurationImpl.java +++ b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/impl/JpsAntConfigurationImpl.java @@ -17,6 +17,7 @@ package org.jetbrains.jps.ant.model.impl; import com.intellij.util.containers.hash.HashMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.ant.model.JpsAntBuildFileOptions; import org.jetbrains.jps.ant.model.JpsAntConfiguration; import org.jetbrains.jps.model.JpsElementChildRole; @@ -30,16 +31,24 @@ import java.util.Map; */ public class JpsAntConfigurationImpl extends JpsElementBase implements JpsAntConfiguration { public static final JpsElementChildRole ROLE = JpsElementChildRoleBase.create("ant configuration"); + private final String myProjectDefaultAntName; private Map myOptionsMap = new HashMap(); - public JpsAntConfigurationImpl(Map options) { + public JpsAntConfigurationImpl(Map options, String projectDefaultAntName) { + myProjectDefaultAntName = projectDefaultAntName; myOptionsMap.putAll(options); } @NotNull @Override public JpsAntConfigurationImpl createCopy() { - return new JpsAntConfigurationImpl(myOptionsMap); + return new JpsAntConfigurationImpl(myOptionsMap, myProjectDefaultAntName); + } + + @Override + @Nullable + public String getProjectDefaultAntName() { + return myProjectDefaultAntName; } @Override diff --git a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/impl/JpsAntInstallationImpl.java b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/impl/JpsAntInstallationImpl.java new file mode 100644 index 000000000000..1db18840e793 --- /dev/null +++ b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/impl/JpsAntInstallationImpl.java @@ -0,0 +1,90 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.jps.ant.model.impl; + +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.ant.model.JpsAntInstallation; +import org.jetbrains.jps.model.ex.JpsElementBase; +import org.jetbrains.jps.model.ex.JpsElementChildRoleBase; +import org.jetbrains.jps.model.ex.JpsElementCollectionRole; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * @author nik + */ +public class JpsAntInstallationImpl extends JpsElementBase implements JpsAntInstallation { + private final File myAntHome; + private final String myName; + private final List myClasspath; + private final List myJarDirectories; + public static final JpsElementChildRoleBase ROLE = JpsElementChildRoleBase.create("ant installation"); + public static final JpsElementCollectionRole COLLECTION_ROLE = JpsElementCollectionRole.create(ROLE); + + public JpsAntInstallationImpl(File antHome, String name, final List classpath, List jarDirectories) { + myAntHome = antHome; + myName = name; + myClasspath = classpath; + myJarDirectories = jarDirectories; + } + + @NotNull + @Override + public JpsAntInstallationImpl createCopy() { + return new JpsAntInstallationImpl(myAntHome, myName, myClasspath, myJarDirectories); + } + + @Override + public String getName() { + return myName; + } + + @Override + public void applyChanges(@NotNull JpsAntInstallationImpl modified) { + } + + @Override + public File getAntHome() { + return myAntHome; + } + + @Override + public List getClasspath() { + return getClasspath(myClasspath, myJarDirectories); + } + + public static List getClasspath(final List classpath, final List jarDirectories) { + List result = new ArrayList(classpath); + for (String directory : jarDirectories) { + addAllJarsFromDirectory(result, new File(directory)); + } + return result; + } + + public static void addAllJarsFromDirectory(List classpath, final File dir) { + File[] files = dir.listFiles(); + if (files != null) { + for (File file : files) { + if (StringUtil.endsWithIgnoreCase(file.getName(), ".jar")) { + classpath.add(file.getAbsolutePath()); + } + } + } + } +} diff --git a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/impl/JpsAntModelSerializerExtension.java b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/impl/JpsAntModelSerializerExtension.java index 7f06d2c861cf..b44a4e704d1e 100644 --- a/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/impl/JpsAntModelSerializerExtension.java +++ b/plugins/ant/jps-plugin/src/org/jetbrains/jps/ant/model/impl/JpsAntModelSerializerExtension.java @@ -24,6 +24,8 @@ import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.ant.model.JpsAntBuildFileOptions; +import org.jetbrains.jps.ant.model.JpsAntConfiguration; +import org.jetbrains.jps.ant.model.JpsAntExtensionService; import org.jetbrains.jps.ant.model.artifacts.JpsAntArtifactExtension; import org.jetbrains.jps.ant.model.impl.artifacts.AntArtifactExtensionProperties; import org.jetbrains.jps.ant.model.impl.artifacts.JpsAntArtifactExtensionImpl; @@ -34,11 +36,10 @@ import org.jetbrains.jps.model.serialization.JpsGlobalExtensionSerializer; import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension; import org.jetbrains.jps.model.serialization.JpsProjectExtensionSerializer; import org.jetbrains.jps.model.serialization.artifact.JpsArtifactExtensionSerializer; +import org.jetbrains.jps.util.JpsPathUtil; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.io.File; +import java.util.*; /** * @author nik @@ -53,7 +54,7 @@ public class JpsAntModelSerializerExtension extends JpsModelSerializerExtension @NotNull @Override public List getProjectExtensionSerializers() { - return Collections.singletonList(new JpsProjectAntConfigurationSerializer()); + return Arrays.asList(new JpsProjectAntConfigurationSerializer(), new JpsWorkspaceAntConfigurationSerializer()); } @Override @@ -80,6 +81,12 @@ public class JpsAntModelSerializerExtension extends JpsModelSerializerExtension } } + @Nullable + private static String getValueAttribute(Element buildFileTag, final String childName) { + Element child = buildFileTag.getChild(childName); + return child != null ? child.getAttributeValue("value") : null; + } + private static class JpsGlobalAntConfigurationSerializer extends JpsGlobalExtensionSerializer { protected JpsGlobalAntConfigurationSerializer() { super("other.xml", "GlobalAntConfiguration"); @@ -87,13 +94,32 @@ public class JpsAntModelSerializerExtension extends JpsModelSerializerExtension @Override public void loadExtension(@NotNull JpsGlobal global, @NotNull Element componentTag) { - } + for (Element antTag : JDOMUtil.getChildren(componentTag.getChild("registeredAnts"), "ant")) { + String name = getValueAttribute(antTag, "name"); + String homeDir = getValueAttribute(antTag, "homeDir"); + List classpath = new ArrayList(); + List jarDirectories = new ArrayList(); + for (Element classpathItemTag : JDOMUtil.getChildren(antTag.getChild("classpath"), "classpathItem")) { + String fileUrl = classpathItemTag.getAttributeValue("path"); + String dirUrl = classpathItemTag.getAttributeValue("dir"); + if (fileUrl != null) { + classpath.add(JpsPathUtil.urlToPath(fileUrl)); + } + else if (dirUrl != null) { + jarDirectories.add(JpsPathUtil.urlToPath(dirUrl)); + } + } + if (name != null && homeDir != null) { + JpsAntExtensionService.addAntInstallation(global, new JpsAntInstallationImpl(new File(homeDir), name, classpath, jarDirectories)); + } + } + } @Override public void saveExtension(@NotNull JpsGlobal global, @NotNull Element componentTag) { } - } + } private static class JpsProjectAntConfigurationSerializer extends JpsProjectExtensionSerializer { private JpsProjectAntConfigurationSerializer() { super("ant.xml", "AntConfiguration"); @@ -108,14 +134,56 @@ public class JpsAntModelSerializerExtension extends JpsModelSerializerExtension options.setMaxHeapSize(StringUtil.parseInt(getValueAttribute(buildFileTag, "maximumHeapSize"), 128)); options.setMaxStackSize(StringUtil.parseInt(getValueAttribute(buildFileTag, "maximumStackSize"), 2)); options.setCustomJdkName(getValueAttribute(buildFileTag, "customJdkName")); + Element antReference = buildFileTag.getChild("antReference"); + if (antReference != null) { + options.setUseProjectDefaultAnt(Boolean.parseBoolean(antReference.getAttributeValue("projectDefault"))); + options.setAntInstallationName(antReference.getAttributeValue("name")); + } + for (Element classpathEntry : JDOMUtil.getChildren(buildFileTag.getChild("additionalClassPath"), "entry")) { + String fileUrl = classpathEntry.getAttributeValue("path"); + String dirUrl = classpathEntry.getAttributeValue("dir"); + if (fileUrl != null) { + options.addJarPath(JpsPathUtil.urlToPath(fileUrl)); + } + else if (dirUrl != null) { + options.addJarDirectory(JpsPathUtil.urlToPath(dirUrl)); + } + } optionsMap.put(url, options); } - project.getContainer().setChild(JpsAntConfigurationImpl.ROLE, new JpsAntConfigurationImpl(optionsMap)); + Element defaultAnt = componentTag.getChild("defaultAnt"); + String projectDefaultAntName; + if (defaultAnt != null) { + projectDefaultAntName = defaultAnt.getAttributeValue("name"); + } + else { + projectDefaultAntName = null; + } + project.getContainer().setChild(JpsAntConfigurationImpl.ROLE, new JpsAntConfigurationImpl(optionsMap, projectDefaultAntName)); } - private static String getValueAttribute(Element buildFileTag, final String childName) { - Element child = buildFileTag.getChild(childName); - return child != null ? child.getAttributeValue("value") : ""; + @Override + public void saveExtension(@NotNull JpsProject project, @NotNull Element componentTag) { + } + } + + private static class JpsWorkspaceAntConfigurationSerializer extends JpsProjectExtensionSerializer { + private JpsWorkspaceAntConfigurationSerializer() { + super(WORKSPACE_FILE, "antWorkspaceConfiguration"); + } + + @Override + public void loadExtension(@NotNull JpsProject project, @NotNull Element componentTag) { + for (Element buildFileTag : JDOMUtil.getChildren(componentTag, "buildFile")) { + String commandLine = getValueAttribute(buildFileTag, "antCommandLine"); + String url = buildFileTag.getAttributeValue("url"); + if (!StringUtil.isEmpty(commandLine)) { + JpsAntConfiguration configuration = project.getContainer().getChild(JpsAntConfigurationImpl.ROLE); + if (configuration != null) { + configuration.getOptions(url).setAntCommandLineParameters(commandLine); + } + } + } } @Override diff --git a/plugins/ant/jps-plugin/testData/ant-project/.idea/ant.xml b/plugins/ant/jps-plugin/testData/ant-project/.idea/ant.xml index 2108febc8771..0ba25642f233 100644 --- a/plugins/ant/jps-plugin/testData/ant-project/.idea/ant.xml +++ b/plugins/ant/jps-plugin/testData/ant-project/.idea/ant.xml @@ -3,7 +3,10 @@ - + + + + diff --git a/plugins/ant/jps-plugin/testData/ant-project/.idea/workspace.xml b/plugins/ant/jps-plugin/testData/ant-project/.idea/workspace.xml new file mode 100644 index 000000000000..86dfdc5f414d --- /dev/null +++ b/plugins/ant/jps-plugin/testData/ant-project/.idea/workspace.xml @@ -0,0 +1,29 @@ + + + + + + diff --git a/plugins/ant/jps-plugin/testData/ant-project/ant-lib/a.jar b/plugins/ant/jps-plugin/testData/ant-project/ant-lib/a.jar new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/plugins/ant/jps-plugin/testData/ant-project/lib/jdom.jar b/plugins/ant/jps-plugin/testData/ant-project/lib/jdom.jar new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/plugins/ant/jps-plugin/testData/config/options/other.xml b/plugins/ant/jps-plugin/testData/config/options/other.xml index 242fd9bb9116..e5cca9ec8e26 100644 --- a/plugins/ant/jps-plugin/testData/config/options/other.xml +++ b/plugins/ant/jps-plugin/testData/config/options/other.xml @@ -19,6 +19,16 @@ + + + + + + + + + + diff --git a/plugins/ant/jps-plugin/testSrc/org/jetbrains/jps/ant/JpsAntSerializationTest.java b/plugins/ant/jps-plugin/testSrc/org/jetbrains/jps/ant/JpsAntSerializationTest.java index e17b0bcd666c..cb44d172b24c 100644 --- a/plugins/ant/jps-plugin/testSrc/org/jetbrains/jps/ant/JpsAntSerializationTest.java +++ b/plugins/ant/jps-plugin/testSrc/org/jetbrains/jps/ant/JpsAntSerializationTest.java @@ -16,21 +16,29 @@ package org.jetbrains.jps.ant; import com.intellij.lang.ant.config.impl.BuildFileProperty; +import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.SystemProperties; +import gnu.trove.THashSet; import org.jetbrains.jps.ant.model.JpsAntBuildFileOptions; import org.jetbrains.jps.ant.model.JpsAntExtensionService; +import org.jetbrains.jps.ant.model.JpsAntInstallation; import org.jetbrains.jps.ant.model.artifacts.JpsAntArtifactExtension; import org.jetbrains.jps.ant.model.impl.artifacts.JpsAntArtifactExtensionImpl; import org.jetbrains.jps.model.artifact.JpsArtifact; import org.jetbrains.jps.model.artifact.JpsArtifactService; import org.jetbrains.jps.model.serialization.JpsSerializationTestCase; +import java.io.File; import java.util.List; +import java.util.Set; /** * @author nik */ public class JpsAntSerializationTest extends JpsSerializationTestCase { public static final String PROJECT_PATH = "plugins/ant/jps-plugin/testData/ant-project"; + public static final String OPTIONS_PATH = "plugins/ant/jps-plugin/testData/config/options"; public void testLoadArtifactProperties() { loadProject(PROJECT_PATH); @@ -65,14 +73,53 @@ public class JpsAntSerializationTest extends JpsSerializationTestCase { assertNull(JpsAntExtensionService.getPreprocessingExtension(jar)); } + public void testLoadAntInstallations() { + loadGlobalSettings(OPTIONS_PATH); + JpsAntInstallation installation = JpsAntExtensionService.findAntInstallation(myModel, "Apache Ant version 1.8.2"); + assertNotNull(installation); + assertEquals(FileUtil.toSystemIndependentName(installation.getAntHome().getAbsolutePath()), + FileUtil.toSystemIndependentName(new File(SystemProperties.getUserHome(), "applications/apache-ant-1.8.2").getAbsolutePath())); + + JpsAntInstallation installation2 = JpsAntExtensionService.findAntInstallation(myModel, "Patched Ant"); + assertNotNull(installation2); + assertContainsElements(toFiles(installation2.getClasspath()), + PathManagerEx.findFileUnderCommunityHome("lib/ant/lib/ant.jar"), + PathManagerEx.findFileUnderCommunityHome("lib/asm.jar"), + PathManagerEx.findFileUnderCommunityHome("lib/dev/easymock.jar")); + } + public void testLoadAntConfiguration() { loadProject(PROJECT_PATH); - JpsAntBuildFileOptions options = JpsAntExtensionService.getOptions(myProject, getUrl("build.xml")); + loadGlobalSettings(OPTIONS_PATH); + String buildXmlUrl = getUrl("build.xml"); + JpsAntBuildFileOptions options = JpsAntExtensionService.getOptions(myProject, buildXmlUrl); assertEquals(128, options.getMaxHeapSize()); + assertEquals("-J-Dmy.ant.prop=123", options.getAntCommandLineParameters()); + assertContainsElements(toFiles(options.getAdditionalClasspath()), + new File(getAbsolutePath("lib/jdom.jar")), + new File(getAbsolutePath("ant-lib/a.jar"))); - JpsAntBuildFileOptions options2 = JpsAntExtensionService.getOptions(myProject, getUrl("empty.xml")); + String emptyFileUrl = getUrl("empty.xml"); + JpsAntBuildFileOptions options2 = JpsAntExtensionService.getOptions(myProject, emptyFileUrl); assertEquals(256, options2.getMaxHeapSize()); assertEquals(10, options2.getMaxStackSize()); assertEquals("1.6", options2.getCustomJdkName()); + + JpsAntInstallation bundled = JpsAntExtensionService.getAntInstallationForBuildFile(myModel, buildXmlUrl); + assertNotNull(bundled); + assertEquals("Bundled Ant", bundled.getName()); + + JpsAntInstallation installation = JpsAntExtensionService.getAntInstallationForBuildFile(myModel, emptyFileUrl); + assertNotNull(installation); + assertEquals("Apache Ant version 1.8.2", installation.getName()); + + } + + private static Set toFiles(List classpath) { + Set result = new THashSet(FileUtil.FILE_HASHING_STRATEGY); + for (String path : classpath) { + result.add(new File(path)); + } + return result; } }