Author: xavier
Date: Wed Nov 28 15:05:25 2007
New Revision: 599186
URL: http://svn.apache.org/viewvc?rev=599186&view=rev
Log:
NEW: support atomic publish operation (IVY-492) (with contribution from Geoff
Reedy)
Added:
incubator/ivy/core/trunk/test/java/org/apache/ivy/core/publish/
incubator/ivy/core/trunk/test/java/org/apache/ivy/core/publish/PublishEngineTest.java
(with props)
Modified:
incubator/ivy/core/trunk/CHANGES.txt
incubator/ivy/core/trunk/src/java/org/apache/ivy/core/publish/PublishEngine.java
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/repository/file/FileRepository.java
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/AbstractResourceResolver.java
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/ChainResolver.java
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/DependencyResolver.java
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/DualResolver.java
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/FileSystemResolver.java
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/RepositoryResolver.java
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/resolver/FileSystemResolverTest.java
Modified: incubator/ivy/core/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/CHANGES.txt?rev=599186&r1=599185&r2=599186&view=diff
==============================================================================
--- incubator/ivy/core/trunk/CHANGES.txt (original)
+++ incubator/ivy/core/trunk/CHANGES.txt Wed Nov 28 15:05:25 2007
@@ -43,11 +43,12 @@
Emmanuel Pellereau
Roshan Punnoose
Damon Rand
+ Geoff Reedy
Christian Riege
- Jean-Baptiste Quenot
Andreas Sahlbach
John Shields
Johan Stuyts
+ Jean-Baptiste Quenot
Tjeerd Verhagen
John Williams
Jaroslaw Wypychowski
@@ -82,6 +83,7 @@
- IMPROVEMENT: Make the root attribute in the ivyrep resolver mandatory
(IVY-625)
- IMPROVEMENT: New text representation for main module metadata concepts
(IVY-649)
+- NEW: support atomic publish operation (IVY-492) (with contribution from
Geoff Reedy)
- NEW: latest compatible conflict manager (IVY-648)
- NEW: Add a task/code to create M2 POM files from Ivy configurations (IVY-416)
- NEW: [Build] Publish the ivy sources (IVY-646) (thanks to Nicolas Lalevée)
Modified:
incubator/ivy/core/trunk/src/java/org/apache/ivy/core/publish/PublishEngine.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/core/publish/PublishEngine.java?rev=599186&r1=599185&r2=599186&view=diff
==============================================================================
---
incubator/ivy/core/trunk/src/java/org/apache/ivy/core/publish/PublishEngine.java
(original)
+++
incubator/ivy/core/trunk/src/java/org/apache/ivy/core/publish/PublishEngine.java
Wed Nov 28 15:05:25 2007
@@ -176,37 +176,48 @@
extraArtifacts[i].getExtraAttributes()));
}
}
- // for each declared published artifact in this descriptor, do:
- for (Iterator iter = artifactsSet.iterator(); iter.hasNext();) {
- Artifact artifact = (Artifact) iter.next();
- // 1) copy the artifact using src patterns and resolver
- boolean published = false;
- for (Iterator iterator = srcArtifactPattern.iterator();
iterator.hasNext()
- && !published;) {
- String pattern = (String) iterator.next();
- published = publish(
- artifact, settings.substitute(pattern), resolver,
options.isOverwrite());
- }
- if (!published) {
- Message.info("missing artifact " + artifact + ":");
- for (Iterator iterator = srcArtifactPattern.iterator();
iterator.hasNext();) {
+ boolean successfullyPublished = false;
+ try {
+ resolver.beginPublishTransaction(md.getModuleRevisionId(),
options.isOverwrite());
+ // for each declared published artifact in this descriptor, do:
+ for (Iterator iter = artifactsSet.iterator(); iter.hasNext();) {
+ Artifact artifact = (Artifact) iter.next();
+ // 1) copy the artifact using src patterns and resolver
+ boolean published = false;
+ for (Iterator iterator = srcArtifactPattern.iterator();
iterator.hasNext()
+ && !published;) {
String pattern = (String) iterator.next();
- Message.info("\t" + new
File(IvyPatternHelper.substitute(pattern, artifact))
- + " file does not exist");
+ published = publish(
+ artifact, settings.substitute(pattern), resolver,
options.isOverwrite());
+ }
+ if (!published) {
+ Message.info("missing artifact " + artifact + ":");
+ for (Iterator iterator = srcArtifactPattern.iterator();
iterator.hasNext();) {
+ String pattern = (String) iterator.next();
+ Message.info("\t"
+ + new
File(IvyPatternHelper.substitute(pattern, artifact))
+ + " file does not exist");
+ }
+ missing.add(artifact);
+ }
+ }
+ if (options.getSrcIvyPattern() != null) {
+ Artifact artifact = MDArtifact.newIvyArtifact(md);
+ if (!publish(
+ artifact, options.getSrcIvyPattern(), resolver,
options.isOverwrite())) {
+ Message.info("missing ivy file for "
+ + md.getModuleRevisionId()
+ + ": "
+ + new
File(IvyPatternHelper.substitute(options.getSrcIvyPattern(),
+ artifact)) + " file does not exist");
+ missing.add(artifact);
}
- missing.add(artifact);
}
- }
- if (options.getSrcIvyPattern() != null) {
- Artifact artifact = MDArtifact.newIvyArtifact(md);
- if (!publish(artifact, options.getSrcIvyPattern(), resolver,
options.isOverwrite())) {
- Message.info("missing ivy file for "
- + md.getModuleRevisionId()
- + ": "
- + new File(IvyPatternHelper
- .substitute(options.getSrcIvyPattern(),
artifact))
- + " file does not exist");
- missing.add(artifact);
+ resolver.commitPublishTransaction();
+ successfullyPublished = true;
+ } finally {
+ if (!successfullyPublished) {
+ resolver.abortPublishTransaction();
}
}
return missing;
Modified:
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/repository/file/FileRepository.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/repository/file/FileRepository.java?rev=599186&r1=599185&r2=599186&view=diff
==============================================================================
---
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/repository/file/FileRepository.java
(original)
+++
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/repository/file/FileRepository.java
Wed Nov 28 15:05:25 2007
@@ -35,6 +35,8 @@
private boolean local = true;
+ private File transactionDirectory;
+
public FileRepository() {
baseDir = null;
}
@@ -55,6 +57,14 @@
public void put(File source, String destination, boolean overwrite) throws
IOException {
fireTransferInitiated(getResource(destination),
TransferEvent.REQUEST_PUT);
copy(source, getFile(destination), overwrite);
+ }
+
+ public void move(File src, File dest) {
+ src.renameTo(dest);
+ }
+
+ public void delete(File f) {
+ FileUtil.forceDelete(f);
}
private void copy(File src, File destination, boolean overwrite) throws
IOException {
Modified:
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java?rev=599186&r1=599185&r2=599186&view=diff
==============================================================================
---
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java
(original)
+++
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java
Wed Nov 28 15:05:25 2007
@@ -17,6 +17,7 @@
*/
package org.apache.ivy.plugins.resolver;
+import java.io.IOException;
import java.util.Map;
import org.apache.ivy.core.IvyContext;
@@ -51,7 +52,7 @@
/**
* True if parsed ivy files should be validated against xsd, false if they
should not, null if
- * default behaviour should be used
+ * default behaviur should be used
*/
private Boolean validate = null;
@@ -309,5 +310,19 @@
}
return matcher.getMatcher(changingPattern);
}
+
+ public void abortPublishTransaction() throws IOException {
+ /* Default implementation is a no-op */
+ }
+
+ public void commitPublishTransaction() throws IOException {
+ /* Default implementation is a no-op */
+ }
+
+ public void beginPublishTransaction(
+ ModuleRevisionId module, boolean overwrite) throws IOException {
+ /* Default implementation is a no-op */
+ }
+
}
Modified:
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/AbstractResourceResolver.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/AbstractResourceResolver.java?rev=599186&r1=599185&r2=599186&view=diff
==============================================================================
---
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/AbstractResourceResolver.java
(original)
+++
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/AbstractResourceResolver.java
Wed Nov 28 15:05:25 2007
@@ -126,6 +126,10 @@
for (ListIterator iter = sorted.listIterator(sorted.size());
iter.hasPrevious();) {
ResolvedResource rres = (ResolvedResource) iter.previous();
+ if (filterNames(new
ArrayList(Collections.singleton(rres.getRevision()))).isEmpty()) {
+ Message.debug("\t" + name + ": filtered by name: " + rres);
+ continue;
+ }
if ((date != null && rres.getLastModified() > date.getTime())) {
Message.verbose("\t" + name + ": too young: " + rres);
rejected.add(rres.getRevision() + " (" +
rres.getLastModified() + ")");
@@ -209,7 +213,7 @@
tokenValues.put(IvyPatternHelper.TYPE_KEY, "ivy");
tokenValues.put(IvyPatternHelper.EXT_KEY, "xml");
findTokenValues(names, getIvyPatterns(), tokenValues, token);
- getSettings().filterIgnore(names);
+ filterNames(names);
return names;
}
@@ -221,6 +225,21 @@
tokenValues.put(IvyPatternHelper.TYPE_KEY, "jar");
tokenValues.put(IvyPatternHelper.EXT_KEY, "jar");
findTokenValues(names, getArtifactPatterns(), tokenValues, token);
+ filterNames(names);
+ return names;
+ }
+
+ /**
+ * Filters names before returning them in the findXXXNames or
findTokenValues method.
+ * <p>
+ * Remember to call the super implementation when overriding this method.
+ * </p>
+ *
+ * @param names
+ * the list to filter.
+ * @return the filtered list
+ */
+ protected Collection filterNames(Collection names) {
getSettings().filterIgnore(names);
return names;
}
Modified:
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/ChainResolver.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/ChainResolver.java?rev=599186&r1=599185&r2=599186&view=diff
==============================================================================
---
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/ChainResolver.java
(original)
+++
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/ChainResolver.java
Wed Nov 28 15:05:25 2007
@@ -28,6 +28,7 @@
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.ArtifactDownloadReport;
import org.apache.ivy.core.report.DownloadReport;
import org.apache.ivy.core.report.DownloadStatus;
@@ -229,10 +230,28 @@
}
public void publish(Artifact artifact, File src, boolean overwrite) throws
IOException {
+
+ getFirstResolver().publish(artifact, src, overwrite);
+ }
+
+ public void abortPublishTransaction() throws IOException {
+ getFirstResolver().abortPublishTransaction();
+ }
+
+ public void beginPublishTransaction(
+ ModuleRevisionId module, boolean overwrite) throws IOException {
+ getFirstResolver().beginPublishTransaction(module, overwrite);
+ }
+
+ public void commitPublishTransaction() throws IOException {
+ getFirstResolver().commitPublishTransaction();
+ }
+
+ private DependencyResolver getFirstResolver() {
if (chain.isEmpty()) {
throw new IllegalStateException("invalid chain resolver with no
sub resolver");
}
- ((DependencyResolver) chain.get(0)).publish(artifact, src, overwrite);
+ return ((DependencyResolver) chain.get(0));
}
public boolean isReturnFirst() {
Modified:
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/DependencyResolver.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/DependencyResolver.java?rev=599186&r1=599185&r2=599186&view=diff
==============================================================================
---
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/DependencyResolver.java
(original)
+++
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/DependencyResolver.java
Wed Nov 28 15:05:25 2007
@@ -24,6 +24,7 @@
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.DownloadReport;
import org.apache.ivy.core.resolve.DownloadOptions;
import org.apache.ivy.core.resolve.ResolveData;
@@ -62,6 +63,10 @@
boolean exists(Artifact artifact);
void publish(Artifact artifact, File src, boolean overwrite) throws
IOException;
+
+ void beginPublishTransaction(ModuleRevisionId module, boolean overwrite)
throws IOException;
+ void abortPublishTransaction() throws IOException;
+ void commitPublishTransaction() throws IOException;
/**
* Reports last resolve failure as Messages
Modified:
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/DualResolver.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/DualResolver.java?rev=599186&r1=599185&r2=599186&view=diff
==============================================================================
---
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/DualResolver.java
(original)
+++
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/DualResolver.java
Wed Nov 28 15:05:25 2007
@@ -23,6 +23,7 @@
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.DownloadReport;
import org.apache.ivy.core.resolve.DownloadOptions;
import org.apache.ivy.core.resolve.ResolveData;
@@ -116,6 +117,24 @@
} else {
artifactResolver.publish(artifact, src, overwrite);
}
+ }
+
+ public void abortPublishTransaction() throws IOException {
+ ivyResolver.abortPublishTransaction();
+ artifactResolver.abortPublishTransaction();
+ }
+
+
+ public void beginPublishTransaction(
+ ModuleRevisionId module, boolean overwrite) throws IOException {
+ ivyResolver.beginPublishTransaction(module, overwrite);
+ artifactResolver.beginPublishTransaction(module, overwrite);
+ }
+
+
+ public void commitPublishTransaction() throws IOException {
+ ivyResolver.commitPublishTransaction();
+ artifactResolver.commitPublishTransaction();
}
public void dumpSettings() {
Modified:
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/FileSystemResolver.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/FileSystemResolver.java?rev=599186&r1=599185&r2=599186&view=diff
==============================================================================
---
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/FileSystemResolver.java
(original)
+++
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/FileSystemResolver.java
Wed Nov 28 15:05:25 2007
@@ -17,11 +17,37 @@
*/
package org.apache.ivy.plugins.resolver;
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.ivy.core.IvyPatternHelper;
+import org.apache.ivy.core.module.descriptor.Artifact;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.plugins.repository.file.FileRepository;
+import org.apache.ivy.util.Message;
/**
*/
public class FileSystemResolver extends RepositoryResolver {
+
+ private static final String TRANSACTION_DESTINATION_SUFFIX = ".part";
+ private static final Pattern TRANSACTION_PATTERN =
+ Pattern.compile("(.*\\[revision\\])[/\\\\][^/\\\\]+");
+
+ private String transactional = "auto"; // one of 'auto', 'true' or 'false'
+
+ private Boolean supportTransaction;
+ private String baseTransactionPattern;
+
+ private boolean overwriteTransaction = false;
+ private File transactionTempDir;
+ private File transactionDestDir;
+
public FileSystemResolver() {
setRepository(new FileRepository());
}
@@ -40,6 +66,148 @@
private FileRepository getFileRepository() {
return (FileRepository) getRepository();
+ }
+
+
+ protected String getDestination(String pattern, Artifact artifact,
ModuleRevisionId mrid) {
+ if (supportTransaction() && !overwriteTransaction) {
+ return IvyPatternHelper.substitute(
+ pattern,
+ ModuleRevisionId.newInstance(
+ mrid, mrid.getRevision() +
TRANSACTION_DESTINATION_SUFFIX),
+ artifact);
+ } else {
+ return super.getDestination(pattern, artifact, mrid);
+ }
+ }
+
+ public void abortPublishTransaction() throws IOException {
+ if (supportTransaction() && !overwriteTransaction) {
+ if (transactionTempDir == null) {
+ throw new IllegalStateException("no current transaction!");
+ }
+ getFileRepository().delete(transactionTempDir);
+ Message.info("\tpublish aborted: deleted " + transactionTempDir);
+ closeTransaction();
+ }
+ }
+
+ public void commitPublishTransaction() throws IOException {
+ if (supportTransaction() && !overwriteTransaction) {
+ if (transactionTempDir == null) {
+ throw new IllegalStateException("no current transaction!");
+ }
+ Message.info("\tpublish commited: moved " + transactionTempDir
+ + " \n\t\tto " + transactionDestDir);
+ getFileRepository().move(transactionTempDir, transactionDestDir);
+ }
+ }
+
+ public void beginPublishTransaction(
+ ModuleRevisionId module, boolean overwrite) throws IOException {
+ if (supportTransaction()) {
+ if (transactionTempDir != null) {
+ throw new IllegalStateException("a transaction is only started
and not closed!");
+ }
+ overwriteTransaction = overwrite;
+ if (overwriteTransaction) {
+ unsupportedTransaction("overwrite transaction not supported
yet");
+ } else {
+ initTransaction(module);
+ }
+ }
+ }
+
+ protected Collection filterNames(Collection values) {
+ if (supportTransaction()) {
+ values = super.filterNames(values);
+ for (Iterator iterator = values.iterator(); iterator.hasNext();) {
+ String v = (String) iterator.next();
+ if (v.endsWith(TRANSACTION_DESTINATION_SUFFIX)) {
+ iterator.remove();
+ }
+ }
+ return values;
+ } else {
+ return super.filterNames(values);
+ }
+ }
+
+ public boolean supportTransaction() {
+ if ("false".equals(transactional)) {
+ return false;
+ }
+ checkSupportTransaction();
+ return supportTransaction.booleanValue();
+ }
+
+ private void closeTransaction() {
+ transactionTempDir = null;
+ transactionDestDir = null;
+ }
+
+ private void checkSupportTransaction() {
+ if (supportTransaction == null) {
+ List ivyPatterns = getIvyPatterns();
+ List artifactPatterns = getArtifactPatterns();
+
+ if (ivyPatterns.size() > 0) {
+ String pattern = (String) ivyPatterns.get(0);
+ Matcher m = TRANSACTION_PATTERN.matcher(pattern);
+ if (!m.matches()) {
+ unsupportedTransaction("ivy pattern does not use revision
as last directory");
+ return;
+ } else {
+ baseTransactionPattern = m.group(1);
+ }
+ }
+ if (artifactPatterns.size() > 0) {
+ String pattern = (String) artifactPatterns.get(0);
+ Matcher m = TRANSACTION_PATTERN.matcher(pattern);
+ if (!m.matches()) {
+ unsupportedTransaction("ivy pattern does not use revision
as last directory");
+ return;
+ } else if (baseTransactionPattern != null) {
+ if (!baseTransactionPattern.equals(m.group(1))) {
+ unsupportedTransaction("ivy pattern and artifact
pattern "
+ + "do not use the same directory for revision");
+ return;
+ }
+ } else {
+ baseTransactionPattern = m.group(1);
+ }
+ }
+ supportTransaction = Boolean.TRUE;
+ }
+ }
+
+ private void unsupportedTransaction(String msg) {
+ String fullMsg = getName() + " do not support transaction. " + msg;
+ if ("true".equals(transactional)) {
+ throw new IllegalStateException(fullMsg
+ + ". Set transactional attribute to 'auto' or 'false' or fix
the problem.");
+ } else {
+ Message.verbose(fullMsg);
+ supportTransaction = Boolean.FALSE;
+ }
+ }
+
+ private void initTransaction(ModuleRevisionId module) {
+ transactionTempDir = new File(IvyPatternHelper.substitute(
+ baseTransactionPattern,
+ ModuleRevisionId.newInstance(
+ module, module.getRevision() +
TRANSACTION_DESTINATION_SUFFIX)));
+ transactionDestDir = new File(IvyPatternHelper.substitute(
+ baseTransactionPattern,
+ module));
+ }
+
+ public String getTransactional() {
+ return transactional;
+ }
+
+ public void setTransactional(String transactional) {
+ this.transactional = transactional;
}
}
Modified:
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/RepositoryResolver.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/RepositoryResolver.java?rev=599186&r1=599185&r2=599186&view=diff
==============================================================================
---
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/RepositoryResolver.java
(original)
+++
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/RepositoryResolver.java
Wed Nov 28 15:05:25 2007
@@ -20,6 +20,7 @@
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
@@ -161,12 +162,16 @@
mrid = convertM2IdForResourceSearch(mrid);
}
- String dest = IvyPatternHelper.substitute(destPattern, mrid, artifact);
+ String dest = getDestination(destPattern, artifact, mrid);
put(artifact, src, dest, overwrite);
Message.info("\tpublished " + artifact.getName() + " to " +
hidePassword(dest));
}
+ protected String getDestination(String pattern, Artifact artifact,
ModuleRevisionId mrid) {
+ return IvyPatternHelper.substitute(pattern, mrid, artifact);
+ }
+
private void put(Artifact artifact, File src, String dest, boolean
overwrite)
throws IOException {
repository.put(artifact, src, dest, overwrite);
@@ -211,11 +216,11 @@
String[] values = ResolverHelper.listTokenValues(repository,
partiallyResolvedPattern,
token);
if (values != null) {
- names.addAll(Arrays.asList(values));
+ names.addAll(filterNames(new
ArrayList(Arrays.asList(values))));
}
}
}
-
+
public String getTypeName() {
return "repository";
}
@@ -242,4 +247,5 @@
public void setAlwaysCheckExactRevision(boolean alwaysCheckExactRevision) {
this.alwaysCheckExactRevision =
Boolean.valueOf(alwaysCheckExactRevision);
}
+
}
Added:
incubator/ivy/core/trunk/test/java/org/apache/ivy/core/publish/PublishEngineTest.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/test/java/org/apache/ivy/core/publish/PublishEngineTest.java?rev=599186&view=auto
==============================================================================
---
incubator/ivy/core/trunk/test/java/org/apache/ivy/core/publish/PublishEngineTest.java
(added)
+++
incubator/ivy/core/trunk/test/java/org/apache/ivy/core/publish/PublishEngineTest.java
Wed Nov 28 15:05:25 2007
@@ -0,0 +1,143 @@
+/*
+ * 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.publish;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.ParseException;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+import org.apache.ivy.core.cache.CacheManager;
+import org.apache.ivy.core.event.EventManager;
+import org.apache.ivy.core.module.descriptor.Artifact;
+import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
+import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
+import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.core.resolve.ResolveData;
+import org.apache.ivy.core.resolve.ResolveEngine;
+import org.apache.ivy.core.resolve.ResolveOptions;
+import org.apache.ivy.core.resolve.ResolvedModuleRevision;
+import org.apache.ivy.core.settings.IvySettings;
+import org.apache.ivy.core.sort.SortEngine;
+import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter;
+import org.apache.ivy.plugins.resolver.FileSystemResolver;
+import org.apache.ivy.util.FileUtil;
+
+public class PublishEngineTest extends TestCase {
+ protected void setUp() throws Exception {
+ FileUtil.forceDelete(new File("build/test/publish"));
+ }
+ protected void tearDown() throws Exception {
+ FileUtil.forceDelete(new File("build/test/publish"));
+ }
+
+ public void testAtomicity() throws Exception {
+ IvySettings settings = new IvySettings();
+ final PublishEngine engine = new PublishEngine(settings);
+ final int[] counter = new int[] {0};
+
+ final DefaultModuleDescriptor md = DefaultModuleDescriptor
+ .newDefaultInstance(ModuleRevisionId.parse("#A;1.0"));
+ final FileSystemResolver resolver = new FileSystemResolver() {
+ public void publish(Artifact artifact, File src, boolean
overwrite) throws IOException {
+ super.publish(artifact, src, overwrite);
+ synchronized (PublishEngineTest.this) {
+ counter[0] ++;
+ }
+ sleepSilently(50);
+ synchronized (PublishEngineTest.this) {
+ counter[0] ++;
+ }
+ }
+ };
+ resolver.setName("test");
+ resolver.setSettings(settings);
+
resolver.addIvyPattern("build/test/publish/repo/[module]/[revision]/[artifact].[ext]");
+
resolver.addArtifactPattern("build/test/publish/repo/[module]/[revision]/[artifact].[ext]");
+
+ FileUtil.copy(
+ new File("test/repositories/1/org1/mod1.1/jars/mod1.1-1.0.jar"),
+ new File("build/test/publish/module/A.jar"), null);
+ XmlModuleDescriptorWriter.write(md, new
File("build/test/publish/module/ivy.xml"));
+
+ resolveAndAssertNotFound(settings, resolver, "#A;latest.integration",
"before publishing");
+
+ // run publish asynchronously
+ new Thread() {
+ public void run() {
+ try {
+ engine.publish(
+ md,
+ Arrays.asList(new String[]
{"build/test/publish/module/[artifact].[ext]"}),
+ resolver,
+ new
PublishOptions().setSrcIvyPattern("build/test/publish/module/[artifact].[ext]"));
+ synchronized (PublishEngineTest.this) {
+ counter[0] ++;
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }.start();
+
+ while(true) {
+ sleepSilently(5);
+ synchronized (this) {
+ if (counter[0] == 5) {
+ break;
+ } else if (counter[0] < 4) {
+ resolveAndAssertNotFound(settings, resolver,
+ "#A;latest.integration", "after "+(counter[0] / 2)+"
artifacts published");
+ }
+ }
+ }
+ resolveAndAssertFound(settings, resolver, "#A;1.0");
+ }
+ private void resolveAndAssertNotFound(
+ IvySettings settings, FileSystemResolver resolver, String module,
String context)
+ throws ParseException {
+ ResolvedModuleRevision rmr = resolveModule(settings, resolver, module);
+ assertNull("module found " + context + ". module="+rmr, rmr);
+ }
+
+ private void resolveAndAssertFound(
+ IvySettings settings, FileSystemResolver resolver, String module)
+ throws ParseException {
+ ResolvedModuleRevision rmr = resolveModule(settings, resolver, module);
+ assertNotNull(rmr);
+ assertEquals(module, rmr.getId().toString());
+ }
+ private ResolvedModuleRevision resolveModule(
+ IvySettings settings, FileSystemResolver resolver, String module)
+ throws ParseException {
+ return resolver.getDependency(
+ new DefaultDependencyDescriptor(ModuleRevisionId.parse(module),
false),
+ new ResolveData(
+ new ResolveEngine(settings, new EventManager(), new
SortEngine(settings)),
+ new ResolveOptions().setCache(
+ new CacheManager(settings, new
File("build/test/publish/cache")))));
+ }
+ private void sleepSilently(int timeout) {
+ try {
+ Thread.sleep(timeout);
+ } catch (InterruptedException e) {
+ }
+ }
+}
Propchange:
incubator/ivy/core/trunk/test/java/org/apache/ivy/core/publish/PublishEngineTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified:
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/resolver/FileSystemResolverTest.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/resolver/FileSystemResolverTest.java?rev=599186&r1=599185&r2=599186&view=diff
==============================================================================
---
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/resolver/FileSystemResolverTest.java
(original)
+++
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/resolver/FileSystemResolverTest.java
Wed Nov 28 15:05:25 2007
@@ -567,18 +567,54 @@
Artifact artifact = new DefaultArtifact(mrid, new Date(),
"myartifact", "mytype",
"myext");
File src = new File("test/repositories/ivysettings.xml");
- resolver.publish(ivyArtifact, src, false);
- resolver.publish(artifact, src, false);
+ boolean successfullyPublished = false;
+ resolver.beginPublishTransaction(mrid, false);
+ try {
+ resolver.publish(ivyArtifact, src, false);
+ resolver.publish(artifact, src, false);
+ resolver.commitPublishTransaction();
+ successfullyPublished = true;
+ } finally {
+ if (!successfullyPublished)
+ resolver.abortPublishTransaction();
+ }
assertTrue(new
File("test/repositories/1/myorg/mymodule/myrevision/ivy.xml").exists());
assertTrue(new File(
"test/repositories/1/myorg/mymodule/mytypes/myartifact-myrevision.myext")
.exists());
} finally {
- Delete del = new Delete();
- del.setProject(new Project());
- del.setDir(new File("test/repositories/1/myorg"));
- del.execute();
+ FileUtil.forceDelete(new File("test/repositories/1/myorg"));
+ }
+ }
+
+ public void testAbortTransaction() throws Exception {
+ try {
+ FileSystemResolver resolver = new FileSystemResolver();
+ resolver.setName("test");
+ resolver.setSettings(settings);
+
+ resolver.addIvyPattern(
+
"test/repositories/1/[organisation]/[module]/[revision]/[artifact].[ext]");
+ resolver.addArtifactPattern(
+
"test/repositories/1/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]");
+
+ ModuleRevisionId mrid = ModuleRevisionId.newInstance("myorg",
"mymodule", "myrevision");
+ Artifact ivyArtifact = new DefaultArtifact(mrid, new Date(),
"ivy", "ivy", "xml");
+ Artifact artifact = new DefaultArtifact(mrid, new Date(),
"myartifact", "mytype",
+ "myext");
+ File src = new File("test/repositories/ivysettings.xml");
+ resolver.beginPublishTransaction(mrid, false);
+ resolver.publish(ivyArtifact, src, false);
+ resolver.publish(artifact, src, false);
+ resolver.abortPublishTransaction();
+
+ assertFalse(new
File("test/repositories/1/myorg/mymodule/myrevision/ivy.xml").exists());
+ assertFalse(new File(
+
"test/repositories/1/myorg/mymodule/mytypes/myartifact-myrevision.myext")
+ .exists());
+ } finally {
+ FileUtil.forceDelete(new File("test/repositories/1/myorg"));
}
}