com.acgist.snail.context.ProtocolContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of snail Show documentation
Show all versions of snail Show documentation
基于Java开发的下载工具,支持下载协议:BT(BitTorrent、磁力链接、种子文件)、HLS(M3U8)、FTP、HTTP。
package com.acgist.snail.context;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.acgist.snail.IContext;
import com.acgist.snail.Snail;
import com.acgist.snail.context.exception.DownloadException;
import com.acgist.snail.downloader.IDownloader;
import com.acgist.snail.pojo.ITaskSession;
import com.acgist.snail.protocol.Protocol;
import com.acgist.snail.utils.StringUtils;
/**
* 下载协议上下文
*
* @author acgist
*/
public final class ProtocolContext implements IContext {
private static final Logger LOGGER = LoggerFactory.getLogger(ProtocolContext.class);
private static final ProtocolContext INSTANCE = new ProtocolContext();
public static final ProtocolContext getInstance() {
return INSTANCE;
}
/**
* 下载协议
*/
private final List protocols;
/**
* 可用状态锁
* 协议没有加载完成阻塞所有获取协议线程
*/
private final AtomicBoolean availableLock;
private ProtocolContext() {
this.protocols = new ArrayList<>();
this.availableLock = new AtomicBoolean(false);
}
/**
* 注册协议
*
* @param protocol 协议
*
* @return ProtocolContext
*/
public ProtocolContext register(Protocol protocol) {
if(this.protocols.contains(protocol)) {
if(LOGGER.isDebugEnabled()) {
LOGGER.debug("下载协议已经注册:{}", protocol.name());
}
} else {
if(LOGGER.isInfoEnabled()) {
LOGGER.info("注册下载协议:{}", protocol.name());
}
this.protocols.add(protocol);
}
return this;
}
/**
* 新建下载器
*
* @param taskSession 任务信息
*
* @return 下载器
*
* @throws DownloadException 下载异常
*/
public IDownloader buildDownloader(ITaskSession taskSession) throws DownloadException {
final var type = taskSession.getType();
final Optional optional = this.protocols.stream()
.filter(Protocol::available)
.filter(protocol -> protocol.type() == type)
.findFirst();
if(optional.isEmpty()) {
throw new DownloadException("不支持的下载类型:" + type);
}
final IDownloader downloader = optional.get().buildDownloader(taskSession);
if(downloader == null) {
throw new DownloadException("不支持的下载类型:" + type);
}
return downloader;
}
/**
* 新建下载任务
*
* @param url 下载链接
*
* @return 任务信息
*
* @throws DownloadException 下载异常
*/
public ITaskSession buildTaskSession(String url) throws DownloadException {
final Optional protocol = this.protocol(url);
if(protocol.isEmpty()) {
throw new DownloadException("不支持的下载链接:" + url);
}
return protocol.get().buildTaskSession(url);
}
/**
* 判断是否支持下载
*
* @param url 下载链接
*
* @return 是否支持
*/
public boolean support(String url) {
return this.protocol(url).isPresent();
}
/**
* 获取下载协议
*
* @param url 下载链接
*
* @return 下载协议
*/
public Optional protocol(final String url) {
if(StringUtils.isEmpty(url)) {
return Optional.empty();
}
final String verify = url.trim();
return this.protocols.stream()
.filter(Protocol::available)
.filter(protocol -> protocol.verify(verify))
.findFirst();
}
/**
* 判断状态是否可用(阻塞线程)
*
* @return 是否可用
*
* @throws DownloadException 下载异常
*/
public boolean available() throws DownloadException {
if(!this.availableLock.get()) {
synchronized (this.availableLock) {
if(!this.availableLock.get()) {
try {
this.availableLock.wait(Short.MAX_VALUE);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
LOGGER.debug("线程等待异常", e);
}
}
}
}
if(Snail.available()) {
return true;
} else {
throw new DownloadException("系统没有启动");
}
}
/**
* 设置可用状态(释放阻塞线程)
*
* @param available 是否可用
*/
public void available(boolean available) {
synchronized (this.availableLock) {
this.availableLock.set(available);
this.availableLock.notifyAll();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy