diff --git a/build.xml b/build.xml index 24276d2c..f9e5f5d0 100644 --- a/build.xml +++ b/build.xml @@ -46,7 +46,7 @@ - + @@ -382,9 +382,9 @@ - + + message="At least one test has failed. See logs (in ${test.xml.dir}) for details (use the target test-report to run the test with a report)"/> diff --git a/doc/doc/tutorial/build-repository/basic.html b/doc/doc/tutorial/build-repository/basic.html index ba871e1f..0330b3fc 100644 --- a/doc/doc/tutorial/build-repository/basic.html +++ b/doc/doc/tutorial/build-repository/basic.html @@ -55,11 +55,13 @@ ibilio

basic, retrieve commons-lang 1.0

Let's have a look at the basic target. - - + + + + -After a call to init-basic, that make the ivy initialization with the right ivysettings file, we only call the task install to retrieve apache commons-lang in it's 1.0 version. +After a declaration of the basic.settings, that make the ivy initialization with the right ivysettings file, we only call the task install to retrieve apache commons-lang in it's 1.0 version. Here is the ant call output :
Z:\ivy-repository>ant basic
 Buildfile: build.xml
@@ -94,8 +96,8 @@ We can see that we have started our own repository by retrieving the commons-lan
 

basic with dependencies, retrieve hibernate 2.1.8

Now let's advance a little more by trying a module that has some dependencies. Here is the target that we will call : - - + + This target is very similar to the basic one, except it defines the transitivity mode to use. By writing, transitive="true", we tell the task to retrieve the corresponding module and it's dependencies. diff --git a/doc/doc/tutorial/multiproject.html b/doc/doc/tutorial/multiproject.html index 0ae95b55..25ed40fb 100644 --- a/doc/doc/tutorial/multiproject.html +++ b/doc/doc/tutorial/multiproject.html @@ -113,23 +113,23 @@ Now that you are a bit more familiar with the structure, let's have a look at th So, here are some aspects of this common build file:

ivy settings

- + -This target configures ivy only by setting two properties: the location for the local repository and the location for the shared repository. It's the only settings done here, since ivy 1.3 is configured by default to work in a team environment (see default settings tutorial for details about this). For sure in a real environment the shared repository location would rather be in a team shared directory (or in a more complex repository, again see the default settings tutorial to see how to use something really different). -This target only indicates in comments how the settings would have been done if the default settings wasn't ok for our purpose. +This declaration configures ivy only by setting two properties: the location for the local repository and the location for the shared repository. It's the only settings done here, since ivy 1.3 is configured by default to work in a team environment (see default settings tutorial for details about this). For sure in a real environment the shared repository location would rather be in a team shared directory (or in a more complex repository, again see the default settings tutorial to see how to use something really different). +There is only in comments how the settings would have been done if the default settings wasn't ok for our purpose.

resolve dependencies

- + diff --git a/doc/doc/use/artifactproperty.html b/doc/doc/use/artifactproperty.html index f957294c..4ec4912c 100644 --- a/doc/doc/use/artifactproperty.html +++ b/doc/doc/use/artifactproperty.html @@ -48,6 +48,7 @@ The property name and value are generated using the classical pattern concept, a haltonfailuretrue to halt the build on ivy failure, false to continueNo. Defaults to true validatetrue to force ivy files validation against ivy.xsd, false to force no validation No. Defaults to default ivy value (as configured in configuration file) + settingsRefA reference to the ivy settings that must be used by this task (since 2.0)No, 'ivy.instance' is taken by default. diff --git a/doc/doc/use/artifactreport.html b/doc/doc/use/artifactreport.html index 83b06b7c..6b8f796b 100644 --- a/doc/doc/use/artifactreport.html +++ b/doc/doc/use/artifactreport.html @@ -79,6 +79,7 @@ Here is an example of generate file: confa comma separated list of the configurations to use to generate the report No. Defaults to the configurations resolved by the last resolve call haltonfailuretrue to halt the build on ivy failure, false to continueNo. Defaults to true + settingsRefA reference to the ivy settings that must be used by this task (since 2.0)No, 'ivy.instance' is taken by default.

Examples

@@ -92,7 +93,6 @@ Generates the artifact report for all configurations resolved during the last re
Generates the artifact report for only the default configuration resolved during the last resolve call. - diff --git a/doc/doc/use/buildlist.html b/doc/doc/use/buildlist.html index b40480c1..af70bddd 100644 --- a/doc/doc/use/buildlist.html +++ b/doc/doc/use/buildlist.html @@ -52,6 +52,7 @@ This is particularly useful combined with subant, to build a set of interelated haltonerrortrue to halt the build when an invalid ivy file is encountered, false to continueNo. Defaults to true skipbuildwithoutivytrue to skip files of the fileset with no corresponding ivy file, false otherwise. If false the file with no corresponding ivy file will be considered as independent of the other and put at the beginning of the built filelist.No. Defaults to false reversetrue to obtain the list in the reverse order, i.e. from the most dependent to the least oneNo. Defaults to default false + settingsRef(since 2.0) A reference to the ivy settings that must be used by this taskNo, 'ivy.instance' is taken by default. @@ -94,8 +95,6 @@ Builds a list of build.xml files sorted according to the ivy.xml files found in Builds a list of build.xml files sorted according to the ivy.xml files found in an ivy directory relative to those build files. Only build.xml files of modules which have dependencies (direct or transitive) on mymodule are put in the result list. - - diff --git a/doc/doc/use/buildnumber.html b/doc/doc/use/buildnumber.html index 20b6aee8..49c29a26 100644 --- a/doc/doc/use/buildnumber.html +++ b/doc/doc/use/buildnumber.html @@ -77,6 +77,7 @@ Note that when asking for revision 1, you can get a revision 10.0. To avoid that No, defaults to '.' prefixthe prefix to use for the property names set (will be prefix.revision, prefix.new.revision, ...) No, defaults to ivy + settingsRef(since 2.0) A reference to the ivy settings that must be used by this taskNo, 'ivy.instance' is taken by default.

Examples

diff --git a/doc/doc/use/cachefileset.html b/doc/doc/use/cachefileset.html index 70560290..dbf1b4e4 100644 --- a/doc/doc/use/cachefileset.html +++ b/doc/doc/use/cachefileset.html @@ -43,6 +43,7 @@ refid. confa comma separated list of the configurations to put in the created path No. Defaults to the configurations resolved by the last resolve call, or * if no resolve was explicitly called typecomma separated list of artifact types to accept in the path, * for allNo. Defaults to * + settingsRef(since 2.0) A reference to the ivy settings that must be used by this taskNo, 'ivy.instance' is taken by default. diff --git a/doc/doc/use/cachepath.html b/doc/doc/use/cachepath.html index 082aea6c..06b110f8 100644 --- a/doc/doc/use/cachepath.html +++ b/doc/doc/use/cachepath.html @@ -52,6 +52,7 @@ Note that if resolve has been called separately, the copy to the cache may have typecomma separated list of artifact types to accept in the path, * for all (since 1.2)No. Defaults to * useOrigintrue to use original location of local artifacts, false to use only cache locations since 1.4 No. Defaults false + settingsRef(since 2.0) A reference to the ivy settings that must be used by this taskNo, 'ivy.instance' is taken by default. diff --git a/doc/doc/use/configure.html b/doc/doc/use/configure.html index 9f3444b9..0fc8efbd 100644 --- a/doc/doc/use/configure.html +++ b/doc/doc/use/configure.html @@ -25,6 +25,8 @@ + + + diff --git a/doc/doc/use/var.html b/doc/doc/use/var.html index 78462a8c..6ead4552 100644 --- a/doc/doc/use/var.html +++ b/doc/doc/use/var.html @@ -47,6 +47,7 @@ See reference page for details about ivy urlthe url from which to read ivy variables prefixPrefix to apply to variables. A "." is appended to the prefix if not specified. No + settingsRefA reference to the ivy settings that must be used by this task (since 2.0)No, 'ivy.instance' is taken by default. diff --git a/doc/toc.json b/doc/toc.json index 425bcf0b..4653d6bb 100644 --- a/doc/toc.json +++ b/doc/toc.json @@ -377,7 +377,7 @@ }, { "id":"doc/configuration", - "title":"Settings", + "title":"Settings Files", "children": [ { "id":"doc/configuration/property", @@ -903,6 +903,14 @@ } ] }, + { + "id":"doc/use/settings", + "title":"settings", + "children": [ + + ] +, + "level":0 }, { "id":"doc/use/var", "title":"var", diff --git a/src/example/build-a-ivy-repository/build.xml b/src/example/build-a-ivy-repository/build.xml index 3041e27a..3a46746c 100644 --- a/src/example/build-a-ivy-repository/build.xml +++ b/src/example/build-a-ivy-repository/build.xml @@ -33,88 +33,59 @@ + + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - + + - - - + - - + + - - - + + - + diff --git a/src/example/dependence/standalone/build.xml b/src/example/dependence/standalone/build.xml index b8b701a7..3819cd62 100644 --- a/src/example/dependence/standalone/build.xml +++ b/src/example/dependence/standalone/build.xml @@ -36,17 +36,12 @@ - - - - + - + diff --git a/src/example/dual/project/build.xml b/src/example/dual/project/build.xml index 6074ce28..0287b50d 100644 --- a/src/example/dual/project/build.xml +++ b/src/example/dual/project/build.xml @@ -34,18 +34,12 @@ - - - - + - + diff --git a/src/example/multi-project/common/common.xml b/src/example/multi-project/common/common.xml index 2745b8d3..8e8933e8 100644 --- a/src/example/multi-project/common/common.xml +++ b/src/example/multi-project/common/common.xml @@ -21,7 +21,6 @@ - - + + + + + + - - - + @@ -156,7 +155,7 @@ - + diff --git a/src/java/org/apache/ivy/Ivy.java b/src/java/org/apache/ivy/Ivy.java index c72cb0c8..2a0f5c35 100644 --- a/src/java/org/apache/ivy/Ivy.java +++ b/src/java/org/apache/ivy/Ivy.java @@ -87,6 +87,13 @@ public class Ivy { return ivy; } + public static Ivy newInstance(IvySettings settings) { + Ivy ivy = new Ivy(); + ivy.setSettings(settings); + ivy.bind(); + return ivy; + } + /** * True if the current processing has been requested to be interrupted, * false otherwise diff --git a/src/java/org/apache/ivy/ant/IvyAntSettings.java b/src/java/org/apache/ivy/ant/IvyAntSettings.java new file mode 100644 index 00000000..f9659ba8 --- /dev/null +++ b/src/java/org/apache/ivy/ant/IvyAntSettings.java @@ -0,0 +1,317 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.ivy.ant; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.text.ParseException; +import java.util.Properties; + +import org.apache.ivy.Ivy; +import org.apache.ivy.core.settings.IvySettings; +import org.apache.ivy.core.settings.IvyVariableContainer; +import org.apache.ivy.util.Message; +import org.apache.ivy.util.url.CredentialsStore; +import org.apache.ivy.util.url.URLHandler; +import org.apache.ivy.util.url.URLHandlerDispatcher; +import org.apache.ivy.util.url.URLHandlerRegistry; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.DataType; + + +public class IvyAntSettings extends DataType { + + public static class Credentials { + private String _realm; + private String _host; + private String _username; + private String _passwd; + + public String getPasswd() { + return _passwd; + } + public void setPasswd(String passwd) { + _passwd = passwd; + } + public String getRealm() { + return _realm; + } + public void setRealm(String realm) { + _realm = format(realm); + } + public String getHost() { + return _host; + } + public void setHost(String host) { + _host = format(host); + } + public String getUsername() { + return _username; + } + public void setUsername(String userName) { + _username = format(userName); + } + } + + + private Ivy _ivyEngine = null; + + private File _file = null; + private URL _url = null; + private String _realm = null; + private String _host = null; + private String _userName = null; + private String _passwd = null; + private String id = null; + + /** + * Returns the default ivy settings of this classloader. If it doesn't exist yet, a new one is created using the given + * project to back the VariableContainer. + * @param project + * @return + */ + public static IvyAntSettings getDefaultInstance(Project project) { + Object defaultInstanceObj = project.getReference("ivy.instance"); + if (defaultInstanceObj!=null && defaultInstanceObj.getClass().getClassLoader()!=IvyAntSettings.class.getClassLoader()) { + Message.warn("ivy.instance reference an ivy:settings defined in an other classloader. An new default one will be used in this project."); + defaultInstanceObj=null; + } + if (defaultInstanceObj!=null && ! (defaultInstanceObj instanceof IvyAntSettings)) { + throw new BuildException("ivy.instance reference a " + + defaultInstanceObj.getClass().getName() + + " an not an IvyAntSettings. Please don't use this reference id ()"); + } + if (defaultInstanceObj==null) { + Message.info("No ivy:settings found for the default reference 'ivy.instance'. A default instance will be used"); + IvyAntSettings defaultInstance = new IvyAntSettings(); + defaultInstance.setProject(project); + defaultInstance.registerAsDefault(); + return defaultInstance; + } else { + return (IvyAntSettings) defaultInstanceObj; + } + + } + + + + protected void registerAsDefault() { + getProject().addReference("ivy.instance", this); + } + + + + public File getFile() { + return _file; + } + public URL getUrl() { + return _url; + } + public String getPasswd() { + return _passwd; + } + public void setPasswd(String passwd) { + _passwd = passwd; + } + public String getRealm() { + return _realm; + } + public void setRealm(String realm) { + _realm = format(realm); + } + public String getHost() { + return _host; + } + public void setHost(String host) { + _host = format(host); + } + public String getUsername() { + return _userName; + } + public void setUsername(String userName) { + _userName = format(userName); + } + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + private static String format(String str) { + return str == null ? str : (str.trim().length() == 0 ? null : str.trim()); + } + + public void addConfiguredCredentials(Credentials c) { + CredentialsStore.INSTANCE.addCredentials(c.getRealm(), c.getHost(), c.getUsername(), c.getPasswd()); + } + + + + + + public void setFile(File file) { + this._file = file; + } + + + public void setUrl(String confUrl) throws MalformedURLException { + this._url = new URL(confUrl); + } + + + + + + /*public void execute() throws BuildException { + ensureMessageInitialised(); + if (getId()==null) { + log("No id specified for the ivy:settings, set the instance as the default one", Project.MSG_DEBUG); + getProject().addReference("ivy.instance", this); + } else { + getProject().addReference(id, this); + } + }*/ + + + /** + * @return + */ + public Ivy getConfiguredIvyInstance() { + if (_ivyEngine==null) { + _ivyEngine = createIvyEngine(); + } + return _ivyEngine; + } + + + private Ivy createIvyEngine() { + IvyAntVariableContainer ivyAntVariableContainer = new IvyAntVariableContainer(getProject()); + + IvySettings settings = new IvySettings(ivyAntVariableContainer); + //NB: It is alrady done in the ivy.configure, but it is required for defineDefaultSettingFile (that should be done before the ivy.configure + settings.addAllVariables(getDefaultProperties(), false); + + Ivy ivy = Ivy.newInstance(settings); + + if (_file == null && _url == null) { + defineDefaultSettingFile(ivyAntVariableContainer); + } + + try { + configureURLHandler(); + if (_file != null) { + if (!_file.exists()) { + throw new BuildException("settings file does not exist: "+_file); + } + ivy.configure(_file); + } else { + if (_url==null) { + throw new AssertionError("ivy setting should have either a file, either an url, and if not defineDefaultSettingFile must set it."); + } + ivy.configure(_url); + } + } catch (ParseException e) { + throw new BuildException("impossible to configure ivy:settings with given "+(_file != null ? "file: "+_file : "url :"+_url)+" :"+e, e); + } catch (IOException e) { + throw new BuildException("impossible to configure ivy:settings with given "+(_file != null ? "file: "+_file : "url :"+_url)+" :"+e, e); + } + return ivy; + } + + + protected Properties getDefaultProperties() { + URL url = IvySettings.getDefaultPropertiesURL(); + // this is copy of loadURL code from ant Property task (not available in 1.5.1) + Properties props = new Properties(); + Message.verbose("Loading " + url); + try { + InputStream is = url.openStream(); + try { + props.load(is); + } finally { + if (is != null) { + is.close(); + } + } + } catch (IOException ex) { + throw new BuildException(ex); + } + return props; + } + + + /** Set _file or _url to its default value + * @param variableContainer */ + private void defineDefaultSettingFile(IvyVariableContainer variableContainer) { + String settingsFileName = variableContainer.getVariable("ivy.conf.file"); + if (settingsFileName != null) { + Message.deprecated("'ivy.conf.file' is deprecated, use 'ivy.settings.file' instead"); + } else { + settingsFileName = variableContainer.getVariable("ivy.settings.file"); + } + File[] settingsLocations = new File[] { + new File(getProject().getBaseDir(), settingsFileName), + new File(getProject().getBaseDir(), "ivyconf.xml"), + new File(settingsFileName), + new File("ivyconf.xml"), + }; + for (int i = 0; i < settingsLocations.length; i++) { + _file = settingsLocations[i]; + Message.verbose("searching settings file: trying "+_file); + if (_file.exists()) { + break; + } + } + if (!_file.exists()) { + if (Boolean.valueOf(getProject().getProperty("ivy.14.compatible")).booleanValue()) { + Message.info("no settings file found, using Ivy 1.4 default..."); + _file = null; + _url = IvySettings.getDefault14SettingsURL(); + } else { + Message.info("no settings file found, using default..."); + _file = null; + _url = IvySettings.getDefaultSettingsURL(); + } + } + } + + + + + + private void configureURLHandler() { + //TODO : the credentialStore should also be scoped + CredentialsStore.INSTANCE.addCredentials(getRealm(), getHost(), getUsername(), getPasswd()); + + URLHandlerDispatcher dispatcher = new URLHandlerDispatcher(); + URLHandler httpHandler = URLHandlerRegistry.getHttp(); + dispatcher.setDownloader("http", httpHandler); + dispatcher.setDownloader("https", httpHandler); + URLHandlerRegistry.setDefault(dispatcher); + } + + + + + + +} diff --git a/src/java/org/apache/ivy/ant/IvyAntVariableContainer.java b/src/java/org/apache/ivy/ant/IvyAntVariableContainer.java new file mode 100644 index 00000000..18cef27a --- /dev/null +++ b/src/java/org/apache/ivy/ant/IvyAntVariableContainer.java @@ -0,0 +1,51 @@ +/** + * + */ +package org.apache.ivy.ant; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.ivy.core.settings.IvyVariableContainer; +import org.apache.ivy.core.settings.IvyVariableContainerImpl; +import org.apache.ivy.util.Message; +import org.apache.tools.ant.Project; + +class IvyAntVariableContainer extends IvyVariableContainerImpl implements IvyVariableContainer{ + + protected Map _overwrittenProperties = new HashMap(); + protected Project _project; + + + public IvyAntVariableContainer(Project project) { + this._project = project; + } + + + public String getVariable(String name) { + String r = (String) _overwrittenProperties.get(name); + if (r==null) { + r=_project.getProperty(name); + } + if (r==null) { + r = super.getVariable(name); + } + return r; + } + + public Map getVariables() { + Map r = new HashMap(super.getVariables()); + r.putAll(_project.getProperties()); + r.putAll(_overwrittenProperties); + return r; + } + + public void setVariable(String varName, String value, boolean overwrite) { + if (overwrite) { + Message.debug("setting '"+varName+"' to '"+value+"'"); + _overwrittenProperties.put(varName, value); + } else { + super.setVariable(varName, value, overwrite); + } + } +} diff --git a/src/java/org/apache/ivy/ant/IvyConfigure.java b/src/java/org/apache/ivy/ant/IvyConfigure.java index 1ca44151..f6b5a156 100644 --- a/src/java/org/apache/ivy/ant/IvyConfigure.java +++ b/src/java/org/apache/ivy/ant/IvyConfigure.java @@ -18,204 +18,81 @@ package org.apache.ivy.ant; import java.io.File; -import java.io.IOException; -import java.io.InputStream; import java.net.MalformedURLException; -import java.net.URL; import java.util.Properties; -import org.apache.ivy.Ivy; -import org.apache.ivy.core.settings.IvySettings; -import org.apache.ivy.util.Message; -import org.apache.ivy.util.url.CredentialsStore; -import org.apache.ivy.util.url.URLHandler; -import org.apache.ivy.util.url.URLHandlerDispatcher; -import org.apache.ivy.util.url.URLHandlerRegistry; +import org.apache.ivy.ant.IvyAntSettings.Credentials; import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Property; - /** * Configure Ivy with an ivysettings.xml file * - * + * @deprecated Use the IvyAntSettings instead. */ public class IvyConfigure extends IvyTask { - public static class Credentials { - private String _realm; - private String _host; - private String _username; - private String _passwd; - - public String getPasswd() { - return _passwd; - } - public void setPasswd(String passwd) { - _passwd = passwd; - } - public String getRealm() { - return _realm; - } - public void setRealm(String realm) { - _realm = format(realm); - } - public String getHost() { - return _host; - } - public void setHost(String host) { - _host = format(host); - } - public String getUsername() { - return _username; - } - public void setUsername(String userName) { - _username = format(userName); - } + + private IvyAntSettings antSettings = new IvyAntSettings(); + + public void doExecute() throws BuildException { + ensureMessageInitialised(); + log( + "ivy:configure is deprecated, please use the data type ivy:settings instead", + Project.MSG_WARN); + // ivyConfigure used to export properties in the ant script. + // ivy:settings doesn't. + try { + loadDefaultProperties(); + } catch (Exception ex) { + throw new BuildException( + "impossible to load ivy default properties file: " + ex, ex); + } + antSettings.registerAsDefault(); } - private File _file = null; - private URL _url = null; - private String _realm = null; - private String _host = null; - private String _userName = null; - private String _passwd = null; + private void loadDefaultProperties() { + Property prop = new Property() { + public void execute() throws BuildException { + Properties props = antSettings.getDefaultProperties(); + addProperties(props); + } + }; + prop.setProject(getProject()); + prop.execute(); + } - public File getFile() { - return _file; - } - public void setFile(File conf) { - _file = conf; - } - public URL getUrl() { - return _url; - } - public void setUrl(String url) throws MalformedURLException { - _url = new URL(url); - } - public String getPasswd() { - return _passwd; - } - public void setPasswd(String passwd) { - _passwd = passwd; - } - public String getRealm() { - return _realm; - } - public void setRealm(String realm) { - _realm = format(realm); - } - public String getHost() { - return _host; - } - public void setHost(String host) { - _host = format(host); - } - public String getUsername() { - return _userName; - } - public void setUsername(String userName) { - _userName = format(userName); - } - private static String format(String str) { - return str == null ? str : (str.trim().length() == 0 ? null : str.trim()); - } - - public void addConfiguredCredentials(Credentials c) { - CredentialsStore.INSTANCE.addCredentials(c.getRealm(), c.getHost(), c.getUsername(), c.getPasswd()); - } + public void addConfiguredCredentials(Credentials c) { + antSettings.addConfiguredCredentials(c); + } - public void doExecute() throws BuildException { - try { - loadDefaultProperties(); - } catch (Exception ex) { - throw new BuildException("impossible to load ivy default properties file: "+ex, ex); - } - ensureMessageInitialised(); - Ivy ivy = Ivy.newInstance(); - try { - configureURLHandler(); - IvySettings settings = ivy.getSettings(); - settings.addAllVariables(getProject().getProperties()); - if (_file == null && _url == null) { - String settingsFileName = getProject().getProperty("ivy.conf.file"); - if (settingsFileName != null) { - Message.deprecated("'ivy.conf.file' is deprecated, use 'ivy.settings.file' instead"); - } else { - settingsFileName = getProject().getProperty("ivy.settings.file"); - } - File[] settingsLocations = new File[] { - new File(getProject().getBaseDir(), settingsFileName), - new File(getProject().getBaseDir(), "ivyconf.xml"), - new File(settingsFileName), - new File("ivyconf.xml"), - }; - for (int i = 0; i < settingsLocations.length; i++) { - _file = settingsLocations[i]; - Message.verbose("searching settings file: trying "+_file); - if (_file.exists()) { - break; - } - } - if (!_file.exists()) { - if (Boolean.valueOf(getProject().getProperty("ivy.14.compatible")).booleanValue()) { - Message.info("no settings file found, using Ivy 1.4 default..."); - _file = null; - _url = IvySettings.getDefault14SettingsURL(); - } else { - Message.info("no settings file found, using default..."); - _file = null; - _url = IvySettings.getDefaultSettingsURL(); - } - } - } - if (_file != null) { - if (!_file.exists()) { - throw new BuildException("settings file does not exist: "+_file); - } else { - ivy.configure(_file); - } - } else { - ivy.configure(_url); - } - setIvyInstance(ivy); - } catch (Exception ex) { - throw new BuildException("impossible to configure ivy with given "+(_file != null ? "file: "+_file : "url :"+_url)+" :"+ex, ex); - } - } + public void setFile(File file) { + antSettings.setFile(file); + } - private void loadDefaultProperties() { - Property prop = new Property() { - public void execute() throws BuildException { - URL url = IvySettings.getDefaultPropertiesURL(); - // this is copy of loadURL code from ant Property task (not available in 1.5.1) - Properties props = new Properties(); - Message.verbose("Loading " + url); - try { - InputStream is = url.openStream(); - try { - props.load(is); - } finally { - if (is != null) { - is.close(); - } - } - addProperties(props); - } catch (IOException ex) { - throw new BuildException(ex, getLocation()); - } - } - }; - prop.setProject(getProject()); - prop.execute(); - } - - private void configureURLHandler() { - CredentialsStore.INSTANCE.addCredentials(getRealm(), getHost(), getUsername(), getPasswd()); + public void setHost(String host) { + antSettings.setHost(host); + } + + public void setPasswd(String passwd) { + antSettings.setPasswd(passwd); + } + + public void setProject(Project prj) { + super.setProject(prj); + antSettings.setProject(prj); + } + + public void setRealm(String realm) { + antSettings.setRealm(realm); + } + + public void setUrl(String confUrl) throws MalformedURLException { + antSettings.setUrl(confUrl); + } + + public void setUsername(String userName) { + antSettings.setUsername(userName); + } - URLHandlerDispatcher dispatcher = new URLHandlerDispatcher(); - URLHandler httpHandler = URLHandlerRegistry.getHttp(); - dispatcher.setDownloader("http", httpHandler); - dispatcher.setDownloader("https", httpHandler); - URLHandlerRegistry.setDefault(dispatcher); - } } diff --git a/src/java/org/apache/ivy/ant/IvyPublish.java b/src/java/org/apache/ivy/ant/IvyPublish.java index 1e5f6840..39aba234 100644 --- a/src/java/org/apache/ivy/ant/IvyPublish.java +++ b/src/java/org/apache/ivy/ant/IvyPublish.java @@ -219,6 +219,7 @@ public class IvyPublish extends IvyTask { File ivyFile = new File(IvyPatternHelper.substitute(_srcivypattern, _organisation, _module, _pubRevision, "ivy", "ivy", "xml")); if (_publishivy && (!ivyFile.exists() || _forcedeliver)) { IvyDeliver deliver = new IvyDeliver(); + deliver.setSettingsRef(getSettingsRef()); deliver.setProject(getProject()); deliver.setCache(getCache()); deliver.setDeliverpattern(getSrcivypattern()); diff --git a/src/java/org/apache/ivy/ant/IvyTask.java b/src/java/org/apache/ivy/ant/IvyTask.java index 11f78cbc..17c80f80 100644 --- a/src/java/org/apache/ivy/ant/IvyTask.java +++ b/src/java/org/apache/ivy/ant/IvyTask.java @@ -20,8 +20,6 @@ package org.apache.ivy.ant; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.HashMap; -import java.util.Map; import org.apache.ivy.Ivy; import org.apache.ivy.core.IvyContext; @@ -32,6 +30,7 @@ import org.apache.ivy.util.Message; import org.apache.ivy.util.StringUtils; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Reference; /** @@ -42,6 +41,7 @@ import org.apache.tools.ant.Task; public abstract class IvyTask extends Task { public static final String ANT_PROJECT_CONTEXT_KEY = "ant-project"; private Boolean _validate = null; + private Reference _antIvyEngineRef = null; protected boolean doValidate(IvySettings ivy) { if (_validate != null) { @@ -56,28 +56,34 @@ public abstract class IvyTask extends Task { _validate = Boolean.valueOf(validate); } + + public void setSettingsRef(Reference ref) { + _antIvyEngineRef = ref; + } + + public Reference getSettingsRef() { + return _antIvyEngineRef; + } + protected IvySettings getSettings() { return getIvyInstance().getSettings(); } protected Ivy getIvyInstance() { - ensureMessageInitialised(); - Object ref = getProject().getReference("ivy.instances"); - if (ref != null && !(ref instanceof Map)) { - throw new BuildException("ivy problem with ant: ivy.instances reference is not a Map. Please do not sett ivy.instances reference in your ant project. current reference: "+ref+" class="+ref.getClass()+" classloader="+ref.getClass().getClassLoader()); - } - Map instances = (Map) ref; - if (instances == null || !instances.containsKey(Ivy.class)) { - Message.verbose("no ivy instance found: auto configuring ivy"); - IvyConfigure configure = new IvyConfigure(); - configure.setProject(getProject()); - configure.execute(); - instances = (Map) getProject().getReference("ivy.instances"); - if (instances == null || !instances.containsKey(Ivy.class)) { - throw new BuildException("ivy internal problem: impossible to get ivy instance after configure... maybe a classloader problem"); - } - } - return (Ivy)instances.get(Ivy.class); + ensureMessageInitialised(); + Object antIvyEngine; + if (_antIvyEngineRef!=null) { + antIvyEngine = _antIvyEngineRef.getReferencedObject(); + if (! antIvyEngine.getClass().getName().equals(IvyAntSettings.class.getName())) { + throw new BuildException(_antIvyEngineRef.getRefId() + " doesn't reference an ivy:settings" , getLocation()); + } + if (! (antIvyEngine instanceof IvyAntSettings)) { + throw new BuildException(_antIvyEngineRef.getRefId() + " has been defined in a different classloader. Please use the same loader when defining your task, or redeclare your ivy:settings in this classloader" , getLocation()); + } + } else { + antIvyEngine = IvyAntSettings.getDefaultInstance(getProject()); + } + return ((IvyAntSettings)antIvyEngine).getConfiguredIvyInstance(); } /** @@ -89,22 +95,6 @@ public abstract class IvyTask extends Task { if (!Message.isInitialised()) { Message.init(new AntMessageImpl(this)); } - - } - protected void setIvyInstance(Ivy ivy) { - // this reference is not used anymore, what is used is the instances map below - getProject().addReference("ivy.instance", ivy); - - if (ivy != null) { - Message.debug("setting ivy.instance on "+getProject()+": "+ivy+" class="+ivy.getClass().getName()+" classloader="+ivy.getClass().getClassLoader()); - // we keep a map of ivy instances per Ivy class, in case of multiple classloaders - Map instances = (Map) getProject().getReference("ivy.instances"); - if (instances == null) { - instances = new HashMap(); - getProject().addReference("ivy.instances", instances); - } - instances.put(ivy.getClass(), ivy); - } } protected void setResolved(ResolveReport report, boolean keep) { diff --git a/src/java/org/apache/ivy/ant/antlib.xml b/src/java/org/apache/ivy/ant/antlib.xml index 6bd528d3..4fc9c4c1 100644 --- a/src/java/org/apache/ivy/ant/antlib.xml +++ b/src/java/org/apache/ivy/ant/antlib.xml @@ -18,6 +18,7 @@ under the License. --> + diff --git a/src/java/org/apache/ivy/core/settings/IvySettings.java b/src/java/org/apache/ivy/core/settings/IvySettings.java index f7cf2dca..942e98f7 100644 --- a/src/java/org/apache/ivy/core/settings/IvySettings.java +++ b/src/java/org/apache/ivy/core/settings/IvySettings.java @@ -107,7 +107,7 @@ public class IvySettings { private Map _circularDependencyStrategies = new HashMap(); // Map (String name -> CircularDependencyStrategy) private List _triggers = new ArrayList(); // List (Trigger) - private Map _variables = new HashMap(); + private IvyVariableContainer _variableContainer = new IvyVariableContainerImpl(); private String _cacheIvyPattern = DEFAULT_CACHE_IVY_PATTERN; private String _cacheResolvedIvyPattern = DEFAULT_CACHE_RESOLVED_IVY_PATTERN; @@ -140,7 +140,13 @@ public class IvySettings { private VersionMatcher _versionMatcher; private StatusManager _statusManager; + public IvySettings() { + this(new IvyVariableContainerImpl()); + } + + public IvySettings(IvyVariableContainer variableContainer) { + setVariableContainer(variableContainer); setVariable("ivy.default.settings.dir", getDefaultSettingsDir(), true); setDeprecatedVariable("ivy.default.conf.dir", "ivy.default.settings.dir"); @@ -442,13 +448,9 @@ public class IvySettings { setVariable(varName, value, true); } + public void setVariable(String varName, String value, boolean overwrite) { - if (overwrite || !_variables.containsKey(varName)) { - Message.debug("setting '"+varName+"' to '"+value+"'"); - _variables.put(varName, substitute(value)); - } else { - Message.debug("'"+varName+"' already set: discarding '"+value+"'"); - } + _variableContainer.setVariable(varName , value, overwrite); } public void addAllVariables(Map variables) { @@ -481,7 +483,7 @@ public class IvySettings { * @return */ public Map getVariables() { - return _variables; + return _variableContainer.getVariables(); } public Class typeDef(String name, String className) { @@ -929,8 +931,7 @@ public class IvySettings { } public String getVariable(String name) { - String val = (String)_variables.get(name); - return val==null?val:substitute(val); + return _variableContainer.getVariable(name); } public ConflictManager getDefaultConflictManager() { @@ -979,19 +980,6 @@ public class IvySettings { _useRemoteConfig = useRemoteConfig; } - /** - * WARNING: Replace all current ivy variables by the given Map. - * Should be used only when restoring variables. - * - * Thr given Map is not copied, but stored by reference. - * @param variables - */ - public void setVariables(Map variables) { - if (variables == null) { - throw new NullPointerException("variables shouldn't be null"); - } - _variables = variables; - } public boolean logModulesInUse() { String var = getVariable("ivy.log.modules.in.use"); return var == null || Boolean.valueOf(var).booleanValue(); @@ -1082,4 +1070,16 @@ public class IvySettings { return _matchers.keySet(); } + public IvyVariableContainer getVariableContainer() { + return _variableContainer; + } + + /** + * Use a different variable container. + * @param variables + */ + public void setVariableContainer(IvyVariableContainer variables) { + _variableContainer = variables; + } + } diff --git a/src/java/org/apache/ivy/core/settings/IvyVariableContainer.java b/src/java/org/apache/ivy/core/settings/IvyVariableContainer.java new file mode 100644 index 00000000..58ee14d6 --- /dev/null +++ b/src/java/org/apache/ivy/core/settings/IvyVariableContainer.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.ivy.core.settings; + +import java.util.Map; + +/** + * Store and provide access to the ivy variables. + * @author gscokart + */ +public interface IvyVariableContainer extends Cloneable{ + + public abstract void setVariable(String varName, String value, + boolean overwrite); + + public abstract Map getVariables(); + + public abstract String getVariable(String name); + + public Object clone(); +} diff --git a/src/java/org/apache/ivy/core/settings/IvyVariableContainerImpl.java b/src/java/org/apache/ivy/core/settings/IvyVariableContainerImpl.java new file mode 100644 index 00000000..0b53f6de --- /dev/null +++ b/src/java/org/apache/ivy/core/settings/IvyVariableContainerImpl.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.ivy.core.settings; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.ivy.core.IvyPatternHelper; +import org.apache.ivy.util.Message; + +public class IvyVariableContainerImpl implements IvyVariableContainer { + + + private HashMap _variables = new HashMap(); + + /* (non-Javadoc) + * @see org.apache.ivy.core.settings.IvyVariableContainer#setVariable(java.lang.String, java.lang.String, boolean) + */ + public void setVariable(String varName, String value, boolean overwrite) { + if (overwrite || !_variables.containsKey(varName)) { + Message.debug("setting '"+varName+"' to '"+value+"'"); + _variables.put(varName, substitute(value)); + } else { + Message.debug("'"+varName+"' already set: discarding '"+value+"'"); + } + + } + + private String substitute(String value) { + return IvyPatternHelper.substituteVariables(value, getVariables()); + } + + /* (non-Javadoc) + * @see org.apache.ivy.core.settings.IvyVariableContainer#getVariables() + */ + public Map getVariables() { + return _variables; + } + + /* (non-Javadoc) + * @see org.apache.ivy.core.settings.IvyVariableContainer#getVariable(java.lang.String) + */ + public String getVariable(String name) { + String val = (String)_variables.get(name); + return val==null?val:substitute(val); + } + + public Object clone() { + IvyVariableContainerImpl clone; + try { + clone = (IvyVariableContainerImpl) super.clone(); + } catch (CloneNotSupportedException e) { + throw new RuntimeException("unable to clone a " + this.getClass()); + } + clone._variables = (HashMap) _variables.clone(); + return clone; + } +} diff --git a/src/java/org/apache/ivy/core/settings/XmlSettingsParser.java b/src/java/org/apache/ivy/core/settings/XmlSettingsParser.java index 5b6ec93e..6a802b83 100644 --- a/src/java/org/apache/ivy/core/settings/XmlSettingsParser.java +++ b/src/java/org/apache/ivy/core/settings/XmlSettingsParser.java @@ -204,7 +204,7 @@ public class XmlSettingsParser extends DefaultHandler { } } } else if ("include".equals(qName)) { - Map variables = new HashMap(_ivy.getVariables()); + IvyVariableContainer variables = (IvyVariableContainer) _ivy.getVariableContainer().clone(); try { String propFilePath = _ivy.substitute((String)attributes.get("file")); URL settingsURL = null; @@ -231,7 +231,7 @@ public class XmlSettingsParser extends DefaultHandler { } new XmlSettingsParser(_ivy).parse(_configurator, settingsURL); } finally { - _ivy.setVariables(variables); + _ivy.setVariableContainer(variables); } } else if ("settings".equals(qName) || "conf".equals(qName)) { if ("conf".equals(qName)) { diff --git a/test/java/org/apache/ivy/ant/IvyConfigureTest.java b/test/java/org/apache/ivy/ant/IvyConfigureTest.java index a262b906..f320f790 100644 --- a/test/java/org/apache/ivy/ant/IvyConfigureTest.java +++ b/test/java/org/apache/ivy/ant/IvyConfigureTest.java @@ -28,9 +28,11 @@ import org.apache.ivy.plugins.resolver.IBiblioResolver; import org.apache.ivy.plugins.resolver.IvyRepResolver; import org.apache.tools.ant.Project; - +/** + * Test the deprecated IvyConfigureTest and the underlying implementation + * AntIvySettings. When IvyConfigure will be removed, this class should be renamed AntIvySettingsTest + */ public class IvyConfigureTest extends TestCase { - private File _cache; private IvyConfigure _configure; protected void setUp() throws Exception { @@ -41,6 +43,10 @@ public class IvyConfigureTest extends TestCase { _configure.setProject(project); } + private Ivy getIvyInstance() { + return IvyAntSettings.getDefaultInstance(_configure.getProject()).getConfiguredIvyInstance(); + } + public void testDefault() throws Exception { // by default configure look in the current directory for an ivysettings.xml file... // but Ivy itself has one, and we don't want to use it @@ -71,12 +77,13 @@ public class IvyConfigureTest extends TestCase { assertTrue(publicResolver instanceof IvyRepResolver); } - public void testFile() throws Exception { + + public void testFile() throws Exception { _configure.setFile(new File("test/repositories/ivysettings.xml")); _configure.execute(); - Ivy ivy = getIvyInstance(); + Ivy ivy = _configure.getIvyInstance(); assertNotNull(ivy); IvySettings settings = ivy.getSettings(); assertNotNull(settings); @@ -98,7 +105,7 @@ public class IvyConfigureTest extends TestCase { _configure.execute(); - IvySettings settings = getIvyInstance().getSettings(); + IvySettings settings = _configure.getIvyInstance().getSettings(); assertEquals(new File("build/cache"), settings.getDefaultCache()); assertEquals(confUrl, settings.getVariables().get("ivy.settings.url")); @@ -112,7 +119,7 @@ public class IvyConfigureTest extends TestCase { _configure.execute(); - IvySettings settings = getIvyInstance().getSettings(); + IvySettings settings = _configure.getIvyInstance().getSettings(); assertNotNull(settings); assertEquals("myvalue", settings.getVariables().get("myproperty")); @@ -125,14 +132,10 @@ public class IvyConfigureTest extends TestCase { _configure.execute(); - IvySettings settings = getIvyInstance().getSettings(); + IvySettings settings = _configure.getIvyInstance().getSettings(); assertNotNull(settings); assertEquals("lib/test/[artifact]-[revision].[ext]", settings.getVariables().get("ivy.retrieve.pattern")); } - private Ivy getIvyInstance() { - return (Ivy)_configure.getProject().getReference("ivy.instance"); - } - } diff --git a/test/java/org/apache/ivy/ant/IvyTaskTest.java b/test/java/org/apache/ivy/ant/IvyTaskTest.java new file mode 100644 index 00000000..d6398e84 --- /dev/null +++ b/test/java/org/apache/ivy/ant/IvyTaskTest.java @@ -0,0 +1,72 @@ +package org.apache.ivy.ant; + +import java.io.File; +import java.net.MalformedURLException; + +import org.apache.ivy.Ivy; +import org.apache.ivy.core.settings.IvySettings; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.Reference; + +import junit.framework.TestCase; + +public class IvyTaskTest extends TestCase { + + public void testDefaultSettings() throws MalformedURLException { + Project p = new Project(); + p.setBasedir("test/repositories"); + //p.setProperty("ivy.settings.file" , "ivysettings.xml"); + p.setProperty("myproperty", "myvalue"); + IvyTask task = new IvyTask() { + public void doExecute() throws BuildException { + } + }; + task.setProject(p); + + Ivy ivy = task.getIvyInstance(); + assertNotNull(ivy); + IvySettings settings = ivy.getSettings(); + assertNotNull(settings); + + assertEquals(new File("build/cache"), settings.getDefaultCache()); + //The next test doesn't always works on windows (mix C: and c: drive) + assertEquals(new File("test/repositories/ivysettings.xml").getAbsolutePath().toUpperCase(), new File((String)settings.getVariables().get("ivy.settings.file")).getAbsolutePath().toUpperCase()); + assertEquals(new File("test/repositories/ivysettings.xml").toURL().toExternalForm().toUpperCase(), ((String)settings.getVariables().get("ivy.settings.url")).toUpperCase()); + assertEquals(new File("test/repositories").getAbsolutePath().toUpperCase(), ((String)settings.getVariables().get("ivy.settings.dir")).toUpperCase()); + assertEquals("myvalue", settings.getVariables().get("myproperty")); + } + + public void testReferencedSettings() throws MalformedURLException { + Project p = new Project(); + //p.setBasedir("test/repositories"); + //p.setProperty("ivy.settings.file" , "ivysettings.xml"); + p.setProperty("myproperty", "myvalue"); + + IvyAntSettings antSettings = new IvyAntSettings(); + antSettings.setProject(p); + //antSettings.setId("mySettings"); + antSettings.setFile(new File("test/repositories/ivysettings.xml")); + p.addReference("mySettings", antSettings); + + IvyTask task = new IvyTask() { + public void doExecute() throws BuildException { + } + }; + task.setProject(p); + task.setSettingsRef(new Reference(p,"mySettings")); + Ivy ivy = task.getIvyInstance(); + assertNotNull(ivy); + IvySettings settings = ivy.getSettings(); + assertNotNull(settings); + + assertEquals(new File("build/cache"), settings.getDefaultCache()); + assertEquals(new File("test/repositories/ivysettings.xml").getAbsolutePath(), settings.getVariables().get("ivy.settings.file")); + assertEquals(new File("test/repositories/ivysettings.xml").toURL().toExternalForm(), settings.getVariables().get("ivy.settings.url")); + assertEquals(new File("test/repositories").getAbsolutePath(), settings.getVariables().get("ivy.settings.dir")); + assertEquals("myvalue", settings.getVariables().get("myproperty")); + + } + + +}