You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
3.5 KiB
82 lines
3.5 KiB
import java.time.LocalDate;
|
|
import java.util.ArrayList;
|
|
import java.util.Comparator;
|
|
import java.util.List;
|
|
import java.util.regex.Pattern;
|
|
|
|
// ─────────────────────────────────────────────
|
|
// 策略接口
|
|
// ─────────────────────────────────────────────
|
|
interface ParseStrategy {
|
|
boolean supports(String url);
|
|
Article parse(String url);
|
|
String getName();
|
|
default int getPriority() { return 100; }
|
|
}
|
|
|
|
// ─────────────────────────────────────────────
|
|
// 策略实现1:GitHub 专属(priority=10)
|
|
// ─────────────────────────────────────────────
|
|
class GithubParseStrategy implements ParseStrategy {
|
|
@Override
|
|
public boolean supports(String url) {
|
|
return url != null && url.matches("^https?://(www\\.)?github\\.com/.*");
|
|
}
|
|
|
|
@Override
|
|
public Article parse(String url) {
|
|
String path = url.replaceFirst("https?://(www\\.)?github\\.com/", "");
|
|
String[] parts = path.split("/");
|
|
String owner = parts.length > 0 ? parts[0] : "unknown";
|
|
String repo = parts.length > 1 ? parts[1] : "repo";
|
|
return new Article("[GitHub] " + owner + "/" + repo, url,
|
|
"(GitHub stub)", owner, LocalDate.now());
|
|
}
|
|
|
|
@Override public String getName() { return "GithubParseStrategy"; }
|
|
@Override public int getPriority(){ return 10; }
|
|
}
|
|
|
|
// ─────────────────────────────────────────────
|
|
// 策略实现2:通用默认兜底(priority=999)
|
|
// ─────────────────────────────────────────────
|
|
class DefaultParseStrategy implements ParseStrategy {
|
|
private static final Pattern URL_PATTERN =
|
|
Pattern.compile("^https?://[^\\s/$.?#].[^\\s]*$");
|
|
|
|
@Override
|
|
public boolean supports(String url) {
|
|
return url != null && URL_PATTERN.matcher(url).matches();
|
|
}
|
|
|
|
@Override
|
|
public Article parse(String url) {
|
|
String domain = url.replaceFirst("https?://", "").replaceAll("/.*", "");
|
|
return new Article("文章来自 " + domain, url,
|
|
"(default stub)", "unknown", LocalDate.now());
|
|
}
|
|
|
|
@Override public String getName() { return "DefaultParseStrategy"; }
|
|
@Override public int getPriority(){ return 999; }
|
|
}
|
|
|
|
// ─────────────────────────────────────────────
|
|
// 策略选择器
|
|
// ─────────────────────────────────────────────
|
|
class StrategySelector {
|
|
private final List<ParseStrategy> strategies = new ArrayList<>();
|
|
|
|
public StrategySelector() {
|
|
strategies.add(new GithubParseStrategy());
|
|
strategies.add(new DefaultParseStrategy());
|
|
strategies.sort(Comparator.comparingInt(ParseStrategy::getPriority));
|
|
}
|
|
|
|
public ParseStrategy select(String url) {
|
|
return strategies.stream()
|
|
.filter(s -> s.supports(url))
|
|
.findFirst().orElse(null);
|
|
}
|
|
|
|
public List<ParseStrategy> getAll() { return List.copyOf(strategies); }
|
|
}
|
|
|