All Downloads are FREE. Search and download functionalities are using the official Maven repository.

bt.torrent.AdhocTorrentRegistry Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2016—2021 Andrei Tomashpolskiy and individual contributors.
 *
 * 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 bt.torrent;

import bt.data.IDataDescriptorFactory;
import bt.data.Storage;
import bt.event.EventSource;
import bt.metainfo.Torrent;
import bt.metainfo.TorrentId;
import bt.torrent.callbacks.FileDownloadCompleteCallback;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Simple in-memory torrent registry, that creates new descriptors upon request.
 *
 * 

Note that this class implements a service. * Hence, is not a part of the public API and is a subject to change.

*/ public class AdhocTorrentRegistry implements TorrentRegistry { private static final Logger LOGGER = LoggerFactory.getLogger(AdhocTorrentRegistry.class); private IDataDescriptorFactory dataDescriptorFactory; private Set torrentIds; private ConcurrentMap torrents; private ConcurrentMap descriptors; @Inject public AdhocTorrentRegistry(IDataDescriptorFactory dataDescriptorFactory, EventSource eventSource) { this.dataDescriptorFactory = dataDescriptorFactory; this.torrentIds = ConcurrentHashMap.newKeySet(); this.torrents = new ConcurrentHashMap<>(); this.descriptors = new ConcurrentHashMap<>(); eventSource.onTorrentStopped(null, e -> unregister(e.getTorrentId())); } @Override public Collection getTorrents() { return Collections.unmodifiableCollection(torrents.values()); } @Override public Collection getTorrentIds() { return Collections.unmodifiableCollection(torrentIds); } @Override public Optional getTorrent(TorrentId torrentId) { Objects.requireNonNull(torrentId, "Missing torrent ID"); return Optional.ofNullable(torrents.get(torrentId)); } @Override public Optional getDescriptor(Torrent torrent) { return Optional.ofNullable(descriptors.get(torrent.getTorrentId())); } @Override public Optional getDescriptor(TorrentId torrentId) { Objects.requireNonNull(torrentId, "Missing torrent ID"); return Optional.ofNullable(descriptors.get(torrentId)); } @Override public TorrentDescriptor getOrCreateDescriptor(Torrent torrent, Storage storage) { return register(torrent, storage, null); } @Override public TorrentDescriptor register(Torrent torrent, Storage storage, FileDownloadCompleteCallback completedFileCallbacks) { TorrentId torrentId = torrent.getTorrentId(); DefaultTorrentDescriptor descriptor = descriptors.computeIfAbsent(torrentId, k -> new DefaultTorrentDescriptor()); if (descriptor.getDataDescriptor() != null) { throw new IllegalStateException( "Torrent already registered and data descriptor created: " + torrent.getTorrentId()); } descriptor.setDataDescriptor(dataDescriptorFactory.createDescriptor(torrent, storage, completedFileCallbacks)); torrentIds.add(torrentId); torrents.putIfAbsent(torrentId, torrent); return descriptor; } @Override public TorrentDescriptor register(TorrentId torrentId) { return getDescriptor(torrentId).orElseGet(() -> { DefaultTorrentDescriptor descriptor = new DefaultTorrentDescriptor(); DefaultTorrentDescriptor existing = descriptors.putIfAbsent(torrentId, descriptor); if (existing != null) { descriptor = existing; } else { torrentIds.add(torrentId); } return descriptor; }); } @Override public boolean isSupportedAndActive(TorrentId torrentId) { Optional descriptor = getDescriptor(torrentId); // it's OK if descriptor is not present -- torrent might be being fetched at the time return getTorrentIds().contains(torrentId) && (!descriptor.isPresent() || descriptor.get().isActive()); } private void unregister(TorrentId torrentId) { torrentIds.remove(torrentId); torrents.remove(torrentId); DefaultTorrentDescriptor torrentDescriptor = descriptors.remove(torrentId); if (torrentDescriptor != null) { try { if (torrentDescriptor.getDataDescriptor() != null) { torrentDescriptor.getDataDescriptor().close(); } } catch (IOException e) { LOGGER.error("closing DataDescriptor error, torrentId: {}", torrentId, e); } } } @Override public void registerSessionState(TorrentId torrentId, TorrentSessionState state) { descriptors.get(torrentId).setSessionState(state); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy