git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@332492 13f79535-47bb-0310-9956-ffa450edef68master
@@ -1,353 +0,0 @@ | |||
<?xml version="1.0"?> | |||
<project name="getlibraries" basedir="." default="init"> | |||
<!-- use the normal one at ibiblio--> | |||
<mavenrepository id="maven"/> | |||
<!-- configure an HTTP proxy --> | |||
<target name="setproxy" unless="setproxy.disabled" > | |||
<!-- put your proxy settings here --> | |||
<property file="${user.home}/.ant/proxy.properties" /> | |||
<property name="proxy.host" value="" /> | |||
<property name="proxy.port" value="80" /> | |||
<property name="proxy.user" value="" /> | |||
<property name="proxy.pass" value="" /> | |||
<echo level="verbose"> | |||
proxy: ${proxy.host}:${proxy.port} [${proxy.user}/${proxy.pass}] | |||
</echo> | |||
<setproxy proxyhost="${proxy.host}" proxyport="${proxy.port}" | |||
proxyuser="${proxy.user}" proxypassword="${proxy.pass}" /> | |||
</target> | |||
<target name="init" depends="setproxy"> | |||
<property name="lib.dir" value="getlib"/> | |||
<property name="commons.logging.project" value="commons-logging"/> | |||
<property name="version" value="1.0.4"/> | |||
<property name="commons.logging.filename" | |||
value="${commons.logging.project}-${version}.jar"/> | |||
<property name="commons.logging" | |||
value="${commons.logging.project}/jars/${commons.logging.filename}"/> | |||
<property name="maven.repository.dir" | |||
location="${user.home}/.maven/repository" /> | |||
<presetdef name="gl1"> | |||
<libraries destDir="${lib.dir}"> | |||
</libraries> | |||
</presetdef> | |||
<presetdef name="getlib"> | |||
<gl1 destDir="${lib.dir}"> | |||
<library archive="commons-logging" project="commons-logging" | |||
version="${version}"/> | |||
</gl1> | |||
</presetdef> | |||
<macrodef name="assert-downloaded"> | |||
<attribute name="library" default="${commons.logging}"/> | |||
<attribute name="repository" default="${lib.dir}"/> | |||
<sequential> | |||
<fail > | |||
Not found: "@{repository}/@{library}" | |||
<condition> | |||
<not> | |||
<available file="@{repository}/@{library}"/> | |||
</not> | |||
</condition> | |||
</fail> | |||
</sequential> | |||
</macrodef> | |||
<!-- <macrodef name="assert-downloaded"> | |||
<attribute name="library" default="${commons.logging}"/> | |||
<sequential> | |||
<property name="@{library}.path" location="${lib.dir}/@{library}" /> | |||
<available property="@{library}.exists" | |||
file="${@{library}.path}"/> | |||
<fail unless="@{library}.exists"> | |||
Not found: ${@{library}.path} | |||
</fail> | |||
</sequential> | |||
</macrodef> --> | |||
<macrodef name="assert-not-downloaded"> | |||
<attribute name="library" default="${commons.logging}"/> | |||
<attribute name="repository" default="${lib.dir}"/> | |||
<sequential> | |||
<fail> | |||
Unexpectedly found: "@{repository}/@{library}" | |||
<condition> | |||
<available file="@{repository}/@{library}"/> | |||
</condition> | |||
</fail> | |||
</sequential> | |||
</macrodef> | |||
</target> | |||
<target name="cleanup" depends="init"> | |||
<delete dir="${lib.dir}"/> | |||
</target> | |||
<target name="teardown" depends="cleanup"/> | |||
<target name="testEmpty" depends="init"> | |||
<libraries/> | |||
</target> | |||
<target name="testEmpty2" depends="init"> | |||
<libraries destDir="${lib.dir}"> | |||
</libraries> | |||
</target> | |||
<target name="testEmpty3" depends="init"> | |||
<libraries destDir="${lib.dir}"> | |||
<repository/> | |||
</libraries> | |||
</target> | |||
<target name="testNoRepo" depends="init"> | |||
<getlib/> | |||
<assert-downloaded/> | |||
</target> | |||
<target name="testUnknownReference" depends="init"> | |||
<getlib> | |||
<repository refid="unknown"/> | |||
</getlib> | |||
</target> | |||
<target name="testFunctionalInline" depends="init"> | |||
<getlib repositoryref="maven"> | |||
</getlib> | |||
<assert-downloaded/> | |||
</target> | |||
<target name="testMavenInline" depends="init"> | |||
<getlib> | |||
<mavenrepository/> | |||
</getlib> | |||
<assert-downloaded/> | |||
</target> | |||
<target name="testTwoRepositories" depends="init"> | |||
<getlib> | |||
<mavenrepository/> | |||
<mavenrepository/> | |||
</getlib> | |||
</target> | |||
<target name="testMavenInlineBadURL" depends="init"> | |||
<getlib> | |||
<mavenrepository url="http://invalid.example.org"/> | |||
</getlib> | |||
</target> | |||
<target name="testRenaming" depends="init"> | |||
<getlib> | |||
<mavenrepository/> | |||
<library archive="commons-logging" project="commons-logging" version="${version}" | |||
destinationName="renamed.jar" | |||
/> | |||
</getlib> | |||
<assert-downloaded/> | |||
<assert-downloaded library="renamed.jar"/> | |||
</target> | |||
<target name="testOverwrite" depends="init"> | |||
<getlib> | |||
<mavenrepository/> | |||
<assertdownloaded count="1" /> | |||
</getlib> | |||
<getlib> | |||
<mavenrepository/> | |||
<assertdownloaded count="0" /> | |||
</getlib> | |||
</target> | |||
<target name="testIf" depends="init"> | |||
<gl1> | |||
<mavenrepository/> | |||
<library archive="commons-logging" project="commons-logging" version="${version}" enabled="true"/> | |||
</gl1> | |||
<assert-downloaded/> | |||
</target> | |||
<target name="testUnless" depends="init"> | |||
<gl1> | |||
<mavenrepository/> | |||
<library archive="commons-logging" project="commons-logging" version="${version}" | |||
enabled="false"/> | |||
</gl1> | |||
<assert-not-downloaded/> | |||
</target> | |||
<target name="testPathID" depends="init"> | |||
<getlib pathid="commons.logging"> | |||
<mavenrepository/> | |||
</getlib> | |||
<available | |||
property="logging.found" | |||
classname="org.apache.commons.logging.Log" | |||
classpathref="commons.logging" | |||
ignoresystemclasses="true" /> | |||
<fail unless="logging.found"> | |||
Did not find commons logging in the path | |||
</fail> | |||
</target> | |||
<target name="testSecurity" depends="init"> | |||
<getlib> | |||
<mavenrepository checkMD5="true"/> | |||
</getlib> | |||
<assert-downloaded/> | |||
</target> | |||
<target name="testSchedule" depends="init"> | |||
<getlib > | |||
<mavenrepository/> | |||
<schedule days="1" markerFile="${lib.dir}/marker.txt"/> | |||
<assertdownloaded count="1" /> | |||
</getlib> | |||
<getlib > | |||
<mavenrepository/> | |||
<schedule days="1" markerFile="${lib.dir}/marker.txt"/> | |||
<assertdownloaded count="0" /> | |||
</getlib> | |||
</target> | |||
<target name="testForceEnabled" depends="init"> | |||
<getlib> | |||
<mavenrepository/> | |||
<force enabled="true" /> | |||
<assertdownloaded count="1" /> | |||
</getlib> | |||
<getlib> | |||
<mavenrepository/> | |||
<force enabled="true" /> | |||
<assertdownloaded count="1" /> | |||
</getlib> | |||
</target> | |||
<target name="testForceDisabled" depends="init"> | |||
<getlib> | |||
<force enabled="true" /> | |||
<assertdownloaded count="1" /> | |||
</getlib> | |||
<getlib > | |||
<force enabled="false" /> | |||
<assertdownloaded count="0" /> | |||
</getlib> | |||
</target> | |||
<target name="testAbsentFiles" depends="init"> | |||
<getlib > | |||
<absentfiles enabled="true" /> | |||
<assertdownloaded count="1" /> | |||
</getlib> | |||
</target> | |||
<target name="testAbsentFilesTwice" depends="testAbsentFiles"> | |||
<getlib > | |||
<absentfiles enabled="true" /> | |||
<assertdownloaded count="0" /> | |||
</getlib> | |||
</target> | |||
<target name="testNoUpdate" depends="init"> | |||
<getlib > | |||
<mavenrepository/> | |||
<force /> | |||
<noupdate /> | |||
<assertdownloaded count="0" /> | |||
</getlib> | |||
</target> | |||
<target name="testTimestamp" depends="testAbsentFiles"> | |||
<getlib > | |||
<mavenrepository/> | |||
<timestamp /> | |||
<assertdownloaded count="0" /> | |||
</getlib> | |||
</target> | |||
<target name="testAssertDownloadedCountSet" depends="init"> | |||
<getlib> | |||
<mavenrepository/> | |||
<assertdownloaded /> | |||
</getlib> | |||
</target> | |||
<target name="testAssertDownloadedCountTested" depends="init"> | |||
<getlib> | |||
<mavenrepository/> | |||
<assertdownloaded count="152" /> | |||
</getlib> | |||
</target> | |||
<target name="testNoArchiveName" depends="init"> | |||
<gl1 destDir="${lib.dir}" > | |||
<library project="commons-logging" version="${version}"/> | |||
<mavenrepository/> | |||
<assertdownloaded count="1"/> | |||
</gl1> | |||
</target> | |||
<target name="testNoVersion" depends="init"> | |||
<gl1 destDir="${lib.dir}" offline="true"> | |||
<library project="commons-logging" /> | |||
<mavenrepository/> | |||
</gl1> | |||
</target> | |||
<target name="testNoProject" depends="init"> | |||
<gl1 destDir="${lib.dir}" offline="true"> | |||
<library archive="commons-logging" version="${version}"/> | |||
<mavenrepository/> | |||
</gl1> | |||
</target> | |||
<target name="testNewSuffix" depends="init"> | |||
<gl1 destDir="${lib.dir}"> | |||
<library project="commons-logging" version="${version}" | |||
suffix=".jar.asc"/> | |||
<mavenrepository checkMD5="false"/> | |||
<assertdownloaded count="1"/> | |||
</gl1> | |||
</target> | |||
<target name="testNoSuffix" depends="init"> | |||
<gl1 destDir="${lib.dir}"> | |||
<library project="commons-logging" version="snapshot-version" suffix=""/> | |||
<assertdownloaded count="1"/> | |||
<mavenrepository checkMD5="false"/> | |||
</gl1> | |||
</target> | |||
<target name="testEmptyArchive" depends="init"> | |||
<gl1 destDir="${lib.dir}"> | |||
<library project="commons-logging" version="${version}" | |||
archive=""/> | |||
<assertdownloaded count="1"/> | |||
<mavenrepository/> | |||
</gl1> | |||
</target> | |||
<target name="testFlatten" depends="init"> | |||
<getlib flatten="true"> | |||
<mavenrepository/> | |||
<assertdownloaded count="1"/> | |||
</getlib> | |||
<assert-downloaded library="${commons.logging.filename}"/> | |||
</target> | |||
</project> | |||
@@ -1,41 +0,0 @@ | |||
/* | |||
* Copyright 2004 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
import java.util.ListIterator; | |||
/** | |||
* This policy only marks absent(enabled) files. | |||
*/ | |||
public class AbsentFilesPolicy extends BaseLibraryPolicy { | |||
/** | |||
* Tell owner to mark all missing libraries as fetchable | |||
* | |||
* @param owner | |||
* @param libraries | |||
* | |||
* @return true if the connection is to go ahead | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* if needed | |||
*/ | |||
public boolean beforeConnect(Libraries owner, ListIterator libraries) { | |||
owner.markMissingLibrariesForFetch(); | |||
return true; | |||
} | |||
} |
@@ -1,81 +0,0 @@ | |||
/* | |||
* Copyright 2004 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
import org.apache.tools.ant.BuildException; | |||
import java.util.ListIterator; | |||
/** | |||
* This policy is really there for testing the tasks, but you can use | |||
* it for debugging your own logic. | |||
*/ | |||
public class AssertDownloaded extends BaseLibraryPolicy { | |||
/** | |||
* our count of files to fetch; null means undefined | |||
*/ | |||
Integer count; | |||
public static final String ERROR_NO_COUNT = "No count declared"; | |||
public static final String ERROR_DOWNLOAD_FAILURE = "Download count mismatch: expected "; | |||
/** | |||
* set the number of files that must be fetched. | |||
* It is an error if the count does not match. | |||
* @param count | |||
*/ | |||
public void setCount(Integer count) { | |||
this.count = count; | |||
} | |||
/** | |||
* Method called before we connect. Caller can manipulate the list, | |||
* | |||
* @param owner | |||
* @param libraries | |||
* | |||
* @return true if the connection is to go ahead | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* if needed | |||
*/ | |||
public boolean beforeConnect(Libraries owner, ListIterator libraries) { | |||
if (count == null) { | |||
throw new BuildException(ERROR_NO_COUNT); | |||
} | |||
return true; | |||
} | |||
/** | |||
* method called after a successful connection process. | |||
* | |||
* @param owner | |||
* @param libraries | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* | |||
*/ | |||
public void afterFetched(Libraries owner, ListIterator libraries) { | |||
int fetched = owner.calculateDownloadedCount(); | |||
if (fetched != count.intValue()) { | |||
throw new BuildException(ERROR_DOWNLOAD_FAILURE | |||
+ count | |||
+ " but fetched " + fetched); | |||
} | |||
} | |||
} |
@@ -1,74 +0,0 @@ | |||
/* | |||
* Copyright 2004 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
import java.util.ListIterator; | |||
/** | |||
*/ | |||
public abstract class BaseLibraryPolicy implements LibraryPolicy { | |||
/** | |||
* enabled flag | |||
*/ | |||
private boolean enabled = true; | |||
/** | |||
* turn policy on/off | |||
* | |||
* @param enabled | |||
*/ | |||
public void setEnabled(boolean enabled) { | |||
this.enabled = enabled; | |||
} | |||
/** | |||
* are we enabled | |||
* @return true if {@link #enabled} is set | |||
*/ | |||
public boolean getEnabled() { | |||
return enabled; | |||
} | |||
/** | |||
* Method called before we connect. Caller can manipulate the list, | |||
* | |||
* @param owner | |||
* @param libraries | |||
* | |||
* @return true if the connection is to go ahead | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* if needed | |||
*/ | |||
public boolean beforeConnect(Libraries owner, ListIterator libraries) { | |||
return true; | |||
} | |||
/** | |||
* method called after a successful connection process. | |||
* | |||
* @param owner | |||
* @param libraries | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* | |||
*/ | |||
public void afterFetched(Libraries owner, ListIterator libraries) { | |||
} | |||
} |
@@ -1,34 +0,0 @@ | |||
/* | |||
* Copyright 2004 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
/** | |||
* This is for any element that is enabled | |||
*/ | |||
public interface EnabledLibraryElement { | |||
/** | |||
* turn element on/off | |||
* @param enabled | |||
*/ | |||
void setEnabled(boolean enabled); | |||
/** | |||
* get the current enablement flag | |||
* @return | |||
*/ | |||
boolean getEnabled(); | |||
} |
@@ -1,101 +0,0 @@ | |||
/* | |||
* Copyright 2004-2005 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
import java.util.Collection; | |||
import java.util.Iterator; | |||
import java.util.LinkedList; | |||
import java.util.NoSuchElementException; | |||
/** | |||
* List with an enablement iterator. | |||
*/ | |||
public class EnabledLibraryElementList extends LinkedList { | |||
/** | |||
* Constructs an empty list. | |||
*/ | |||
public EnabledLibraryElementList() { | |||
} | |||
/** | |||
* return an iterator that only iterates over enabled stuff | |||
* @return | |||
*/ | |||
public Iterator enabledIterator() { | |||
return new EnabledIterator(this); | |||
} | |||
/** | |||
* iterator through a list that skips everything that is not enabled | |||
*/ | |||
private static class EnabledIterator implements Iterator { | |||
private Iterator underlyingIterator; | |||
private EnabledLibraryElement next; | |||
/** | |||
* constructor | |||
* | |||
* @param collection | |||
*/ | |||
EnabledIterator(Collection collection) { | |||
underlyingIterator = collection.iterator(); | |||
} | |||
/** | |||
* test for having another enabled component | |||
* | |||
* @return | |||
*/ | |||
public boolean hasNext() { | |||
while (next == null && underlyingIterator.hasNext()) { | |||
EnabledLibraryElement candidate = | |||
(EnabledLibraryElement) underlyingIterator.next(); | |||
if (candidate.getEnabled()) { | |||
next = candidate; | |||
} | |||
} | |||
return (next != null); | |||
} | |||
/** | |||
* get the next element | |||
* | |||
* @return | |||
*/ | |||
public Object next() { | |||
if (!hasNext()) { | |||
throw new NoSuchElementException(); | |||
} | |||
EnabledLibraryElement result = next; | |||
next = null; | |||
return result; | |||
} | |||
/** | |||
* removal is not supported | |||
* | |||
* @throws UnsupportedOperationException always | |||
*/ | |||
public void remove() { | |||
throw new UnsupportedOperationException(); | |||
} | |||
} | |||
} |
@@ -1,74 +0,0 @@ | |||
/* | |||
* Copyright 2004-2005 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
import org.apache.tools.ant.BuildException; | |||
import java.util.Iterator; | |||
import java.util.ListIterator; | |||
/** | |||
* This update policy marks all libraries for download. | |||
* After downloading, it will raise an error if any one of the files was not | |||
* retrieved. | |||
*/ | |||
public class ForceUpdatePolicy extends BaseLibraryPolicy { | |||
public static final String ERROR_FORCED_DOWNLOAD_FAILED = "Failed to download file:"; | |||
public String getName() { | |||
return "force"; | |||
} | |||
/** | |||
* | |||
* @param owner | |||
* @param libraries | |||
* | |||
* @return true if the connection is to go ahead | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* if needed | |||
*/ | |||
public boolean beforeConnect(Libraries owner, ListIterator libraries) { | |||
owner.markAllLibrariesForFetch(true); | |||
owner.setUseTimestamp(false); | |||
return true; | |||
} | |||
/** | |||
* method called after a successful connection process. | |||
* | |||
* @param owner | |||
* @param libraries | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* | |||
*/ | |||
public void afterFetched(Libraries owner, ListIterator libraries) { | |||
//here verify that everything came in | |||
Iterator downloaded = owner.enabledLibrariesIterator(); | |||
while (downloaded.hasNext()) { | |||
Library library = (Library) downloaded.next(); | |||
if (library.isToFetch() && !library.wasFetched()) { | |||
throw new BuildException(ERROR_FORCED_DOWNLOAD_FAILED | |||
+ library.getDestFilename()); | |||
} | |||
} | |||
} | |||
} |
@@ -1,304 +0,0 @@ | |||
/* | |||
* Copyright 2004-2005 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.Project; | |||
import org.apache.tools.ant.taskdefs.Get; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.net.MalformedURLException; | |||
import java.net.URL; | |||
/** | |||
* This is a base class for repositories that are built on URLs. Although you | |||
* can share this datatype, it is *not* thread safe; you can only use it in one | |||
* thread at at time | |||
* | |||
* Although it is biased towards HTTP, because the underlying <get> task | |||
* supports different protocols, one is actually able to use other protocols | |||
* such as ftp: or file: to retrieve content. | |||
* | |||
* @since Ant1.7 | |||
*/ | |||
public abstract class HttpRepository extends Repository { | |||
/** | |||
* repositoryURL of repository | |||
*/ | |||
private String url; | |||
/** | |||
* username | |||
*/ | |||
private String username; | |||
/** | |||
* password | |||
*/ | |||
private String password; | |||
/** | |||
* auth realm; can be null | |||
*/ | |||
// private String realm; | |||
/** | |||
* no repository URL | |||
*/ | |||
public static final String ERROR_NO_REPOSITORY_URL = "No repository URL"; | |||
/** | |||
* owner class | |||
*/ | |||
private Libraries owner; | |||
/** | |||
* retry logic | |||
*/ | |||
public static final String ERROR_REENTRANT_USE = "Repository is already in use"; | |||
/** | |||
* get the base URL of the repository | |||
* | |||
* @return | |||
*/ | |||
public String getUrl() { | |||
return url; | |||
} | |||
/** | |||
* Set the base URL of the repository | |||
* | |||
* @param url | |||
*/ | |||
public void setUrl(String url) { | |||
this.url = url; | |||
} | |||
/** | |||
* set the base directory of the repository | |||
* This creates a URL of the <tt>file://</tt> type | |||
* and binds the URL of the repository to it. | |||
* @param basedir | |||
*/ | |||
public void setBaseDir(File basedir) { | |||
try { | |||
URL u = basedir.toURL(); | |||
setUrl(u.toExternalForm()); | |||
} catch (MalformedURLException e) { | |||
throw new BuildException(e); | |||
} | |||
} | |||
public String getUsername() { | |||
return username; | |||
} | |||
/** | |||
* set the username for the remote repository | |||
* | |||
* @param username | |||
*/ | |||
public void setUsername(String username) { | |||
this.username = username; | |||
} | |||
public String getPassword() { | |||
return password; | |||
} | |||
/** | |||
* set the password for the remote repository | |||
* | |||
* @param password | |||
*/ | |||
public void setPassword(String password) { | |||
this.password = password; | |||
} | |||
public Libraries getOwner() { | |||
return owner; | |||
} | |||
/** | |||
* validate yourself | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* if unhappy | |||
*/ | |||
public void validate() { | |||
super.validate(); | |||
checkChildrenAllowed(); | |||
checkAttributesAllowed(); | |||
if (url == null || url.length() == 0) { | |||
throw new BuildException(ERROR_NO_REPOSITORY_URL); | |||
} | |||
} | |||
/** | |||
* override point: connection is called at the start of the retrieval | |||
* process | |||
* | |||
* @param newOwner | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* | |||
*/ | |||
public void connect(Libraries newOwner) { | |||
this.owner = newOwner; | |||
if (!url.endsWith("/")) { | |||
url = url + '/'; | |||
} | |||
try { | |||
//validate the URL | |||
new URL(url); | |||
} catch (MalformedURLException e) { | |||
throw new BuildException(e); | |||
} | |||
} | |||
/** | |||
* override point: connection is called at the start of the retrieval | |||
* process | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* | |||
*/ | |||
public void disconnect() { | |||
} | |||
/** | |||
* Test for a repository being reachable. This method is called after {@link | |||
* #connect(org.apache.tools.ant.taskdefs.repository.Libraries)} | |||
* is called, before any files are to be retrieved. | |||
* <p/> | |||
* If it returns false the repository considers itself offline. Similarly, | |||
* any ioexception is interpreted as being offline. | |||
* <p/> | |||
* The Http implementation does nothing | |||
* @return true if the repository is online. | |||
* | |||
* @throws java.io.IOException | |||
*/ | |||
public boolean checkRepositoryReachable() throws IOException { | |||
return true; | |||
} | |||
/** | |||
* fetch a library from the repository | |||
* | |||
* @param library | |||
* | |||
* @param useTimestamp | |||
* @return true if we retrieved | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* | |||
*/ | |||
public boolean fetch(Library library, boolean useTimestamp) throws IOException { | |||
String path = getRemoteLibraryURL(library); | |||
log("Downloading " + path + " to " + library.getAbsolutePath()); | |||
URL remoteURL = new URL(path); | |||
long start, finish; | |||
start = System.currentTimeMillis(); | |||
boolean success = get(remoteURL, library.getLibraryFile(), useTimestamp, | |||
username, password); | |||
finish = System.currentTimeMillis(); | |||
long diff = finish - start; | |||
logVerbose("downloaded in " + diff / 1000 + " seconds"); | |||
return success; | |||
} | |||
/** | |||
* get the | |||
* @param url | |||
* @param destFile | |||
* @param useTimestamp | |||
* @return | |||
*/ | |||
public boolean get(URL url, File destFile, boolean useTimestamp, String user, String passwd) | |||
throws IOException { | |||
//create the destination dir | |||
destFile.getParentFile().mkdirs(); | |||
Get getTask = new Get(); | |||
getTask.setProject(getProject()); | |||
getTask.setTaskName(owner.getTaskName()); | |||
getTask.setDest(destFile); | |||
getTask.setUsername(user); | |||
getTask.setPassword(passwd); | |||
getTask.setUseTimestamp(useTimestamp); | |||
getTask.setSrc(url); | |||
getTask.setIgnoreErrors(true); | |||
return getTask.doGet(Project.MSG_VERBOSE, null); | |||
} | |||
/** | |||
* log something at the verbose level | |||
* | |||
* @param message text to log | |||
*/ | |||
protected void logVerbose(String message) { | |||
getOwner().log(message, | |||
Project.MSG_VERBOSE); | |||
} | |||
/** | |||
* log at debug level | |||
* @param message | |||
*/ | |||
protected void logDebug(String message) { | |||
getOwner().log(message, | |||
Project.MSG_DEBUG); | |||
} | |||
/** | |||
* Get the path to a remote library. This is the full URL | |||
* | |||
* @param library | |||
* | |||
* @return URL to library | |||
*/ | |||
protected abstract String getRemoteLibraryURL(Library library); | |||
/** | |||
* Returns a string representation of the repository | |||
* Used for scheduled updates. | |||
* @return the base URL | |||
*/ | |||
public String toString() { | |||
return "Repository at " + getUrl(); | |||
} | |||
/** | |||
* this is a string that uniquely describes the repository and can be used | |||
* for equality tests <i>across</i> instances. | |||
* | |||
* @return | |||
*/ | |||
public String getRepositoryURI() { | |||
return "HttpRepository://" + getUrl(); | |||
} | |||
} |
@@ -1,649 +0,0 @@ | |||
/* | |||
* Copyright 2004-2005 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.Project; | |||
import org.apache.tools.ant.Task; | |||
import org.apache.tools.ant.types.Path; | |||
import org.apache.tools.ant.types.Reference; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.ListIterator; | |||
/** | |||
* This task will retrieve one or more libraries from a repository. | |||
* <ol> | |||
* <li>Users must declare a repository, either inline or by reference</li> | |||
* <li>Dependency checking is used (timestamps) unless forceDownload=true</li> | |||
* <li>It is an error if, at the end of the task, a library is missing. | |||
* </ol> | |||
* | |||
* @ant.task | |||
* @since Ant 1.7 | |||
*/ | |||
public final class Libraries extends Task { | |||
/** | |||
* destination | |||
*/ | |||
private File destDir; | |||
/** | |||
* flag to force offline | |||
*/ | |||
private boolean offline = false; | |||
/** | |||
* list of libraries | |||
*/ | |||
private EnabledLibraryElementList libraries = new EnabledLibraryElementList(); | |||
/** | |||
* helper list | |||
*/ | |||
private EnabledLibraryElementList policies = new EnabledLibraryElementList(); | |||
/** | |||
* repository for retrieval | |||
*/ | |||
private Repository repository; | |||
/** | |||
* Optional. A name for a path to define from the dependencies specified. | |||
*/ | |||
private String pathid; | |||
/** | |||
* should we be timestamp aware in downloads? | |||
*/ | |||
private boolean useTimestamp = false; | |||
/** | |||
* flag to indicate if the libraries should be stored | |||
* flat or in maven-style ($(project)/jars/) subdirectories. | |||
*/ | |||
private boolean flatten = false; | |||
public static final String ERROR_ONE_REPOSITORY_ONLY = "Only one repository is allowed"; | |||
//public static final String ERROR_NO_DEST_DIR = "No destination directory"; | |||
public static final String ERROR_NO_REPOSITORY = "No repository defined"; | |||
public static final String ERROR_NO_LIBRARIES = "No libraries declared"; | |||
public static final String ERROR_REPO_PROBE_FAILED = "Repository probe failed with "; | |||
public static final String ERROR_LIBRARY_FETCH_FAILED = "Failed to retrieve "; | |||
public static final String ERROR_INCOMPLETE_RETRIEVAL = "Missing Libraries :"; | |||
public static final String MSG_NO_RETRIEVE = "Connections disabled"; | |||
public static final String MSG_NO_LIBRARIES_TO_FETCH = "No libraries marked for retrieval"; | |||
/** | |||
* where maven stores stuff, and where we save stuff too, unless | |||
* declared otherwise. | |||
*/ | |||
public static final String MAVEN_LOCATION = ".maven/repository"; | |||
/** | |||
* name of the property which can provide an override of the repository dir | |||
* from {@link #MAVEN_LOCATION} | |||
*/ | |||
public static final String REPOSITORY_DIR_PROPERTY = "ant.maven.repository.dir"; | |||
/** | |||
* name of the property which can provide an override of the repository URL | |||
*/ | |||
public static final String REPOSITORY_URL_PROPERTY = "ant.maven.repository.url"; | |||
/** | |||
* Init the task | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* if something goes wrong with the build | |||
*/ | |||
public void init() throws BuildException { | |||
super.init(); | |||
//set our default polocy | |||
add(new AbsentFilesPolicy()); | |||
} | |||
/** | |||
* locate the default directory, by looking for the property | |||
* {@link #REPOSITORY_DIR_PROPERTY}, and if not defined, | |||
* ${user.home}/.maven/repository | |||
* @return file for the default dest dir; may not exist yet. | |||
*/ | |||
private File locateDefaultDestDirectory() { | |||
//set the dest dir up to the default. | |||
File mavenDir | |||
= new File(System.getProperty("user.home"), MAVEN_LOCATION); | |||
String propertyDir = getProject().getProperty(REPOSITORY_DIR_PROPERTY); | |||
if (propertyDir != null) { | |||
mavenDir = getProject().resolveFile(propertyDir); | |||
} | |||
return mavenDir; | |||
} | |||
/** | |||
* add a repository. Only one is (currently) supported | |||
* | |||
* @param repo | |||
*/ | |||
public void add(Repository repo) { | |||
if (repository != null) { | |||
throw new BuildException(ERROR_ONE_REPOSITORY_ONLY); | |||
} | |||
repository = repo; | |||
} | |||
/** | |||
* add a repository. Unless there is explicit support for a subclass | |||
* | |||
* @param repo | |||
*/ | |||
public void addRepository(RepositoryRef repo) { | |||
add(repo); | |||
} | |||
/** | |||
* bind to a repository. | |||
*/ | |||
public void setRepositoryRef(final Reference ref) { | |||
//create a special repository that can only | |||
//resolve references. | |||
Repository r = new RepositoryRef(getProject(), ref); | |||
add(r); | |||
} | |||
/** | |||
* add anything that implements the library policy interface | |||
* @param policy | |||
*/ | |||
public void add(LibraryPolicy policy) { | |||
policies.add(policy); | |||
} | |||
/** | |||
* add a schedule | |||
* @param update | |||
*/ | |||
public void addSchedule(ScheduledUpdatePolicy update) { | |||
add(update); | |||
} | |||
/** | |||
* Declare that the update should be forced: everything | |||
* must be fetched; it will be a failure if any are not | |||
* @param policy | |||
*/ | |||
public void addForce(ForceUpdatePolicy policy) { | |||
add(policy); | |||
} | |||
/** | |||
* Declare that no files should be fetched | |||
* @param policy | |||
*/ | |||
public void addNoupdate(NoUpdatePolicy policy) { | |||
add(policy); | |||
} | |||
/** | |||
* declare that the update should be timestamp driven | |||
* @param policy | |||
*/ | |||
public void addTimestamp(TimestampPolicy policy) { | |||
add(policy); | |||
} | |||
/** | |||
* declare that only absent files are to be fetched | |||
* @param policy | |||
*/ | |||
public void addAbsentfiles(AbsentFilesPolicy policy) { | |||
add(policy); | |||
} | |||
/** | |||
* make a declaration about the number of files to fetch | |||
* | |||
* @param policy | |||
*/ | |||
public void addAssertDownloaded(AssertDownloaded policy) { | |||
add(policy); | |||
} | |||
/** | |||
* add a library for retrieval | |||
* | |||
* @param lib | |||
*/ | |||
public void addLibrary(Library lib) { | |||
libraries.add(lib); | |||
} | |||
/** | |||
* destination directory for all library files | |||
* | |||
* @param destDir | |||
*/ | |||
public void setDestDir(File destDir) { | |||
this.destDir = destDir; | |||
} | |||
/** | |||
* test for being offline | |||
* | |||
* @return true if the offline flag is set | |||
*/ | |||
public boolean isOffline() { | |||
return offline; | |||
} | |||
/** | |||
* declare the system offline. This disables any attempt to retrieve files. | |||
* In this mode, only the presence of files is verified. If forceDownload is | |||
* true, or there is a missing library, then an error will be raised. | |||
* | |||
* @param offline | |||
*/ | |||
public void setOffline(boolean offline) { | |||
this.offline = offline; | |||
} | |||
/** | |||
* get the destination directory | |||
* @return | |||
*/ | |||
public File getDestDir() { | |||
return destDir; | |||
} | |||
/** | |||
* get the list of libraries | |||
* @return | |||
*/ | |||
public List getLibraries() { | |||
return libraries; | |||
} | |||
/** | |||
* get our repository | |||
* @return | |||
*/ | |||
public Repository getRepository() { | |||
return repository; | |||
} | |||
/** | |||
* get the pathID if defined | |||
* @return | |||
*/ | |||
public String getPathid() { | |||
return pathid; | |||
} | |||
/** | |||
* the name of a path reference to be created referring | |||
* to the libraries. | |||
* @param pathid | |||
*/ | |||
public void setPathid(String pathid) { | |||
this.pathid = pathid; | |||
} | |||
/** | |||
* get the current timestamp flag | |||
* @return | |||
*/ | |||
public boolean isUseTimestamp() { | |||
return useTimestamp; | |||
} | |||
/** | |||
* set the timestamp flag. Not for export into XML | |||
* @param useTimestamp | |||
*/ | |||
public void setUseTimestamp(boolean useTimestamp) { | |||
this.useTimestamp = useTimestamp; | |||
} | |||
public boolean isFlatten() { | |||
return flatten; | |||
} | |||
/** | |||
* Flatten flag. | |||
* Store downloaded libraries into a single directory if true, | |||
* store in project/jar subdirectores if false. | |||
* default: false | |||
* @param flatten | |||
*/ | |||
public void setFlatten(boolean flatten) { | |||
this.flatten = flatten; | |||
} | |||
/** | |||
* get the current policy list | |||
* @return | |||
*/ | |||
public List getPolicies() { | |||
return policies; | |||
} | |||
/** | |||
* validate ourselves | |||
* | |||
* @throws BuildException | |||
*/ | |||
public void validate() { | |||
if (destDir == null) { | |||
destDir = locateDefaultDestDirectory(); | |||
} | |||
if (repository == null) { | |||
MavenRepository maven = | |||
(MavenRepository) getProject().createDataType(MavenRepository.TYPE_NAME); | |||
repository = maven; | |||
} | |||
Iterator it = libraries.iterator(); | |||
while (it.hasNext()) { | |||
Library library = (Library) it.next(); | |||
library.validate(); | |||
} | |||
} | |||
/** | |||
* Called by the project to let the task do its work. | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* if something goes wrong with the build | |||
*/ | |||
public void execute() throws BuildException { | |||
validate(); | |||
//execute | |||
doExecute(); | |||
//validate the state | |||
verifyAllLibrariesPresent(); | |||
//create the path | |||
if (pathid != null) { | |||
createPath(); | |||
} | |||
} | |||
/** | |||
* This is the real worker method | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* if something goes wrong with the build | |||
*/ | |||
private void doExecute() throws BuildException { | |||
destDir.mkdirs(); | |||
//get the ultimate repository | |||
Repository repo = repository.resolve(); | |||
//validate it | |||
repo.validate(); | |||
if (libraries.size() == 0) { | |||
//bail out on an empty library | |||
throw new BuildException(ERROR_NO_LIBRARIES); | |||
} | |||
log("Getting libraries from " + repo.toString(), Project.MSG_VERBOSE); | |||
log("Saving libraries to " + destDir.toString(), Project.MSG_VERBOSE); | |||
//map libraries to files | |||
bindAllLibraries(); | |||
//flag to indicate whether the download should go ahead | |||
boolean retrieve = true; | |||
List processedPolicies = new ArrayList(policies.size()); | |||
//iterate through all policies and execute their preload task | |||
Iterator policyIterator = policies.enabledIterator(); | |||
while (retrieve && policyIterator.hasNext()) { | |||
LibraryPolicy libraryPolicy = (LibraryPolicy) policyIterator.next(); | |||
retrieve = libraryPolicy.beforeConnect(this, libraryIterator()); | |||
if (retrieve) { | |||
//add all processed properties to the list, 'cept for anything that | |||
//broke the chain | |||
processedPolicies.add(libraryPolicy); | |||
} else { | |||
log("Policy " + libraryPolicy.getClass().getName() | |||
+ " disabled retrieval", | |||
Project.MSG_VERBOSE); | |||
} | |||
} | |||
if (isOffline()) { | |||
log("No retrieval, task is \"offline\""); | |||
retrieve = false; | |||
} | |||
//see if we need to do a download | |||
if (!retrieve) { | |||
//if not, log it | |||
log(MSG_NO_RETRIEVE); | |||
} else { | |||
int downloads = calculateFetchCount(); | |||
if (downloads > 0) { | |||
//get the files | |||
connectAndRetrieve(repo, useTimestamp); | |||
} else { | |||
//nothing to fetch | |||
log(MSG_NO_LIBRARIES_TO_FETCH, Project.MSG_VERBOSE); | |||
} | |||
} | |||
//now reverse iterate through all processed policies. | |||
for (int i = processedPolicies.size() - 1; i >= 0; i--) { | |||
LibraryPolicy libraryPolicy = (LibraryPolicy) processedPolicies.get(i); | |||
//and call their post-processor | |||
libraryPolicy.afterFetched(this, libraryIterator()); | |||
} | |||
} | |||
/** | |||
* connect to the remote system, retrieve files | |||
* @param repo | |||
* @param useTimestamp | |||
* @return number of failed retrievals. | |||
*/ | |||
private int connectAndRetrieve(Repository repo, boolean useTimestamp) { | |||
//connect to the repository | |||
int failures = 0; | |||
repo.connect(this); | |||
try { | |||
//check for reachability. | |||
//it is up to each repository to decide that. | |||
boolean reachable; | |||
try { | |||
log("Checking repository for reachability", Project.MSG_DEBUG); | |||
reachable = repo.checkRepositoryReachable(); | |||
} catch (IOException e) { | |||
log(ERROR_REPO_PROBE_FAILED + e.getMessage(), | |||
Project.MSG_VERBOSE); | |||
reachable = false; | |||
} | |||
if (!reachable) { | |||
log("repository is not reachable", Project.MSG_INFO); | |||
return 0; | |||
} | |||
//iterate through the libs we have enabled | |||
Iterator it = enabledLibrariesIterator(); | |||
while (it.hasNext()) { | |||
Library library = (Library) it.next(); | |||
//check to see if it is for fetching | |||
if (library.isToFetch()) { | |||
log("Fetching " + library.getNormalFilename(), Project.MSG_VERBOSE); | |||
try { | |||
//fetch it | |||
boolean fetched = repo.fetch(library, useTimestamp); | |||
//record the fact in the library | |||
log("success; marking as fetched", | |||
Project.MSG_DEBUG); | |||
library.assignFetched(fetched); | |||
} catch (IOException e) { | |||
log(ERROR_LIBRARY_FETCH_FAILED + library); | |||
log(e.getMessage()); | |||
//add failures | |||
failures++; | |||
} | |||
} else { | |||
//no fetch | |||
log("Skipping " + library.getNormalFilename(), Project.MSG_VERBOSE); | |||
} | |||
} | |||
} finally { | |||
log("disconnecting", Project.MSG_VERBOSE); | |||
repo.disconnect(); | |||
} | |||
return failures; | |||
} | |||
/** | |||
* bind all libraries to our destination | |||
*/ | |||
public void bindAllLibraries() { | |||
Iterator it = libraries.iterator(); | |||
while (it.hasNext()) { | |||
Library library = (Library) it.next(); | |||
library.bind(destDir, flatten); | |||
} | |||
} | |||
/** | |||
* set/clear the fetch flag on all libraries. | |||
* @param fetch | |||
*/ | |||
public void markAllLibrariesForFetch(boolean fetch) { | |||
Iterator it = libraryIterator(); | |||
while (it.hasNext()) { | |||
Library library = (Library) it.next(); | |||
library.assignToFetch(fetch); | |||
} | |||
} | |||
/** | |||
* set the fetch flag on all libraries that are absent; clear | |||
* it from all those that exist | |||
* | |||
*/ | |||
public void markMissingLibrariesForFetch() { | |||
Iterator it = libraryIterator(); | |||
while (it.hasNext()) { | |||
Library library = (Library) it.next(); | |||
library.assignToFetch(!library.exists()); | |||
} | |||
} | |||
/** | |||
* work out how many libraries to fetch | |||
* @return count of enabled libraries with the to fetch bit set | |||
*/ | |||
public int calculateFetchCount() { | |||
int count = 0; | |||
Iterator it = enabledLibrariesIterator(); | |||
while (it.hasNext()) { | |||
Library library = (Library) it.next(); | |||
if (library.isToFetch()) { | |||
count++; | |||
} | |||
} | |||
return count; | |||
} | |||
/** | |||
* work out how many libraries were fetched | |||
* @return number of libraries that are enabled with the | |||
* {@link Library#wasFetched()} flag true. | |||
*/ | |||
public int calculateDownloadedCount() { | |||
int count = 0; | |||
//here verify that everything came in | |||
Iterator downloaded = enabledLibrariesIterator(); | |||
while (downloaded.hasNext()) { | |||
Library library = (Library) downloaded.next(); | |||
if (library.wasFetched()) { | |||
count++; | |||
} | |||
} | |||
return count; | |||
} | |||
/** | |||
* verify that all libraries are present | |||
*/ | |||
protected void verifyAllLibrariesPresent() { | |||
//iterate through the libs we have | |||
boolean missing = false; | |||
StringBuffer buffer = new StringBuffer(); | |||
Iterator it = enabledLibrariesIterator(); | |||
while (it.hasNext()) { | |||
Library library = (Library) it.next(); | |||
//check for the library existing | |||
if (!library.exists()) { | |||
//and log if one is missing | |||
buffer.append(library.toString() + "; "); | |||
log("Missing: " + library.toString(), | |||
Project.MSG_ERR); | |||
missing = true; | |||
} | |||
} | |||
if (missing) { | |||
throw new BuildException(ERROR_INCOMPLETE_RETRIEVAL + buffer); | |||
} | |||
} | |||
/** | |||
* create a path; requires pathID!=null | |||
*/ | |||
private void createPath() { | |||
Path path = new Path(getProject()); | |||
for (Iterator iterator = enabledLibrariesIterator(); | |||
iterator.hasNext();) { | |||
((Library) iterator.next()).appendToPath(path); | |||
} | |||
getProject().addReference(pathid, path); | |||
} | |||
/** | |||
* get a filtered iterator of the dependencies | |||
* @return a new iterator that ignores disabled libraries | |||
*/ | |||
public Iterator enabledLibrariesIterator() { | |||
return libraries.enabledIterator(); | |||
} | |||
/** | |||
* get a list iterator for the files | |||
* This gives you more power | |||
* @return | |||
*/ | |||
public ListIterator libraryIterator() { | |||
return libraries.listIterator(); | |||
} | |||
} |
@@ -1,424 +0,0 @@ | |||
/* | |||
* Copyright 2004-2005 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.types.Path; | |||
import org.apache.tools.ant.util.FileUtils; | |||
import java.io.File; | |||
/** | |||
* How we represent libraries | |||
* | |||
* @since Ant1.7 | |||
*/ | |||
public class Library implements EnabledLibraryElement { | |||
/** | |||
* enabled flag | |||
*/ | |||
private boolean enabled = true; | |||
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | |||
/** | |||
* turn policy on/off | |||
* | |||
* @param enabled | |||
*/ | |||
public void setEnabled(boolean enabled) { | |||
this.enabled = enabled; | |||
} | |||
/** | |||
* are we enabled | |||
* | |||
* @return true if {@link #enabled} is set | |||
*/ | |||
public boolean getEnabled() { | |||
return enabled; | |||
} | |||
//project "ant" | |||
private String project; | |||
//version "1.5" | |||
private String version; | |||
//archive prefix "ant-optional" | |||
private String archive; | |||
/** | |||
* very optional attribute; name of the destination. Autocalculated if not | |||
* set. | |||
*/ | |||
private String destinationName; | |||
/** | |||
* this is a file reference which is created during binding | |||
*/ | |||
private File libraryFile; | |||
/** | |||
* we fetch every library by default; note the enabled/disabled | |||
* flag has precedence, and this flag is not visible in the XML | |||
*/ | |||
private boolean toFetch = true; | |||
/** | |||
* flag set after fetching | |||
*/ | |||
private boolean fetched = false; | |||
public static final String ERROR_NO_ARCHIVE = "No archive defined"; | |||
public static final String ERROR_NO_PROJECT = "No project defined"; | |||
public static final String ERROR_NO_VERSION = "No version defined"; | |||
public static final String ERROR_FILE_IS_A_DIR = "Library file is a directory:"; | |||
/** | |||
* suffix | |||
*/ | |||
private String suffix = ".jar"; | |||
/** | |||
* the project that provides this library | |||
* @return the project or null | |||
*/ | |||
public String getProject() { | |||
return project; | |||
} | |||
/** | |||
* the project that provides this library | |||
* @param project | |||
*/ | |||
public void setProject(String project) { | |||
this.project = project; | |||
} | |||
/** | |||
* Get the version string of this library | |||
* @return | |||
*/ | |||
public String getVersion() { | |||
return version; | |||
} | |||
/** | |||
* set the version string of this library | |||
* @param version | |||
*/ | |||
public void setVersion(String version) { | |||
this.version = version; | |||
} | |||
/** | |||
* get the base name of this library | |||
* @return | |||
*/ | |||
public String getArchive() { | |||
return archive; | |||
} | |||
/** | |||
* set the base name of this library | |||
* @param archive | |||
*/ | |||
public void setArchive(String archive) { | |||
this.archive = archive; | |||
} | |||
/** | |||
* get the destination name attribute. | |||
* @return | |||
*/ | |||
public String getDestinationName() { | |||
return destinationName; | |||
} | |||
/** | |||
* set the name of the library when downloaded, | |||
* relative to the base directory | |||
* @param destinationName | |||
*/ | |||
public void setDestinationName(String destinationName) { | |||
this.destinationName = destinationName; | |||
} | |||
/** | |||
* get the suffix for this file. | |||
* | |||
* @return | |||
*/ | |||
public String getSuffix() { | |||
return suffix; | |||
} | |||
/** | |||
* set the suffix for this file; default is ".jar" | |||
* @param suffix | |||
*/ | |||
public void setSuffix(String suffix) { | |||
this.suffix = suffix; | |||
} | |||
/** | |||
* get the library file | |||
* (only non-null after binding) | |||
* @return library file or null | |||
*/ | |||
public File getLibraryFile() { | |||
return libraryFile; | |||
} | |||
/** | |||
* set the library file. Hidden from Ant users. | |||
* @param file | |||
*/ | |||
public void assignLibraryFile(File file) { | |||
this.libraryFile = file; | |||
} | |||
/** | |||
* fault if the field is null or empty | |||
* | |||
* @param field | |||
* @param message text for fault | |||
* | |||
* @throws BuildException if the field is not set up | |||
*/ | |||
private void faultIfEmpty(String field, String message) { | |||
if (field == null || field.length() == 0) { | |||
throw new BuildException(message); | |||
} | |||
} | |||
/** | |||
* validate; | |||
* | |||
* @throws BuildException if invalid | |||
*/ | |||
public void validate() { | |||
faultIfEmpty(project, ERROR_NO_PROJECT); | |||
if (archive == null) { | |||
//adopt the name of the project if no archive is specced | |||
archive = project; | |||
} | |||
faultIfEmpty(version, ERROR_NO_VERSION); | |||
if (suffix == null) { | |||
suffix = ""; | |||
} | |||
} | |||
/** | |||
* string is for debug | |||
* @return | |||
*/ | |||
public String toString() { | |||
return "Library " + getNormalFilename() | |||
+ " from project " + project | |||
+ " to " + getDestinationName(); | |||
} | |||
/** | |||
* calculate the destination file of a library; set {@link #libraryFile} | |||
* to the File thereof. | |||
* | |||
* @param baseDir dir that is used as the base for the operations | |||
* | |||
* @param flatten flag to indicate whether the directory path is 'flat' or not. | |||
* @throws BuildException if invalid | |||
*/ | |||
public void bind(File baseDir, boolean flatten) { | |||
validate(); | |||
if (destinationName == null) { | |||
if (flatten) { | |||
destinationName = getNormalFilename(); | |||
} else { | |||
destinationName = getMavenPath('/'); | |||
} | |||
} | |||
libraryFile = FILE_UTILS.resolveFile(baseDir, destinationName); | |||
if (libraryFile.isDirectory()) { | |||
throw new BuildException(ERROR_FILE_IS_A_DIR | |||
+ libraryFile); | |||
} | |||
} | |||
/** | |||
* Test for a library | |||
* only valid after binding | |||
* | |||
* @return | |||
*/ | |||
public boolean exists() { | |||
return libraryFile.exists(); | |||
} | |||
/** | |||
* get the last modified date | |||
* only valid after binding | |||
* @return | |||
*/ | |||
public long getLastModified() { | |||
return libraryFile.lastModified(); | |||
} | |||
/** | |||
* get the filename from the rule of archive+version+'.'+suffix. Clearly | |||
* only valid if all fields are defined. | |||
* | |||
* @return a string representing the expected name of the file at the | |||
* source | |||
*/ | |||
public String getNormalFilename() { | |||
return archive + "-" + version + suffix; | |||
} | |||
/** | |||
* get the filename of the destination; no path. | |||
* | |||
* @return | |||
*/ | |||
public String getDestFilename() { | |||
if (destinationName == null) { | |||
return getNormalFilename(); | |||
} else { | |||
return destinationName; | |||
} | |||
} | |||
/** | |||
* get a maven path (project/filename) | |||
* | |||
* @param separator directory separator | |||
* | |||
* @return | |||
*/ | |||
public String getMavenPath(char separator) { | |||
return project + separator + "jars" + separator + getNormalFilename(); | |||
} | |||
/** | |||
* get the absolute path of this library | |||
* | |||
* @return | |||
*/ | |||
public String getAbsolutePath() { | |||
return libraryFile.getAbsolutePath(); | |||
} | |||
/** | |||
* prefixed to avoid ant picking up on it, this sets | |||
* the fetch/no-fetch flag. | |||
* @param toFetchFlag | |||
*/ | |||
public void assignToFetch(boolean toFetchFlag) { | |||
this.toFetch = toFetchFlag; | |||
} | |||
/** | |||
* get the fetch flag. | |||
* @return | |||
*/ | |||
public boolean isToFetch() { | |||
return toFetch; | |||
} | |||
/** | |||
* get a flag that marks if a file is fetched | |||
* @return | |||
*/ | |||
public boolean wasFetched() { | |||
return fetched; | |||
} | |||
/** | |||
* another not-for-end-users attribute; a flag set to true if the | |||
* library has been fetched. | |||
* @param fetchflag | |||
*/ | |||
public void assignFetched(boolean fetchflag) { | |||
this.fetched = fetchflag; | |||
} | |||
/** | |||
* add our location to a filepath | |||
* @param path | |||
*/ | |||
public void appendToPath(Path path) { | |||
Path.PathElement pathElement = path.createPathElement(); | |||
pathElement.setLocation(getLibraryFile()); | |||
} | |||
/** | |||
* equality test uses archive, destinationName, project, suffix and version | |||
* fields (any of which can be null) | |||
* @param o | |||
* @return | |||
*/ | |||
public boolean equals(Object o) { | |||
if (this == o) { | |||
return true; | |||
} | |||
if (!(o instanceof Library)) { | |||
return false; | |||
} | |||
final Library library = (Library) o; | |||
if (archive != null ? !archive.equals(library.archive) : library.archive != null) { | |||
return false; | |||
} | |||
if (destinationName != null ? !destinationName.equals( | |||
library.destinationName) : library.destinationName != null) { | |||
return false; | |||
} | |||
if (project != null ? !project.equals(library.project) : library.project != null) { | |||
return false; | |||
} | |||
if (suffix != null ? !suffix.equals(library.suffix) : library.suffix != null) { | |||
return false; | |||
} | |||
if (version != null ? !version.equals(library.version) : library.version != null) { | |||
return false; | |||
} | |||
return true; | |||
} | |||
/** | |||
* Hash code uses the name fields as {@link #equals(Object)} | |||
* This sequence | |||
* @return | |||
*/ | |||
public int hashCode() { | |||
int result; | |||
result = (project != null ? project.hashCode() : 0); | |||
result = 29 * result + (version != null ? version.hashCode() : 0); | |||
result = 29 * result + (archive != null ? archive.hashCode() : 0); | |||
result = 29 * result + (destinationName != null ? destinationName.hashCode() : 0); | |||
result = 29 * result + (suffix != null ? suffix.hashCode() : 0); | |||
return result; | |||
} | |||
} |
@@ -1,71 +0,0 @@ | |||
/* | |||
* Copyright 2004-2005 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
import java.util.ListIterator; | |||
/** | |||
* An interface that things can support to change the library behaviour. | |||
* Example uses could be: extra validation (signatures, etc), filename remapping | |||
* | |||
* | |||
* Here is the use | |||
* <ol> | |||
* <li>Policies are executed in order of declaration. | |||
* <li>The {@link #beforeConnect(org.apache.tools.ant.taskdefs.repository.Libraries, | |||
* java.util.ListIterator)} call, | |||
* is called before any connection has been initiated; policies can manipulate | |||
* the library list, set/reset their toFetch list, rename destination files, etc. | |||
* <li>If any policy returns false from the method, the connection does not proceed. | |||
* This is not an error, provided the files are actually present. | |||
* <li>After running through the fetch of all files marked for download, | |||
* every policy implementation will again be called in order of declaration. | |||
* <li>The {@link #afterFetched(org.apache.tools.ant.taskdefs.repository.Libraries, | |||
* java.util.ListIterator)} method | |||
* does not return anything. | |||
* <li>Either method can throw a BuildException to indicate some kind of error. | |||
* </ol> | |||
* | |||
*/ | |||
public interface LibraryPolicy extends EnabledLibraryElement { | |||
/** | |||
* Method called before we connect. Caller can manipulate the list, | |||
* | |||
* | |||
* @param owner | |||
* | |||
* @param libraries | |||
* @return true if the connection is to go ahead | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* if needed | |||
*/ | |||
boolean beforeConnect(Libraries owner, ListIterator libraries); | |||
/** | |||
* method called after a successful connection process. | |||
* @param owner | |||
* @param libraries | |||
* @throws org.apache.tools.ant.BuildException | |||
*/ | |||
void afterFetched(Libraries owner, ListIterator libraries); | |||
} |
@@ -1,177 +0,0 @@ | |||
/* | |||
* Copyright 2004-2005 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
import org.apache.tools.ant.util.FileUtils; | |||
import org.apache.tools.ant.BuildException; | |||
import java.io.File; | |||
import java.io.FileInputStream; | |||
import java.io.IOException; | |||
import java.io.InputStreamReader; | |||
import java.io.Reader; | |||
import java.net.URL; | |||
/** | |||
* A Maven repository knows about maven repository layout rules It also defaults | |||
* to http://www.ibiblio.org/maven/ | |||
* | |||
* @link http://maven.apache.org/reference/user-guide.html#Remote_Repository_Layout | |||
* @link | |||
* @since Ant1.7 | |||
*/ | |||
public class MavenRepository extends HttpRepository { | |||
public static final String MAVEN_URL = "http://www.ibiblio.org/maven/"; | |||
/** | |||
* check the MD5 flag | |||
*/ | |||
public boolean checkMD5; | |||
/** | |||
* this is what we think the MD5 type is | |||
*/ | |||
protected static final String MAVEN_MD5_FILE_TYPE = "US-ASCII"; | |||
public static final String TYPE_NAME = "mavenrepository"; | |||
/** | |||
* bind to the main maven repository | |||
*/ | |||
public MavenRepository() { | |||
} | |||
/** | |||
* set this to check the MD5 signatures. SECURITY IS NOT YET FUNCTIONAL | |||
* @param checkMD5 | |||
*/ | |||
public void setCheckMD5(boolean checkMD5) { | |||
this.checkMD5 = checkMD5; | |||
} | |||
/** | |||
* Validation time is where the final fixup of repositories exist; this | |||
* is the last chance to examine properties to see if there is an override. | |||
* | |||
* @throws BuildException if unhappy | |||
*/ | |||
public void validate() { | |||
if (getUrl() == null) { | |||
//we have no URL yet; so use the maven one | |||
if (getProject() != null) { | |||
String urlProperty = getProject() | |||
.getProperty(Libraries.REPOSITORY_URL_PROPERTY); | |||
if (urlProperty != null) { | |||
setUrl(urlProperty); | |||
} else { | |||
setUrl(MAVEN_URL); | |||
} | |||
} | |||
} | |||
super.validate(); | |||
} | |||
/** | |||
* Get the path to a remote library. This is the full URL | |||
* | |||
* @param library | |||
* | |||
* @return URL to library | |||
*/ | |||
protected String getRemoteLibraryURL(Library library) { | |||
String base = getUrl(); | |||
if (!base.endsWith("/")) { | |||
base = base + '/'; | |||
} | |||
return base + library.getMavenPath('/'); | |||
} | |||
/** | |||
* Returns a string representation of the repository | |||
* | |||
* @return the base URL | |||
*/ | |||
public String toString() { | |||
return "Maven Repository at " + getUrl(); | |||
} | |||
/** | |||
* this is a string that uniquely describes the repository and can be used | |||
* for equality tests <i>across</i> instances. | |||
* | |||
* @return maven identifier | |||
*/ | |||
public String getRepositoryURI() { | |||
return "maven://" + getUrl(); | |||
} | |||
/** | |||
* fetch a library from the repository | |||
* | |||
* @param library | |||
* | |||
* @param useTimestamp | |||
* @return true if we retrieved | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* | |||
*/ | |||
public boolean fetch(Library library, boolean useTimestamp) throws IOException { | |||
boolean fetched = super.fetch(library, useTimestamp); | |||
if (fetched && checkMD5) { | |||
//we got here if there was a fetch. so we now get the MD5 info from the file, | |||
boolean successful = false; | |||
String md5path = getRemoteLibraryURL(library) + ".md5"; | |||
File md5file = File.createTempFile(library.getArchive(), ".md5"); | |||
Reader in = null; | |||
try { | |||
URL md5url = new URL(md5path); | |||
logVerbose("getting md5 file from " + md5path + " to " + md5file.getAbsolutePath()); | |||
get(md5url, md5file, false, getUsername(), getPassword()); | |||
in = new InputStreamReader(new FileInputStream(md5file), MAVEN_MD5_FILE_TYPE); | |||
char md5data[] = new char[32]; | |||
in.read(md5data); | |||
logDebug("md5 data " + md5data); | |||
//TODO: verify this against a <checksum> generated signature. | |||
successful = true; | |||
} catch (IOException e) { | |||
logVerbose("IO failure on MD5 fetch " + e.getMessage()); | |||
throw e; | |||
} finally { | |||
FileUtils.close(in); | |||
if (md5file.exists()) { | |||
md5file.delete(); | |||
} | |||
if (!successful) { | |||
//if security checks failed for any reason, | |||
//delete the library file | |||
//brute force paranoia | |||
library.getLibraryFile().delete(); | |||
} | |||
} | |||
} | |||
return fetched; | |||
} | |||
} |
@@ -1,42 +0,0 @@ | |||
/* | |||
* Copyright 2004 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
import java.util.ListIterator; | |||
/** | |||
* Reset the fetch bit on all libraries | |||
*/ | |||
public class NoUpdatePolicy extends BaseLibraryPolicy { | |||
/** | |||
* Method called before we connect. Caller can manipulate the list, | |||
* | |||
* @param owner | |||
* @param libraries | |||
* | |||
* @return true if the connection is to go ahead | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* if needed | |||
*/ | |||
public boolean beforeConnect(Libraries owner, ListIterator libraries) { | |||
// mark all files as no Fetch | |||
owner.markAllLibrariesForFetch(false); | |||
return true; | |||
} | |||
} |
@@ -1,116 +0,0 @@ | |||
/* | |||
* Copyright 2004-2005 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.types.DataType; | |||
import java.io.IOException; | |||
/** | |||
* This type represents a repository; a place that stores libraries for | |||
* retrieval. To use this type, you must use a non-abstract class, either one | |||
* that ships with Ant, or one you implement and declare yourself. | |||
* <p/> | |||
* The <libraries> task lets you supply a repository by reference | |||
* inline {@link Libraries#add(Repository)} or on the command line {@link | |||
* Libraries#setRepositoryRef(org.apache.tools.ant.types.Reference)} | |||
* | |||
* @since Ant1.7 | |||
*/ | |||
public abstract class Repository extends DataType { | |||
/** | |||
* validate yourself | |||
* | |||
* @throws BuildException if unhappy | |||
*/ | |||
public void validate() { | |||
} | |||
/** | |||
* recursively resolve any references to get the real repository | |||
* | |||
* @return | |||
*/ | |||
public final Repository resolve() { | |||
if (getRefid() == null) { | |||
return this; | |||
} else { | |||
Repository repository = (Repository) getCheckedRef(Repository.class, | |||
"Repository"); | |||
return repository; | |||
} | |||
} | |||
/** | |||
* override point: connection is called at the start of the retrieval | |||
* process | |||
* | |||
* @param owner owner of the libraries | |||
* | |||
* @throws BuildException | |||
*/ | |||
public void connect(Libraries owner) { | |||
} | |||
/** | |||
* override point: connection is called at the start of the retrieval | |||
* process | |||
* | |||
* @throws BuildException | |||
*/ | |||
public void disconnect() { | |||
} | |||
/** | |||
* Test for a repository being reachable. This method is called after {@link | |||
* #connect(Libraries)} is called, before any files are to be retrieved. | |||
* <p/> | |||
* If it returns false the repository considers itself offline. Similarly, | |||
* any ioexception is interpreted as being offline. | |||
* | |||
* @return true if the repository is online. | |||
* | |||
* @throws IOException | |||
*/ | |||
public abstract boolean checkRepositoryReachable() throws IOException; | |||
/** | |||
* fetch a library from the repository | |||
* | |||
* @param library library to fetch | |||
* | |||
* @param useTimestamp flag to indicate the timestamp of the lib should be used | |||
* @return | |||
*/ | |||
public abstract boolean fetch(Library library, boolean useTimestamp) throws IOException; | |||
/** | |||
* this is a string that uniquely describes the repository | |||
* and can be used for equality tests <i>across</i> instances. | |||
* @return | |||
*/ | |||
public abstract String getRepositoryURI(); | |||
} |
@@ -1,89 +0,0 @@ | |||
/* | |||
* Copyright 2004-2005 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.Project; | |||
import org.apache.tools.ant.types.Reference; | |||
import java.io.IOException; | |||
/** | |||
* not a real repository; one to paste a reference into the chain for | |||
* resolution. | |||
* | |||
* @since Ant1.7 | |||
*/ | |||
public final class RepositoryRef extends Repository { | |||
/** this constant name is only funny to COM developers | |||
*/ | |||
public static final String E_NOTIMPL = "Not Implemented"; | |||
/** | |||
* create a repository reference | |||
* | |||
* @param reference | |||
*/ | |||
public RepositoryRef(Project project, Reference reference) { | |||
setRefid(reference); | |||
setProject(project); | |||
} | |||
/** | |||
* empty constructor | |||
*/ | |||
public RepositoryRef() { | |||
} | |||
/** | |||
* Test for a repository being reachable. This method is called after {@link | |||
* #connect(Libraries)} is called, before any files are to be retrieved. | |||
* <p/> | |||
* If it returns false the repository considers itself offline. Similarly, | |||
* any ioexception is interpreted as being offline. | |||
* | |||
* @return true if the repository is online. | |||
* | |||
* @throws java.io.IOException | |||
*/ | |||
public boolean checkRepositoryReachable() throws IOException { | |||
return false; | |||
} | |||
/** | |||
* fetch a library from the repository | |||
* | |||
* @param library | |||
* | |||
* @param useTimestamp | |||
* @return | |||
*/ | |||
public boolean fetch(Library library, boolean useTimestamp) throws IOException { | |||
throw new BuildException(E_NOTIMPL); | |||
} | |||
/** | |||
* this is a string that uniquely describes the repository and can be used | |||
* for equality tests <i>across</i> instances. | |||
* | |||
* @return | |||
*/ | |||
public String getRepositoryURI() { | |||
return "ref://" + getRefid(); | |||
} | |||
} |
@@ -1,244 +0,0 @@ | |||
/* | |||
* Copyright 2004-2005 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.Project; | |||
import org.apache.tools.ant.util.FileUtils; | |||
import java.io.BufferedInputStream; | |||
import java.io.BufferedOutputStream; | |||
import java.io.File; | |||
import java.io.FileInputStream; | |||
import java.io.FileOutputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.OutputStream; | |||
import java.util.Iterator; | |||
import java.util.ListIterator; | |||
import java.util.Properties; | |||
/** | |||
* This {@link org.apache.tools.ant.taskdefs.repository.LibraryPolicy} updates the files only | |||
* when the schedule indicates that it should. | |||
* <p/> | |||
* The default interval is eleven hours; it's prime, it encourages | |||
* regular but not excessive days. | |||
* <p/> | |||
* It requires a marker file which is used to save a list of all files | |||
* that were saved. If anything in the list of files changes then the | |||
* update is triggered again. | |||
*/ | |||
public class ScheduledUpdatePolicy extends BaseLibraryPolicy { | |||
private File markerFile; | |||
private int hours = 17; | |||
private int days = 0; | |||
/** | |||
* if not null, this means that we have a marker file to save | |||
*/ | |||
private Properties markerFileToSave; | |||
public static final String ERROR_NO_MARKER_FILE | |||
= "No marker file"; | |||
public static final String MARKER_MISMATCH | |||
= "No match between last update and current one"; | |||
public static final String INTERVAL_TRIGGERS_UPDATE | |||
= "Interval between updates is long; updating"; | |||
public static final String INTERVAL_SHORT_NO_UPDATE | |||
= "Interval between updates is short; no update"; | |||
public File getMarkerFile() { | |||
return markerFile; | |||
} | |||
/** | |||
* set a file that stores the history of the operation | |||
* @param markerFile | |||
*/ | |||
public void setMarkerFile(File markerFile) { | |||
this.markerFile = markerFile; | |||
} | |||
public int getHours() { | |||
return hours; | |||
} | |||
/** | |||
* set the interval between updates in hours | |||
* @param hours | |||
*/ | |||
public void setHours(int hours) { | |||
this.hours = hours; | |||
} | |||
public int getDays() { | |||
return days; | |||
} | |||
/** | |||
* set the interval between updates in days. | |||
* @param days | |||
*/ | |||
public void setDays(int days) { | |||
this.days = days; | |||
} | |||
/** | |||
* get the refresh interval in milliseconds | |||
* @return | |||
*/ | |||
public long getInterval() { | |||
return ((days * 24) + hours) * 60 * 60000; | |||
} | |||
/** | |||
* Method called before we connect | |||
* | |||
* @param owner | |||
* | |||
* @param libraries | |||
* @return true if the connection is to go ahead | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* if needed | |||
*/ | |||
public boolean beforeConnect(Libraries owner, ListIterator libraries) { | |||
Repository repository = owner.getRepository(); | |||
if (markerFile == null) { | |||
throw new BuildException(ERROR_NO_MARKER_FILE); | |||
} | |||
Properties now = makeProperties(owner.enabledLibrariesIterator(), repository); | |||
try { | |||
if (markerFile.exists()) { | |||
long timestamp = markerFile.lastModified(); | |||
Properties then = loadMarkerFile(); | |||
long currentTime = System.currentTimeMillis(); | |||
long diff = currentTime - timestamp; | |||
if (now.equals(then)) { | |||
if (diff < getInterval()) { | |||
owner.log(INTERVAL_SHORT_NO_UPDATE, | |||
Project.MSG_VERBOSE); | |||
return false; | |||
} else { | |||
owner.log(INTERVAL_TRIGGERS_UPDATE, | |||
Project.MSG_VERBOSE); | |||
return true; | |||
} | |||
} else { | |||
owner.log(MARKER_MISMATCH, | |||
Project.MSG_VERBOSE); | |||
} | |||
} else { | |||
owner.log("Marker file not found", Project.MSG_VERBOSE); | |||
} | |||
markerFileToSave = now; | |||
return true; | |||
} catch (IOException e) { | |||
throw new BuildException( | |||
"Marker file " + markerFile.getAbsolutePath() + " access failed", e); | |||
} | |||
} | |||
/** | |||
* method called after a (nominally successful fetch) | |||
* | |||
* @param owner | |||
* @param libraries | |||
*/ | |||
public void afterFetched(Libraries owner, ListIterator libraries) { | |||
if (markerFileToSave != null) { | |||
//if we get here, we need to save the file | |||
try { | |||
saveMarkerFile(markerFileToSave); | |||
} catch (IOException e) { | |||
throw new BuildException("Failed to save marker file " | |||
+ markerFile, | |||
e); | |||
} | |||
} else { | |||
//touch the file anyway | |||
markerFile.setLastModified(System.currentTimeMillis()); | |||
} | |||
} | |||
/** | |||
* make a properties file from the library list | |||
* @param libraries iterator of type Library. | |||
* @return a new properties file | |||
*/ | |||
protected Properties makeProperties(Iterator libraries, Repository repository) { | |||
Properties props = new Properties(); | |||
int counter = 1; | |||
while (libraries.hasNext()) { | |||
Library library = (Library) libraries.next(); | |||
String name = makeEntry(library); | |||
props.put(Integer.toString(counter), name); | |||
} | |||
props.put("repository", repository.getRepositoryURI()); | |||
return props; | |||
} | |||
/** | |||
* save a property file to disk. | |||
* @param props | |||
* @throws IOException | |||
*/ | |||
protected void saveMarkerFile(Properties props) | |||
throws IOException { | |||
markerFile.getParentFile().mkdirs(); | |||
OutputStream out = new BufferedOutputStream(new FileOutputStream(markerFile)); | |||
try { | |||
props.store(out, null); | |||
} finally { | |||
FileUtils.close(out); | |||
} | |||
} | |||
/** | |||
* Load an input stream | |||
* @return | |||
* @throws IOException | |||
*/ | |||
protected Properties loadMarkerFile() throws IOException { | |||
Properties props = new Properties(); | |||
InputStream in = new BufferedInputStream(new FileInputStream(markerFile)); | |||
try { | |||
props.load(in); | |||
return props; | |||
} finally { | |||
FileUtils.close(in); | |||
} | |||
} | |||
/** | |||
* make an entry for the properties file | |||
* @param lib | |||
* @return | |||
*/ | |||
protected String makeEntry(Library lib) { | |||
return lib.getMavenPath('/') + "//" + lib.getNormalFilename(); | |||
} | |||
} |
@@ -1,45 +0,0 @@ | |||
/* | |||
* Copyright 2004-2005 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs.repository; | |||
import java.util.ListIterator; | |||
/** | |||
* Mark all files for fetching, but timestamp driven | |||
* This will only update changed files. Unlike {@link ForceUpdatePolicy}, | |||
* there is no post-download verification that everything got fetched | |||
*/ | |||
public class TimestampPolicy extends BaseLibraryPolicy { | |||
/** | |||
* Method called before we connect. Caller can manipulate the list, | |||
* | |||
* @param owner | |||
* @param libraries | |||
* | |||
* @return true if the connection is to go ahead | |||
* | |||
* @throws org.apache.tools.ant.BuildException | |||
* if needed | |||
*/ | |||
public boolean beforeConnect(Libraries owner, ListIterator libraries) { | |||
owner.markAllLibrariesForFetch(true); | |||
owner.setUseTimestamp(true); | |||
return true; | |||
} | |||
} |
@@ -1,226 +0,0 @@ | |||
/* | |||
* Copyright 2004-2005 The Apache Software Foundation | |||
* | |||
* 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.apache.tools.ant.taskdefs; | |||
import org.apache.tools.ant.BuildFileTest; | |||
import org.apache.tools.ant.taskdefs.repository.AssertDownloaded; | |||
import org.apache.tools.ant.taskdefs.repository.Libraries; | |||
import org.apache.tools.ant.taskdefs.repository.Library; | |||
/** | |||
* test the test libraries stuff. | |||
* skip all the tests if we are offline | |||
*/ | |||
public class LibrariesTest extends BuildFileTest { | |||
private final static String TASKDEFS_DIR = "src/etc/testcases/taskdefs/"; | |||
public LibrariesTest(String name) { | |||
super(name); | |||
} | |||
public void setUp() { | |||
configureProject(TASKDEFS_DIR + "libraries.xml"); | |||
} | |||
protected boolean offline() { | |||
return "true".equals(System.getProperty("offline")); | |||
} | |||
public void tearDown() { | |||
executeTarget("cleanup"); | |||
} | |||
public void testEmpty() { | |||
expectBuildException("testEmpty", Libraries.ERROR_NO_LIBRARIES); | |||
} | |||
public void testEmpty2() { | |||
expectBuildException("testEmpty2", Libraries.ERROR_NO_LIBRARIES); | |||
} | |||
public void testEmpty3() { | |||
expectBuildException("testEmpty3", Libraries.ERROR_NO_LIBRARIES); | |||
} | |||
public void testNoRepo() { | |||
execIfOnline("testNoRepo"); | |||
} | |||
public void testUnknownReference() { | |||
expectBuildException("testUnknownReference", "Reference unknown not found."); | |||
} | |||
/** | |||
* refs are broken | |||
* */ | |||
public void testFunctionalInline() { | |||
execIfOnline("testFunctionalInline"); | |||
} | |||
public void testMavenInline() { | |||
String targetName = "testMavenInline"; | |||
execIfOnline(targetName); | |||
} | |||
/** | |||
* exec a target, but only if we are online | |||
* @param targetName | |||
*/ | |||
private void execIfOnline(String targetName) { | |||
if (offline()) { | |||
return; | |||
} | |||
executeTarget(targetName); | |||
} | |||
public void testTwoRepositories() { | |||
expectBuildException("testTwoRepositories", | |||
Libraries.ERROR_ONE_REPOSITORY_ONLY); | |||
} | |||
public void testMavenInlineBadURL() { | |||
expectExceptionIfOnline("testMavenInlineBadURL", | |||
"testMavenInlineBadURL", | |||
Libraries.ERROR_INCOMPLETE_RETRIEVAL); | |||
} | |||
/** | |||
* exec a target if we are online; expect an eception | |||
* @param target | |||
* @param cause cause of the fault | |||
* @param message | |||
*/ | |||
private void expectExceptionIfOnline(String target, String cause,String message) { | |||
if (offline()) { | |||
return; | |||
} | |||
expectBuildExceptionContaining(target,cause, | |||
message); | |||
} | |||
public void testRenaming() { | |||
execIfOnline("testRenaming"); | |||
} | |||
public void testOverwrite() { | |||
execIfOnline("testOverwrite"); | |||
} | |||
public void testIf() { | |||
execIfOnline("testIf"); | |||
} | |||
public void testUnless() { | |||
execIfOnline("testUnless"); | |||
} | |||
public void testPathID() { | |||
execIfOnline("testPathID"); | |||
} | |||
public void testSecurity() { | |||
execIfOnline("testSecurity"); | |||
} | |||
public void testSchedule() { | |||
execIfOnline("testSchedule"); | |||
} | |||
public void testForceEnabled() { | |||
execIfOnline("testForceEnabled"); | |||
} | |||
public void testForceDisabled() { | |||
execIfOnline("testForceDisabled"); | |||
} | |||
public void testAbsentFiles() { | |||
execIfOnline("testAbsentFiles"); | |||
} | |||
public void testAbsentFilesTwice() { | |||
execIfOnline("testAbsentFilesTwice"); | |||
} | |||
public void testNoUpdate() { | |||
expectExceptionIfOnline("testNoUpdate", | |||
"update disabled; dest file missing", | |||
Libraries.ERROR_INCOMPLETE_RETRIEVAL); | |||
} | |||
public void testTimestamp() { | |||
execIfOnline("testTimestamp"); | |||
} | |||
public void testAssertDownloadedCountSet() { | |||
expectExceptionIfOnline("testAssertDownloadedCountSet", | |||
"No count in assertdownloaded", | |||
AssertDownloaded.ERROR_NO_COUNT); | |||
} | |||
public void testAssertDownloadedCountTested() { | |||
expectExceptionIfOnline("testAssertDownloadedCountTested", | |||
"Wrong count in assertdownloaded", | |||
AssertDownloaded.ERROR_DOWNLOAD_FAILURE); | |||
} | |||
public void testNoVersion() { | |||
expectBuildException("testNoVersion", | |||
Library.ERROR_NO_PROJECT); | |||
} | |||
public void testNoProject() { | |||
expectBuildException("testNoProject", | |||
Library.ERROR_NO_PROJECT); | |||
} | |||
public void testNoArchiveName() { | |||
execIfOnline("testNoArchiveName"); | |||
} | |||
public void testEmptyArchive() { | |||
expectBuildException("testEmptyArchive", | |||
Library.ERROR_NO_ARCHIVE); | |||
} | |||
public void testNoSuffix() { | |||
execIfOnline("testNoSuffix"); | |||
} | |||
public void testFlatten() { | |||
execIfOnline("testFlatten"); | |||
} | |||
/* | |||
public void testMavenNaming() { | |||
Library lib=new Library(); | |||
lib.setProject("unknown"); | |||
lib.setArchive("test"); | |||
lib.setVersion("3.4"); | |||
assertEquals(".jar",lib.getSuffix()); | |||
assertNull("lib.getClassifier()!=null", lib.getClassifier()); | |||
String shortname=Maven2Layout.createFilename(lib); | |||
assertEquals("test-3.4.jar",shortname); | |||
//add a classifierand test that works | |||
lib.setClassifier("src"); | |||
assertNotNull("lib.getClassifier()==null", lib.getClassifier()); | |||
shortname = Maven2Layout.createFilename(lib); | |||
assertEquals("test-3.4-src.jar", shortname); | |||
} | |||
*/ | |||
} |