Browse Source

新增4个工具类文件

main
Fuyuxinge 3 weeks ago
parent
commit
ac9e656c7b
  1. 63
      w10/AnalyzeCommand.java
  2. 35
      w10/ArticleRepository.java
  3. 30
      w11/RetryUtils.java
  4. 12
      w11/UrlFormatException.java

63
w10/AnalyzeCommand.java

@ -0,0 +1,63 @@
public class AnalyzeCommand implements Command {
private static final Pattern URL_PATTERN =
Pattern.compile("^(https?://)?([\\w-]+\\.)+[\\w-]+(/[\\w-./?%&=]*)*$");
private final ConsoleView view;
private final StrategyFactory strategyFactory;
public AnalyzeCommand(ConsoleView view, StrategyFactory strategyFactory) {
this.view = view;
this.strategyFactory = strategyFactory;
}
@Override
public String getName() {
return "analyze";
}
@Override
public void execute(String[] args, List<Article> unused) {
if (args.length < 2) {
view.printError("用法:analyze <url>");
return;
}
String url = args[1];
if (!isValidUrl(url)) {
view.printError("无效的URL格式:" + url);
return;
}
try {
List<Article> parsedArticles = strategyFactory.getStrategy(url).crawl(url);
printAnalysisResult(url, parsedArticles);
} catch (Exception e) {
view.printError("解析失败:" + e.getMessage());
}
}
private void printAnalysisResult(String url, List<Article> articles) {
view.printInfo("解析统计结果 ");
view.printInfo("目标 URL:" + url);
view.printInfo("解析到文章数量:" + articles.size());
if (!articles.isEmpty()) {
Article first = articles.get(0);
view.printInfo("首篇文章标题:" + first.getTitle());
view.printInfo("首篇文章作者:" + first.getAuthor());
view.printInfo("首篇发布日期:" + first.getPublishDate());
}
}
private boolean isValidUrl(String url) {
return url != null && URL_PATTERN.matcher(url).matches();
}
}

35
w10/ArticleRepository.java

@ -0,0 +1,35 @@
package w10;
public class ArticleRepository {
private final List<Article> articles = new ArrayList<>();
public void add(Article article) {
if (article == null) {
throw new IllegalArgumentException("Article cannot be null");
}
articles.add(article);
}
public void addAll(List<Article> newArticles) {
if (newArticles == null) {
return;
}
for (Article article : newArticles) {
if (article != null) {
articles.add(article);
}
}
}
public List<Article> getAll() {
return Collections.unmodifiableList(articles);
}
public int size() {
return articles.size();
}
public void clear() {
articles.clear();
}
}

30
w11/RetryUtils.java

@ -0,0 +1,30 @@
package w11;
public class RetryUtils {
private static final long BASE_DELAY_MS = 500;
@FunctionalInterface
public interface RetryTask<T> {
T run() throws Exception;
}
public static <T> T retry(int maxRetries, RetryTask<T> task) throws Exception {
int attempt = 0;
while (true) {
try {
return task.run();
} catch (Exception e) {
if (attempt >= maxRetries) {
throw e;
}
long delay = BASE_DELAY_MS * (1L << attempt);
Thread.sleep(delay);
attempt++;
}
}
}
}

12
w11/UrlFormatException.java

@ -0,0 +1,12 @@
package w11;
public class UrlFormatException extends RuntimeException {
public UrlFormatException(String message) {
super(message);
}
public UrlFormatException(String message, Throwable cause) {
super(message, cause);
}
Loading…
Cancel
Save