We are the wild!
This commit is contained in:
2
.project
2
.project
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<projectDescription>
|
<projectDescription>
|
||||||
<name>lab5-test</name>
|
<name>lab5-lab5-itmo</name>
|
||||||
<comment>Project lab5-test created by Buildship.</comment>
|
<comment>Project lab5-test created by Buildship.</comment>
|
||||||
<projects>
|
<projects>
|
||||||
</projects>
|
</projects>
|
||||||
|
@ -1,2 +1,13 @@
|
|||||||
connection.project.dir=app
|
arguments=--init-script /home/oxff/.cache/jdtls/config/org.eclipse.osgi/58/0/.cp/gradle/init/init.gradle
|
||||||
|
auto.sync=false
|
||||||
|
build.scans.enabled=false
|
||||||
|
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||||
|
connection.project.dir=
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
|
gradle.user.home=
|
||||||
|
java.home=/usr/lib/jvm/java-21-openjdk
|
||||||
|
jvm.arguments=
|
||||||
|
offline.mode=false
|
||||||
|
override.workspace.settings=true
|
||||||
|
show.console.view=true
|
||||||
|
show.executions.view=true
|
||||||
|
@ -12,6 +12,13 @@
|
|||||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
|
<classpathentry kind="src" output="bin/test" path="src/test/java">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="gradle_scope" value="test"/>
|
||||||
|
<attribute name="gradle_used_by_scope" value="test"/>
|
||||||
|
<attribute name="test" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21/"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21/"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||||
<classpathentry kind="output" path="bin/default"/>
|
<classpathentry kind="output" path="bin/default"/>
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
arguments=--init-script /home/oxff/.cache/jdtls/config/org.eclipse.osgi/58/0/.cp/gradle/init/init.gradle
|
arguments=
|
||||||
auto.sync=false
|
auto.sync=false
|
||||||
build.scans.enabled=false
|
build.scans.enabled=false
|
||||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(LOCAL_INSTALLATION(/usr/share/java/gradle))
|
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||||
connection.project.dir=
|
connection.project.dir=..
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
gradle.user.home=
|
gradle.user.home=
|
||||||
java.home=/usr/lib/jvm/java-21-openjdk
|
java.home=
|
||||||
jvm.arguments=
|
jvm.arguments=
|
||||||
offline.mode=false
|
offline.mode=false
|
||||||
override.workspace.settings=true
|
override.workspace.settings=false
|
||||||
show.console.view=true
|
show.console.view=false
|
||||||
show.executions.view=true
|
show.executions.view=false
|
||||||
|
@ -19,9 +19,19 @@ import itmo.lab5.models.Flat;
|
|||||||
import itmo.lab5.parser.Reader;
|
import itmo.lab5.parser.Reader;
|
||||||
import itmo.lab5.cli.helpers.History;
|
import itmo.lab5.cli.helpers.History;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is an entry point of the application that manages a collection of
|
||||||
|
* {@code Flat} objects.
|
||||||
|
* The main method creates REPL that provide ability create or modificate data
|
||||||
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
private static final Logger LOGGER = Logger.getLogger(FileHandler.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(FileHandler.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main method that serves as the entry point for the application.
|
||||||
|
*
|
||||||
|
* @param g_args command-line arguments (not used)
|
||||||
|
*/
|
||||||
public static void main(String[] g_args) {
|
public static void main(String[] g_args) {
|
||||||
Path dataFilePath = null;
|
Path dataFilePath = null;
|
||||||
var history = new History();
|
var history = new History();
|
||||||
@ -37,7 +47,6 @@ public class App {
|
|||||||
.register("remove_key", new RemoveKeyCommand())
|
.register("remove_key", new RemoveKeyCommand())
|
||||||
.register("history", new HistoryCommand())
|
.register("history", new HistoryCommand())
|
||||||
.register("insert", new InsertCommand())
|
.register("insert", new InsertCommand())
|
||||||
.register("update", new UpdateCommand())
|
|
||||||
.register("save", new SaveCommand())
|
.register("save", new SaveCommand())
|
||||||
.register("execute_script", new ExecuteCommand())
|
.register("execute_script", new ExecuteCommand())
|
||||||
.register("print_field_ascending_number_of_rooms", new FieldCommand())
|
.register("print_field_ascending_number_of_rooms", new FieldCommand())
|
||||||
@ -51,7 +60,7 @@ public class App {
|
|||||||
dataFilePath = getDataFileFromEnv("LAB5_DATA");
|
dataFilePath = getDataFileFromEnv("LAB5_DATA");
|
||||||
flats = new Reader().parseCSV(dataFilePath.toFile());
|
flats = new Reader().parseCSV(dataFilePath.toFile());
|
||||||
} catch (IllegalArgumentException | IOException e) {
|
} catch (IllegalArgumentException | IOException e) {
|
||||||
LOGGER.log(Level.WARNING, "There's error while loading file: " + e.getMessage());
|
LOGGER.log(Level.WARNING, "There's error while loading file: {0}", e.getMessage());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,14 +88,22 @@ public class App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the path to the data file from the specified environment variable.
|
||||||
|
*
|
||||||
|
* @param envVariable the name of the environment variable that contains the
|
||||||
|
* file path
|
||||||
|
* @return the path to the data file
|
||||||
|
* @throws IOException if an I/O error happens
|
||||||
|
* @throws IllegalArgumentException if the env variable is not set or invalid
|
||||||
|
*/
|
||||||
public static Path getDataFileFromEnv(String envVariable) throws IOException {
|
public static Path getDataFileFromEnv(String envVariable) throws IOException {
|
||||||
String envPath = System.getenv(envVariable);
|
String envPath = System.getenv(envVariable);
|
||||||
final Path path;
|
final Path path;
|
||||||
|
|
||||||
if (envPath == null || envPath.trim().isEmpty()) {
|
if (envPath == null || envPath.trim().isEmpty())
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Environment variable '" + envVariable + "' is not set or empty.");
|
"Environment variable '" + envVariable + "' is not set or empty.");
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
path = Paths.get(envPath);
|
path = Paths.get(envPath);
|
||||||
@ -97,18 +114,15 @@ public class App {
|
|||||||
ex);
|
ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Files.exists(path)) {
|
if (!Files.exists(path))
|
||||||
throw new IllegalArgumentException("The file at path '" + path + "' does not exist.");
|
throw new IllegalArgumentException("The file at path '" + path + "' does not exist.");
|
||||||
}
|
|
||||||
|
|
||||||
if (!Files.isRegularFile(path)) {
|
if (!Files.isRegularFile(path))
|
||||||
throw new IllegalArgumentException("The path '" + path + "' is not a file. Check twice!");
|
throw new IllegalArgumentException("The path '" + path + "' is not a file. Check twice!");
|
||||||
}
|
|
||||||
|
|
||||||
if (!Files.isReadable(path)) {
|
if (!Files.isReadable(path))
|
||||||
throw new IllegalArgumentException("The file at path '" + path + "' is not readable. " +
|
throw new IllegalArgumentException("The file at path '" + path + "' is not readable. " +
|
||||||
"Check file permissions!");
|
"Check file permissions!");
|
||||||
}
|
|
||||||
|
|
||||||
LOGGER.info("File '" + path + "' exists and is readable.");
|
LOGGER.info("File '" + path + "' exists and is readable.");
|
||||||
return path;
|
return path;
|
||||||
|
@ -2,18 +2,37 @@ package itmo.lab5.cli;
|
|||||||
|
|
||||||
import itmo.lab5.interfaces.Command;
|
import itmo.lab5.interfaces.Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is responsible for constructing a CommandRegistry
|
||||||
|
* which contains all commands
|
||||||
|
*/
|
||||||
public class CommandBuilder {
|
public class CommandBuilder {
|
||||||
private final CommandRegistry registry;
|
private final CommandRegistry registry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new instance, initializing an empty CommandRegistry.
|
||||||
|
*/
|
||||||
public CommandBuilder() {
|
public CommandBuilder() {
|
||||||
this.registry = new CommandRegistry();
|
this.registry = new CommandRegistry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a new command with the specified name in the command registry.
|
||||||
|
*
|
||||||
|
* @param name the name of the command to register
|
||||||
|
* @param newCommand the command instance to be registered
|
||||||
|
* @return the current instance for method chaining
|
||||||
|
*/
|
||||||
public CommandBuilder register(String name, Command newCommand) {
|
public CommandBuilder register(String name, Command newCommand) {
|
||||||
this.registry.register(name, newCommand);
|
this.registry.register(name, newCommand);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds and returns the constructed CommandRegistry containing all registered commands.
|
||||||
|
*
|
||||||
|
* @return the constructed CommandRegistry
|
||||||
|
*/
|
||||||
public CommandRegistry build() {
|
public CommandRegistry build() {
|
||||||
return this.registry;
|
return this.registry;
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,29 @@ package itmo.lab5.cli;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class provides a context for storing and retrieving key-value pairs
|
||||||
|
*/
|
||||||
public class CommandContext {
|
public class CommandContext {
|
||||||
private HashMap<String, Object> data = new HashMap<>();
|
private HashMap<String, Object> data = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores a value associated with the specified key in the context.
|
||||||
|
*
|
||||||
|
* @param key the key under which the value is to be stored
|
||||||
|
* @param value the value to be stored in the context
|
||||||
|
*/
|
||||||
public void set(String key, Object value) {
|
public void set(String key, Object value) {
|
||||||
this.data.put(key, value);
|
this.data.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the value associated with the specified key from the context.
|
||||||
|
*
|
||||||
|
* @param name the key associated with value
|
||||||
|
* @return the value associated with the specified key, or {@code null}
|
||||||
|
* if the key does not exist
|
||||||
|
*/
|
||||||
public Object get(String name) {
|
public Object get(String name) {
|
||||||
return this.data.get(name);
|
return this.data.get(name);
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,37 @@ package itmo.lab5.cli;
|
|||||||
import itmo.lab5.cli.helpers.History;
|
import itmo.lab5.cli.helpers.History;
|
||||||
import itmo.lab5.interfaces.*;
|
import itmo.lab5.interfaces.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes commands from a command registry and maintains command history.
|
||||||
|
*/
|
||||||
public class CommandInvoker {
|
public class CommandInvoker {
|
||||||
|
|
||||||
private final CommandRegistry registry;
|
private final CommandRegistry registry;
|
||||||
private final CommandContext context;
|
private final CommandContext context;
|
||||||
private final History history;
|
private final History history;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a CommandInvoker with the specified command registry,
|
||||||
|
* context, and history.
|
||||||
|
*
|
||||||
|
* @param registry the command registry to retrieve commands from.
|
||||||
|
* @param context the context to be passed to commands during execution.
|
||||||
|
* @param history the history object to track executed commands.
|
||||||
|
*/
|
||||||
public CommandInvoker(CommandRegistry registry, CommandContext context, History history) {
|
public CommandInvoker(CommandRegistry registry, CommandContext context, History history) {
|
||||||
this.registry = registry;
|
this.registry = registry;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.history = history;
|
this.history = history;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a command by its name with the provided arguments.
|
||||||
|
*
|
||||||
|
* @param commandName the name of the command to execute.
|
||||||
|
* @param args an array of arguments to pass to the command.
|
||||||
|
* @return the result of the command execution, or an error message if
|
||||||
|
* the command is unknown or an exception occurs during execution.
|
||||||
|
*/
|
||||||
public String executeCommand(String commandName, String[] args) {
|
public String executeCommand(String commandName, String[] args) {
|
||||||
Command command = registry.getByName(commandName);
|
Command command = registry.getByName(commandName);
|
||||||
if (command != null) {
|
if (command != null) {
|
||||||
|
@ -4,17 +4,40 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import itmo.lab5.interfaces.Command;
|
import itmo.lab5.interfaces.Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages the registration and retrieval of commands.
|
||||||
|
*/
|
||||||
public class CommandRegistry {
|
public class CommandRegistry {
|
||||||
|
|
||||||
private final Map<String, Command> commands = new HashMap<>();
|
private final Map<String, Command> commands = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a new command with the specified name.
|
||||||
|
*
|
||||||
|
* @param name the name of the command to register.
|
||||||
|
* @param newCommand the command instance to register.
|
||||||
|
*/
|
||||||
public void register(String name, Command newCommand) {
|
public void register(String name, Command newCommand) {
|
||||||
this.commands.put(name, newCommand);
|
this.commands.put(name, newCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a command by its name.
|
||||||
|
*
|
||||||
|
* @param name the name of the command to retrieve.
|
||||||
|
* @return the command associated with the specified name, or null
|
||||||
|
* if no command is found.
|
||||||
|
*/
|
||||||
public Command getByName(String name) {
|
public Command getByName(String name) {
|
||||||
return this.commands.get(name);
|
return this.commands.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a map of all registered commands.
|
||||||
|
*
|
||||||
|
* @return a map where the keys are command names and the values are
|
||||||
|
* the corresponding command instances.
|
||||||
|
*/
|
||||||
public Map<String, Command> getAllCommands() {
|
public Map<String, Command> getAllCommands() {
|
||||||
return this.commands;
|
return this.commands;
|
||||||
}
|
}
|
||||||
|
@ -6,18 +6,34 @@ import itmo.lab5.cli.CommandContext;
|
|||||||
import itmo.lab5.interfaces.Command;
|
import itmo.lab5.interfaces.Command;
|
||||||
import itmo.lab5.models.Flat;
|
import itmo.lab5.models.Flat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the Command interface and provides
|
||||||
|
* functionality to clear the collection of Flat objects.
|
||||||
|
*
|
||||||
|
* When executed, this command retrieves the collection from the command context
|
||||||
|
* and removes all items from it, effectively emptying the collection.
|
||||||
|
*/
|
||||||
public class ClearCommand implements Command {
|
public class ClearCommand implements Command {
|
||||||
@Override
|
|
||||||
public String execute(String args[], CommandContext context) {
|
|
||||||
var collection = new HashMap<Integer, Flat>();
|
|
||||||
|
|
||||||
try {
|
/**
|
||||||
collection = (HashMap<Integer, Flat>) context.get("collection");
|
* Executes the clear command, removing all items from the collection
|
||||||
} catch (ClassCastException e) {
|
* of flats.
|
||||||
return "Can't clear collection. It might be missed";
|
*
|
||||||
|
* @param args an array of arguments passed to the command
|
||||||
|
* @param context the command context that contains the collection of flats
|
||||||
|
* @return a message indicating the result of the operation, or an error message if the collection cannot be parsed
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String execute(String args[], CommandContext context) {
|
||||||
|
var collection = new HashMap<Integer, Flat>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
collection = (HashMap<Integer, Flat>) context.get("collection");
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
return "Can't clear collection. It might be missed.";
|
||||||
|
}
|
||||||
|
|
||||||
|
collection.clear();
|
||||||
|
return "Collection was successfully cleared!";
|
||||||
}
|
}
|
||||||
|
|
||||||
collection.clear();
|
|
||||||
return "Collection was successfuly cleared!";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -10,52 +10,68 @@ import itmo.lab5.cli.CommandInvoker;
|
|||||||
import itmo.lab5.cli.CommandContext;
|
import itmo.lab5.cli.CommandContext;
|
||||||
import itmo.lab5.interfaces.*;
|
import itmo.lab5.interfaces.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the Command} interface and provides
|
||||||
|
* functionality to execute a script file containing a series of commands.
|
||||||
|
*
|
||||||
|
* When executed, this command reads commands from the specified script file and
|
||||||
|
* executes them sequentially. It also checks for recursive script execution
|
||||||
|
* to prevent infinite loops.
|
||||||
|
*/
|
||||||
public class ExecuteCommand implements Command {
|
public class ExecuteCommand implements Command {
|
||||||
private static final Set<String> executingScripts = new HashSet<String>();
|
private static final Set<String> executingScripts = new HashSet<String>();
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public String execute(String args[], CommandContext context) {
|
* Executes the script command, running the commands specified in the given
|
||||||
if (args.length < 1) {
|
* script file.
|
||||||
return "Usage: execute_script <file_name>";
|
*
|
||||||
}
|
* @param args an array of arguments passed to the command, where the first element is expected to be the name of the script file
|
||||||
|
* @param context the command context that contains the command invoker
|
||||||
String fileName = args[0];
|
* @return a string containing the output of the executed commands, or an error message if the script file cannot be found or executed
|
||||||
File scriptFile = new File(fileName);
|
*/
|
||||||
|
@Override
|
||||||
if (executingScripts.contains(scriptFile.getAbsolutePath())) {
|
public String execute(String args[], CommandContext context) {
|
||||||
return "Error: Recursive script execution detected for file: " + fileName;
|
if (args.length < 1) {
|
||||||
}
|
return "Usage: execute_script <file_name>";
|
||||||
|
|
||||||
executingScripts.add(scriptFile.getAbsolutePath());
|
|
||||||
|
|
||||||
try (Scanner fileScanner = new Scanner(scriptFile)) {
|
|
||||||
CommandInvoker commandInvoker = (CommandInvoker) context.get("commandInvoker");
|
|
||||||
StringBuilder output = new StringBuilder();
|
|
||||||
|
|
||||||
while (fileScanner.hasNextLine()) {
|
|
||||||
String line = fileScanner.nextLine().trim();
|
|
||||||
if (line.isEmpty() || line.startsWith("#")) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
String fileName = args[0];
|
||||||
String[] parts = line.split(" ", 2);
|
File scriptFile = new File(fileName);
|
||||||
String commandName = parts[0];
|
|
||||||
String[] commandArgs = parts.length > 1 ? parts[1].split(" ") : new String[0];
|
|
||||||
|
|
||||||
String result = commandInvoker.executeCommand(commandName, commandArgs);
|
if (executingScripts.contains(scriptFile.getAbsolutePath())) {
|
||||||
output.append("> ").append(line).append("\n").append(result).append("\n");
|
return "Error: Recursive script execution detected for file: " + fileName;
|
||||||
} catch (Exception e) {
|
|
||||||
output.append("Error executing command '").append(line).append("': ")
|
|
||||||
.append(e.getMessage()).append("\n");
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return output.toString();
|
executingScripts.add(scriptFile.getAbsolutePath());
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
return "Error: Script file not found: " + fileName;
|
try (Scanner fileScanner = new Scanner(scriptFile)) {
|
||||||
} finally {
|
CommandInvoker commandInvoker = (CommandInvoker) context.get("commandInvoker");
|
||||||
executingScripts.remove(scriptFile.getAbsolutePath());
|
StringBuilder output = new StringBuilder();
|
||||||
|
|
||||||
|
while (fileScanner.hasNextLine()) {
|
||||||
|
String line = fileScanner.nextLine().trim();
|
||||||
|
if (line.isEmpty() || line.startsWith("#")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
String[] parts = line.split(" ", 2);
|
||||||
|
String commandName = parts[0];
|
||||||
|
String[] commandArgs = parts.length > 1 ? parts[1].split(" ") : new String[0];
|
||||||
|
|
||||||
|
String result = commandInvoker.executeCommand(commandName, commandArgs);
|
||||||
|
output.append("> ").append(line).append("\n").append(result).append("\n");
|
||||||
|
} catch (Exception e) {
|
||||||
|
output.append("Error executing command '").append(line).append("': ")
|
||||||
|
.append(e.getMessage()).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output.toString();
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
return "Error: Script file not found: " + fileName;
|
||||||
|
} finally {
|
||||||
|
executingScripts.remove(scriptFile.getAbsolutePath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,24 @@ package itmo.lab5.cli.commands;
|
|||||||
import itmo.lab5.cli.CommandContext;
|
import itmo.lab5.cli.CommandContext;
|
||||||
import itmo.lab5.interfaces.Command;
|
import itmo.lab5.interfaces.Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the Command interface and provides
|
||||||
|
* functionality to terminate the application.
|
||||||
|
*
|
||||||
|
* When called, main loop will immediately stop.
|
||||||
|
*/
|
||||||
public class ExitCommand implements Command {
|
public class ExitCommand implements Command {
|
||||||
@Override
|
|
||||||
public String execute(String[] args, CommandContext context) {
|
/**
|
||||||
System.exit(0);
|
* Executes the exit command, terminating the application.
|
||||||
return "";
|
*
|
||||||
}
|
* @param args an array of arguments passed to the command
|
||||||
|
* @param context the command context that may contain additional data
|
||||||
|
* @return an empty string
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String execute(String[] args, CommandContext context) {
|
||||||
|
System.exit(0);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
@ -7,7 +7,25 @@ import itmo.lab5.models.Flat;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a command that processes a collection of Flat objects.
|
||||||
|
* This command sorts the flats by the number of rooms and prints the sorted
|
||||||
|
* entries.
|
||||||
|
*
|
||||||
|
* Implements the Command interface.
|
||||||
|
*/
|
||||||
public class FieldCommand implements Command {
|
public class FieldCommand implements Command {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the command, sorting and displaying the flats from the provided
|
||||||
|
* collection.
|
||||||
|
*
|
||||||
|
* @param args an array of arguments passed to the command.
|
||||||
|
* @param context the context containing the collection of flats to be processed.
|
||||||
|
* @return a message indicating the result of the execution. If the collection is empty,
|
||||||
|
* it returns "Nothing to show!". If the collection cannot be parsed, it returns
|
||||||
|
* "Can't parse collection!".
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String execute(String args[], CommandContext context) {
|
public String execute(String args[], CommandContext context) {
|
||||||
var collection = new HashMap<Integer, Flat>();
|
var collection = new HashMap<Integer, Flat>();
|
||||||
@ -18,18 +36,17 @@ public class FieldCommand implements Command {
|
|||||||
return "Can't parse collection!";
|
return "Can't parse collection!";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collection.isEmpty() || collection.size() == 0) {
|
if (collection.isEmpty()) {
|
||||||
return "Nothing to show!";
|
return "Nothing to show!";
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Map.Entry<Integer, Flat>> sortedEntries = collection.entrySet().stream()
|
var sortedEntries = collection.entrySet().stream()
|
||||||
.sorted(Comparator.comparingInt(entry -> entry.getValue().getNumberOfRooms()))
|
.sorted(Comparator.comparingInt(entry -> entry.getValue().getNumberOfRooms()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
sortedEntries.forEach(entry -> {
|
sortedEntries.forEach(entry ->
|
||||||
System.out.println("Key: " + entry.getKey() +
|
System.out.println("Key: " + entry.getKey() +
|
||||||
", Rooms: " + entry.getValue().getNumberOfRooms());
|
", Rooms: " + entry.getValue().getNumberOfRooms()));
|
||||||
});
|
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,38 @@ import java.util.HashMap;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a command that filters a collection of {@link Flat} objects
|
||||||
|
* based on a specified classificator and a threshold value.
|
||||||
|
*
|
||||||
|
* Implements the Command interface.
|
||||||
|
*/
|
||||||
public class FilterCommand implements Command {
|
public class FilterCommand implements Command {
|
||||||
private String classificator;
|
private String classificator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a FilterCommand with the specified classificator.
|
||||||
|
*
|
||||||
|
* @param classificator the type of filtering to apply ("less" or "greater").
|
||||||
|
*/
|
||||||
|
public FilterCommand(String classificator) {
|
||||||
|
this.classificator = classificator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the command, filtering and displaying the flats from the
|
||||||
|
* provided collection based on the threshold value.
|
||||||
|
*
|
||||||
|
* @param args an array of arguments where the first element is the
|
||||||
|
* threshold value for filtering.
|
||||||
|
* @param context the context containing the collection of flats to be
|
||||||
|
* processed.
|
||||||
|
* @return a message indicating the result of the execution. If no
|
||||||
|
* classificator is provided, it returns "There's no
|
||||||
|
* classificator provided!". If the collection cannot be parsed,
|
||||||
|
* it returns "Can't parse collection!". If the collection is
|
||||||
|
* empty or the threshold is null, it returns "Nothing to show!".
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String execute(String args[], CommandContext context) {
|
public String execute(String args[], CommandContext context) {
|
||||||
if (args.length < 1)
|
if (args.length < 1)
|
||||||
@ -22,36 +51,32 @@ public class FilterCommand implements Command {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
collection = (HashMap<Integer, Flat>) context.get("collection");
|
collection = (HashMap<Integer, Flat>) context.get("collection");
|
||||||
threshold = Integer.parseInt(args[0]);
|
threshold = Integer.valueOf(args[0]);
|
||||||
} catch (ClassCastException e) {
|
} catch (ClassCastException e) {
|
||||||
return "Can't parse collection!";
|
return "Can't parse collection!";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collection.isEmpty() || collection.size() == 0 || threshold == null) {
|
if (collection.isEmpty() || threshold == null)
|
||||||
return "Nothing to show!";
|
return "Nothing to show!";
|
||||||
}
|
|
||||||
|
|
||||||
final int finalThreshold = threshold;
|
final int finalThreshold = threshold;
|
||||||
if (classificator == "less") {
|
if (classificator.equals("less")) {
|
||||||
result = collection.values().stream()
|
result = collection.values().stream()
|
||||||
.filter(flat -> flat.getView() != null && flat.getView().ordinal() < finalThreshold)
|
.filter(flat -> flat.getView() != null &&
|
||||||
|
flat.getView().ordinal() < finalThreshold)
|
||||||
.sorted(Comparator.comparingInt(flat -> flat.getView().ordinal()))
|
.sorted(Comparator.comparingInt(flat -> flat.getView().ordinal()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
} else {
|
} else {
|
||||||
result = collection.values().stream()
|
result = collection.values().stream()
|
||||||
.filter(flat -> flat.getView() != null && flat.getView().ordinal() > finalThreshold)
|
.filter(flat -> flat.getView() != null &&
|
||||||
|
flat.getView().ordinal() > finalThreshold)
|
||||||
.sorted(Comparator.comparingInt(flat -> flat.getView().ordinal()))
|
.sorted(Comparator.comparingInt(flat -> flat.getView().ordinal()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
result.forEach(entry -> {
|
result.forEach(entry -> System.out.println(entry));
|
||||||
System.out.println(entry);
|
|
||||||
});
|
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public FilterCommand(String classificator) {
|
|
||||||
this.classificator = classificator;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,25 +4,40 @@ import itmo.lab5.cli.CommandContext;
|
|||||||
import itmo.lab5.cli.CommandRegistry;
|
import itmo.lab5.cli.CommandRegistry;
|
||||||
import itmo.lab5.interfaces.Command;
|
import itmo.lab5.interfaces.Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the Command interface and provides
|
||||||
|
* functionality to display a list of available commands in the application.
|
||||||
|
*
|
||||||
|
* When executed, this command retrieves the command registry from the context
|
||||||
|
* and constructs a string that lists all registered commands.
|
||||||
|
* If no commands are available, it informs user.
|
||||||
|
*/
|
||||||
public class HelpCommand implements Command {
|
public class HelpCommand implements Command {
|
||||||
@Override
|
|
||||||
public String execute(String args[], CommandContext context) {
|
|
||||||
var registry = (CommandRegistry) context.get("registry");
|
|
||||||
StringBuilder result = new StringBuilder();
|
|
||||||
|
|
||||||
if (registry == null) {
|
/**
|
||||||
result.append("There aren't any avaliable commands!");
|
* Executes the help command, returning a list of available commands.
|
||||||
return result.toString();
|
*
|
||||||
|
* @param args an array of arguments passed to the command
|
||||||
|
* @param context the command context that contains the command registry
|
||||||
|
* @return a string listing all available commands, or a message indicating that no commands are available
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String execute(String args[], CommandContext context) {
|
||||||
|
var registry = (CommandRegistry) context.get("registry");
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
|
||||||
|
if (null == registry) {
|
||||||
|
result.append("There aren't any available commands!");
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
result.append("List of available commands: ");
|
||||||
|
registry.getAllCommands().keySet().forEach(command ->
|
||||||
|
result.append(command).append(", "));
|
||||||
|
|
||||||
|
return result
|
||||||
|
.delete(result.length() - 2, result.length())
|
||||||
|
.append(".")
|
||||||
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append("List of avaliable commands: ");
|
|
||||||
for (String command : registry.getAllCommands().keySet()) {
|
|
||||||
result.append(command + ", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
.delete(result.length() - 2, result.length())
|
|
||||||
.append(".")
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,20 +4,37 @@ import itmo.lab5.cli.CommandContext;
|
|||||||
import itmo.lab5.interfaces.Command;
|
import itmo.lab5.interfaces.Command;
|
||||||
import itmo.lab5.cli.helpers.*;
|
import itmo.lab5.cli.helpers.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the Command interface and provides
|
||||||
|
* functionality to display the command history of the application.
|
||||||
|
*
|
||||||
|
* When executed, this command retrieves the history from the command context
|
||||||
|
* and returns a string representation of the command history. If the history is
|
||||||
|
* null or cannot be parsed, an appropriate error message is returned.
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class HistoryCommand implements Command {
|
public class HistoryCommand implements Command {
|
||||||
@Override
|
|
||||||
public String execute(String args[], CommandContext context) {
|
|
||||||
var history = new History();
|
|
||||||
|
|
||||||
try {
|
/**
|
||||||
history = (History) context.get("history");
|
* Executes the history command, returning latest 8 (by design).
|
||||||
} catch (ClassCastException e) {
|
*
|
||||||
return "There's problem with history. It might be null :(";
|
* @param args an array of arguments passed to the command
|
||||||
|
* @param context the command context that contains the history of commands
|
||||||
|
* @return a string representation of the command history, or an error message if the history cannot be parsed
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String execute(String args[], CommandContext context) {
|
||||||
|
var history = new History();
|
||||||
|
|
||||||
|
try {
|
||||||
|
history = (History) context.get("history");
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
return "There's a problem with history. It might be null :(";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null == history)
|
||||||
|
return "We reach the end of history. Somewhere in the world, one Fukuyama is rejoicing :_)";
|
||||||
|
|
||||||
|
return history.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (history == null)
|
|
||||||
return "We reach End of History. Somewhere in the world, one Fukuyama is rejoicing :_)";
|
|
||||||
|
|
||||||
return history.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -5,26 +5,40 @@ import itmo.lab5.cli.CommandContext;
|
|||||||
import itmo.lab5.interfaces.Command;
|
import itmo.lab5.interfaces.Command;
|
||||||
import itmo.lab5.models.Flat;
|
import itmo.lab5.models.Flat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the Command interface and provides
|
||||||
|
* functionality to display information about the collection.
|
||||||
|
*
|
||||||
|
* When executed, this command retrieves the collection from the command context
|
||||||
|
* and returns details about the collection, including its type, the type of its
|
||||||
|
* items, and the number of items.
|
||||||
|
*/
|
||||||
public class InfoCommand implements Command {
|
public class InfoCommand implements Command {
|
||||||
@Override
|
/**
|
||||||
public String execute(String args[], CommandContext context) {
|
* Executes the info command, returning information about the collection of
|
||||||
var flats = new HashMap<Integer, Flat>();
|
* flats.
|
||||||
|
*
|
||||||
|
* @param args an array of arguments passed to the command
|
||||||
|
* @param context the command context that contains the collection of flats
|
||||||
|
* @return a string containing information about the collection, or an error message if the collection cannot be parsed
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String execute(String args[], CommandContext context) {
|
||||||
|
var flats = new HashMap<Integer, Flat>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
flats = (HashMap<Integer, Flat>) context.get("collection");
|
flats = (HashMap<Integer, Flat>) context.get("collection");
|
||||||
} catch (ClassCastException e) {
|
} catch (ClassCastException e) {
|
||||||
return "Can't parse collection. Something goes wrong!";
|
return "Can't parse collection. Something goes wrong!";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null == flats || flats.isEmpty())
|
||||||
|
return "Collection is empty now!";
|
||||||
|
|
||||||
|
var anyFlat = flats.values().iterator().next();
|
||||||
|
|
||||||
|
return ("Collections stores in: Information about collection: " + flats.getClass().getName() + "\n" +
|
||||||
|
"Collection consists of: " + anyFlat.getClass().getName() + "\n" +
|
||||||
|
"Items: " + flats.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flats == null || flats.isEmpty()) {
|
|
||||||
return "Collection is empty now!";
|
|
||||||
}
|
|
||||||
|
|
||||||
var anyFlat = flats.values().iterator().next();
|
|
||||||
|
|
||||||
return ("Information about collection: \n" +
|
|
||||||
"Collections stores in: " + flats.getClass().getName() + "\n" +
|
|
||||||
"Collection consists of: " + anyFlat.getClass().getName() + "\n" +
|
|
||||||
"Items: " + flats.size());
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,10 +1,8 @@
|
|||||||
package itmo.lab5.cli.commands;
|
package itmo.lab5.cli.commands;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import itmo.lab5.cli.helpers.*;
|
import itmo.lab5.cli.helpers.*;
|
||||||
import itmo.lab5.cli.CommandContext;
|
import itmo.lab5.cli.CommandContext;
|
||||||
@ -12,84 +10,115 @@ import itmo.lab5.interfaces.Command;
|
|||||||
import itmo.lab5.models.enums.*;
|
import itmo.lab5.models.enums.*;
|
||||||
import itmo.lab5.models.*;
|
import itmo.lab5.models.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the Command interface and provides
|
||||||
|
* functionality to insert a new Flat object into the collection.
|
||||||
|
*
|
||||||
|
* This command can be executed in two modes: interactively, where the user is
|
||||||
|
* prompted for input, or with command-line arguments, where parameters are
|
||||||
|
* passed as key-value pairs. The command gathers all necessary information to
|
||||||
|
* create a new flat and adds it to the collection.
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class InsertCommand implements Command {
|
public class InsertCommand implements Command {
|
||||||
private final Scanner scanner = new Scanner(System.in);
|
private final Scanner scanner = new Scanner(System.in);
|
||||||
private final ReaderUtil inputReader = new ReaderUtil(scanner);
|
private final ReaderUtil inputReader = new ReaderUtil(scanner);
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public String execute(String[] args, CommandContext context) {
|
* Executes the insert command, either interactively or with provided
|
||||||
if (args.length == 0) {
|
* arguments.
|
||||||
return executeInteractive(context);
|
*
|
||||||
|
* @param args an array of arguments passed to the command; if empty, the command will execute interactively
|
||||||
|
* @param context the command context that contains the collection of flats
|
||||||
|
* @return a message indicating the result of the operation, or an error message if the collection cannot be parsed
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String execute(String[] args, CommandContext context) {
|
||||||
|
if (args.length == 0)
|
||||||
|
return executeInteractive(context);
|
||||||
|
|
||||||
|
return executeWithArgs(args, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return executeWithArgs(args, context);
|
/**
|
||||||
}
|
* Executes the insert command interactively, prompting the user for input
|
||||||
|
* to create a new flat.
|
||||||
|
*
|
||||||
|
* @param context the command context that contains the collection of flats
|
||||||
|
* @return a message indicating the result of the operation
|
||||||
|
*/
|
||||||
|
private String executeInteractive(CommandContext context) {
|
||||||
|
Date creationDate = new Date();
|
||||||
|
String name = inputReader.promptString("- Enter name: ", false, null);
|
||||||
|
|
||||||
private String executeInteractive(CommandContext context) {
|
System.out.println("- Coordinates ");
|
||||||
Date creationDate = new Date();
|
int x = inputReader.promptNumber("\t Enter x: ", Integer.MIN_VALUE, Integer.MAX_VALUE, Integer::parseInt, null);
|
||||||
String name = inputReader.promptString("- Enter name: ", false, null);
|
Long y = inputReader.promptNumber("\t Enter y: ", Long.MIN_VALUE, Long.MAX_VALUE, Long::parseLong, null);
|
||||||
|
var coordinates = new Coordinates(x, y);
|
||||||
|
|
||||||
System.out.println("- Coordinates ");
|
Double area = inputReader.promptNumber("\t Enter square: ", 0.0, 626.0, Double::parseDouble, null);
|
||||||
int x = inputReader.promptNumber("\t Enter x: ", Integer.MIN_VALUE, Integer.MAX_VALUE, Integer::parseInt, null);
|
int numberOfRooms = inputReader.promptNumber("\t Enter rooms count: ", 1, Integer.MAX_VALUE, Integer::parseInt, null);
|
||||||
Long y = inputReader.promptNumber("\t Enter y: ", Long.MIN_VALUE, Long.MAX_VALUE, Long::parseLong, null);
|
|
||||||
var coordinates = new Coordinates(x, y);
|
|
||||||
|
|
||||||
Double area = inputReader.promptNumber("\t Enter square: ", 0.0, 626.0, Double::parseDouble, null);
|
System.out.println("- Furnish");
|
||||||
int numberOfRooms = inputReader.promptNumber("\t Enter rooms count: ", 1, Integer.MAX_VALUE, Integer::parseInt,
|
Furnish furnish = inputReader.promptEnum("\t Enter furnish type: ", Furnish.class, null);
|
||||||
null);
|
|
||||||
|
|
||||||
System.out.println("- Furnish");
|
System.out.println("- View");
|
||||||
Furnish furnish = inputReader.promptEnum("\t Enter furnish type: ", Furnish.class, null);
|
View view = inputReader.promptEnumNullable("\t Enter view type: ", View.class, null);
|
||||||
|
|
||||||
System.out.println("- View");
|
System.out.println("- Transport");
|
||||||
View view = inputReader.promptEnumNullable("\t Enter view type: ", View.class, null);
|
Transport transport = inputReader.promptEnum("\t Enter transport type: ", Transport.class, null);
|
||||||
|
|
||||||
System.out.println("- Transport");
|
System.out.println("- House");
|
||||||
Transport transport = inputReader.promptEnum("\t Enter transport type: ", Transport.class, null);
|
System.out.print("\t Enter house name: ");
|
||||||
|
String houseName = scanner.nextLine().trim();
|
||||||
|
|
||||||
System.out.println("- House");
|
House house = null;
|
||||||
System.out.print("\t Enter house name: ");
|
|
||||||
String houseName = scanner.nextLine().trim();
|
|
||||||
|
|
||||||
House house = null;
|
if (!houseName.isEmpty()) {
|
||||||
|
int year = inputReader.promptNumber("\t Enter house age: ", 1, 959, Integer::parseInt, null);
|
||||||
|
long floors = inputReader.promptNumber("\t Enter house floors count: ", 1L, 77L, Long::parseLong, null);
|
||||||
|
house = new House(houseName, year, floors);
|
||||||
|
}
|
||||||
|
|
||||||
if (!houseName.isEmpty()) {
|
try {
|
||||||
int year = inputReader.promptNumber("\t Enter house age: ", 1, 959, Integer::parseInt, null);
|
HashMap<Integer, Flat> collection = (HashMap<Integer, Flat>) context.get("collection");
|
||||||
long floors = inputReader.promptNumber("\t Enter house floors count: ", 1L, 77L, Long::parseLong, null);
|
int newID = collection.size() + 1;
|
||||||
house = new House(houseName, year, floors);
|
Flat flat = new Flat(
|
||||||
|
newID,
|
||||||
|
name,
|
||||||
|
coordinates,
|
||||||
|
creationDate,
|
||||||
|
area,
|
||||||
|
numberOfRooms,
|
||||||
|
furnish,
|
||||||
|
view,
|
||||||
|
transport,
|
||||||
|
house);
|
||||||
|
|
||||||
|
collection.put(newID, flat);
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
return "There's an error while trying to add new element. Collection is broken.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "New flat was successfully inserted!";
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
/**
|
||||||
HashMap<Integer, Flat> collection = (HashMap<Integer, Flat>) context.get("collection");
|
* Executes the insert command with provided arguments, creating a new flat
|
||||||
int newID = collection.size() + 1;
|
* based on the key-value pairs.
|
||||||
Flat flat = new Flat(
|
*
|
||||||
newID,
|
* @param args an array of arguments passed to the command
|
||||||
name,
|
* @param context the command context that contains the collection of flats
|
||||||
coordinates,
|
* @return a message indicating the result of the operation
|
||||||
creationDate,
|
*/
|
||||||
area,
|
|
||||||
numberOfRooms,
|
|
||||||
furnish,
|
|
||||||
view,
|
|
||||||
transport,
|
|
||||||
house);
|
|
||||||
|
|
||||||
collection.put(newID, flat);
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
return "There's an error while trying to add new element. Collection is broken.";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "New flat was successfully inserted!";
|
|
||||||
}
|
|
||||||
|
|
||||||
private String executeWithArgs(String[] args, CommandContext context) {
|
private String executeWithArgs(String[] args, CommandContext context) {
|
||||||
HashMap<String, String> params = new HashMap<>();
|
HashMap<String, String> params = new HashMap<>();
|
||||||
|
|
||||||
for (String arg : args) {
|
for (String arg : args) {
|
||||||
String[] parts = arg.split("=", 2);
|
String[] parts = arg.split("=", 2);
|
||||||
if (parts.length == 2) {
|
|
||||||
|
if (parts.length == 2)
|
||||||
params.put(parts[0], parts[1]);
|
params.put(parts[0], parts[1]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Date creationDate = new Date();
|
Date creationDate = new Date();
|
||||||
@ -194,10 +223,10 @@ public class InsertCommand implements Command {
|
|||||||
public static <E extends Enum<E>> boolean isValidEnumValue(Class<E> enumClass, String value) {
|
public static <E extends Enum<E>> boolean isValidEnumValue(Class<E> enumClass, String value) {
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (E constant : enumClass.getEnumConstants()) {
|
for (E constant : enumClass.getEnumConstants()) {
|
||||||
if (constant.name().equals(value)) {
|
if (constant.name().equals(value))
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -6,34 +6,51 @@ import itmo.lab5.cli.CommandContext;
|
|||||||
import itmo.lab5.interfaces.Command;
|
import itmo.lab5.interfaces.Command;
|
||||||
import itmo.lab5.models.Flat;
|
import itmo.lab5.models.Flat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the Command interface and provides
|
||||||
|
* functionality to remove a object from the collection based on its ID.
|
||||||
|
*
|
||||||
|
* When executed, this command retrieves the collection from the command
|
||||||
|
* context, checks for the specified ID in the arguments, and removes
|
||||||
|
* the corresponding object if it exists. If the ID is invalid
|
||||||
|
* or the collection is empty, appropriate error messages are returned.
|
||||||
|
*/
|
||||||
public class RemoveKeyCommand implements Command {
|
public class RemoveKeyCommand implements Command {
|
||||||
@Override
|
|
||||||
public String execute(String args[], CommandContext context) {
|
|
||||||
HashMap<Integer, Flat> flats = new HashMap<Integer, Flat>();
|
|
||||||
Integer idToDelete = null;
|
|
||||||
|
|
||||||
try {
|
/**
|
||||||
flats = (HashMap<Integer, Flat>) context.get("collection");
|
* Executes the remove key command, deleting a flat by ID.
|
||||||
} catch (ClassCastException e) {
|
*
|
||||||
return "There's a problem with collection parsing";
|
* @param args an array of arguments passed to the command, where the first element is expected to be the ID of the flat to remove
|
||||||
|
* @param context the command context that contains the collection of flats
|
||||||
|
* @return a message indicating the result of the operation, or an error message if the collection cannot be parsed or the ID is invalid
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String execute(String args[], CommandContext context) {
|
||||||
|
HashMap<Integer, Flat> flats = new HashMap<>();
|
||||||
|
Integer idToDelete = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
flats = (HashMap<Integer, Flat>) context.get("collection");
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
return "There's a problem with collection parsing.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flats == null)
|
||||||
|
return "Collection is empty. Can't delete anything :(";
|
||||||
|
|
||||||
|
try {
|
||||||
|
idToDelete = Integer.valueOf(args[0]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return "You provided a mistyped argument!";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idToDelete < 0)
|
||||||
|
return "Check argument's value twice.";
|
||||||
|
|
||||||
|
if (!flats.containsKey(idToDelete))
|
||||||
|
return "Can't find flat with such ID.";
|
||||||
|
|
||||||
|
flats.remove(idToDelete);
|
||||||
|
return "Successfully deleted flat!";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flats == null)
|
|
||||||
return "Collection is empty. Can't delete anything :(";
|
|
||||||
|
|
||||||
try {
|
|
||||||
idToDelete = Integer.parseInt(args[0]);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return "You provide misstyped argument!";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (idToDelete == null)
|
|
||||||
return "Check argument's value twice";
|
|
||||||
|
|
||||||
if (!flats.containsKey(idToDelete))
|
|
||||||
return "Can't find flat with such id";
|
|
||||||
|
|
||||||
flats.remove(idToDelete);
|
|
||||||
return "Successfuly deleted flat!";
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -2,50 +2,223 @@ package itmo.lab5.cli.commands;
|
|||||||
|
|
||||||
import itmo.lab5.cli.CommandContext;
|
import itmo.lab5.cli.CommandContext;
|
||||||
import itmo.lab5.interfaces.*;
|
import itmo.lab5.interfaces.*;
|
||||||
import itmo.lab5.models.Flat;
|
import itmo.lab5.models.*;
|
||||||
|
import itmo.lab5.models.enums.*;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a command that replaces a flat in a collection based on a
|
||||||
|
* specified classificator ("greater" or "lower") and a given id.
|
||||||
|
*
|
||||||
|
* Implements the {@link Command} interface.
|
||||||
|
*/
|
||||||
public class ReplaceCommand implements Command {
|
public class ReplaceCommand implements Command {
|
||||||
private String classificator;
|
|
||||||
|
|
||||||
|
private final String classificator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a ReplaceCommand with the specified classificator.
|
||||||
|
*
|
||||||
|
* @param classificator the type of comparison for replacement, must be
|
||||||
|
* either "greater" or "lower".
|
||||||
|
* @throws IllegalArgumentException if the classificator is not valid.
|
||||||
|
*/
|
||||||
public ReplaceCommand(String classificator) {
|
public ReplaceCommand(String classificator) {
|
||||||
this.classificator = classificator;
|
if (!classificator.equalsIgnoreCase("greater") &&
|
||||||
|
!classificator.equalsIgnoreCase("lower")) {
|
||||||
|
throw new IllegalArgumentException("Classificator must be either " +
|
||||||
|
"'greater' or 'lower'");
|
||||||
|
}
|
||||||
|
this.classificator = classificator.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the command, replacing a flat in the collection if the
|
||||||
|
* specified condition is met.
|
||||||
|
*
|
||||||
|
* @param args an array of arguments where the first element is the id
|
||||||
|
* of the flat to be replaced, followed by optional parameters
|
||||||
|
* for the new flat.
|
||||||
|
*
|
||||||
|
* @param context the context containing the collection of flats to be
|
||||||
|
* processed.
|
||||||
|
*
|
||||||
|
* @return a message indicating the result of the execution. If no
|
||||||
|
* arguments are provided, it returns "No arguments provided.".
|
||||||
|
* If the id format is invalid, it returns "Invalid id format.".
|
||||||
|
* If the collection cannot be parsed, it returns "Collection is
|
||||||
|
* corrupted or not found in context.". If the flat with the
|
||||||
|
* specified id does not exist, it returns "No element with id
|
||||||
|
* {id}". If the flat is successfully replaced, it returns a
|
||||||
|
* success message; otherwise, it indicates that the condition
|
||||||
|
* for replacement was not met.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String execute(String args[], CommandContext context) {
|
public String execute(String[] args, CommandContext context) {
|
||||||
var collection = new HashMap<Integer, Flat>();
|
if (args.length == 0)
|
||||||
int idToUpdate;
|
return "No arguments provided.";
|
||||||
|
|
||||||
|
int id;
|
||||||
|
try {
|
||||||
|
id = Integer.parseInt(args[0]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return "Invalid id format.";
|
||||||
|
}
|
||||||
|
|
||||||
|
HashMap<Integer, Flat> collection;
|
||||||
|
try {
|
||||||
|
collection = (HashMap<Integer, Flat>) context.get("collection");
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
return "Collection is corrupted or not found in context.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!collection.containsKey(id))
|
||||||
|
return "No element with id " + id;
|
||||||
|
|
||||||
|
Flat oldFlat = collection.get(id);
|
||||||
|
Flat updatedFlat = buildFlatFromArgs(args, oldFlat);
|
||||||
|
|
||||||
|
if (updatedFlat == null)
|
||||||
|
return "Failed to create a new flat from arguments.";
|
||||||
|
|
||||||
|
int result = compareFlats(updatedFlat, oldFlat);
|
||||||
|
boolean shouldReplace = classificator.equals("greater") ? result > 0 : result < 0;
|
||||||
|
|
||||||
|
if (shouldReplace) {
|
||||||
|
collection.put(id, updatedFlat);
|
||||||
|
return "Flat with id " + id + " was replaced.";
|
||||||
|
} else {
|
||||||
|
return "Flat was not replaced: condition not met.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a new Flat object from the provided arguments, using the
|
||||||
|
* existing flat's properties as defaults.
|
||||||
|
*
|
||||||
|
* @param args an array of arguments containing the new flat's properties.
|
||||||
|
* @param oldFlat the existing flat to use as a reference for default values.
|
||||||
|
* @return a new Flat object or null if the creation fails.
|
||||||
|
*/
|
||||||
|
private Flat buildFlatFromArgs(String[] args, Flat oldFlat) {
|
||||||
HashMap<String, String> params = new HashMap<>();
|
HashMap<String, String> params = new HashMap<>();
|
||||||
|
|
||||||
for (String arg : args) {
|
for (String arg : args) {
|
||||||
String[] parts = arg.split("=", 2);
|
String[] parts = arg.split("=", 2);
|
||||||
|
|
||||||
if (parts.length == 2)
|
if (parts.length == 2)
|
||||||
params.put(parts[0], parts[1]);
|
params.put(parts[0], parts[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.length < 1)
|
|
||||||
return "Can't get value without id!";
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
collection = (HashMap<Integer, Flat>) context.get("collection");
|
String name = params.getOrDefault("name", oldFlat.getName());
|
||||||
} catch (ClassCastException e) {
|
|
||||||
return "Can't parse collection!";
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
Coordinates coordinates = oldFlat.getCoordinates();
|
||||||
idToUpdate = Integer.parseInt(args[0]);
|
if (params.containsKey("x") || params.containsKey("y")) {
|
||||||
|
int x = params.containsKey("x") ? Integer.parseInt(params.get("x")) : coordinates.getX();
|
||||||
|
long y = params.containsKey("y") ? Long.parseLong(params.get("y")) : coordinates.getY();
|
||||||
|
coordinates = new Coordinates(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Double area = params.containsKey("area") ? Double.parseDouble(params.get("area")) : oldFlat.getArea();
|
||||||
|
int numberOfRooms = params.containsKey("numberOfRooms") ? Integer.parseInt(params.get("numberOfRooms"))
|
||||||
|
: oldFlat.getNumberOfRooms();
|
||||||
|
Furnish furnish = params.containsKey("furnish") ? Furnish.valueOf(params.get("furnish").toUpperCase())
|
||||||
|
: oldFlat.getFurnish();
|
||||||
|
View view = params.containsKey("view") ? View.valueOf(params.get("view").toUpperCase()) : oldFlat.getView();
|
||||||
|
Transport transport = params.containsKey("transport") ? Transport.valueOf(params.get("transport").toUpperCase())
|
||||||
|
: oldFlat.getTransport();
|
||||||
|
|
||||||
|
House house = oldFlat.getHouse();
|
||||||
|
if (params.containsKey("name") || params.containsKey("year") || params.containsKey("floors")) {
|
||||||
|
String houseName = params.containsKey("name") ? params.get("name") : house.getName();
|
||||||
|
int year = params.containsKey("year") ? Integer.parseInt(params.get("year")) : house.getYear();
|
||||||
|
long floors = params.containsKey("houseFloors") ? Long.parseLong(params.get("houseFloors"))
|
||||||
|
: house.getNumberOfFloors();
|
||||||
|
house = new House(houseName, year, floors);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Flat(
|
||||||
|
oldFlat.getId(),
|
||||||
|
name,
|
||||||
|
coordinates,
|
||||||
|
new Date(),
|
||||||
|
area,
|
||||||
|
numberOfRooms,
|
||||||
|
furnish,
|
||||||
|
view,
|
||||||
|
transport,
|
||||||
|
house);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
return "Can't parse provided id!";
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two Flat objects based on various attributes such as area,
|
||||||
|
* number of rooms, furnish type, view, transport, and house details.
|
||||||
|
*
|
||||||
|
* @param f1 the first flat to compare.
|
||||||
|
* @param f2 the second flat to compare.
|
||||||
|
* @return a negative integer, zero, or a positive integer as the first
|
||||||
|
* flat is less than, equal to, or greater than the second flat.
|
||||||
|
*/
|
||||||
|
private int compareFlats(Flat f1, Flat f2) {
|
||||||
|
int result = safeCompare(f1.getArea(), f2.getArea());
|
||||||
|
if (result != 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = Integer.compare(f1.getNumberOfRooms(), f2.getNumberOfRooms());
|
||||||
|
if (result != 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = safeCompare(f1.getFurnish(), f2.getFurnish());
|
||||||
|
if (result != 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = safeCompare(f1.getView(), f2.getView());
|
||||||
|
if (result != 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = safeCompare(f1.getTransport(), f2.getTransport());
|
||||||
|
if (result != 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
House h1 = f1.getHouse(), h2 = f2.getHouse();
|
||||||
|
if (h1 != null && h2 != null) {
|
||||||
|
result = Integer.compare(h1.getYear(), h2.getYear());
|
||||||
|
if (result != 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = Long.compare(h1.getNumberOfFloors(), h2.getNumberOfFloors());
|
||||||
|
if (result != 0)
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collection.isEmpty() || collection.size() == 0)
|
return 0;
|
||||||
return "Nothing to show!";
|
}
|
||||||
|
|
||||||
var currentFlat = collection.get(idToUpdate);
|
/**
|
||||||
|
* Safely compares two comparable objects, handling null values.
|
||||||
return "";
|
*
|
||||||
|
* @param a the first object to compare.
|
||||||
|
* @param b the second object to compare.
|
||||||
|
* @param <T> the type of the objects being compared, which must extend
|
||||||
|
* Comparable.
|
||||||
|
*
|
||||||
|
* @return a negative integer, zero, or a positive integer as the first
|
||||||
|
* object is less than, equal to, or greater than the second
|
||||||
|
* object. If both are null, returns 0; if one is null, the
|
||||||
|
* other is considered greater.
|
||||||
|
*/
|
||||||
|
private <T extends Comparable<T>> int safeCompare(T a, T b) {
|
||||||
|
if (a == null && b == null)
|
||||||
|
return 0;
|
||||||
|
if (a == null)
|
||||||
|
return -1;
|
||||||
|
if (b == null)
|
||||||
|
return 1;
|
||||||
|
return a.compareTo(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,71 +3,45 @@ package itmo.lab5.cli.commands;
|
|||||||
import itmo.lab5.interfaces.Command;
|
import itmo.lab5.interfaces.Command;
|
||||||
import itmo.lab5.cli.*;
|
import itmo.lab5.cli.*;
|
||||||
import itmo.lab5.models.*;
|
import itmo.lab5.models.*;
|
||||||
|
import itmo.lab5.parser.Writer;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.io.BufferedWriter;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the Command interface and provides
|
||||||
|
* functionality to save the current collection of Flat objects to a specified
|
||||||
|
* file.
|
||||||
|
*
|
||||||
|
* When executed, this command retrieves the collection and the file path from
|
||||||
|
* the command context and uses a Writer instance to write the collection to the
|
||||||
|
* specified file. If the collection or file path cannot be retrieved, an
|
||||||
|
* appropriate error message is returned.
|
||||||
|
*/
|
||||||
public class SaveCommand implements Command {
|
public class SaveCommand implements Command {
|
||||||
@Override
|
|
||||||
public String execute(String args[], CommandContext context) {
|
|
||||||
var collection = new HashMap<Integer, Flat>();
|
|
||||||
String filePath = null;
|
|
||||||
|
|
||||||
try {
|
/**
|
||||||
collection = (HashMap<Integer, Flat>) context.get("collection");
|
* Executes the save command, saving the current collection of flats to a
|
||||||
filePath = (String) context.get("path");
|
* file.
|
||||||
} catch (ClassCastException e) {
|
*
|
||||||
return "Can't parse collection!";
|
* @param args an array of arguments passed to the command (not used in this command)
|
||||||
}
|
* @param context the command context that contains the collection of flats and the file path
|
||||||
|
* @return a message indicating the result of the save operation, or an error message if the collection or file path cannot be parsed
|
||||||
if (filePath != null && collection != null) {
|
*/
|
||||||
return saveCollectionToFile(collection, filePath);
|
@Override
|
||||||
} else {
|
public String execute(String args[], CommandContext context) {
|
||||||
return "Can't parse some object! Check filePath!";
|
var writer = new Writer();
|
||||||
}
|
var collection = new HashMap<Integer, Flat>();
|
||||||
}
|
String filePath = null;
|
||||||
|
|
||||||
static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
|
||||||
|
|
||||||
public String saveCollectionToFile(HashMap<Integer, Flat> flats, String filename) {
|
|
||||||
try (FileOutputStream fos = new FileOutputStream(filename);
|
|
||||||
OutputStreamWriter osw = new OutputStreamWriter(fos);
|
|
||||||
BufferedWriter writer = new BufferedWriter(osw)) {
|
|
||||||
|
|
||||||
for (Flat flat : flats.values()) {
|
|
||||||
String date = "";
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
date = dateFormat.format(flat.getCreationDate()).toString();
|
collection = (HashMap<Integer, Flat>) context.get("collection");
|
||||||
} catch (Exception e) {
|
filePath = (String) context.get("path");
|
||||||
System.out.println(e.getMessage());
|
} catch (ClassCastException e) {
|
||||||
|
return "Can't parse collection!";
|
||||||
}
|
}
|
||||||
|
|
||||||
String line = String.format("%d,%s,%d,%d,%s,%.2f,%d,%s,%s,%s,%s,%d,%d\n",
|
if (filePath != null && collection != null)
|
||||||
flat.getId(),
|
return writer.writeCollection(filePath, collection);
|
||||||
flat.getName(),
|
else
|
||||||
flat.getCoordinates().getX(),
|
return "Can't parse some object! Check filePath!";
|
||||||
flat.getCoordinates().getY(),
|
|
||||||
date,
|
|
||||||
flat.getArea(),
|
|
||||||
flat.getNumberOfRooms(),
|
|
||||||
flat.getFurnish(),
|
|
||||||
flat.getView() != null ? flat.getView() : "",
|
|
||||||
flat.getTransport(),
|
|
||||||
flat.getHouse() != null ? flat.getHouse().getName() : "",
|
|
||||||
flat.getHouse() != null ? flat.getHouse().getYear() : 0,
|
|
||||||
flat.getHouse() != null ? flat.getHouse().getNumberOfFloors() : 0);
|
|
||||||
writer.write(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Collection has been saved to the file successfully.";
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return "An error occurred while saving the collection to file.";
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -6,25 +6,40 @@ import itmo.lab5.models.Flat;
|
|||||||
import itmo.lab5.interfaces.Command;
|
import itmo.lab5.interfaces.Command;
|
||||||
import itmo.lab5.cli.CommandContext;
|
import itmo.lab5.cli.CommandContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the Command interface and provides
|
||||||
|
* functionality to display the contents of the collection of Flat objects.
|
||||||
|
*
|
||||||
|
* When executed, this command retrieves the collection from the command context
|
||||||
|
* and prints each Flat object to the standard output. If the collection is
|
||||||
|
* empty, it returns a message indicating that there is nothing to show.
|
||||||
|
*/
|
||||||
public class ShowCommand implements Command {
|
public class ShowCommand implements Command {
|
||||||
@Override
|
|
||||||
public String execute(String args[], CommandContext context) {
|
|
||||||
var collection = new HashMap<Integer, Flat>();
|
|
||||||
|
|
||||||
try {
|
/**
|
||||||
collection = (HashMap<Integer, Flat>) context.get("collection");
|
* Executes the show command, displaying the contents of the collection
|
||||||
} catch (ClassCastException e) {
|
* of flats.
|
||||||
return "Can't parse collection!";
|
*
|
||||||
|
* @param args an array of arguments passed to the command
|
||||||
|
* @param context the command context that contains the collection of flats
|
||||||
|
* @return an empty string if the collection is displayed successfully, or an error message if the collection cannot be parsed
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String execute(String args[], CommandContext context) {
|
||||||
|
var collection = new HashMap<Integer, Flat>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
collection = (HashMap<Integer, Flat>) context.get("collection");
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
return "Can't parse collection!";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (collection.isEmpty())
|
||||||
|
return "Nothing to show!";
|
||||||
|
|
||||||
|
for (Flat flat : collection.values())
|
||||||
|
System.out.println(flat);
|
||||||
|
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collection.isEmpty() || collection.size() == 0) {
|
|
||||||
return "Nothing to show!";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Flat flat : collection.values()) {
|
|
||||||
System.out.println(flat);
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -8,89 +8,105 @@ import itmo.lab5.interfaces.Command;
|
|||||||
import itmo.lab5.models.enums.*;
|
import itmo.lab5.models.enums.*;
|
||||||
import itmo.lab5.models.*;
|
import itmo.lab5.models.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the Command interface and provides
|
||||||
|
* functionality to update an existing Flat object in the collection based on
|
||||||
|
* its ID.
|
||||||
|
*
|
||||||
|
* When executed, this command retrieves the flat with the specified ID from
|
||||||
|
* the collection, prompts the user for new values to update the flat's
|
||||||
|
* properties, and then saves the updated flat back to the collection.
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class UpdateCommand implements Command {
|
public class UpdateCommand implements Command {
|
||||||
private final Scanner scanner = new Scanner(System.in);
|
private final Scanner scanner = new Scanner(System.in);
|
||||||
private final ReaderUtil inputReader = new ReaderUtil(scanner);
|
private final ReaderUtil inputReader = new ReaderUtil(scanner);
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public String execute(String[] args, CommandContext context) {
|
* Executes the update command, updating the flat with the specified ID.
|
||||||
if (args.length < 1) {
|
*
|
||||||
return "Usage: update id {element}";
|
* @param args an array of arguments passed to the command, where the first element is expected to be the ID of the flat to update
|
||||||
|
* @param context the command context that contains the collection of flats
|
||||||
|
* @return a message indicating the result of the operation, or an error message if the ID is invalid or the collection cannot be parsed
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String execute(String[] args, CommandContext context) {
|
||||||
|
if (args.length < 1)
|
||||||
|
return "Usage: update id {element}";
|
||||||
|
|
||||||
|
Map<Integer, Flat> collection = null;
|
||||||
|
|
||||||
|
int idToUpdate;
|
||||||
|
try {
|
||||||
|
idToUpdate = Integer.parseInt(args[0]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return "Invalid ID format.";
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
collection = (Map<Integer, Flat>) context.get("collection");
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
return "There's an error while trying to parse collection.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!collection.containsKey(idToUpdate))
|
||||||
|
return "No flat with ID: " + idToUpdate;
|
||||||
|
|
||||||
|
Flat oldFlat = collection.get(idToUpdate);
|
||||||
|
|
||||||
|
System.out.println("Updating flat with ID: " + idToUpdate);
|
||||||
|
String name = inputReader.promptString("- Enter name:", false, oldFlat.getName());
|
||||||
|
|
||||||
|
System.out.println("- Coordinates:");
|
||||||
|
int x = inputReader.promptNumber("\t Enter x:", Integer.MIN_VALUE, Integer.MAX_VALUE, Integer::parseInt,
|
||||||
|
oldFlat.getCoordinates().getX());
|
||||||
|
Long y = inputReader.promptNumber("\t Enter y:", Long.MIN_VALUE, Long.MAX_VALUE, Long::parseLong,
|
||||||
|
oldFlat.getCoordinates().getY());
|
||||||
|
Coordinates coordinates = new Coordinates(x, y);
|
||||||
|
|
||||||
|
Double area = inputReader.promptNumber("\t Enter square:", 0.0, 626.0, Double::parseDouble, oldFlat.getArea());
|
||||||
|
int rooms = inputReader.promptNumber("\t Enter rooms count:", 1, Integer.MAX_VALUE, Integer::parseInt,
|
||||||
|
oldFlat.getNumberOfRooms());
|
||||||
|
|
||||||
|
System.out.println("- Furnish:");
|
||||||
|
Furnish furnish = inputReader.promptEnum("\t Enter furnish type:", Furnish.class, oldFlat.getFurnish());
|
||||||
|
|
||||||
|
System.out.println("- View:");
|
||||||
|
View view = inputReader.promptEnumNullable("\t Enter view type:", View.class, oldFlat.getView());
|
||||||
|
|
||||||
|
System.out.println("- Transport:");
|
||||||
|
Transport transport = inputReader.promptEnum("\t Enter transport type:", Transport.class, oldFlat.getTransport());
|
||||||
|
|
||||||
|
System.out.println("- House:");
|
||||||
|
System.out.print("\t Enter house name: ");
|
||||||
|
String houseName = scanner.nextLine().trim();
|
||||||
|
|
||||||
|
House house = oldFlat.getHouse();
|
||||||
|
if (!houseName.isEmpty()) {
|
||||||
|
int year = inputReader.promptNumber("\t Enter house age: ", 1, 959, Integer::parseInt,
|
||||||
|
(house != null ? house.getYear() : 1));
|
||||||
|
|
||||||
|
long floors = inputReader.promptNumber("\t Enter house floors count: ", 1L, 77L, Long::parseLong,
|
||||||
|
(house != null ? house.getNumberOfFloors() : 1L));
|
||||||
|
|
||||||
|
house = new House(houseName, year, floors);
|
||||||
|
}
|
||||||
|
|
||||||
|
Date creationDate = new Date();
|
||||||
|
|
||||||
|
Flat updatedFlat = new Flat(
|
||||||
|
idToUpdate,
|
||||||
|
name,
|
||||||
|
coordinates,
|
||||||
|
creationDate,
|
||||||
|
area,
|
||||||
|
rooms,
|
||||||
|
furnish,
|
||||||
|
view,
|
||||||
|
transport,
|
||||||
|
house);
|
||||||
|
|
||||||
|
collection.put(idToUpdate, updatedFlat);
|
||||||
|
return "Flat with ID " + idToUpdate + " was successfully updated.";
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Integer, Flat> collection = null;
|
|
||||||
|
|
||||||
int idToUpdate;
|
|
||||||
try {
|
|
||||||
idToUpdate = Integer.parseInt(args[0]);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
return "Invalid ID format.";
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
collection = (Map<Integer, Flat>) context.get("collection");
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
return "There's an error while trying to parse collection";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!collection.containsKey(idToUpdate))
|
|
||||||
return "No flat with ID: " + idToUpdate;
|
|
||||||
|
|
||||||
Flat oldFlat = collection.get(idToUpdate);
|
|
||||||
|
|
||||||
System.out.println("Updating flat with ID: " + idToUpdate);
|
|
||||||
String name = inputReader.promptString("- Enter name:", false, oldFlat.getName());
|
|
||||||
|
|
||||||
System.out.println("- Coordinates:");
|
|
||||||
int x = inputReader.promptNumber("\t Enter x:", Integer.MIN_VALUE, Integer.MAX_VALUE, Integer::parseInt,
|
|
||||||
oldFlat.getCoordinates().getX());
|
|
||||||
Long y = inputReader.promptNumber("\t Enter y:", Long.MIN_VALUE, Long.MAX_VALUE, Long::parseLong,
|
|
||||||
oldFlat.getCoordinates().getY());
|
|
||||||
Coordinates coordinates = new Coordinates(x, y);
|
|
||||||
|
|
||||||
Double area = inputReader.promptNumber("\t Enter square:", 0.0, 626.0, Double::parseDouble, oldFlat.getArea());
|
|
||||||
int rooms = inputReader.promptNumber("\t Enter rooms count:", 1, Integer.MAX_VALUE, Integer::parseInt,
|
|
||||||
oldFlat.getNumberOfRooms());
|
|
||||||
|
|
||||||
System.out.println("- Furnish:");
|
|
||||||
Furnish furnish = inputReader.promptEnum("\t Enter furnish type:", Furnish.class, oldFlat.getFurnish());
|
|
||||||
|
|
||||||
System.out.println("- View:");
|
|
||||||
View view = inputReader.promptEnumNullable("\t Enter view type:", View.class, oldFlat.getView());
|
|
||||||
|
|
||||||
System.out.println("- Transport:");
|
|
||||||
Transport transport = inputReader.promptEnum("\t Enter transport type:", Transport.class, oldFlat.getTransport());
|
|
||||||
|
|
||||||
System.out.println("- House:");
|
|
||||||
System.out.print("\t Enter house name: ");
|
|
||||||
String houseName = scanner.nextLine().trim();
|
|
||||||
|
|
||||||
House house = oldFlat.getHouse();
|
|
||||||
if (!houseName.isEmpty()) {
|
|
||||||
int year = inputReader.promptNumber("\t Enter house age: ", 1, 959, Integer::parseInt,
|
|
||||||
(house != null ? house.getYear() : 1));
|
|
||||||
|
|
||||||
long floors = inputReader.promptNumber("\t Enter house floors count: ", 1L, 77L, Long::parseLong,
|
|
||||||
(house != null ? house.getNumberOfFloors() : 1L));
|
|
||||||
|
|
||||||
house = new House(houseName, year, floors);
|
|
||||||
}
|
|
||||||
|
|
||||||
Date creationDate = new Date();
|
|
||||||
|
|
||||||
Flat updatedFlat = new Flat(
|
|
||||||
idToUpdate,
|
|
||||||
name,
|
|
||||||
coordinates,
|
|
||||||
creationDate,
|
|
||||||
area,
|
|
||||||
rooms,
|
|
||||||
furnish,
|
|
||||||
view,
|
|
||||||
transport,
|
|
||||||
house);
|
|
||||||
|
|
||||||
collection.put(idToUpdate, updatedFlat);
|
|
||||||
return "Flat with ID " + idToUpdate + " was successfully updated.";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,20 @@ package itmo.lab5.cli.helpers;
|
|||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages the history of executed commands, maintaining a fixed size.
|
||||||
|
*/
|
||||||
public class History {
|
public class History {
|
||||||
private static final int MAX_SIZE = 8;
|
|
||||||
private final Deque<String> history = new ArrayDeque<String>(MAX_SIZE);
|
|
||||||
|
|
||||||
|
private static final int MAX_SIZE = 8;
|
||||||
|
private final Deque<String> history = new ArrayDeque<>(MAX_SIZE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a command to the history. If the history exceeds the maximum
|
||||||
|
* size, the oldest command is removed.
|
||||||
|
*
|
||||||
|
* @param command the command to add to the history.
|
||||||
|
*/
|
||||||
public void add(String command) {
|
public void add(String command) {
|
||||||
if (history.size() >= MAX_SIZE)
|
if (history.size() >= MAX_SIZE)
|
||||||
history.removeFirst();
|
history.removeFirst();
|
||||||
@ -14,17 +24,36 @@ public class History {
|
|||||||
history.add(command);
|
history.add(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a command from the history by its index.
|
||||||
|
*
|
||||||
|
* @param x the index of the command to retrieve.
|
||||||
|
* @return the command at the specified index, or an empty string
|
||||||
|
* if the index is out of bounds.
|
||||||
|
*/
|
||||||
public String get(int x) {
|
public String get(int x) {
|
||||||
if (x >= MAX_SIZE)
|
if (x >= MAX_SIZE || x < 0)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
return (String) history.toArray()[x];
|
return (String) history.toArray()[x];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of the entire command history.
|
||||||
|
*
|
||||||
|
* @return a string listing all commands in the history.
|
||||||
|
*/
|
||||||
public String get() {
|
public String get() {
|
||||||
return history.toString();
|
return history.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a formatted string representation of the command history.
|
||||||
|
*
|
||||||
|
* @return a string that lists all commands in the history with
|
||||||
|
* a prefix.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
var builder = new StringBuilder("History: \n");
|
var builder = new StringBuilder("History: \n");
|
||||||
history.forEach(command -> builder.append(" - " + command + "\n"));
|
history.forEach(command -> builder.append(" - " + command + "\n"));
|
||||||
|
@ -3,13 +3,30 @@ package itmo.lab5.cli.helpers;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for reading user input with various prompt methods.
|
||||||
|
*/
|
||||||
public class ReaderUtil {
|
public class ReaderUtil {
|
||||||
|
|
||||||
private final Scanner scanner;
|
private final Scanner scanner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a ReaderUtil with the specified Scanner for input.
|
||||||
|
*
|
||||||
|
* @param scanner the Scanner to read user input.
|
||||||
|
*/
|
||||||
public ReaderUtil(Scanner scanner) {
|
public ReaderUtil(Scanner scanner) {
|
||||||
this.scanner = scanner;
|
this.scanner = scanner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompts the user for a string input, allowing for an optional old value.
|
||||||
|
*
|
||||||
|
* @param message the message to display to the user.
|
||||||
|
* @param allowEmpty whether to allow empty input.
|
||||||
|
* @param oldValue the previous value to display as a hint.
|
||||||
|
* @return the user input or the old value if input is empty.
|
||||||
|
*/
|
||||||
public String promptString(String message, boolean allowEmpty, String oldValue) {
|
public String promptString(String message, boolean allowEmpty, String oldValue) {
|
||||||
while (true) {
|
while (true) {
|
||||||
System.out.print(message);
|
System.out.print(message);
|
||||||
@ -27,6 +44,15 @@ public class ReaderUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompts the user to select an enum value from the specified options.
|
||||||
|
*
|
||||||
|
* @param message the message to display to the user.
|
||||||
|
* @param enumClass the class of the enum type.
|
||||||
|
* @param oldValue the previous value to display as a hint.
|
||||||
|
* @param <T> the type of the enum.
|
||||||
|
* @return the selected enum value or the old value if input is empty.
|
||||||
|
*/
|
||||||
public <T extends Enum<T>> T promptEnum(String message, Class<T> enumClass, T oldValue) {
|
public <T extends Enum<T>> T promptEnum(String message, Class<T> enumClass, T oldValue) {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (oldValue != null)
|
if (oldValue != null)
|
||||||
@ -34,8 +60,8 @@ public class ReaderUtil {
|
|||||||
|
|
||||||
System.out.print(
|
System.out.print(
|
||||||
message + "(options: " +
|
message + "(options: " +
|
||||||
String.join(", ", Arrays.stream(enumClass.getEnumConstants()).map(Enum::name).toList()) +
|
String.join(", ", Arrays.stream(enumClass.getEnumConstants())
|
||||||
"): ");
|
.map(Enum::name).toList()) + "): ");
|
||||||
|
|
||||||
String input = scanner.nextLine().trim();
|
String input = scanner.nextLine().trim();
|
||||||
|
|
||||||
@ -46,10 +72,18 @@ public class ReaderUtil {
|
|||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
System.out.println("Invalid name; Please, try again: ");
|
System.out.println("Invalid name; Please, try again: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompts the user to select an enum value, allowing for a nullable option.
|
||||||
|
*
|
||||||
|
* @param message the message to display to the user.
|
||||||
|
* @param enumClass the class of the enum type.
|
||||||
|
* @param oldValue the previous value to display as a hint.
|
||||||
|
* @param <T> the type of the enum.
|
||||||
|
* @return the selected enum value or the old value if input is empty.
|
||||||
|
*/
|
||||||
public <T extends Enum<T>> T promptEnumNullable(String message, Class<T> enumClass, T oldValue) {
|
public <T extends Enum<T>> T promptEnumNullable(String message, Class<T> enumClass, T oldValue) {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (oldValue != null)
|
if (oldValue != null)
|
||||||
@ -57,8 +91,8 @@ public class ReaderUtil {
|
|||||||
|
|
||||||
System.out.print(
|
System.out.print(
|
||||||
message + "(options: " +
|
message + "(options: " +
|
||||||
String.join(", ", Arrays.stream(enumClass.getEnumConstants()).map(Enum::name).toList()) +
|
String.join(", ", Arrays.stream(enumClass.getEnumConstants())
|
||||||
"): ");
|
.map(Enum::name).toList()) + "): ");
|
||||||
|
|
||||||
String input = scanner.nextLine().trim();
|
String input = scanner.nextLine().trim();
|
||||||
|
|
||||||
@ -72,6 +106,17 @@ public class ReaderUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompts the user for a number input within specified bounds.
|
||||||
|
*
|
||||||
|
* @param message the message to display to the user.
|
||||||
|
* @param min the minimum acceptable value.
|
||||||
|
* @param max the maximum acceptable value.
|
||||||
|
* @param parser the parser to convert input to the desired type.
|
||||||
|
* @param oldValue the previous value to display as a hint.
|
||||||
|
* @param <T> the type of the number, which must be comparable.
|
||||||
|
* @return the user input as a number or the old value if input is empty.
|
||||||
|
*/
|
||||||
public <T extends Comparable<T>> T promptNumber(String message, T min, T max, Parser<T> parser, T oldValue) {
|
public <T extends Comparable<T>> T promptNumber(String message, T min, T max, Parser<T> parser, T oldValue) {
|
||||||
while (true) {
|
while (true) {
|
||||||
System.out.print(message + " (" + oldValue + "): ");
|
System.out.print(message + " (" + oldValue + "): ");
|
||||||
|
@ -2,6 +2,18 @@ package itmo.lab5.interfaces;
|
|||||||
|
|
||||||
import itmo.lab5.cli.CommandContext;
|
import itmo.lab5.cli.CommandContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a command that can be executed with a set of arguments
|
||||||
|
* and a command context.
|
||||||
|
*/
|
||||||
public interface Command {
|
public interface Command {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the command with the provided arguments and context.
|
||||||
|
*
|
||||||
|
* @param args an array of arguments to be used during execution.
|
||||||
|
* @param context the context in which the command is executed.
|
||||||
|
* @return a string representing the result of the command execution.
|
||||||
|
*/
|
||||||
String execute(String[] args, CommandContext context);
|
String execute(String[] args, CommandContext context);
|
||||||
}
|
}
|
@ -1,5 +1,8 @@
|
|||||||
package itmo.lab5.models;
|
package itmo.lab5.models;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a point in the provided task.
|
||||||
|
*/
|
||||||
public class Coordinates {
|
public class Coordinates {
|
||||||
private int x;
|
private int x;
|
||||||
private Long y; // Поле не может быть null
|
private Long y; // Поле не может быть null
|
||||||
|
@ -5,6 +5,9 @@ import itmo.lab5.models.enums.*;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a flat, provided by se.ifmo.ru (no 462025)
|
||||||
|
*/
|
||||||
public class Flat {
|
public class Flat {
|
||||||
private int id; // Значение поля должно быть больше 0, Значение этого поля должно быть
|
private int id; // Значение поля должно быть больше 0, Значение этого поля должно быть
|
||||||
// уникальным, Значение этого поля должно генерироваться автоматически
|
// уникальным, Значение этого поля должно генерироваться автоматически
|
||||||
@ -19,6 +22,20 @@ public class Flat {
|
|||||||
private Transport transport; // Поле не может быть null
|
private Transport transport; // Поле не может быть null
|
||||||
private House house; // Поле может быть null
|
private House house; // Поле может быть null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a Flat object with the specified attributes.
|
||||||
|
*
|
||||||
|
* @param id the unique identifier of the flat (must be greater than 0).
|
||||||
|
* @param name the name of the flat (must not be null or empty).
|
||||||
|
* @param coordinates the coordinates of the flat (must not be null).
|
||||||
|
* @param creationDate the creation date of the flat (must not be null).
|
||||||
|
* @param area the area of the flat (must be greater than 0 and less than or equal to 626).
|
||||||
|
* @param numberOfRooms the number of rooms in the flat (must be greater than 0).
|
||||||
|
* @param furnish the furnish type of the flat (must not be null).
|
||||||
|
* @param view the view from the flat (can be null).
|
||||||
|
* @param transport the transport type associated with the flat (must not be null).
|
||||||
|
* @param house the house details associated with the flat (can be null).
|
||||||
|
*/
|
||||||
public Flat(int id, String name, Coordinates coordinates, Date creationDate, Double area,
|
public Flat(int id, String name, Coordinates coordinates, Date creationDate, Double area,
|
||||||
int numberOfRooms, Furnish furnish, View view, Transport transport, House house) {
|
int numberOfRooms, Furnish furnish, View view, Transport transport, House house) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@ -33,90 +50,201 @@ public class Flat {
|
|||||||
this.house = house;
|
this.house = house;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor for creating an empty Flat object.
|
||||||
|
*/
|
||||||
public Flat() {
|
public Flat() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the unique identifier of the flat.
|
||||||
|
*
|
||||||
|
* @return the id of the flat.
|
||||||
|
*/
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the unique identifier of the flat.
|
||||||
|
*
|
||||||
|
* @param id the new id of the flat (must be greater than 0).
|
||||||
|
*/
|
||||||
public void setId(int id) {
|
public void setId(int id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name of the flat.
|
||||||
|
*
|
||||||
|
* @return the name of the flat.
|
||||||
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the name of the flat.
|
||||||
|
*
|
||||||
|
* @param name the new name of the flat (must not be null or empty).
|
||||||
|
*/
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the coordinates of the flat.
|
||||||
|
*
|
||||||
|
* @return the coordinates of the flat (must not be null).
|
||||||
|
*/
|
||||||
public Coordinates getCoordinates() {
|
public Coordinates getCoordinates() {
|
||||||
return coordinates;
|
return coordinates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the coordinates of the flat.
|
||||||
|
*
|
||||||
|
* @param coordinates the new coordinates of the flat (must not be null).
|
||||||
|
*/
|
||||||
public void setCoordinates(Coordinates coordinates) {
|
public void setCoordinates(Coordinates coordinates) {
|
||||||
this.coordinates = coordinates;
|
this.coordinates = coordinates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the creation date of the flat.
|
||||||
|
*
|
||||||
|
* @return the creation date of the flat (must not be null).
|
||||||
|
*/
|
||||||
public Date getCreationDate() {
|
public Date getCreationDate() {
|
||||||
return creationDate;
|
return creationDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the creation date of the flat.
|
||||||
|
*
|
||||||
|
* @param creationDate the new creation date of the flat (must not be null).
|
||||||
|
*/
|
||||||
public void setCreationDate(Date creationDate) {
|
public void setCreationDate(Date creationDate) {
|
||||||
this.creationDate = creationDate;
|
this.creationDate = creationDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the area of the flat.
|
||||||
|
*
|
||||||
|
* @return the area of the flat (must be greater than 0 and less than or equal to 626).
|
||||||
|
*/
|
||||||
public Double getArea() {
|
public Double getArea() {
|
||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the area of the flat.
|
||||||
|
*
|
||||||
|
* @param area the new area of the flat (must be greater than 0 and less than or equal to 626).
|
||||||
|
*/
|
||||||
public void setArea(Double area) {
|
public void setArea(Double area) {
|
||||||
this.area = area;
|
this.area = area;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of rooms in the flat.
|
||||||
|
*
|
||||||
|
* @return the number of rooms in the flat (must be greater than 0).
|
||||||
|
*/
|
||||||
public int getNumberOfRooms() {
|
public int getNumberOfRooms() {
|
||||||
return numberOfRooms;
|
return numberOfRooms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the number of rooms in the flat.
|
||||||
|
*
|
||||||
|
* @param numberOfRooms the new number of rooms in the flat (must be greater than 0).
|
||||||
|
*/
|
||||||
public void setNumberOfRooms(int numberOfRooms) {
|
public void setNumberOfRooms(int numberOfRooms) {
|
||||||
this.numberOfRooms = numberOfRooms;
|
this.numberOfRooms = numberOfRooms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the furnish type of the flat.
|
||||||
|
*
|
||||||
|
* @return the furnish type of the flat (must not be null).
|
||||||
|
*/
|
||||||
public Furnish getFurnish() {
|
public Furnish getFurnish() {
|
||||||
return furnish;
|
return furnish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the furnish type of the flat.
|
||||||
|
*
|
||||||
|
* @param furnish the new furnish type of the flat (must not be null).
|
||||||
|
*/
|
||||||
public void setFurnish(Furnish furnish) {
|
public void setFurnish(Furnish furnish) {
|
||||||
this.furnish = furnish;
|
this.furnish = furnish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the view from the flat.
|
||||||
|
*
|
||||||
|
* @return the view from the flat (can be null).
|
||||||
|
*/
|
||||||
public View getView() {
|
public View getView() {
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the view from the flat.
|
||||||
|
*
|
||||||
|
* @param view the new view from the flat (can be null).
|
||||||
|
*/
|
||||||
public void setView(View view) {
|
public void setView(View view) {
|
||||||
this.view = view;
|
this.view = view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the transport type associated with the flat.
|
||||||
|
*
|
||||||
|
* @return the transport type associated with this class
|
||||||
|
*/
|
||||||
public Transport getTransport() {
|
public Transport getTransport() {
|
||||||
return transport;
|
return transport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the transport associated with this flat.
|
||||||
|
*
|
||||||
|
* @param transport the transport to be set
|
||||||
|
*/
|
||||||
public void setTransport(Transport transport) {
|
public void setTransport(Transport transport) {
|
||||||
this.transport = transport;
|
this.transport = transport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the house associated with this flat.
|
||||||
|
*
|
||||||
|
* @return the house
|
||||||
|
*/
|
||||||
public House getHouse() {
|
public House getHouse() {
|
||||||
return house;
|
return house;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the house associated with this flat.
|
||||||
|
*
|
||||||
|
* @param house the house to be set
|
||||||
|
*/
|
||||||
public void setHouse(House house) {
|
public void setHouse(House house) {
|
||||||
this.house = house;
|
this.house = house;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of the flat, including its ID, name,
|
||||||
|
* coordinates, creation date, area, number of rooms, furnishing status,
|
||||||
|
* view, transport, and house.
|
||||||
|
*
|
||||||
|
* @return a string representation of the flat
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
var sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
var sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||||||
|
@ -1,28 +1,64 @@
|
|||||||
package itmo.lab5.models;
|
package itmo.lab5.models;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a house with a name, year of construction, and number of floors.
|
||||||
|
* The name cannot be null, the year must be greater than 0 and less than or equal to 959,
|
||||||
|
* and the number of floors must be greater than 0 and less than or equal to 77.
|
||||||
|
*/
|
||||||
public class House {
|
public class House {
|
||||||
private String name; // Поле не может быть null
|
private String name; // Поле не может быть null
|
||||||
private int year; // Максимальное значение поля: 959, Значение поля должно быть больше 0
|
private int year; // Максимальное значение поля: 959, Значение поля должно быть больше 0
|
||||||
private long numberOfFloors; // Максимальное значение поля: 77, Значение поля должно быть больше 0
|
private long numberOfFloors; // Максимальное значение поля: 77, Значение поля должно быть больше 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a House with the specified name, year, and number of floors.
|
||||||
|
*
|
||||||
|
* @param name the name of the house, must not be null
|
||||||
|
* @param year the year of construction, must be greater than 0 and less
|
||||||
|
* than or equal to 959
|
||||||
|
* @param numberOfFloors the number of floors, must be greater than 0 and
|
||||||
|
* less than or equal to 77
|
||||||
|
*/
|
||||||
public House(String name, int year, long numberOfFloors) {
|
public House(String name, int year, long numberOfFloors) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.year = year;
|
this.year = year;
|
||||||
this.numberOfFloors = numberOfFloors;
|
this.numberOfFloors = numberOfFloors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the house.
|
||||||
|
*
|
||||||
|
* @return the name of the house
|
||||||
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the year of construction of the house.
|
||||||
|
*
|
||||||
|
* @return the year of construction
|
||||||
|
*/
|
||||||
public int getYear() {
|
public int getYear() {
|
||||||
return this.year;
|
return this.year;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of floors in the house.
|
||||||
|
*
|
||||||
|
* @return the number of floors
|
||||||
|
*/
|
||||||
public long getNumberOfFloors() {
|
public long getNumberOfFloors() {
|
||||||
return this.numberOfFloors;
|
return this.numberOfFloors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of the house, including its name, year of construction,
|
||||||
|
* and number of floors.
|
||||||
|
*
|
||||||
|
* @return a string representation of the house
|
||||||
|
*/
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "House(" +
|
return "House(" +
|
||||||
"name = '" + name +
|
"name = '" + name +
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package itmo.lab5.models.enums;
|
package itmo.lab5.models.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the different types of furnishing available for a flat.
|
||||||
|
*/
|
||||||
public enum Furnish {
|
public enum Furnish {
|
||||||
DESIGNER,
|
DESIGNER,
|
||||||
FINE,
|
FINE,
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package itmo.lab5.models.enums;
|
package itmo.lab5.models.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the different *strange* levels of transport
|
||||||
|
*/
|
||||||
public enum Transport {
|
public enum Transport {
|
||||||
FEW,
|
FEW,
|
||||||
NONE,
|
NONE,
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package itmo.lab5.models.enums;
|
package itmo.lab5.models.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the different types of views available from a flat.
|
||||||
|
*/
|
||||||
public enum View {
|
public enum View {
|
||||||
STREET,
|
STREET,
|
||||||
PARK,
|
PARK,
|
||||||
|
50
app/src/main/java/itmo/lab5/parser/Writer.java
Normal file
50
app/src/main/java/itmo/lab5/parser/Writer.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package itmo.lab5.parser;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import itmo.lab5.models.Flat;
|
||||||
|
|
||||||
|
public class Writer {
|
||||||
|
static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
||||||
|
|
||||||
|
public String writeCollection(String filename, HashMap<Integer, Flat> flats) {
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(filename);
|
||||||
|
OutputStreamWriter osw = new OutputStreamWriter(fos);
|
||||||
|
BufferedWriter writer = new BufferedWriter(osw)) {
|
||||||
|
|
||||||
|
for (Flat flat : flats.values()) {
|
||||||
|
String date = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
date = dateFormat.format(flat.getCreationDate()).toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
String line = String.format("%d,%s,%d,%d,%s,%.2f,%d,%s,%s,%s,%s,%d,%d\n",
|
||||||
|
flat.getId(),
|
||||||
|
flat.getName(),
|
||||||
|
flat.getCoordinates().getX(),
|
||||||
|
flat.getCoordinates().getY(),
|
||||||
|
date,
|
||||||
|
flat.getArea(),
|
||||||
|
flat.getNumberOfRooms(),
|
||||||
|
flat.getFurnish(),
|
||||||
|
flat.getView() != null ? flat.getView() : "",
|
||||||
|
flat.getTransport(),
|
||||||
|
flat.getHouse() != null ? flat.getHouse().getName() : "",
|
||||||
|
flat.getHouse() != null ? flat.getHouse().getYear() : 0,
|
||||||
|
flat.getHouse() != null ? flat.getHouse().getNumberOfFloors() : 0);
|
||||||
|
|
||||||
|
writer.write(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Collection has been saved to the file successfully.";
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "An error occurred while saving the collection to file.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user