4 changed files with 159 additions and 0 deletions
Binary file not shown.
@ -0,0 +1,63 @@ |
|||||
|
package com.crawler; |
||||
|
|
||||
|
import com.crawler.command.*; |
||||
|
import com.crawler.controller.CrawlerController; |
||||
|
import com.crawler.repository.ArticleRepository; |
||||
|
import com.crawler.repository.InMemoryArticleRepository; |
||||
|
import com.crawler.view.ConsoleView; |
||||
|
|
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
import java.util.concurrent.atomic.AtomicBoolean; |
||||
|
|
||||
|
public class App { |
||||
|
private final Map<String, Command> commands = new HashMap<>(); |
||||
|
private final ConsoleView view; |
||||
|
private final AtomicBoolean running = new AtomicBoolean(true); |
||||
|
|
||||
|
public App() { |
||||
|
view = new ConsoleView(); |
||||
|
ArticleRepository repository = new InMemoryArticleRepository(); |
||||
|
CrawlerController controller = new CrawlerController(repository, view); |
||||
|
|
||||
|
commands.put("crawl", new CrawlCommand(controller, view)); |
||||
|
commands.put("list", new ListCommand(controller)); |
||||
|
commands.put("save", new SaveCommand(controller)); |
||||
|
commands.put("load", new LoadCommand(controller)); |
||||
|
commands.put("help", new HelpCommand(view)); |
||||
|
commands.put("exit", new ExitCommand(view, () -> running.set(false))); |
||||
|
} |
||||
|
|
||||
|
public void run() { |
||||
|
view.displayWelcome(); |
||||
|
view.displayHelp(); |
||||
|
|
||||
|
while (running.get()) { |
||||
|
try { |
||||
|
String input = view.readInput(); |
||||
|
if (input.isEmpty()) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
String[] parts = input.split("\\s+", 3); |
||||
|
String commandName = parts[0].toLowerCase(); |
||||
|
String[] args = parts.length > 1 ? java.util.Arrays.copyOfRange(parts, 1, parts.length) : new String[0]; |
||||
|
|
||||
|
Command command = commands.get(commandName); |
||||
|
if (command != null) { |
||||
|
command.execute(args); |
||||
|
} else { |
||||
|
view.displayError("Unknown command: " + commandName); |
||||
|
view.displayInfo("Type 'help' for available commands"); |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
view.displayError("Error: " + e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static void main(String[] args) { |
||||
|
App app = new App(); |
||||
|
app.run(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
package com.crawler.repository; |
||||
|
|
||||
|
import com.crawler.model.Article; |
||||
|
import java.util.List; |
||||
|
import java.util.Optional; |
||||
|
|
||||
|
public interface ArticleRepository { |
||||
|
void save(Article article); |
||||
|
void saveAll(List<Article> articles); |
||||
|
Optional<Article> findById(String id); |
||||
|
Optional<Article> findByUrl(String url); |
||||
|
List<Article> findAll(); |
||||
|
List<Article> findBySource(String source); |
||||
|
void deleteById(String id); |
||||
|
void deleteAll(); |
||||
|
int count(); |
||||
|
boolean existsByUrl(String url); |
||||
|
} |
||||
@ -0,0 +1,78 @@ |
|||||
|
package com.crawler.repository; |
||||
|
|
||||
|
import com.crawler.model.Article; |
||||
|
import java.util.*; |
||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||
|
import java.util.concurrent.atomic.AtomicInteger; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
public class InMemoryArticleRepository implements ArticleRepository { |
||||
|
private final Map<String, Article> articles = new ConcurrentHashMap<>(); |
||||
|
private final Map<String, String> urlToIdMap = new ConcurrentHashMap<>(); |
||||
|
private final AtomicInteger idGenerator = new AtomicInteger(1); |
||||
|
|
||||
|
@Override |
||||
|
public void save(Article article) { |
||||
|
if (article.getId() == null) { |
||||
|
article.setId(String.valueOf(idGenerator.getAndIncrement())); |
||||
|
} |
||||
|
articles.put(article.getId(), article); |
||||
|
if (article.getUrl() != null) { |
||||
|
urlToIdMap.put(article.getUrl(), article.getId()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void saveAll(List<Article> articleList) { |
||||
|
for (Article article : articleList) { |
||||
|
save(article); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Optional<Article> findById(String id) { |
||||
|
return Optional.ofNullable(articles.get(id)); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Optional<Article> findByUrl(String url) { |
||||
|
String id = urlToIdMap.get(url); |
||||
|
return id != null ? Optional.ofNullable(articles.get(id)) : Optional.empty(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public List<Article> findAll() { |
||||
|
return new ArrayList<>(articles.values()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public List<Article> findBySource(String source) { |
||||
|
return articles.values().stream() |
||||
|
.filter(a -> source.equals(a.getSource())) |
||||
|
.collect(Collectors.toList()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void deleteById(String id) { |
||||
|
Article article = articles.remove(id); |
||||
|
if (article != null && article.getUrl() != null) { |
||||
|
urlToIdMap.remove(article.getUrl()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void deleteAll() { |
||||
|
articles.clear(); |
||||
|
urlToIdMap.clear(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int count() { |
||||
|
return articles.size(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean existsByUrl(String url) { |
||||
|
return urlToIdMap.containsKey(url); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue