Skip to content
Snippets Groups Projects
Commit 998a802c authored by Hallvard Trætteberg's avatar Hallvard Trætteberg
Browse files

Fjernet simple-example, konfigurert pages

parent 30f6732a
No related branches found
No related tags found
No related merge requests found
Showing
with 38 additions and 1353 deletions
image: gradle:jdk12
image: gradle:jdk16-hotspot
before_script:
- export GRADLE_USER_HOME=`pwd`/.gradle
......@@ -14,5 +14,9 @@ build:
- ./gradlew -Pci=gitlab build
artifacts:
paths:
- lectures/build/docs
expire_in: 1 week
- public/lectures/build/docs
pages:
script:
- ./gradlew -Pci=gitlab build
- cp -r lectures/build/docs/asciidoc public/lectures
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "gradle run",
"type": "shell",
"command": "gradle",
"args": ["run"]
},
{
"label": "gradle version",
"type": "shell",
"command": "gradle",
"args": ["--version"]
},
{
"label": "java -version",
"type": "shell",
"command": "java",
"args": ["-version"]
},
{
"label": "sdk use java 12.0.2-open",
"type": "shell",
"command": "sdk",
"args": ["use", "java", "12.0.2-open"]
}
]
}
\ No newline at end of file
rootProject.name = 'course-material'
include 'lectures'
include 'simpleexample'
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="bin/main" path="src/main/java">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/main" path="src/main/resources">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</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"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/resources">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-10/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>
# Ignore Gradle project-specific cache directory
.gradle
# Ignore Gradle build output directory
build/
bin/
# Ignore Gradle project-specific cache directory
.gradle
# Ignore Gradle build output directory
build
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>simpleexample</name>
<comment>Project simpleexample created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
</projectDescription>
connection.project.dir=
eclipse.preferences.version=1
# Simpleexample
Dette prosjektet er et eksempel på en nokså minimalistisk trelagsapplikasjon, altså med et domenelag, brukergrensesnitt (UI) og persistens (lagring). Prosjektet inneholder tester for alle lagene, med rimelig god dekningsgrad. Prosjektet er konfigurert med gradle som byggesystem.
## Organisering av koden
Prosjektet er organisert med 2 * 2 = 4 kildekodemapper, kode og ressurser for henholdsvis applikasjonen selv og testene:
- **src/main/java** for koden til applikasjonen
- **src/main/resources** for tilhørende ressurser, f.eks. data-filer og FXML-filer, som brukes av applikasjonen.
- **src/test/java** for testkoden
- **src/test/resources** for tilhørende ressurser, f.eks. data-filer og FXML-filer, som brukes av testene.
Dette er en vanlig organisering for prosjekter som bygges med gradle (og maven).
## Domenelaget
Domenelaget inneholder alle klasser og logikk knyttet til dataene som applikasjonen handler om og håndterer. Dette laget skal være helt uavhengig av brukergrensesnittet eller lagingsteknikken som brukes.
Vår app handler om samlinger av såkalte geo-lokasjoner, altså steder identifisert med lengde- og breddegrader. Domenelaget inneholder klasser for å representere og håndtere slike, og disse finnes i **[simpleex.core](src/main/java/simpleex/core/README.md)**-pakken.
## Brukergrensesnittlaget
Brukergrensesnittlaget inneholder alle klasser og logikk knyttet til visning og handlinger på dataene i domenelaget. Brukergrensesnittet til vår app viser frem en liste av geo-lokasjoner, den som velges vises på et kart. En flytte og legge til geo-lokasjoner. Samlingen med geo-lokasjoner kan lagres og evt. leses inn igjen.
Brukergrensesnittet er laget med JavaFX og FXML og finnes i **[simpleex.ui](src/main/java/simpleex/ui/README.md)**-pakken (JavaFX-koden i **src/main/java** og FXML-filen i **src/main/resources**)
## Persistenslaget
Persistenslaget inneholder alle klasser og logikk for lagring (skriving og lesing) av dataene i domenelaget. Vårt persistenslag implementerer fillagring med JSON-syntaks.
Persistenslaget finnes i **[simpleex.json](src/main/java/simpleex/json/README.md)**-pakken.
## Bygging med gradle
For litt mer komplekse prosjekter, er det lurt å bruke et såkalt byggeverktøy, f.eks. gradle eller maven, for å automatisere oppgaver som kjøring av tester, sjekk av ulike typer kvalitet osv. Vårt prosjekt er konfigurert til å bruke [gradle](https://gradle.org), og følgelig har prosjektet en del filer og mapper spesifikt for det:
- gradle, gradlew og gradlew.bat - mappe og filer for kjøring av gradle, som regel rigget opp en gang for alle ved opprettelse av prosjektet
- settings.gradle - inneholder navnet på prosjektet og evt. navnet på mapper for delprosjekter (ikke brukt her)
- build.gradle - konfigurasjon av gradle-tillegg basert på typen prosjekt
Av disse er det build.gradle som krever mest forklaring, settings.gradle trenger bare å inneholde én linje, som navngir prosjektet: `rootProject.name = 'simpleexample'`. For litt bakgrunn om bygging generelt og gradle spesielt, se [her](ci-gradle.md).
Vårt gradle-bygg er satt opp med tillegg for java-applikasjoner generelt (**application**) og med JavaFX spesielt (**org.openjfx.javafxplugin**). Vi trenger (minst) java-versjon 10 og javafx-version 11.
I tillegg bruker vi diverse kodekvalitetsanalyseverktøy ([jacoco](https://github.com/jacoco/jacoco) med **[jacoco](https://docs.gradle.org/current/userguide/jacoco_plugin.html)**, [PMD](https://pmd.github.io) med **[pmd](https://docs.gradle.org/current/userguide/pmd_plugin.html)**, [spotbugs](https://spotbugs.github.io) med **[com.github.spotbugs](https://spotbugs.readthedocs.io/en/latest/gradle.html)** og [checkstyle](https://checkstyle.sourceforge.io) med **[checkstyle](https://docs.gradle.org/current/userguide/checkstyle_plugin.html)**). Disse er satt opp slik at de ikke stopper bygget om ikke alt er på stell. spotbugs er satt opp til å lage rapport med html i stedet for xml.
De fleste avhengighetene hentes fra de vanlige sentrale repo-ene, med unntak av FxMapControl som er lagt ved som jar-fil i **libs**-mappa.
plugins {
// java application with main method
id 'application'
// use javafx modules
id 'org.openjfx.javafxplugin' version '0.0.8'
// test coverage
id 'jacoco'
// code quality with PMD
id 'pmd'
// code quality with SpotBugs
id 'com.github.spotbugs' version '2.0.0'
// code quality with checkstyle
id 'checkstyle'
}
repositories {
jcenter()
maven {
url "https://plugins.gradle.org/m2/"
}
flatDir {
dirs 'libs'
}
}
application {
sourceCompatibility = JavaVersion.VERSION_1_10
targetCompatibility = JavaVersion.VERSION_1_10
mainClassName = 'simpleex.ui.FxApp' // application plugin
}
// javafx specific way of specifying dependencies
javafx {
version = '11'
modules = [ 'javafx.controls', 'javafx.fxml' ]
// run with --debug-jvm flag and
// launch debugger using Remote Java Application debug launch configuration
}
test {
// don't run UI test on server (that cannot run javafx)
if (project.hasProperty('ci') && "$ci" == 'gitlab') {
exclude 'simpleex/ui/*'
}
}
pmd {
// See https://docs.gradle.org/current/dsl/org.gradle.api.plugins.quality.PmdExtension.html
ignoreFailures = true
// Consider turning these off
// <rule ref="category/java/errorprone.xml/BeanMembersShouldSerialize" />
// <rule ref="category/java/errorprone.xml/DataflowAnomalyAnalysis" />
}
spotbugs {
// see http://gradle.monochromeroad.com/docs/dsl/org.gradle.api.plugins.quality.FindBugsExtension.html
ignoreFailures = true
}
// To generate an HTML report instead of XML
tasks.withType(com.github.spotbugs.SpotBugsTask) {
reports {
xml.enabled = false
html.enabled = true
}
}
checkstyle {
configFile = project.file("config/checkstyle/google_checks.xml")
}
dependencies {
// persistens
implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
// brukergrensesnitt
implementation name: 'fx-map-control-1.0'
testImplementation 'junit:junit:4.12'
// brukergrensesnitt
testImplementation 'org.testfx:testfx-core:4.0.16-alpha'
testImplementation 'org.testfx:testfx-junit:4.0.16-alpha'
testImplementation 'org.mockito:mockito-core:2.28.2'
}
# Bygging med gradle
## Hva er bygging?
Moderne IDE-er gjør det nokså greit å sett opp et prosjekt slik at kompilering gjøres automatisk og kontinuerlig og kjøring gjøres med et tastetrykk eller klikk. I det skjulte håndteres riktig oppsett og bruk av biblioteker, tilsvarende å kalle java-kompilatoren med riktig classpath (evt. modulepath med den siste versjonenen av java). Så mens man i gamle dager måtte skrive inn kompileringskommandoer i terminal, så gjøres det nå automatisk. I tillegg kommer editoren med alskens automatiske forslag til koden basert på full oversikt over tilgjengelige API-er.
Dette er vel og bra, men utvikling av applikasjoner handler ikke bare om å skrive kode, det er mange relaterte aktiviteter som er med og sikrer kvaliteten. Hvis en f.eks. skriver tester, så må disse forholde seg til egne testbibliotek (som [junit](https://junit.org/) og [mockito](https://site.mockito.org)) og kjøres jevnlig. Testkjøring av systemer som består av mange moduler, kanskje én av dem er en web-server som skal startes som en del av en test, gjør det mer komplisert.
Det er lurt å måle hvor stor del av koden som faktisk kjøres av tester, f.eks. med [jacoco](https://github.com/jacoco/jacoco). Noen prosjekter består av mange deler som både testes hver for seg og sammen. Det finnes andre kvaliteter enn korrekthet som også kan analyseres av diverse verktøy, f.eks. ryddighet, om man har fulgt konvensjoner for koding og unngått typiske kodingsfeil.
Hvis alt dette skal gjøres/kjøres manuelt, så gidder man ikke å gjøre det (ofte nok). IDE-er kan riktignok være til hjelp, men da blir det til gjengjeld opp til hver utvikler å sette det opp og det kan kreve nokså mye konfigurasjon. I stedet konfigurerer man prosjektet til å bruke et såkalt *byggeverktøy*, som lar deg kjøre utvalgte *byggeoppgaver* i riktig sekvens, basert på deklarasjoner om hva slags prosjekt en har, hvilke byggetrinn som skal være med og detaljer ved disse. Innstillingene er uavhengig av hvilken IDE du bruker, skrevet i et (mer eller mindre) leselig format og kan sjekkes inn i kode-repo og deles med alle.
## Gradle
[Gradle](https://docs.gradle.org/current/userguide/userguide.html) er et slikt byggesystem, som automatiserer oppgaver knyttet til utvikling og kvalitetssikring av programvare, f.eks.
kompilering, kjøring av enhetstester og integrasjonstester, konvertering av dokumentasjon til HTML, pakking som kjørbart program, osv. Det finnes teknisk sett ikke grenser for hva byggesystem som gradle kan gjøre, generelt handler det om å automatisere bort alt praktisk fikkel, som ellers hindrer en å jobbe effektivt.
Det finnes flere byggesystem, de viktigste i Java-verdenen er [Maven](https://maven.apache.org) og altså Gradle, mens Javascript-verdenen har sine, bl.a. [npm](https://docs.npmjs.com). Når vi velger å bruke gradle, så er det fordi det er enklere å skrive og lese oppsettet og trigge kjøring, mer fleksiblet, og det vi ønsker å automatisere i akkurat dette prosjektet håndteres godt av Gradle. For andre Java-prosjekter [kan Maven være et bedre alternativ](https://phauer.com/2018/moving-back-from-gradle-to-maven/).
Gradle er bygget rundt tre sentrale elementer:
- oppgaver (tasks) - det som automatiseres, f.eks. kompilering, kjøring av tester, osv.
- prosjekter - enhetene som oppgaver utføres innenfor
- tillegg (plugins) - angir hvilke oppgaver som hører til et visst type prosjekt
Disse tre elementene beskrives i to filer. **settings.gradle**-fila angir navn på prosjektet og eventuelle delprosjekter. Resten angis i **build.gradle**-fila, bl.a. hvilke avhengigheter det er til eksterne moduler og mellom prosjektene, hvilke tillegg som bør aktiveres for disse prosjektene (basert på hva slags type prosjekt det er) og hvordan hver type oppgave skal konfigureres.
Det litt spesielle med Gradle er at filene for å sette opp et Gradle-bygg egentlig er [kode skrevet i det Java-lignende språket Groovy](https://docs.gradle.org/current/userguide/groovy_build_script_primer.html). Koden brukes primært til konfigurasjon, altså bygge opp beskrivelsen av oppgavene, prosjektene og tilleggene og. API-et er utformet slik at koden skal se deklarativ ut.
En kan flette inn vanlig kode også, hvis en skjønner litt om hvordan API-et virker. Dette gir enorm fleksibilitet, men kan også gjøre filene vanskelige å forstå.
## Gradle-tillegg
`plugins`-blokken i **build.gradle** angir hvilke tillegg som skal aktiveres for prosjektet. Det handler dels om hva slags prosjekt en har, f.eks. om det er et Java-prosjekt og evt. bruker JavaFX, dels om hva som skal automatiseres. Deklarasjonen under angir at prosjektet er et Java-applikasjonsprosjekt og en ønsker å automatisere måling av testdekningsgrad (code coverage) med **jacoco**.
```
plugins {
// java application with main method
id 'application'
// test coverage
id 'jacoco'
}
```
## Konfigurasjon av oppgaver
For hvert tillegg vil en gjerne ha ytterligere konfigurasjon, enten som enkeltinstruksjoner eller blokker. F.eks. angir instruksjonen `mainClassName = ...` hvilken klasse som inneholder `main`-metoden, og dette brukes av `application`-tillegget. Detaljene finner en typisk ved å google, prøv f.eks. å søke på `gradle application plugin`.
## Avhengigheter
En av de viktigste blokkene i **build.gradle** er `dependencies`, altså *avhengigheter*. Her lister man opp hvilke kodebiblioteker (jar-filer) ens egen kode er avhengig av og til hva slags formål. Dette hjelper ulike tillegg å bruke riktig classpath til kompilering og kjøring av både vanlig kode og testkoden. Blokken under angir f.eks. at koden bruker `jackson-databind`-biblioteket og at en til testing også trenger `junit`-biblioteket:
```
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
testImplementation 'junit:junit:4.12'
}
```
Denne blokken angir hvilke biblioteker en trenger, men ikke hvor de finnes. Med `repositories`-blokken lister en opp hvor Gradle vil søke etter biblioteker (inkludert Gradle-tilleggene). De fleste vanlige bibliotek finnes i `jcenter()`, men det hender en må inkludere jar-filer (i mapper) i prosjektet. Med blokken under vil Gradle først søke etter biblioteker i `jcenter()` og deretter i mappa `libs`.
```
repositories {
jcenter()
flatDir {
dirs 'libs'
}
}
```
Formatet for identifikasjon av et bibliotek er avhengig av hvor (hva slags sted) det finnes. `jcenter()` bruker såkalte *maven-koordinater* på formatet *gruppe*:*navn*:*versjon*. Så siden `jackson`-biblioteket finnes i `jcenter()` så brukes `com.fasterxml.jackson.core:jackson-databind:2.9.8` i eksemplet over. Hvis en har et bibliotek i en lokal mappe, så brukes `name:` etterfulgt av jar-filnavnet (uten .jar).
This diff is collapsed.
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<!--
Checkstyle configuration that checks the Google coding conventions from Google Java Style
that can be found at https://google.github.io/styleguide/javaguide.html
Checkstyle is very configurable. Be sure to read the documentation at
http://checkstyle.sf.net (or in your downloaded distribution).
To completely disable a check, just comment it out or delete it from the file.
Authors: Max Vetrenko, Ruslan Diachenko, Roman Ivanov.
-->
<module name = "Checker">
<property name="charset" value="UTF-8"/>
<property name="severity" value="warning"/>
<property name="fileExtensions" value="java, properties, xml"/>
<!-- Excludes all 'module-info.java' files -->
<!-- See https://checkstyle.org/config_filefilters.html -->
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="module\-info\.java$"/>
</module>
<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
</module>
<module name="TreeWalker">
<module name="OuterTypeFilename"/>
<module name="IllegalTokenText">
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
<property name="format"
value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
<property name="message"
value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
</module>
<module name="AvoidEscapedUnicodeCharacters">
<property name="allowEscapesForControlCharacters" value="true"/>
<property name="allowByTailComment" value="true"/>
<property name="allowNonPrintableEscapes" value="true"/>
</module>
<module name="LineLength">
<property name="max" value="100"/>
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
</module>
<module name="AvoidStarImport"/>
<module name="OneTopLevelClass"/>
<module name="NoLineWrap"/>
<module name="EmptyBlock">
<property name="option" value="TEXT"/>
<property name="tokens"
value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
</module>
<module name="NeedBraces"/>
<module name="LeftCurly"/>
<module name="RightCurly">
<property name="id" value="RightCurlySame"/>
<property name="tokens"
value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE,
LITERAL_DO"/>
</module>
<module name="RightCurly">
<property name="id" value="RightCurlyAlone"/>
<property name="option" value="alone"/>
<property name="tokens"
value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT,
INSTANCE_INIT"/>
</module>
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true"/>
<property name="allowEmptyLambdas" value="true"/>
<property name="allowEmptyMethods" value="true"/>
<property name="allowEmptyTypes" value="true"/>
<property name="allowEmptyLoops" value="true"/>
<message key="ws.notFollowed"
value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/>
<message key="ws.notPreceded"
value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
</module>
<module name="OneStatementPerLine"/>
<module name="MultipleVariableDeclarations"/>
<module name="ArrayTypeStyle"/>
<module name="MissingSwitchDefault"/>
<module name="FallThrough"/>
<module name="UpperEll"/>
<module name="ModifierOrder"/>
<module name="EmptyLineSeparator">
<property name="allowNoEmptyLineBetweenFields" value="true"/>
</module>
<module name="SeparatorWrap">
<property name="id" value="SeparatorWrapDot"/>
<property name="tokens" value="DOT"/>
<property name="option" value="nl"/>
</module>
<module name="SeparatorWrap">
<property name="id" value="SeparatorWrapComma"/>
<property name="tokens" value="COMMA"/>
<property name="option" value="EOL"/>
</module>
<module name="SeparatorWrap">
<!-- ELLIPSIS is EOL until https://github.com/google/styleguide/issues/258 -->
<property name="id" value="SeparatorWrapEllipsis"/>
<property name="tokens" value="ELLIPSIS"/>
<property name="option" value="EOL"/>
</module>
<module name="SeparatorWrap">
<!-- ARRAY_DECLARATOR is EOL until https://github.com/google/styleguide/issues/259 -->
<property name="id" value="SeparatorWrapArrayDeclarator"/>
<property name="tokens" value="ARRAY_DECLARATOR"/>
<property name="option" value="EOL"/>
</module>
<module name="SeparatorWrap">
<property name="id" value="SeparatorWrapMethodRef"/>
<property name="tokens" value="METHOD_REF"/>
<property name="option" value="nl"/>
</module>
<module name="PackageName">
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
<message key="name.invalidPattern"
value="Package name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="TypeName">
<message key="name.invalidPattern"
value="Type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="MemberName">
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
<message key="name.invalidPattern"
value="Member name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ParameterName">
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="LambdaParameterName">
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Lambda parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="CatchParameterName">
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Catch parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="LocalVariableName">
<property name="tokens" value="VARIABLE_DEF"/>
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Local variable name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ClassTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
value="Class type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="MethodTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
value="Method type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="InterfaceTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
value="Interface type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="NoFinalizer"/>
<module name="GenericWhitespace">
<message key="ws.followed"
value="GenericWhitespace ''{0}'' is followed by whitespace."/>
<message key="ws.preceded"
value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
<message key="ws.illegalFollow"
value="GenericWhitespace ''{0}'' should followed by whitespace."/>
<message key="ws.notPreceded"
value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
</module>
<module name="Indentation">
<property name="basicOffset" value="2"/>
<property name="braceAdjustment" value="0"/>
<property name="caseIndent" value="2"/>
<property name="throwsIndent" value="4"/>
<property name="lineWrappingIndentation" value="4"/>
<property name="arrayInitIndent" value="2"/>
</module>
<module name="AbbreviationAsWordInName">
<property name="ignoreFinal" value="false"/>
<property name="allowedAbbreviationLength" value="1"/>
</module>
<module name="OverloadMethodsDeclarationOrder"/>
<module name="VariableDeclarationUsageDistance"/>
<module name="CustomImportOrder">
<property name="sortImportsInGroupAlphabetically" value="true"/>
<property name="separateLineBetweenGroups" value="true"/>
<property name="customImportOrderRules" value="STATIC###THIRD_PARTY_PACKAGE"/>
</module>
<module name="MethodParamPad"/>
<module name="NoWhitespaceBefore">
<property name="tokens"
value="COMMA, SEMI, POST_INC, POST_DEC, DOT, ELLIPSIS, METHOD_REF"/>
<property name="allowLineBreaks" value="true"/>
</module>
<module name="ParenPad"/>
<module name="OperatorWrap">
<property name="option" value="NL"/>
<property name="tokens"
value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR,
LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR, METHOD_REF "/>
</module>
<module name="AnnotationLocation">
<property name="id" value="AnnotationLocationMostCases"/>
<property name="tokens"
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF"/>
</module>
<module name="AnnotationLocation">
<property name="id" value="AnnotationLocationVariables"/>
<property name="tokens" value="VARIABLE_DEF"/>
<property name="allowSamelineMultipleAnnotations" value="true"/>
</module>
<module name="NonEmptyAtclauseDescription"/>
<!-- Removed due to instantiation exception
<module name="InvalidJavadocPosition"/>
-->
<module name="JavadocTagContinuationIndentation"/>
<module name="SummaryJavadoc">
<property name="forbiddenSummaryFragments"
value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/>
</module>
<module name="JavadocParagraph"/>
<module name="AtclauseOrder">
<property name="tagOrder" value="@param, @return, @throws, @deprecated"/>
<property name="target"
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
</module>
<module name="JavadocMethod">
<property name="scope" value="public"/>
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingThrowsTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
<property name="allowedAnnotations" value="Override, Test"/>
<property name="allowThrowsTagsForSubclasses" value="true"/>
</module>
<!-- Removed due to instantiation exception
<module name="MissingJavadocMethod">
<property name="scope" value="public"/>
<property name="minLineCount" value="2"/>
<property name="allowedAnnotations" value="Override, Test"/>
</module>
-->
<module name="MethodName">
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/>
<message key="name.invalidPattern"
value="Method name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="SingleLineJavadoc">
<property name="ignoreInlineTags" value="false"/>
</module>
<module name="EmptyCatchBlock">
<property name="exceptionVariableName" value="expected"/>
</module>
<module name="CommentsIndentation"/>
</module>
</module>
File deleted
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem http://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
File deleted
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user manual at https://docs.gradle.org/5.4/userguide/multi_project_builds.html
*/
rootProject.name = 'simpleexample'
package simpleex.core;
/**
* Represents a geo-location as a latitude, longitude pair.
* @author hal
*
*/
public class LatLong {
public static final String SEPARATOR = ",";
private final double latitude;
private final double longitude;
/**
* Initialize a LatLong with provided latitude and longitude.
* @param latitude the latitude
* @param longitude the longitude
*/
public LatLong(final double latitude, final double longitude) {
super();
this.latitude = latitude;
this.longitude = longitude;
}
/**
* Gets the latitude.
* @return the latitude
*/
public double getLatitude() {
return latitude;
}
/**
* Gets the longitude.
* @return the longitude
*/
public double getLongitude() {
return longitude;
}
@Override
public String toString() {
return latitude + SEPARATOR + longitude;
}
@Override
public int hashCode() {
final int prime = 31;
long temp = Double.doubleToLongBits(latitude);
int result = prime + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(longitude);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
final LatLong other = (LatLong) obj;
return (Double.doubleToLongBits(latitude) == Double.doubleToLongBits(other.latitude)
&& Double.doubleToLongBits(longitude) == Double.doubleToLongBits(other.longitude));
}
/**
* Creates a LatLong object from a String.
* The format is &lt;latitude&gt;,&lt;longitude&gt;.
* @param s the String to parse
* @return the new LatLong object
*/
public static LatLong valueOf(final String s) {
return valueOf(s, SEPARATOR);
}
/**
* Creates a LatLong object from a String, using a specific separator.
* The format is &lt;latitude&gt;&lt;separator&gt;&lt;longitude&gt;.
* @param s
* @param sep
* @return
*/
public static LatLong valueOf(final String s, final String sep) {
final int pos = s.indexOf(sep);
if (pos < 0) {
throw new IllegalArgumentException("No '" + sep + "' in " + s);
}
final double lat = Double.valueOf(s.substring(0, pos).trim());
final double lon = Double.valueOf(s.substring(pos + sep.length()).trim());
return new LatLong(lat, lon);
}
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :: : */
/* :: This routine calculates the distance between two points (given the : */
/* :: latitude/longitude of those points). It is being used to calculate : */
/* :: the distance between two locations using GeoDataSource (TM) products : */
/* :: : */
/* :: Definitions: : */
/* :: South latitudes are negative, east longitudes are positive : */
/* :: : */
/* :: Passed to function: : */
/* :: lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees) : */
/* :: lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees) : */
/* :: Worldwide cities and other features databases with latitude longitude : */
/* :: are available at http://www.geodatasource.com : */
/* :: : */
/* :: For enquiries, please contact sales@geodatasource.com : */
/* :: : */
/* :: Official Web site: http://www.geodatasource.com : */
/* :: : */
/* :: GeoDataSource.com (C) All Rights Reserved 2015 : */
/* :: : */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
public static double distance(final double lat1, final double lon1, final double lat2,
final double lon2) {
if (lon1 == lon2 && lat1 == lat2) {
return 0.0;
}
final double theta = lon1 - lon2;
double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))
+ Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
dist = Math.acos(dist);
// convert to degrees
dist = rad2deg(dist);
dist = dist * 60 * 1.1515;
// convert to meters
dist = dist * 1609.344;
return dist;
}
/**
* Computes the distance in meters between two LatLong objects.
* @param latLong1 the first LatLong
* @param latLong2 the other LatLong
* @return the distance in meters
*/
public static double distance(final LatLong latLong1, final LatLong latLong2) {
return distance(latLong1.latitude, latLong1.longitude, latLong2.latitude, latLong2.longitude);
}
/**
* Computes the distance in meters between this LatLong and an other one.
* @param latLong2 the other LatLong
* @return the distance in meters
*/
public double distance(final LatLong latLong2) {
return distance(latitude, longitude, latLong2.latitude, latLong2.longitude);
}
/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :: This function converts decimal degrees to radians : */
/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
private static double deg2rad(final double deg) {
return (deg * Math.PI / 180.0);
}
/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :: This function converts radians to decimal degrees : */
/* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
private static double rad2deg(final double rad) {
return (rad * 180 / Math.PI);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment