| /* |
| * 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. |
| */ |
| /* |
| * Contributor(s): theanuradha@netbeans.org |
| */ |
| |
| package org.netbeans.modules.maven.indexer; |
| |
| import java.io.IOException; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.atomic.AtomicBoolean; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import org.apache.maven.index.updater.ResourceFetcher; |
| import org.apache.maven.wagon.events.TransferEvent; |
| import org.apache.maven.wagon.events.TransferListener; |
| import org.netbeans.api.annotations.common.NonNull; |
| import org.netbeans.api.progress.ProgressHandle; |
| import org.netbeans.modules.maven.indexer.api.RepositoryInfo; |
| import org.openide.util.Cancellable; |
| import org.openide.util.NbBundle.Messages; |
| |
| public class RemoteIndexTransferListener implements TransferListener, Cancellable { |
| |
| private static final Logger LOG = Logger.getLogger(RemoteIndexTransferListener.class.getName()); |
| |
| private final @NonNull ProgressHandle handle; |
| private final RepositoryInfo info; |
| private long lastunit;/*last work unit*/ |
| private long units; |
| private ResourceFetcher fetcher; |
| |
| private final AtomicBoolean canceled = new AtomicBoolean(); |
| private final AtomicBoolean unpacking = new AtomicBoolean(); |
| |
| private static Map<Thread, Integer> transfers = new HashMap<Thread, Integer>(); |
| private static final Object TRANSFERS_LOCK = new Object(); |
| |
| @SuppressWarnings("LeakingThisInConstructor") |
| @Messages({"# {0} - repo name", "LBL_Transfer=Transferring Maven repository index: {0}"}) |
| public RemoteIndexTransferListener(RepositoryInfo info) { |
| this.info = info; |
| Cancellation.register(this); |
| handle = ProgressHandle.createHandle(Bundle.LBL_Transfer(info.getName()), this); |
| handle.start(); |
| } |
| |
| void setFetcher(ResourceFetcher fetcher) { |
| this.fetcher = fetcher; |
| } |
| |
| public @Override void transferInitiated(TransferEvent e) { |
| String u = e.getWagon().getRepository().getUrl() + e.getResource(); |
| LOG.log(Level.FINE, "initiated transfer: {0}", u); |
| handle.progress(u); |
| checkCancel(); |
| } |
| |
| public @Override void transferStarted(TransferEvent e) { |
| checkCancel(); |
| long contentLength = e.getResource().getContentLength(); |
| LOG.log(Level.FINE, "contentLength: {0}", contentLength); |
| // #189806: could be resumed due to FNFE in DefaultIndexUpdater (*.gz -> *.zip) |
| this.units = contentLength / 1024; |
| handle.switchToDeterminate(100); |
| } |
| |
| public @Override boolean cancel() { |
| handle.finish(); |
| if (fetcher != null) { |
| try { |
| fetcher.disconnect(); |
| } catch (IOException x) { |
| LOG.log(Level.INFO, "closing " + info.getId(), x); |
| } |
| } |
| return canceled.compareAndSet(false, true); |
| } |
| |
| private void checkCancel() throws Cancellation { |
| if (canceled.get()) { |
| throw new Cancellation(); |
| } |
| } |
| |
| public @Override void transferProgress(TransferEvent e, byte[] buffer, int length) { |
| checkCancel(); |
| LOG.log(Level.FINER, "progress: {0}", length); |
| int work = length / 1024; |
| if(units > 0) { |
| lastunit += work; |
| handle.progress(Math.min(100, (int)(((double) lastunit / units) * 100))); |
| } |
| } |
| |
| public @Override void transferCompleted(TransferEvent e) { |
| LOG.fine("completed"); |
| handle.switchToIndeterminate(); |
| } |
| |
| public @Override void transferError(TransferEvent e) { |
| LOG.log(Level.FINE, "error transferring", e.getException()); |
| handle.switchToIndeterminate(); |
| } |
| |
| public @Override void debug(String message) { |
| checkCancel(); |
| } |
| |
| static void addToActive (Thread t) { |
| synchronized (TRANSFERS_LOCK) { |
| Integer count = transfers.get(t); |
| if (count == null) { |
| count = 1; |
| } else { |
| count = count + 1; |
| } |
| transfers.put(t, count); |
| } |
| } |
| |
| static void removeFromActive (Thread t) { |
| synchronized (TRANSFERS_LOCK) { |
| Integer count = transfers.get(t); |
| if (count == null) { |
| return; |
| } |
| if (count <= 1) { |
| transfers.remove(t); |
| } else { |
| count = count - 1; |
| transfers.put(t, count); |
| } |
| } |
| } |
| |
| static Set<Thread> getActiveTransfersOrScans () { |
| synchronized (TRANSFERS_LOCK) { |
| return transfers.keySet(); |
| } |
| } |
| |
| @Messages({"# {0} - repo name", "LBL_unpacking=Unpacking index for {0}"}) |
| void unpackingProgress(String label) { |
| checkCancel(); |
| if (unpacking.compareAndSet(false, true)) { |
| handle.setDisplayName(Bundle.LBL_unpacking(info.getName())); |
| } |
| handle.progress(label); |
| } |
| |
| void close() { |
| handle.finish(); |
| } |
| |
| long getUnits() { |
| return units; |
| } |
| |
| } |