diff --git a/w12/.DS_Store b/w12/.DS_Store new file mode 100644 index 0000000..97af285 Binary files /dev/null and b/w12/.DS_Store differ diff --git a/w12/App.java b/w12/App.java new file mode 100644 index 0000000..a7b17d4 --- /dev/null +++ b/w12/App.java @@ -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 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(); + } +} diff --git a/w12/repository/ArticleRepository.java b/w12/repository/ArticleRepository.java new file mode 100644 index 0000000..0feb516 --- /dev/null +++ b/w12/repository/ArticleRepository.java @@ -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
articles); + Optional
findById(String id); + Optional
findByUrl(String url); + List
findAll(); + List
findBySource(String source); + void deleteById(String id); + void deleteAll(); + int count(); + boolean existsByUrl(String url); +} diff --git a/w12/repository/InMemoryArticleRepository.java b/w12/repository/InMemoryArticleRepository.java new file mode 100644 index 0000000..31c5578 --- /dev/null +++ b/w12/repository/InMemoryArticleRepository.java @@ -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 articles = new ConcurrentHashMap<>(); + private final Map 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
articleList) { + for (Article article : articleList) { + save(article); + } + } + + @Override + public Optional
findById(String id) { + return Optional.ofNullable(articles.get(id)); + } + + @Override + public Optional
findByUrl(String url) { + String id = urlToIdMap.get(url); + return id != null ? Optional.ofNullable(articles.get(id)) : Optional.empty(); + } + + @Override + public List
findAll() { + return new ArrayList<>(articles.values()); + } + + @Override + public List
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); + } +}