Browse Source

basic structure

master
283375 2 months ago
commit
c34817cf50
Failed to extract signature
  1. 33
      .gitignore
  2. 15
      pom.xml
  3. 24
      src/main/java/internal/hw/crawler/Main.java
  4. 72
      src/main/java/internal/hw/crawler/MainController.java
  5. 13
      src/main/java/internal/hw/crawler/commands/Command.java
  6. 39
      src/main/java/internal/hw/crawler/commands/CommandArg.java
  7. 28
      src/main/java/internal/hw/crawler/commands/CrawlCommand.java
  8. 13
      src/main/java/internal/hw/crawler/commands/ExitCommand.java
  9. 65
      src/main/java/internal/hw/crawler/commands/HelpCommand.java
  10. 42
      src/main/java/internal/hw/crawler/models/Article.java
  11. 30
      src/main/java/internal/hw/crawler/repositories/ArticleRepository.java
  12. 29
      src/main/java/internal/hw/crawler/views/ConsoleView.java

33
.gitignore

@ -0,0 +1,33 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
.kotlin
### IntelliJ IDEA ###
.idea/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

15
pom.xml

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>internal.hw.crawler</groupId>
<artifactId>homework-final</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
</project>

24
src/main/java/internal/hw/crawler/Main.java

@ -0,0 +1,24 @@
package internal.hw.crawler;
import internal.hw.crawler.commands.CrawlCommand;
import internal.hw.crawler.commands.ExitCommand;
import internal.hw.crawler.commands.HelpCommand;
import internal.hw.crawler.repositories.ArticleRepository;
import internal.hw.crawler.views.ConsoleView;
public class Main {
public static void main(String[] args) {
ConsoleView view = new ConsoleView();
MainController controller = new MainController(view);
ArticleRepository repository = new ArticleRepository();
controller.registerCommand(new ExitCommand());
controller.registerCommand(new CrawlCommand(repository));
controller.registerCommand(new HelpCommand(controller.getCommands()));
view.printSuccess("Welcome to crawler. Type `help` for a list of available commands.");
while (true) {
controller.handleInput(view.readLine());
}
}
}

72
src/main/java/internal/hw/crawler/MainController.java

@ -0,0 +1,72 @@
package internal.hw.crawler;
import internal.hw.crawler.commands.Command;
import internal.hw.crawler.commands.CommandArg;
import internal.hw.crawler.views.ConsoleView;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainController {
private final Map<String, Command> commands = new HashMap<>();
private final ConsoleView view;
public MainController(ConsoleView view) {
this.view = view;
}
public Map<String, Command> getCommands() {
return Collections.unmodifiableMap(commands);
}
public void registerCommand(Command command) {
commands.put(command.getName(), command);
}
public void handleInput(String input) {
String text = input == null ? "" : input.trim();
if (text.isEmpty()) {
return;
}
String[] args = text.split("\\s+");
String cmdName = args[0].toLowerCase();
Command command = commands.get(cmdName);
if (command == null) {
view.printError("Unknown command: " + cmdName);
return;
}
if (!validateArgs(command, args)) {
return;
}
command.execute(args);
}
private boolean validateArgs(Command command, String[] args) {
List<CommandArg> cmdArgs = command.getArgs();
long required = cmdArgs.stream().filter(CommandArg::required).count();
int provided = args.length - 1;
if (provided < required) {
view.printError("Usage: " + command.getName() + " " + formatUsage(cmdArgs));
return false;
}
return true;
}
private String formatUsage(List<CommandArg> cmdArgs) {
StringBuilder sb = new StringBuilder();
for (CommandArg arg : cmdArgs) {
if (arg.required()) {
sb.append("<").append(arg.name()).append("> ");
} else {
sb.append("[").append(arg.name()).append("] ");
}
}
return sb.toString().trim();
}
}

13
src/main/java/internal/hw/crawler/commands/Command.java

@ -0,0 +1,13 @@
package internal.hw.crawler.commands;
import java.util.List;
public interface Command {
String getName();
default List<CommandArg> getArgs() {
return List.of();
}
void execute(String[] args);
}

39
src/main/java/internal/hw/crawler/commands/CommandArg.java

@ -0,0 +1,39 @@
package internal.hw.crawler.commands;
import java.util.Objects;
public final class CommandArg {
private final String name;
private final String description;
private final boolean required;
public CommandArg(String name, String description, boolean required) {
this.name = Objects.requireNonNull(name);
this.description = Objects.requireNonNull(description);
this.required = required;
}
public String name() { return name; }
public String description() { return description; }
public boolean required() { return required; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof CommandArg)) return false;
CommandArg that = (CommandArg) o;
return required == that.required
&& name.equals(that.name)
&& description.equals(that.description);
}
@Override
public int hashCode() {
return Objects.hash(name, description, required);
}
@Override
public String toString() {
return "CommandArg[name=" + name + ", description=" + description + ", required=" + required + "]";
}
}

28
src/main/java/internal/hw/crawler/commands/CrawlCommand.java

@ -0,0 +1,28 @@
package internal.hw.crawler.commands;
import internal.hw.crawler.repositories.ArticleRepository;
import java.util.List;
public class CrawlCommand implements Command {
private ArticleRepository repository;
public CrawlCommand(ArticleRepository repository) {
this.repository = repository;
}
@Override
public String getName() {
return "crawl";
}
@Override
public List<CommandArg> getArgs() {
return List.of(new CommandArg("url", "The website to crawl", true));
}
@Override
public void execute(String[] args) {
System.out.printf("Will crawl %s%n", args[1]);
}
}

13
src/main/java/internal/hw/crawler/commands/ExitCommand.java

@ -0,0 +1,13 @@
package internal.hw.crawler.commands;
public class ExitCommand implements Command {
@Override
public String getName() {
return "exit";
}
@Override
public void execute(String[] args) {
System.exit(0);
}
}

65
src/main/java/internal/hw/crawler/commands/HelpCommand.java

@ -0,0 +1,65 @@
package internal.hw.crawler.commands;
import java.util.List;
import java.util.Map;
public class HelpCommand implements Command {
private final Map<String, Command> commands;
public HelpCommand(Map<String, Command> commands) {
this.commands = commands;
}
@Override
public String getName() {
return "help";
}
@Override
public List<CommandArg> getArgs() {
return List.of(
new CommandArg("command", "Command name to show detailed help for", false)
);
}
@Override
public void execute(String[] args) {
if (args.length >= 2) {
showDetail(args[1]);
} else {
showAll();
}
}
private void showAll() {
System.out.println("Available commands:");
for (Command cmd : commands.values()) {
System.out.printf(" %s", cmd.getName());
System.out.println();
}
System.out.println("Type `help <command>` to show detailed help for a specific command.");
}
private void showDetail(String name) {
Command cmd = commands.get(name);
if (cmd == null) {
System.out.println("Unknown command: " + name);
return;
}
System.out.println("Command: " + cmd.getName());
List<CommandArg> cmdArgs = cmd.getArgs();
if (cmdArgs.isEmpty()) {
System.out.println(" No arguments.");
return;
}
System.out.println("Arguments:");
for (CommandArg arg : cmdArgs) {
System.out.printf(" %s %s %s%n",
arg.required() ? "[R]" : " ",
arg.name(),
arg.description());
}
}
}

42
src/main/java/internal/hw/crawler/models/Article.java

@ -0,0 +1,42 @@
package internal.hw.crawler.models;
public class Article {
private String url;
private String title;
private String content;
public Article(String url, String title, String content) {
this.url = url;
this.title = title;
this.content = content;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return String.format("Article{%s}", url);
}
}

30
src/main/java/internal/hw/crawler/repositories/ArticleRepository.java

@ -0,0 +1,30 @@
package internal.hw.crawler.repositories;
import internal.hw.crawler.models.Article;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
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 List<Article> getAll() {
return Collections.unmodifiableList(articles);
}
public int size() {
return articles.size();
}
public void clear() {
articles.clear();
}
}

29
src/main/java/internal/hw/crawler/views/ConsoleView.java

@ -0,0 +1,29 @@
package internal.hw.crawler.views;
import java.util.Scanner;
public class ConsoleView {
private static final String ANSI_RESET = "\u001B[0m";
private static final String ANSI_GREEN = "\u001B[32m";
private static final String ANSI_RED = "\u001B[31m";
private static final String ANSI_BLUE = "\u001B[34m";
private final Scanner scanner = new Scanner(System.in);
public String readLine() {
System.out.print("> ");
return scanner.nextLine();
}
public void printSuccess(String msg) {
System.out.println(ANSI_GREEN + msg + ANSI_RESET);
}
public void printError(String msg) {
System.out.println(ANSI_RED + msg + ANSI_RESET);
}
public void printInfo(String msg) {
System.out.println(ANSI_BLUE + msg + ANSI_RESET);
}
}
Loading…
Cancel
Save