pax_global_header 0000666 0000000 0000000 00000000064 14041410226 0014504 g ustar 00root root 0000000 0000000 52 comment=f07555d96cb039bde6a71195dfc56e7304d816a0
2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/ 0000775 0000000 0000000 00000000000 14041410226 0020561 5 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/.gitignore 0000664 0000000 0000000 00000002024 14041410226 0022547 0 ustar 00root root 0000000 0000000 # Created by .ignore support plugin (hsz.mobi)
### Java template
*.class
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
*.iml
## Directory-based project format:
.idea/
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Maven template
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
### NetBeans template
nbproject/private/
build/
nbbuild/
dist/
nbdist/
nbactions.xml
nb-configuration.xml
.nb-gradle/
# Vim
*.un~
# OS X .DS_Store
.DS_Store
2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/.gitlab-ci.yml 0000664 0000000 0000000 00000000162 14041410226 0023214 0 ustar 00root root 0000000 0000000 image: maven:3-jdk-11
build:
script:
- mvn clean install -B -Dcheckstyle.fail=true
tags:
- shared-fi
2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/README.md 0000664 0000000 0000000 00000012551 14041410226 0022044 0 ustar 00root root 0000000 0000000 Homework assignment no. 2, Text
====================================
**Publication date:** April 23, 2021
**Submission deadline:** May 9, 2021
General information
-------------------
In this assignment you will create a program which allows for a simple line processing of text files.
The application should support the following operations.
| Operation | Type | CLI option | Description |
| ------ | ------ | ------ | ------ |
| unique | intermediate | -u | Filter unique lines |
| sort | intermediate | -s | Sort lines by natural ordering |
| duplicates | intermediate | -d | Filter duplicate lines |
| lines | terminal | lines | Print lines (default operation) |
| count | terminal | count | Count lines |
| sizes | terminal | sizes | Counts the characters for each line (excluding line separators)|
| similar | terminal | similar | Lists pairs of most similar (distinct) lines according to Levenshtein distance |
In addition to operations the application should also support these command line options
| CLI option | Description |
| ------ | ------ |
| --help | Print application usage |
| --file | Path to file operated on by the application |
For more details about the CLI see the section "Running the application" in this README as well as JUnit tests.
### Evaluation
Beside functional correctness this assignment is focused on object oriented design.
This means that the way you structure your program will be an important part of its evaluation.
On the other hand the given set of tests is not trying to provide an elaborate test coverage and incorrect behaviour in corner-cases should not have a large impact on the evaluation.
Note that all this is at your seminar teacher's discretion.
The maximum number of points for this assignment is **10**.
- **6 points** for passing the tests (attached tests do not guarantee a 100% correctness).
- **4 points** for correct and clean implementation (evaluated by your class teacher).
### Preconditions
To successfully implement this assignment you need to know the following
1. Creating object design of an application
2. Working with collections
3. Exception handling
4. Ability to work with 3rd party code
### Project structure
The structure of project provided as a base for your implementation should meet the following criteria.
1. Package ```cz.muni.fi.pb162.hw02``` contains classes and interfaces provided as part of the assignment.
- **Do not modify or add any classes or subpackages into this package.**
2. Package ```cz.muni.fi.pb162.hw02.impl``` should contain your implementation.
- **Anything outside this package will be ignored during evaluation.**
### Names in this document
Unless fully classified name is provided, all class names are relative to package ```cz.muni.fi.pb162.hw02``` or ```cz.muni.fi.pb162.hw02.impl``` for classes implemented as part of your solution.
### Compiling the project
The project can be compiled and packaged in the same way you already know
```bash
$ mvn clean install
```
The only difference is, that unlike with seminar project, this time checks for missing documentation and style violation will produce an error.
You can temporarily disable this behavior when running this command.
```bash
$ mvn clean install -Dcheckstyle.fail=false
```
### Running the application
Build command mentioned above will produce a runnable jar file ``target/application.jar``.
The following are example usages of developed application.
```bash
# Basic print of file lines
$ java -jar application.jar --file /example/path/duplicities.txt lines
This is a single line!
This is another one!
This is another one!
This is a single line!
This one is unique!
# Lines operation is the default
$ java -jar application.jar --file /example/path/duplicities.txt
This is a single line!
This is another one!
This is another one!
This is a single line!
This one is unique!
# Print of sorted lines
$ java -jar application.jar --file /example/path/duplicities.txt -s
This is a single line!
This is a single line!
This is another one!
This is another one!
This one is unique!
# Print unique lines
$ java -jar application.jar --file /example/path/duplicities.txt -u
This is a single line!
This is another one!
This one is unique!
# Print duplicate lines
$ java -jar application.jar --file /example/path/duplicities.txt -d
This is another one!
This is a single line!
# Count lines in the file
$ java -jar application.jar --file /example/path/duplicities.txt count
5
# Count unique lines
$ java -jar application.jar --file /example/path/duplicities.txt -u count
3
# Find most similar lines by Levenshtein distance
$ java -jar application.jar --file /example/path/duplicities.txt similar
Distance of 9
This is a single line! ~= This is another one!
```
You can consult your seminar teacher to help you set the ```checkstyle.fail``` property in your IDE (or just google it).
### Submitting the assignment
The procedure to submit your solution may differ based on your seminar group. However generally it should be OK to submit ```target/homework02-2021-1.0-SNAPSHOT-sources.jar``` to the homework vault.
## Implementation
Generally speaking there are no mandatory requirements on the structure of your code as long as the command line interface of ```Appplication``` class works correctly.
These requirements are described above and covered by JUnit tests.
The use of classes, enums and interfaces, provided as part of the project skeleton is up to your decision.
2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/pb162_codestyle.xml 0000664 0000000 0000000 00000007363 14041410226 0024221 0 ustar 00root root 0000000 0000000
2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/pom.xml 0000775 0000000 0000000 00000012346 14041410226 0022107 0 ustar 00root root 0000000 0000000
4.0.0
cz.muni.fi.pb162
homework02-2021
1.0-SNAPSHOT
11
11
2.17
2.4
5.6.2
3.19.0
1.78
true
UTF-8
com.beust
jcommander
${version.jcommander}
org.junit.jupiter
junit-jupiter
${version.junit}
test
org.assertj
assertj-core
${version.assertj}
test
org.apache.maven.plugins
maven-source-plugin
${version.plugin.source}
attach-sources
jar
org.apache.maven.plugins
maven-shade-plugin
3.2.2
package
shade
application
true
cz.muni.fi.pb162.hw02.impl.Application
com.beust:jcommander
META-INF/*.MF
org.apache.maven.plugins
maven-surefire-plugin
2.22.2
false
org.apache.maven.plugins
maven-checkstyle-plugin
${version.plugin.checkstyle}
validate
validate
pb162_codestyle.xml
UTF-8
true
${checkstyle.fail}
warning
false
*/**/Demo
check
2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/ 0000775 0000000 0000000 00000000000 14041410226 0021350 5 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/main/ 0000775 0000000 0000000 00000000000 14041410226 0022274 5 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/main/java/ 0000775 0000000 0000000 00000000000 14041410226 0023215 5 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/main/java/cz/ 0000775 0000000 0000000 00000000000 14041410226 0023631 5 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/main/java/cz/muni/ 0000775 0000000 0000000 00000000000 14041410226 0024601 5 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/main/java/cz/muni/fi/ 0000775 0000000 0000000 00000000000 14041410226 0025177 5 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/main/java/cz/muni/fi/pb162/ 0000775 0000000 0000000 00000000000 14041410226 0026031 5 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/main/java/cz/muni/fi/pb162/hw02/ 0000775 0000000 0000000 00000000000 14041410226 0026611 5 ustar 00root root 0000000 0000000 FileLoader.java 0000664 0000000 0000000 00000000757 14041410226 0031414 0 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/main/java/cz/muni/fi/pb162/hw02 package cz.muni.fi.pb162.hw02;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
/**
* Facade for file reading
*/
public class FileLoader {
/**
* Reads file as lines
* @param path path of the file
* @return content of read file as lines
* @throws IOException on IO error
*/
public List loadAsLines(String path) throws IOException {
return Files.readAllLines(Paths.get(path));
}
}
Messages.java 0000664 0000000 0000000 00000000550 14041410226 0031144 0 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/main/java/cz/muni/fi/pb162/hw02 package cz.muni.fi.pb162.hw02;
/**
* Error messages
*/
public final class Messages {
private Messages() {
// intentionally private to prevent instantiation
}
public static final String IO_ERROR = "Unable to process file '%s'!";
public static final String INVALID_OPTION_COMBINATION = "Invalid combination of options was used!";
}
TerminalOperation.java 0000664 0000000 0000000 00000001263 14041410226 0033033 0 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/main/java/cz/muni/fi/pb162/hw02 package cz.muni.fi.pb162.hw02;
import java.util.Arrays;
/**
* Terminal Operations
*/
public enum TerminalOperation {
LINES,
COUNT,
SIZES,
SIMILAR;
@Override
public String toString() {
return name().toLowerCase();
}
/**
* Returns {@link TerminalOperation} for given name in case insensitive manner
* @param name name of the operation
* @return {@link TerminalOperation} instance
*/
public static TerminalOperation forName(String name) {
return Arrays
.stream(values())
.filter(o -> o.name().equalsIgnoreCase(name))
.findAny()
.orElseThrow();
}
}
2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/main/java/cz/muni/fi/pb162/hw02/cmd/ 0000775 0000000 0000000 00000000000 14041410226 0027354 5 ustar 00root root 0000000 0000000 CommandLine.java 0000664 0000000 0000000 00000002310 14041410226 0032322 0 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/main/java/cz/muni/fi/pb162/hw02/cmd package cz.muni.fi.pb162.hw02.cmd;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.ParameterException;
/**
* Command Line Interface
*/
public final class CommandLine {
private final JCommander commander;
/**
* Constructs new CLI instance
*
* @param application application object to be populated with arguments
*/
public CommandLine(Object application) {
commander = JCommander.newBuilder()
.addObject(application)
.build();
commander.setProgramName(application.getClass().getSimpleName());
}
/**
* Parses command line arguments (terminates on error)
*
* @param args command line arguments of the application
*/
public void parseArguments(String[] args) {
try {
commander.parse(args);
} catch (ParameterException ex) {
System.err.println("Error: " + ex.getMessage());
showUsage(1);
}
}
/**
* Shows usage of the application and terminates
*/
public void showUsage() {
showUsage(0);
}
private void showUsage(int status) {
commander.usage();
System.exit(status);
}
}
TerminalOperationConverter.java 0000664 0000000 0000000 00000001143 14041410226 0035463 0 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/main/java/cz/muni/fi/pb162/hw02/cmd package cz.muni.fi.pb162.hw02.cmd;
import com.beust.jcommander.converters.BaseConverter;
import cz.muni.fi.pb162.hw02.TerminalOperation;
/**
* Converter for terminal operation command line option
*/
public class TerminalOperationConverter extends BaseConverter {
/**
* Constructor for this class
* @param optionName name of the command line option
*/
public TerminalOperationConverter(String optionName) {
super(optionName);
}
@Override
public TerminalOperation convert(String value) {
return TerminalOperation.forName(value);
}
}
2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/main/java/cz/muni/fi/pb162/hw02/impl/ 0000775 0000000 0000000 00000000000 14041410226 0027552 5 ustar 00root root 0000000 0000000 .gitkeep 0000664 0000000 0000000 00000000000 14041410226 0031112 0 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/main/java/cz/muni/fi/pb162/hw02/impl 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/test/ 0000775 0000000 0000000 00000000000 14041410226 0022327 5 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/test/java/ 0000775 0000000 0000000 00000000000 14041410226 0023250 5 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/test/java/cz/ 0000775 0000000 0000000 00000000000 14041410226 0023664 5 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/test/java/cz/muni/ 0000775 0000000 0000000 00000000000 14041410226 0024634 5 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/test/java/cz/muni/fi/ 0000775 0000000 0000000 00000000000 14041410226 0025232 5 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/test/java/cz/muni/fi/pb162/ 0000775 0000000 0000000 00000000000 14041410226 0026064 5 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/test/java/cz/muni/fi/pb162/hw02/ 0000775 0000000 0000000 00000000000 14041410226 0026644 5 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/test/java/cz/muni/fi/pb162/hw02/.gitkeep0000664 0000000 0000000 00000000000 14041410226 0030263 0 ustar 00root root 0000000 0000000 FileLoaderTest.java 0000664 0000000 0000000 00000001726 14041410226 0032304 0 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/test/java/cz/muni/fi/pb162/hw02 package cz.muni.fi.pb162.hw02;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import static cz.muni.fi.pb162.hw02.TestUtils.resourcePath;
import static org.assertj.core.api.Assertions.assertThat;
class FileLoaderTest {
private FileLoader fileLoader;
@BeforeEach
void setup() {
fileLoader = new FileLoader();
}
@Test
void shouldReadSingleLineFileAsLines() throws URISyntaxException, IOException {
List lines = fileLoader.loadAsLines(resourcePath("/line.txt"));
assertThat(lines).containsExactly("This is a single line!");
}
@Test
void shouldReadMultiLineFileAsLines() throws URISyntaxException, IOException {
List lines = fileLoader.loadAsLines(resourcePath("/lines.txt"));
assertThat(lines).containsExactly("This is a single line!", "This is another one!");
}
}
TestUtils.java 0000664 0000000 0000000 00000000522 14041410226 0031367 0 ustar 00root root 0000000 0000000 2021-hw02-text-f07555d96cb039bde6a71195dfc56e7304d816a0/src/test/java/cz/muni/fi/pb162/hw02 package cz.muni.fi.pb162.hw02;
import java.net.URISyntaxException;
import java.nio.file.Paths;
public class TestUtils {
private TestUtils() {
}
public static String resourcePath(String path) throws URISyntaxException {
return Paths.get(TestUtils.class.getResource(path).toURI()).toAbsolutePath().toString();
}
}