Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Lukáš Gorazd Hrodek
2021-hw03-csv
Commits
a294e06e
Commit
a294e06e
authored
May 22, 2021
by
jcechace
Browse files
Initial project assignment
parents
Changes
18
Hide whitespace changes
Inline
Side-by-side
.gitignore
0 → 100644
View file @
a294e06e
# 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
.gitlab-ci.yml
0 → 100644
View file @
a294e06e
image
:
maven:3-jdk-11
build
:
script
:
-
mvn clean install -B -Dcheckstyle.fail=true
tags
:
-
shared-fi
pb162_codestyle.xml
0 → 100644
View file @
a294e06e
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module
name=
"Checker"
>
<!--<property name="fileExtensions" value="java, xml, properties"/>-->
<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<module
name=
"FileTabCharacter"
/>
<module
name=
"TreeWalker"
>
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module
name=
"JavadocMethod"
>
<property
name=
"scope"
value=
"public"
/>
<property
name=
"allowMissingPropertyJavadoc"
value=
"true"
/>
</module>
<module
name=
"JavadocType"
>
<property
name=
"scope"
value=
"public"
/>
</module>
<module
name=
"JavadocStyle"
>
<property
name=
"scope"
value=
"public"
/>
<property
name=
"checkFirstSentence"
value=
"false"
/>
</module>
<!-- Checks for Naming Conventions. -->
<!-- See http://checkstyle.sf.net/config_naming.html -->
<module
name=
"ConstantName"
/>
<module
name=
"LocalFinalVariableName"
/>
<module
name=
"LocalVariableName"
/>
<module
name=
"MemberName"
/>
<module
name=
"MethodName"
/>
<module
name=
"PackageName"
/>
<module
name=
"ParameterName"
/>
<module
name=
"StaticVariableName"
/>
<module
name=
"TypeName"
/>
<!-- Checks for imports -->
<!-- See http://checkstyle.sf.net/config_import.html -->
<module
name=
"AvoidStarImport"
/>
<module
name=
"IllegalImport"
/>
<!-- defaults to sun.* packages -->
<module
name=
"RedundantImport"
/>
<module
name=
"UnusedImports"
/>
<!-- Checks for Size Violations. -->
<!-- See http://checkstyle.sf.net/config_sizes.html -->
<module
name=
"LineLength"
>
<property
name=
"max"
value=
"120"
/>
</module>
<module
name=
"MethodLength"
>
<property
name=
"max"
value=
"50"
/>
<property
name=
"countEmpty"
value=
"false"
/>
</module>
<module
name=
"ParameterNumber"
/>
<!-- Modifier Checks -->
<!-- See http://checkstyle.sf.net/config_modifier.html -->
<module
name=
"ModifierOrder"
/>
<module
name=
"RedundantModifier"
/>
<!-- Checks for blocks. You know, those {}'s -->
<!-- See http://checkstyle.sf.net/config_blocks.html -->
<module
name=
"AvoidNestedBlocks"
/>
<module
name=
"LeftCurly"
>
<property
name=
"option"
value=
"eol"
/>
</module>
<module
name=
"NeedBraces"
>
<property
name=
"allowSingleLineStatement"
value=
"false"
/>
</module>
<module
name=
"RightCurly"
/>
<!-- Checks for common coding problems -->
<!-- See http://checkstyle.sf.net/config_coding.html -->
<module
name=
"EmptyStatement"
/>
<module
name=
"EqualsHashCode"
/>
<module
name=
"MissingSwitchDefault"
/>
<module
name=
"SimplifyBooleanExpression"
/>
<module
name=
"SimplifyBooleanReturn"
/>
<!-- Checks for class design -->
<!-- See http://checkstyle.sf.net/config_design.html -->
<module
name=
"FinalClass"
/>
<module
name=
"InterfaceIsType"
/>
<module
name=
"VisibilityModifier"
>
<property
name=
"protectedAllowed"
value=
"true"
/>
</module>
<!-- Miscellaneous other checks. -->
<!-- See http://checkstyle.sf.net/config_misc.html -->
<module
name=
"ArrayTypeStyle"
/>
</module>
</module>
pom.xml
0 → 100755
View file @
a294e06e
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns=
"http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<groupId>
cz.muni.fi.pb162
</groupId>
<artifactId>
homework03-2021
</artifactId>
<version>
1.0-SNAPSHOT
</version>
<properties>
<maven.compiler.source>
11
</maven.compiler.source>
<maven.compiler.target>
11
</maven.compiler.target>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
<checkstyle.fail>
true
</checkstyle.fail>
<!-- dependency versions -->
<version.plugin.checkstyle>
2.17
</version.plugin.checkstyle>
<version.plugin.source>
2.4
</version.plugin.source>
<version.junit>
5.6.2
</version.junit>
<version.mockito>
3.9.0
</version.mockito>
<version.assertj>
3.19.0
</version.assertj>
<version.jcommander>
1.78
</version.jcommander>
<version.system-labda>
1.2.0
</version.system-labda>
</properties>
<dependencies>
<dependency>
<groupId>
com.beust
</groupId>
<artifactId>
jcommander
</artifactId>
<version>
${version.jcommander}
</version>
</dependency>
<dependency>
<groupId>
org.junit.jupiter
</groupId>
<artifactId>
junit-jupiter
</artifactId>
<version>
${version.junit}
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.assertj
</groupId>
<artifactId>
assertj-core
</artifactId>
<version>
${version.assertj}
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.mockito
</groupId>
<artifactId>
mockito-core
</artifactId>
<version>
${version.mockito}
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.mockito
</groupId>
<artifactId>
mockito-inline
</artifactId>
<version>
${version.mockito}
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
com.github.stefanbirkner
</groupId>
<artifactId>
system-lambda
</artifactId>
<version>
${version.system-labda}
</version>
<scope>
test
</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Include sources into JAR -->
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-source-plugin
</artifactId>
<version>
${version.plugin.source}
</version>
<executions>
<execution>
<id>
attach-sources
</id>
<goals>
<goal>
jar
</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Executable jar -->
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-shade-plugin
</artifactId>
<version>
3.2.2
</version>
<executions>
<execution>
<phase>
package
</phase>
<goals>
<goal>
shade
</goal>
</goals>
<configuration>
<finalName>
application
</finalName>
<shadedArtifactAttached>
true
</shadedArtifactAttached>
<transformers>
<transformer
implementation=
"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"
>
<mainClass>
cz.muni.fi.pb162.hw03.app.impl.Application
</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<artifact>
com.beust:jcommander
</artifact>
<excludes>
<exclude>
META-INF/*.MF
</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<!-- surefire Config -->
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-surefire-plugin
</artifactId>
<version>
2.22.2
</version>
<configuration>
<useSystemClassLoader>
false
</useSystemClassLoader>
</configuration>
</plugin>
<!-- Check code style -->
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-checkstyle-plugin
</artifactId>
<version>
${version.plugin.checkstyle}
</version>
<executions>
<execution>
<id>
validate
</id>
<phase>
validate
</phase>
<configuration>
<configLocation>
pb162_codestyle.xml
</configLocation>
<encoding>
UTF-8
</encoding>
<consoleOutput>
true
</consoleOutput>
<failOnViolation>
${checkstyle.fail}
</failOnViolation>
<violationSeverity>
warning
</violationSeverity>
<includeTestSourceDirectory>
false
</includeTestSourceDirectory>
<excludes>
*/**/Demo
</excludes>
</configuration>
<goals>
<goal>
check
</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
src/main/java/cz/muni/fi/pb162/hw03/csv/CsvParser.java
0 → 100644
View file @
a294e06e
package
cz.muni.fi.pb162.hw03.csv
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.nio.charset.Charset
;
import
java.nio.charset.StandardCharsets
;
import
java.nio.file.Path
;
import
java.util.List
;
import
java.util.Map
;
/**
* CSV Parser able to either open a source of CSV data or to directly read all the data
*/
public
interface
CsvParser
{
/**
* Default delimiter is a comma
*/
String
DEFAULT_DELIMITER
=
","
;
/**
* Default character encoding
*/
Charset
DEFAULT_CHARSET
=
StandardCharsets
.
UTF_8
;
/**
* Opens {@link CsvReader} from given path to read data from
*
* @param path file path
* @return instance of @{CsvReader} capable of reading plain CSV data
* @throws IOException on any IO error
*/
CsvReader
<
List
<
String
>>
open
(
Path
path
)
throws
IOException
;
/**
* Opens {@link CsvReader} from given {@link InputStream} to read CSV data from
*
* @param is source of data
* @return instance of @{CsvReader} capable of reading plain CSV data
* @throws IOException on any IO error
*/
CsvReader
<
List
<
String
>>
open
(
InputStream
is
)
throws
IOException
;
/**
* Opens {@link CsvReader} from given {@link InputStream} to read CSV data with header from
*
* @param path file path
* @return instance of @{CsvReader} capable of reading CSV data <strong>with header</strong>
* @throws IOException on any IO error
*/
CsvReader
<
Map
<
String
,
String
>>
openWithHeader
(
Path
path
)
throws
IOException
;
/**
* Opens {@link CsvReader} from given {@link InputStream} to read CSV data with header from
*
* @param is source of data
* @return instance of @{CsvReader} capable of reading CSV data <strong>with header</strong>
* @throws IOException on any IO error
*/
CsvReader
<
Map
<
String
,
String
>>
openWithHeader
(
InputStream
is
)
throws
IOException
;
/**
* Reads all CSV data from given path
*
* @param path file path
* @return read CSV data
* @throws IOException on any IO error
*/
List
<
List
<
String
>>
readAll
(
Path
path
)
throws
IOException
;
/**
* Reads all CSV data <strong>with header</strong> from given path
*
* @param path file path
* @return read CSV data <strong>with header</strong>
* @throws IOException on any IO error
*/
List
<
Map
<
String
,
String
>>
readAllWithHeader
(
Path
path
)
throws
IOException
;
}
src/main/java/cz/muni/fi/pb162/hw03/csv/CsvReader.java
0 → 100644
View file @
a294e06e
package
cz.muni.fi.pb162.hw03.csv
;
import
java.io.Closeable
;
import
java.io.IOException
;
import
java.util.function.Consumer
;
/**
* Interface for classes providing the capability of reading CSV data
*
* @param <T> type parameter of {@link #read()} result
*/
public
interface
CsvReader
<
T
>
extends
Closeable
{
/**
* Reads single line of CSV data
* Trims leading and trailing whitespaces around row entries
*
* @return process line of CSV
* @throws IOException on any IO error
*/
T
read
()
throws
IOException
;
/**
* Consumes each line of CSV data
*
* @param consumer consumer called with each line of CSV
* @throws IOException on any IO error
*/
void
forEach
(
Consumer
<
T
>
consumer
)
throws
IOException
;
}
src/main/java/cz/muni/fi/pb162/hw03/csv/Messages.java
0 → 100644
View file @
a294e06e
package
cz.muni.fi.pb162.hw03.csv
;
/**
* Error messages
*/
public
final
class
Messages
{
private
Messages
()
{
// intentionally private to prevent instantiation
}
public
static
final
String
INVALID_FORMAT
=
"Invalid file format"
;
}
src/main/java/cz/muni/fi/pb162/hw03/csv/impl/CsvToolkit.java
0 → 100644
View file @
a294e06e
package
cz.muni.fi.pb162.hw03.csv.impl
;
import
cz.muni.fi.pb162.hw03.csv.CsvParser
;
import
java.nio.charset.Charset
;
/**
* Factory class for CSV processing
*/
public
final
class
CsvToolkit
{
private
CsvToolkit
()
{
// intentionally private to prevent instantiation
}
/**
* Creates instance of {@link CsvParser} with default delimiter and charset
*
* @return parser
*/
public
static
CsvParser
parser
()
{
throw
new
UnsupportedOperationException
(
"Implement this method!"
);
}
/**
* Creates instance of {@link CsvParser} with given delimiter
*
* @param delimiter value delimiter
* @param charset character encoding
* @return parser
*/
public
static
CsvParser
parser
(
String
delimiter
,
Charset
charset
)
{
throw
new
UnsupportedOperationException
(
"Implement this method!"
);
}
}
src/test/java/cz/muni/fi/pb162/hw03/TestUtils.java
0 → 100644
View file @
a294e06e
package
cz.muni.fi.pb162.hw03
;
import
java.net.URISyntaxException
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
public
class
TestUtils
{
private
TestUtils
()
{
}
public
static
Path
resourcePath
(
String
path
)
throws
URISyntaxException
{
return
Paths
.
get
(
TestUtils
.
class
.
getResource
(
path
).
toURI
());
}
}
\ No newline at end of file
src/test/java/cz/muni/fi/pb162/hw03/csv/CsvParserEncodingTest.java
0 → 100644
View file @
a294e06e
package
cz.muni.fi.pb162.hw03.csv
;
import
cz.muni.fi.pb162.hw03.csv.impl.CsvToolkit
;
import
org.assertj.core.api.SoftAssertions
;
import
org.assertj.core.api.junit.jupiter.InjectSoftAssertions
;
import
org.assertj.core.api.junit.jupiter.SoftAssertionsExtension
;
import
org.junit.jupiter.api.BeforeEach
;
import
org.junit.jupiter.api.DisplayName
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.api.extension.ExtendWith
;
import
java.nio.charset.Charset
;
import
java.util.ArrayList
;
import
java.util.List
;
import
static
cz
.
muni
.
fi
.
pb162
.
hw03
.
TestUtils
.
resourcePath
;
@ExtendWith
(
SoftAssertionsExtension
.
class
)
public
class
CsvParserEncodingTest
{
@InjectSoftAssertions
private
SoftAssertions
softly
;
private
CsvParser
parser
;
@BeforeEach
void
setUp
()
{
parser
=
CsvToolkit
.
parser
(
","
,
Charset
.
forName
(
"ISO-8859-2"
));
}
@Test
@DisplayName
(
"Loads plain CSV data with Latin 2 encoding"
)
public
void
plainCsv
()
throws
Exception
{
List
<
List
<
String
>>
data
=
parser
.
readAll
(
resourcePath
(
"/plain_iso-8859-2.csv"
));
softly
.
assertThat
(
data
).
containsExactlyElementsOf
(
List
.
of
(
List
.
of
(
"příliš"
,
"žluťoučký"
,
"kůň"
),
List
.
of
(
"úpěl"
,
"ďábelské"
,
"ódy"
)
));
}
@Test
@DisplayName
(
"Loads plain CSV data with Latin 2 encoding"
)
public
void
plainCsvWithReader
()
throws
Exception
{
var
expected
=
List
.
of
(
List
.
of
(
"příliš"
,
"žluťoučký"
,
"kůň"
),
List
.
of
(
"úpěl"
,
"ďábelské"
,
"ódy"
)
);
List
<
List
<
String
>>
actual
=
new
ArrayList
<>();
try
(
var
reader
=
parser
.
open
((
resourcePath
(
"/plain_iso-8859-2.csv"
))))
{
reader
.
forEach
(
actual:
:
add
);
softly
.
assertThat
(
reader
.
read
()).
isNull
();
}
softly
.
assertThat
(
actual
).
containsExactlyElementsOf
(
expected
);
}
}
src/test/java/cz/muni/fi/pb162/hw03/csv/CsvParserTest.java
0 → 100644
View file @
a294e06e
package
cz.muni.fi.pb162.hw03.csv
;
import
cz.muni.fi.pb162.hw03.csv.impl.CsvToolkit
;
import
org.assertj.core.api.SoftAssertions
;
import
org.assertj.core.api.junit.jupiter.InjectSoftAssertions
;
import
org.assertj.core.api.junit.jupiter.SoftAssertionsExtension
;
import
org.junit.jupiter.api.BeforeEach
;
import
org.junit.jupiter.api.DisplayName
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.api.extension.ExtendWith
;
import
java.io.IOException
;
import
java.nio.charset.StandardCharsets
;
import
java.nio.file.Path
;
import
java.util.List
;
import
java.util.Map
;
import
static
cz
.
muni
.
fi
.
pb162
.
hw03
.
TestUtils
.
resourcePath
;
@ExtendWith
(
SoftAssertionsExtension
.
class
)
public
class
CsvParserTest
{
@InjectSoftAssertions
private
SoftAssertions
softly
;
private
CsvParser
parser
;
@BeforeEach
void
setUp
()
{
parser
=
CsvToolkit
.
parser
(
","
,
StandardCharsets
.
UTF_8
);
}
@Test
@DisplayName
(
"Loads plain CSV data"
)
public
void
plainCsv
()
throws
Exception
{
List
<
List
<
String
>>
data
=
parser
.
readAll
(
resourcePath
(
"/plain.csv"
));
softly
.
assertThat
(
data
).
containsExactlyElementsOf
(
List
.
of
(
List
.
of
(
"1"
,
"H"
,
"Hydrogen"
,
"gas"
,
"nonmetal"
,
"1766"
),
List
.
of
(
"2"
,
"He"
,
"Helium"
,
"gas"
,
"noble gas"
,
"1868"
),
List
.
of
(
"3"
,
"Li"
,
"Lithium"
,
"solid"
,
"alkali metal"
,
"1817"
)
));
}
@Test
@DisplayName
(
"Loads plain CSV data with different row lengths"
)
public
void
plainCsvDifferentRowLength
()
throws
Exception
{
List
<
List
<
String
>>
data
=
parser
.
readAll
(
resourcePath
(
"/plain_broken.csv"
));
softly
.
assertThat
(
data
).
containsExactlyElementsOf
(
List
.
of
(
List
.
of
(
"1"
,
"H"
,
"Hydrogen"
,
"gas"
,
"nonmetal"
,
"1766"
),
List
.
of
(
"2"
,
"He"
,
"Helium"
,
"gas"
,
"noble gas"
,
"1868"
,
"broken"
)
));
}
@Test
@DisplayName
(
"Loads CSV data with header as plain"
)
public
void
headedCsvAsPlain
()
throws
Exception
{
List
<
List
<
String
>>
data
=
parser
.
readAll
(
resourcePath
(
"/header.csv"
));
softly
.
assertThat
(
data
).
containsExactlyElementsOf
(
List
.
of
(
List
.
of
(
"atomicNumber"
,
"symbol"
,
"name"
,
"standardState"
,
"groupBlock"
,
"yearDiscovered"
),
List
.
of
(
"1"
,
"H"
,
"Hydrogen"
,
"gas"
,
"nonmetal"
,
"1766"
),
List
.
of
(
"2"
,
"He"
,
"Helium"
,
"gas"
,
"noble gas"
,
"1868"
),
List
.
of
(
"3"
,
"Li"
,
"Lithium"
,
"solid"
,
"alkali metal"
,
"1817"
),
List
.
of
(
"4"
,
"Be"
,
"Beryllium"
,
"solid"
,
"alkaline earth metal"
,
"1798"
)