blob: 8dc6930a6ec9dcc497559a2eb1b521c05e0c6732 [file] [log] [blame]
/*
* 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.netbeans.modules.maven.embedder.exec;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicBoolean;
import org.netbeans.api.progress.aggregate.AggregateProgressFactory;
import org.netbeans.api.progress.aggregate.AggregateProgressHandle;
import org.netbeans.api.progress.aggregate.ProgressContributor;
import static org.netbeans.modules.maven.embedder.exec.Bundle.*;
import org.openide.util.Cancellable;
import org.openide.util.NbBundle.Messages;
import org.eclipse.aether.transfer.TransferCancelledException;
import org.eclipse.aether.transfer.TransferEvent;
import org.eclipse.aether.transfer.TransferListener;
import org.eclipse.aether.transfer.TransferResource;
public class ProgressTransferListener implements TransferListener {
private static final ThreadLocal<ProgressTransferListener> activeListener = new ThreadLocal<ProgressTransferListener>() {
protected @Override ProgressTransferListener initialValue() {
return new ProgressTransferListener();
}
};
private ProgressTransferListener() {}
public static ProgressTransferListener activeListener() {
return activeListener.get();
}
private int length;
private ProgressContributor contrib;
private ProgressContributor pomcontrib;
private int pomCount;
private final Stack<ProgressContributor> contribStack = new Stack<ProgressContributor>();
private AggregateProgressHandle handle;
public AtomicBoolean cancel;
private static final int POM_MAX = 20;
public static void setAggregateHandle(AggregateProgressHandle hndl) {
ProgressTransferListener ptl = activeListener();
ptl.handle = hndl;
ProgressContributor pc = AggregateProgressFactory.createProgressContributor("Pom files");
hndl.addContributor(pc);
pc.start(POM_MAX);
ptl.pomcontrib = pc;
}
public static void clearAggregateHandle() {
activeListener.remove();
}
/**
* Produces a token which may be passed to {@link AggregateProgressFactory#createHandle}
* in order to permit progress to be canceled.
* If an event is received after a cancel request has been made, {@link ThreadDeath} will
* be thrown (which you probably also want to catch and handle gracefully).
* Due to AETHER-95, {@link IllegalStateException} with a cause of {@link ThreadDeath} might also be thrown.
* Must be called by the same thread as will call {@link #setAggregateHandle} and runs the process.
* @return a cancellation token
*/
public static Cancellable cancellable() {
final AtomicBoolean b = new AtomicBoolean();
activeListener().cancel = b;
return new Cancellable() {
public @Override boolean cancel() {
return b.compareAndSet(false, true);
}
};
}
private void checkCancel() {
if (cancel != null && cancel.get()) {
throw new ThreadDeath();
}
}
private String getResourceName(TransferResource res) {
int lastSlash = res.getResourceName().lastIndexOf('/');
return lastSlash > -1 ? res.getResourceName().substring(lastSlash + 1) : res.getResourceName();
}
@Messages({
"# {0} - downloaded resource name",
"TXT_Download=Downloading {0}",
"# {0} - uploaded resource name",
"TXT_Uploading=Uploading {0}",
"# {0} - transferred resource name",
"TXT_Started={0} - Transfer Started..."
})
@Override
public void transferInitiated(TransferEvent te) throws TransferCancelledException {
if (handle == null) {
//maybe log?
return;
}
TransferResource res = te.getResource();
String resName = getResourceName(res);
if (!resName.endsWith(".pom")) { //NOI18N
ProgressContributor pc = !contribStack.empty() ? contribStack.pop() : null;
if (pc == null) {
String name = (te.getRequestType() == TransferEvent.RequestType.GET
? TXT_Download(resName)
: TXT_Uploading(resName));
pc = AggregateProgressFactory.createProgressContributor(name);
handle.addContributor(pc);
}
contrib = pc;
} else {
String name = (te.getRequestType() == TransferEvent.RequestType.GET
? TXT_Download(resName)
: TXT_Uploading(resName));
ProgressContributor pc = AggregateProgressFactory.createProgressContributor(name);
contribStack.add(pc);
handle.addContributor(pc);
if (pomCount < POM_MAX - 1) {
pomcontrib.progress(TXT_Started(resName), ++pomCount);
} else {
pomcontrib.progress(TXT_Started(resName));
}
}
}
@Override
public void transferStarted(TransferEvent te) throws TransferCancelledException {
ProgressContributor c = contrib;
if (c == null || handle == null) {
return;
}
TransferResource res = te.getResource();
int total = (int)Math.min((long)Integer.MAX_VALUE, res.getContentLength());
if (total < 0) {
c.start(0);
} else {
c.start(total);
}
length = total;
c.progress(TXT_Started(getResourceName(res)));
}
@Messages({
"# {0} - transferring resource name",
"TXT_Transferring={0} - Transferring...",
"# {0} - transferring resource name",
"# {1} - transferred amount",
"TXT_Transferred={0} - Transferred {1}"
})
@Override
public void transferProgressed(TransferEvent te) throws TransferCancelledException {
checkCancel();
ProgressContributor c = contrib;
if (c == null) {
return;
}
long cnt = te.getTransferredBytes();
cnt = Math.min((long)Integer.MAX_VALUE, cnt);
if (length < 0) {
c.progress(TXT_Transferring(getResourceName(te.getResource())));
} else {
cnt = Math.min(cnt, (long)length);
c.progress(TXT_Transferred(getResourceName(te.getResource()), cnt), (int)cnt);
}
}
@Override
public void transferCorrupted(TransferEvent te) throws TransferCancelledException {
ProgressContributor c = contrib;
contrib = null;
if (c != null) {
c.finish();
}
}
@Override
public void transferSucceeded(TransferEvent te) {
ProgressContributor c = contrib;
contrib = null;
if (c != null) {
c.finish();
}
}
@Override
public void transferFailed(TransferEvent te) {
ProgressContributor c = contrib;
contrib = null;
if (c != null) {
c.finish();
}
}
}