Functional, not fully understood, but functional.
This commit is contained in:
parent
40f5c8b460
commit
1fa5250338
45 changed files with 4680 additions and 441 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,5 @@
|
||||||
|
build
|
||||||
|
|
||||||
.gradle
|
.gradle
|
||||||
gradlew*
|
gradlew*
|
||||||
gradle/
|
gradle/
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -39,6 +39,16 @@
|
||||||
</option>
|
</option>
|
||||||
</configuration>
|
</configuration>
|
||||||
</facet>
|
</facet>
|
||||||
|
<facet type="jpa" name="JPA">
|
||||||
|
<configuration>
|
||||||
|
<setting name="validation-enabled" value="true" />
|
||||||
|
<setting name="provider-name" value="" />
|
||||||
|
<datasource-mapping>
|
||||||
|
<factory-entry name="employee" />
|
||||||
|
</datasource-mapping>
|
||||||
|
<deploymentDescriptor name="persistence.xml" url="file://$MODULE_DIR$/../../src/main/resources/META-INF/persistence.xml" />
|
||||||
|
</configuration>
|
||||||
|
</facet>
|
||||||
</component>
|
</component>
|
||||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||||
<output url="file://$MODULE_DIR$/../../build/classes/main" />
|
<output url="file://$MODULE_DIR$/../../build/classes/main" />
|
||||||
|
@ -50,8 +60,10 @@
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="library" name="Gradle: javax.inject:javax.inject:1" level="project" />
|
<orderEntry type="library" name="Gradle: javax.inject:javax.inject:1" level="project" />
|
||||||
|
<orderEntry type="library" name="Gradle: commons-codec:commons-codec:1.10" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: com.google.guava:guava:21.0" level="project" />
|
<orderEntry type="library" name="Gradle: com.google.guava:guava:21.0" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: joda-time:joda-time:2.9.9" level="project" />
|
<orderEntry type="library" name="Gradle: joda-time:joda-time:2.9.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Gradle: com.github.rholder.fauxflake:fauxflake-core:1.1.0" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: org.projectlombok:lombok:1.16.16" level="project" />
|
<orderEntry type="library" name="Gradle: org.projectlombok:lombok:1.16.16" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: org.postgresql:postgresql:42.0.0" level="project" />
|
<orderEntry type="library" name="Gradle: org.postgresql:postgresql:42.0.0" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: org.eclipse.persistence:eclipselink:2.6.4" level="project" />
|
<orderEntry type="library" name="Gradle: org.eclipse.persistence:eclipselink:2.6.4" level="project" />
|
||||||
|
|
|
@ -51,8 +51,10 @@
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="module" module-name="farsite_main" />
|
<orderEntry type="module" module-name="farsite_main" />
|
||||||
<orderEntry type="library" name="Gradle: javax.inject:javax.inject:1" level="project" />
|
<orderEntry type="library" name="Gradle: javax.inject:javax.inject:1" level="project" />
|
||||||
|
<orderEntry type="library" name="Gradle: commons-codec:commons-codec:1.10" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: com.google.guava:guava:21.0" level="project" />
|
<orderEntry type="library" name="Gradle: com.google.guava:guava:21.0" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: joda-time:joda-time:2.9.9" level="project" />
|
<orderEntry type="library" name="Gradle: joda-time:joda-time:2.9.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Gradle: com.github.rholder.fauxflake:fauxflake-core:1.1.0" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: org.projectlombok:lombok:1.16.16" level="project" />
|
<orderEntry type="library" name="Gradle: org.projectlombok:lombok:1.16.16" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: org.postgresql:postgresql:42.0.0" level="project" />
|
<orderEntry type="library" name="Gradle: org.postgresql:postgresql:42.0.0" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: org.eclipse.persistence:eclipselink:2.6.4" level="project" />
|
<orderEntry type="library" name="Gradle: org.eclipse.persistence:eclipselink:2.6.4" level="project" />
|
||||||
|
@ -68,6 +70,12 @@
|
||||||
<orderEntry type="library" name="Gradle: org.zalando:logbook-core:1.1.1" level="project" />
|
<orderEntry type="library" name="Gradle: org.zalando:logbook-core:1.1.1" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: com.github.javafaker:javafaker:0.13" level="project" />
|
<orderEntry type="library" name="Gradle: com.github.javafaker:javafaker:0.13" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: junit:junit:4.12" level="project" />
|
<orderEntry type="library" name="Gradle: junit:junit:4.12" level="project" />
|
||||||
|
<orderEntry type="library" name="Gradle: org.mockito:mockito-all:1.10.19" level="project" />
|
||||||
|
<orderEntry type="library" name="Gradle: org.assertj:assertj-core:2.6.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Gradle: com.github.stefanbirkner:system-rules:1.16.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Gradle: nl.jqno.equalsverifier:equalsverifier:1.7.8" level="project" />
|
||||||
|
<orderEntry type="library" name="Gradle: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Gradle: org.quicktheories:quicktheories:0.13" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: org.eclipse.persistence:commonj.sdo:2.1.1" level="project" />
|
<orderEntry type="library" name="Gradle: org.eclipse.persistence:commonj.sdo:2.1.1" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: javax.validation:validation-api:1.1.0.Final" level="project" />
|
<orderEntry type="library" name="Gradle: javax.validation:validation-api:1.1.0.Final" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: org.glassfish:javax.json:1.0.4" level="project" />
|
<orderEntry type="library" name="Gradle: org.glassfish:javax.json:1.0.4" level="project" />
|
||||||
|
@ -84,7 +92,6 @@
|
||||||
<orderEntry type="library" name="Gradle: com.google.gag:gag:1.0.1" level="project" />
|
<orderEntry type="library" name="Gradle: com.google.gag:gag:1.0.1" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: org.apache.commons:commons-lang3:3.5" level="project" />
|
<orderEntry type="library" name="Gradle: org.apache.commons:commons-lang3:3.5" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: com.github.mifmif:generex:1.0.2" level="project" />
|
<orderEntry type="library" name="Gradle: com.github.mifmif:generex:1.0.2" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: org.hamcrest:hamcrest-core:1.3" level="project" />
|
|
||||||
<orderEntry type="library" name="Gradle: com.google.protobuf:protobuf-java:2.6.1" level="project" />
|
<orderEntry type="library" name="Gradle: com.google.protobuf:protobuf-java:2.6.1" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: io.netty:netty:3.6.1.Final" level="project" />
|
<orderEntry type="library" name="Gradle: io.netty:netty:3.6.1.Final" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: dk.brics.automaton:automaton:1.11-8" level="project" />
|
<orderEntry type="library" name="Gradle: dk.brics.automaton:automaton:1.11-8" level="project" />
|
||||||
|
|
50
NOTES
Normal file
50
NOTES
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
http://wiki.eclipse.org/EclipseLink/Examples/JPA/Employee
|
||||||
|
http://java-persistence-performance.blogspot.com/2013/06/cool-performance-features-of.html
|
||||||
|
|
||||||
|
pkill -9 crdb && rm -rf /tmp/far/* && (cd /tmp/far; crdb start --background --http-port=9090 --vmodule=executor=2; sleep 1) && echo "create database farsite;" | crdb sql && tail -f /tmp/far/cockroach-data/logs/crdb.log
|
||||||
|
|
||||||
|
|
||||||
|
// jpa weaving
|
||||||
|
def entitiesBasePackage = 'com.example.farsite.model'
|
||||||
|
|
||||||
|
compileJava {
|
||||||
|
destinationDir file("$buildDir/compiled-classes")
|
||||||
|
}
|
||||||
|
|
||||||
|
task copyNonPersistentClasses(type: Copy, dependsOn: compileJava) {
|
||||||
|
from "$buildDir/compiled-classes"
|
||||||
|
into sourceSets.main.output.classesDir
|
||||||
|
exclude '**/' + entitiesBasePackage.replaceAll('\\.','/') + '/**'
|
||||||
|
includeEmptyDirs = false
|
||||||
|
}
|
||||||
|
task copyPersistentClasses(type: Copy, dependsOn: compileJava) {
|
||||||
|
from "$buildDir/compiled-classes"
|
||||||
|
into "$buildDir/unwoven-persistent-classes"
|
||||||
|
include '**/' + entitiesBasePackage.replaceAll('\\.','/') + '/**'
|
||||||
|
includeEmptyDirs = false
|
||||||
|
}
|
||||||
|
task weaveJpaEntities(type: JavaExec, dependsOn: [copyPersistentClasses,processResources]) {
|
||||||
|
main = 'org.eclipse.persistence.tools.weaving.jpa.StaticWeave'
|
||||||
|
classpath configurations.weave.incoming.files
|
||||||
|
args '-persistenceinfo'
|
||||||
|
args processResources.destinationDir.absolutePath
|
||||||
|
args '-classpath'
|
||||||
|
args configurations.compile.incoming.files.asPath
|
||||||
|
args '-loglevel'
|
||||||
|
args 'INFO'
|
||||||
|
args copyPersistentClasses.destinationDir.absolutePath
|
||||||
|
args sourceSets.main.output.classesDir.absolutePath
|
||||||
|
|
||||||
|
inputs.files fileTree(copyPersistentClasses.destinationDir),fileTree(processResources.destinationDir).matching({pattern -> pattern.include('**/META-INF/persistence.xml')})
|
||||||
|
outputs.dir sourceSets.main.output.classesDir
|
||||||
|
}
|
||||||
|
//classes.dependsOn copyNonPersistentClasses,weaveJpaEntities
|
||||||
|
|
||||||
|
dependencies
|
||||||
|
weave group: 'org.eclipse.persistence', name: 'javax.persistence', version: '2.+'
|
||||||
|
weave group: 'org.eclipse.persistence', name: 'org.eclipse.persistence.jpa', version: '2.+'
|
||||||
|
|
||||||
|
configurations
|
||||||
|
weave
|
||||||
|
|
||||||
|
mainClassName = "com.example.farsite.Main"
|
46
build.gradle
46
build.gradle
|
@ -24,20 +24,19 @@ apply plugin: 'com.uber.okbuck'
|
||||||
apply plugin: 'nebula.dependency-lock'
|
apply plugin: 'nebula.dependency-lock'
|
||||||
apply plugin: 'application'
|
apply plugin: 'application'
|
||||||
|
|
||||||
mainClassName = "com.example.farsite.Main"
|
|
||||||
applicationDefaultJvmArgs = ["-Dgreeting.language=en"]
|
applicationDefaultJvmArgs = ["-Dgreeting.language=en"]
|
||||||
|
|
||||||
|
task wrapper(type: Wrapper) {
|
||||||
|
gradleVersion = '2.2'
|
||||||
|
}
|
||||||
|
|
||||||
task execute(type:JavaExec) {
|
task execute(type:JavaExec) {
|
||||||
classpath = sourceSets.main.runtimeClasspath
|
classpath = sourceSets.main.runtimeClasspath
|
||||||
main = project.hasProperty("mainClass") ? project.getProperty("mainClass") : "com.example.farsite.Main"
|
main = project.hasProperty("mainClass") ? project.getProperty("mainClass") : "com.example.farsite.test.Main"
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
testCompile 'junit:junit:4.12'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
baseName = ''
|
baseName = 'farsite'
|
||||||
version = '0.0.1-SNAPSHOT'
|
version = '0.0.1-SNAPSHOT'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,12 +64,18 @@ dependencies {
|
||||||
// Some Java Extras
|
// Some Java Extras
|
||||||
compile group: 'javax.inject', name: 'javax.inject', version: '1'
|
compile group: 'javax.inject', name: 'javax.inject', version: '1'
|
||||||
|
|
||||||
|
// Apache Commons
|
||||||
|
compile group: 'commons-codec', name: 'commons-codec', version: '1.+'
|
||||||
|
|
||||||
// Google Guava, "For all the Goodness(TM)"
|
// Google Guava, "For all the Goodness(TM)"
|
||||||
compile group: 'com.google.guava', name: 'guava', version: '21.+'
|
compile group: 'com.google.guava', name: 'guava', version: '21.+'
|
||||||
|
|
||||||
// Joda Time, "Because time is hard(TM)"
|
// Joda Time, "Because time is hard(TM)"
|
||||||
compile group: 'joda-time', name: 'joda-time', version: '2.+'
|
compile group: 'joda-time', name: 'joda-time', version: '2.+'
|
||||||
|
|
||||||
|
// Flake ID generation
|
||||||
|
compile group: 'com.github.rholder.fauxflake', name: 'fauxflake-core', version: '1.+'
|
||||||
|
|
||||||
// Lombok, "Where less is more(TM)"
|
// Lombok, "Where less is more(TM)"
|
||||||
compile group: 'org.projectlombok', name: 'lombok', version: '1.+'
|
compile group: 'org.projectlombok', name: 'lombok', version: '1.+'
|
||||||
|
|
||||||
|
@ -83,7 +88,6 @@ dependencies {
|
||||||
compile group: 'org.eclipse.persistence', name: 'javax.persistence', version: '2.+'
|
compile group: 'org.eclipse.persistence', name: 'javax.persistence', version: '2.+'
|
||||||
compile group: 'org.eclipse.persistence', name: 'org.eclipse.persistence.jpa', version: '2.+'
|
compile group: 'org.eclipse.persistence', name: 'org.eclipse.persistence.jpa', version: '2.+'
|
||||||
|
|
||||||
|
|
||||||
// Dropwizard (aka. CodaHale) Metrics, "Measure all the things!(TM)"
|
// Dropwizard (aka. CodaHale) Metrics, "Measure all the things!(TM)"
|
||||||
compile group: 'io.dropwizard.metrics', name: 'metrics-core', version: '3.+'
|
compile group: 'io.dropwizard.metrics', name: 'metrics-core', version: '3.+'
|
||||||
compile group: 'io.dropwizard.metrics', name: 'metrics-jvm', version: '3.+'
|
compile group: 'io.dropwizard.metrics', name: 'metrics-jvm', version: '3.+'
|
||||||
|
@ -96,11 +100,31 @@ dependencies {
|
||||||
compile group: 'org.slf4j', name: 'log4j-over-slf4j', version: '1.+'
|
compile group: 'org.slf4j', name: 'log4j-over-slf4j', version: '1.+'
|
||||||
compile group: 'org.zalando', name: 'logbook-core', version: '1.+'
|
compile group: 'org.zalando', name: 'logbook-core', version: '1.+'
|
||||||
|
|
||||||
// Fake data generator
|
|
||||||
compile group: 'com.github.javafaker', name: 'javafaker', version: '0.+'
|
compile group: 'com.github.javafaker', name: 'javafaker', version: '0.+'
|
||||||
|
|
||||||
|
// Testing
|
||||||
|
testCompile group: 'junit', name: 'junit', version: '4.+'
|
||||||
|
testCompile group: 'org.mockito', name: 'mockito-all', version: '1.+'
|
||||||
|
testCompile group: 'org.assertj', name: 'assertj-core', version: '2.+'
|
||||||
|
testCompile group: 'com.github.stefanbirkner', name: 'system-rules', version: '1.+'
|
||||||
|
testCompile group: 'nl.jqno.equalsverifier', name: 'equalsverifier', version: '1.+'
|
||||||
|
testCompile group: 'org.hamcrest', name: 'hamcrest-core', version: '1.3'
|
||||||
|
testCompile group: 'org.quicktheories', name: 'quicktheories', version: '0.+'
|
||||||
}
|
}
|
||||||
|
|
||||||
task wrapper(type: Wrapper) {
|
task performJPAWeaving(type: JavaExec, dependsOn: "compileJava"){
|
||||||
gradleVersion = '2.2'
|
inputs.dir compileJava.destinationDir
|
||||||
|
outputs.dir compileJava.destinationDir
|
||||||
|
main "org.eclipse.persistence.tools.weaving.jpa.StaticWeave"
|
||||||
|
args "-persistenceinfo",
|
||||||
|
"src/main/resources",
|
||||||
|
compileJava.destinationDir.getAbsolutePath(),
|
||||||
|
compileJava.destinationDir.getAbsolutePath()
|
||||||
|
classpath = configurations.compile
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile){
|
||||||
|
doLast{
|
||||||
|
tasks.performJPAWeaving.execute()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
"locked": "21.0",
|
"locked": "21.0",
|
||||||
"requested": "21.+"
|
"requested": "21.+"
|
||||||
},
|
},
|
||||||
|
"commons-codec:commons-codec": {
|
||||||
|
"locked": "1.10",
|
||||||
|
"requested": "1.+"
|
||||||
|
},
|
||||||
"io.dropwizard.metrics:metrics-core": {
|
"io.dropwizard.metrics:metrics-core": {
|
||||||
"locked": "3.2.2",
|
"locked": "3.2.2",
|
||||||
"requested": "3.+"
|
"requested": "3.+"
|
||||||
|
@ -82,6 +86,10 @@
|
||||||
"locked": "21.0",
|
"locked": "21.0",
|
||||||
"requested": "21.+"
|
"requested": "21.+"
|
||||||
},
|
},
|
||||||
|
"commons-codec:commons-codec": {
|
||||||
|
"locked": "1.10",
|
||||||
|
"requested": "1.+"
|
||||||
|
},
|
||||||
"io.dropwizard.metrics:metrics-core": {
|
"io.dropwizard.metrics:metrics-core": {
|
||||||
"locked": "3.2.2",
|
"locked": "3.2.2",
|
||||||
"requested": "3.+"
|
"requested": "3.+"
|
||||||
|
@ -152,6 +160,10 @@
|
||||||
"locked": "21.0",
|
"locked": "21.0",
|
||||||
"requested": "21.+"
|
"requested": "21.+"
|
||||||
},
|
},
|
||||||
|
"commons-codec:commons-codec": {
|
||||||
|
"locked": "1.10",
|
||||||
|
"requested": "1.+"
|
||||||
|
},
|
||||||
"io.dropwizard.metrics:metrics-core": {
|
"io.dropwizard.metrics:metrics-core": {
|
||||||
"locked": "3.2.2",
|
"locked": "3.2.2",
|
||||||
"requested": "3.+"
|
"requested": "3.+"
|
||||||
|
@ -218,10 +230,18 @@
|
||||||
"locked": "0.13",
|
"locked": "0.13",
|
||||||
"requested": "0.+"
|
"requested": "0.+"
|
||||||
},
|
},
|
||||||
|
"com.github.stefanbirkner:system-rules": {
|
||||||
|
"locked": "1.16.1",
|
||||||
|
"requested": "1.+"
|
||||||
|
},
|
||||||
"com.google.guava:guava": {
|
"com.google.guava:guava": {
|
||||||
"locked": "21.0",
|
"locked": "21.0",
|
||||||
"requested": "21.+"
|
"requested": "21.+"
|
||||||
},
|
},
|
||||||
|
"commons-codec:commons-codec": {
|
||||||
|
"locked": "1.10",
|
||||||
|
"requested": "1.+"
|
||||||
|
},
|
||||||
"io.dropwizard.metrics:metrics-core": {
|
"io.dropwizard.metrics:metrics-core": {
|
||||||
"locked": "3.2.2",
|
"locked": "3.2.2",
|
||||||
"requested": "3.+"
|
"requested": "3.+"
|
||||||
|
@ -252,7 +272,15 @@
|
||||||
},
|
},
|
||||||
"junit:junit": {
|
"junit:junit": {
|
||||||
"locked": "4.12",
|
"locked": "4.12",
|
||||||
"requested": "4.12"
|
"requested": "4.+"
|
||||||
|
},
|
||||||
|
"nl.jqno.equalsverifier:equalsverifier": {
|
||||||
|
"locked": "1.7.8",
|
||||||
|
"requested": "1.+"
|
||||||
|
},
|
||||||
|
"org.assertj:assertj-core": {
|
||||||
|
"locked": "2.6.0",
|
||||||
|
"requested": "2.+"
|
||||||
},
|
},
|
||||||
"org.eclipse.persistence:eclipselink": {
|
"org.eclipse.persistence:eclipselink": {
|
||||||
"locked": "2.6.4",
|
"locked": "2.6.4",
|
||||||
|
@ -266,6 +294,14 @@
|
||||||
"locked": "2.6.4",
|
"locked": "2.6.4",
|
||||||
"requested": "2.+"
|
"requested": "2.+"
|
||||||
},
|
},
|
||||||
|
"org.hamcrest:hamcrest-core": {
|
||||||
|
"locked": "1.3",
|
||||||
|
"requested": "1.3"
|
||||||
|
},
|
||||||
|
"org.mockito:mockito-all": {
|
||||||
|
"locked": "1.10.19",
|
||||||
|
"requested": "1.+"
|
||||||
|
},
|
||||||
"org.postgresql:postgresql": {
|
"org.postgresql:postgresql": {
|
||||||
"locked": "42.0.0",
|
"locked": "42.0.0",
|
||||||
"requested": "42.+"
|
"requested": "42.+"
|
||||||
|
@ -274,6 +310,10 @@
|
||||||
"locked": "1.16.16",
|
"locked": "1.16.16",
|
||||||
"requested": "1.+"
|
"requested": "1.+"
|
||||||
},
|
},
|
||||||
|
"org.quicktheories:quicktheories": {
|
||||||
|
"locked": "0.13",
|
||||||
|
"requested": "0.+"
|
||||||
|
},
|
||||||
"org.slf4j:log4j-over-slf4j": {
|
"org.slf4j:log4j-over-slf4j": {
|
||||||
"locked": "1.7.25",
|
"locked": "1.7.25",
|
||||||
"requested": "1.+"
|
"requested": "1.+"
|
||||||
|
@ -292,10 +332,18 @@
|
||||||
"locked": "0.13",
|
"locked": "0.13",
|
||||||
"requested": "0.+"
|
"requested": "0.+"
|
||||||
},
|
},
|
||||||
|
"com.github.stefanbirkner:system-rules": {
|
||||||
|
"locked": "1.16.1",
|
||||||
|
"requested": "1.+"
|
||||||
|
},
|
||||||
"com.google.guava:guava": {
|
"com.google.guava:guava": {
|
||||||
"locked": "21.0",
|
"locked": "21.0",
|
||||||
"requested": "21.+"
|
"requested": "21.+"
|
||||||
},
|
},
|
||||||
|
"commons-codec:commons-codec": {
|
||||||
|
"locked": "1.10",
|
||||||
|
"requested": "1.+"
|
||||||
|
},
|
||||||
"io.dropwizard.metrics:metrics-core": {
|
"io.dropwizard.metrics:metrics-core": {
|
||||||
"locked": "3.2.2",
|
"locked": "3.2.2",
|
||||||
"requested": "3.+"
|
"requested": "3.+"
|
||||||
|
@ -326,7 +374,15 @@
|
||||||
},
|
},
|
||||||
"junit:junit": {
|
"junit:junit": {
|
||||||
"locked": "4.12",
|
"locked": "4.12",
|
||||||
"requested": "4.12"
|
"requested": "4.+"
|
||||||
|
},
|
||||||
|
"nl.jqno.equalsverifier:equalsverifier": {
|
||||||
|
"locked": "1.7.8",
|
||||||
|
"requested": "1.+"
|
||||||
|
},
|
||||||
|
"org.assertj:assertj-core": {
|
||||||
|
"locked": "2.6.0",
|
||||||
|
"requested": "2.+"
|
||||||
},
|
},
|
||||||
"org.eclipse.persistence:eclipselink": {
|
"org.eclipse.persistence:eclipselink": {
|
||||||
"locked": "2.6.4",
|
"locked": "2.6.4",
|
||||||
|
@ -340,6 +396,14 @@
|
||||||
"locked": "2.6.4",
|
"locked": "2.6.4",
|
||||||
"requested": "2.+"
|
"requested": "2.+"
|
||||||
},
|
},
|
||||||
|
"org.hamcrest:hamcrest-core": {
|
||||||
|
"locked": "1.3",
|
||||||
|
"requested": "1.3"
|
||||||
|
},
|
||||||
|
"org.mockito:mockito-all": {
|
||||||
|
"locked": "1.10.19",
|
||||||
|
"requested": "1.+"
|
||||||
|
},
|
||||||
"org.postgresql:postgresql": {
|
"org.postgresql:postgresql": {
|
||||||
"locked": "42.0.0",
|
"locked": "42.0.0",
|
||||||
"requested": "42.+"
|
"requested": "42.+"
|
||||||
|
@ -348,6 +412,10 @@
|
||||||
"locked": "1.16.16",
|
"locked": "1.16.16",
|
||||||
"requested": "1.+"
|
"requested": "1.+"
|
||||||
},
|
},
|
||||||
|
"org.quicktheories:quicktheories": {
|
||||||
|
"locked": "0.13",
|
||||||
|
"requested": "0.+"
|
||||||
|
},
|
||||||
"org.slf4j:log4j-over-slf4j": {
|
"org.slf4j:log4j-over-slf4j": {
|
||||||
"locked": "1.7.25",
|
"locked": "1.7.25",
|
||||||
"requested": "1.+"
|
"requested": "1.+"
|
||||||
|
|
184
farsite.ipr
184
farsite.ipr
|
@ -71,6 +71,127 @@
|
||||||
<option name="languageVersion" value="1.1" />
|
<option name="languageVersion" value="1.1" />
|
||||||
<option name="apiVersion" value="1.1" />
|
<option name="apiVersion" value="1.1" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="Palette2">
|
||||||
|
<group name="Swing">
|
||||||
|
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Button" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="RadioButton" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="CheckBox" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Label" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||||
|
<preferred-size width="-1" height="20" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
</group>
|
||||||
|
</component>
|
||||||
<component name="ProjectModuleManager">
|
<component name="ProjectModuleManager">
|
||||||
<modules>
|
<modules>
|
||||||
<module fileurl="file://$PROJECT_DIR$/farsite.iml" filepath="$PROJECT_DIR$/farsite.iml" />
|
<module fileurl="file://$PROJECT_DIR$/farsite.iml" filepath="$PROJECT_DIR$/farsite.iml" />
|
||||||
|
@ -133,6 +254,24 @@
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.mifmif/generex/1.0.2/d1f52c4efe0b20154faf35f8df5c08a234dc41db/generex-1.0.2-sources.jar!/" />
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.mifmif/generex/1.0.2/d1f52c4efe0b20154faf35f8df5c08a234dc41db/generex-1.0.2-sources.jar!/" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
</library>
|
</library>
|
||||||
|
<library name="Gradle: com.github.rholder.fauxflake:fauxflake-core:1.1.0">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.rholder.fauxflake/fauxflake-core/1.1.0/79755968bfe210f7e35f3193038dc30767e1c7b/fauxflake-core-1.1.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.rholder.fauxflake/fauxflake-core/1.1.0/b7ac69d18566c495cb4737ab600051e715406c18/fauxflake-core-1.1.0-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
<library name="Gradle: com.github.stefanbirkner:system-rules:1.16.1">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.stefanbirkner/system-rules/1.16.1/cb9e42b003d0668f6445505c0f81dd9a244a05d5/system-rules-1.16.1.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.stefanbirkner/system-rules/1.16.1/ed9fd29e5a3e83887038d5fc4cf0cc931a1a4eff/system-rules-1.16.1-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
<library name="Gradle: com.github.stephenc.jcip:jcip-annotations:1.0-1">
|
<library name="Gradle: com.github.stephenc.jcip:jcip-annotations:1.0-1">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.stephenc.jcip/jcip-annotations/1.0-1/ef31541dd28ae2cefdd17c7ebf352d93e9058c63/jcip-annotations-1.0-1.jar!/" />
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.stephenc.jcip/jcip-annotations/1.0-1/ef31541dd28ae2cefdd17c7ebf352d93e9058c63/jcip-annotations-1.0-1.jar!/" />
|
||||||
|
@ -178,6 +317,15 @@
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.protobuf/protobuf-java/2.6.1/cf47bfc6a10f85d14bc4c078a48d163b5903a291/protobuf-java-2.6.1-sources.jar!/" />
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.protobuf/protobuf-java/2.6.1/cf47bfc6a10f85d14bc4c078a48d163b5903a291/protobuf-java-2.6.1-sources.jar!/" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
</library>
|
</library>
|
||||||
|
<library name="Gradle: commons-codec:commons-codec:1.10">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/commons-codec/commons-codec/1.10/4b95f4897fa13f2cd904aee711aeafc0c5295cd8/commons-codec-1.10.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/commons-codec/commons-codec/1.10/11fb3d88ae7e3b757d70237064210ceb954a5a04/commons-codec-1.10-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
<library name="Gradle: dk.brics.automaton:automaton:1.11-8">
|
<library name="Gradle: dk.brics.automaton:automaton:1.11-8">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/dk.brics.automaton/automaton/1.11-8/6ebfa65eb431ff4b715a23be7a750cbc4cc96d0f/automaton-1.11-8.jar!/" />
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/dk.brics.automaton/automaton/1.11-8/6ebfa65eb431ff4b715a23be7a750cbc4cc96d0f/automaton-1.11-8.jar!/" />
|
||||||
|
@ -286,6 +434,15 @@
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/a6c32b40bf3d76eca54e3c601e5d1470c86fcdfa/junit-4.12-sources.jar!/" />
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/a6c32b40bf3d76eca54e3c601e5d1470c86fcdfa/junit-4.12-sources.jar!/" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
</library>
|
</library>
|
||||||
|
<library name="Gradle: nl.jqno.equalsverifier:equalsverifier:1.7.8">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/nl.jqno.equalsverifier/equalsverifier/1.7.8/a5dd63f30427b8ff868efa6e7d54f3c9fe365144/equalsverifier-1.7.8.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/nl.jqno.equalsverifier/equalsverifier/1.7.8/9aa3ffb236b046aa40102e487fca9e0acdc2d880/equalsverifier-1.7.8-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
<library name="Gradle: org.apache.commons:commons-lang3:3.5">
|
<library name="Gradle: org.apache.commons:commons-lang3:3.5">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-lang3/3.5/6c6c702c89bfff3cd9e80b04d668c5e190d588c6/commons-lang3-3.5.jar!/" />
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-lang3/3.5/6c6c702c89bfff3cd9e80b04d668c5e190d588c6/commons-lang3-3.5.jar!/" />
|
||||||
|
@ -295,6 +452,15 @@
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-lang3/3.5/f7d878153e86a1cdddf6b37850e00a9f8bff726f/commons-lang3-3.5-sources.jar!/" />
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-lang3/3.5/f7d878153e86a1cdddf6b37850e00a9f8bff726f/commons-lang3-3.5-sources.jar!/" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
</library>
|
</library>
|
||||||
|
<library name="Gradle: org.assertj:assertj-core:2.6.0">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.assertj/assertj-core/2.6.0/b532c3fc4f66bcfee4989a3514f1cd56203a33ad/assertj-core-2.6.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.assertj/assertj-core/2.6.0/86e8fd98e5ec52e93e3fa46d9bf5df7cca6d1bce/assertj-core-2.6.0-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
<library name="Gradle: org.eclipse.persistence:commonj.sdo:2.1.1">
|
<library name="Gradle: org.eclipse.persistence:commonj.sdo:2.1.1">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.eclipse.persistence/commonj.sdo/2.1.1/90d4c89ce0a69f58619f1a247bbf420122139ff5/commonj.sdo-2.1.1.jar!/" />
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.eclipse.persistence/commonj.sdo/2.1.1/90d4c89ce0a69f58619f1a247bbf420122139ff5/commonj.sdo-2.1.1.jar!/" />
|
||||||
|
@ -385,6 +551,15 @@
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/1dc37250fbc78e23a65a67fbbaf71d2e9cbc3c0b/hamcrest-core-1.3-sources.jar!/" />
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/1dc37250fbc78e23a65a67fbbaf71d2e9cbc3c0b/hamcrest-core-1.3-sources.jar!/" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
</library>
|
</library>
|
||||||
|
<library name="Gradle: org.mockito:mockito-all:1.10.19">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.mockito/mockito-all/1.10.19/539df70269cc254a58cccc5d8e43286b4a73bf30/mockito-all-1.10.19.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.mockito/mockito-all/1.10.19/8269667b73d9616600359a9b0ba1b1c7d0cf7a97/mockito-all-1.10.19-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
<library name="Gradle: org.postgresql:postgresql:42.0.0">
|
<library name="Gradle: org.postgresql:postgresql:42.0.0">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.postgresql/postgresql/42.0.0/938ede0cdf862cc4eaba5023a86254783af1d261/postgresql-42.0.0.jar!/" />
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.postgresql/postgresql/42.0.0/938ede0cdf862cc4eaba5023a86254783af1d261/postgresql-42.0.0.jar!/" />
|
||||||
|
@ -403,6 +578,15 @@
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.projectlombok/lombok/1.16.16/c4b112e9645070ac05946084317cc5d01cf4ddcd/lombok-1.16.16-sources.jar!/" />
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.projectlombok/lombok/1.16.16/c4b112e9645070ac05946084317cc5d01cf4ddcd/lombok-1.16.16-sources.jar!/" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
</library>
|
</library>
|
||||||
|
<library name="Gradle: org.quicktheories:quicktheories:0.13">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.quicktheories/quicktheories/0.13/311a7ac8e80b4a4ec6dc0d9af81204713b54f180/quicktheories-0.13.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.quicktheories/quicktheories/0.13/37283aaf93ae4b34a16d6647dcf4b314da922196/quicktheories-0.13-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
<library name="Gradle: org.slf4j:log4j-over-slf4j:1.7.25">
|
<library name="Gradle: org.slf4j:log4j-over-slf4j:1.7.25">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.slf4j/log4j-over-slf4j/1.7.25/a87bb47468f47ee7aabbd54f93e133d4215769c3/log4j-over-slf4j-1.7.25.jar!/" />
|
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.slf4j/log4j-over-slf4j/1.7.25/a87bb47468f47ee7aabbd54f93e133d4215769c3/log4j-over-slf4j-1.7.25.jar!/" />
|
||||||
|
|
1649
farsite.iws
1649
farsite.iws
File diff suppressed because it is too large
Load diff
|
@ -1,47 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
||||||
|
|
||||||
<!-- https://jcp.org/aboutJava/communityprocess/final/jsr338/index.html -->
|
|
||||||
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
|
|
||||||
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
|
|
||||||
version="2.1">
|
|
||||||
|
|
||||||
<persistence-unit name="people" transaction-type="JTA">
|
|
||||||
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
|
|
||||||
|
|
||||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
|
||||||
<properties>
|
|
||||||
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
|
|
||||||
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://127.0.0.1:26257/farsite?sslmode=disable" />
|
|
||||||
<property name="javax.persistence.jdbc.user" value="root" />
|
|
||||||
<property name="javax.persistence.jdbc.password" value="" />
|
|
||||||
|
|
||||||
<!-- EclipseLink should create the database schema automatically -->
|
|
||||||
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
|
|
||||||
<property name="eclipselink.ddl-generation.output-mode" value="database" />
|
|
||||||
|
|
||||||
<property name="eclipselink.target-database" value="PostgreSQL"/>
|
|
||||||
<property name="eclipselink.logging.level" value="FINE"/>
|
|
||||||
<property name="eclipselink.logging.logger" value="JavaLogger"/>
|
|
||||||
</properties>
|
|
||||||
</persistence-unit>
|
|
||||||
|
|
||||||
<persistence-unit name="todos" transaction-type="RESOURCE_LOCAL">
|
|
||||||
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
|
|
||||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
|
||||||
<properties>
|
|
||||||
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
|
|
||||||
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://127.0.0.1:26257/farsite?sslmode=disable" />
|
|
||||||
<property name="javax.persistence.jdbc.user" value="root" />
|
|
||||||
<property name="javax.persistence.jdbc.password" value="" />
|
|
||||||
|
|
||||||
<!-- EclipseLink should create the database schema automatically -->
|
|
||||||
<property name="eclipselink.ddl-generation" value="create-tables" />
|
|
||||||
<property name="eclipselink.ddl-generation.output-mode" value="database" />
|
|
||||||
|
|
||||||
<property name="eclipselink.logging.level" value="FINE"/>
|
|
||||||
<property name="eclipselink.logging.logger" value="JavaLogger"/>
|
|
||||||
</properties>
|
|
||||||
</persistence-unit>
|
|
||||||
</persistence>
|
|
|
@ -1,36 +0,0 @@
|
||||||
package com.example.farsite;
|
|
||||||
|
|
||||||
import com.example.farsite.model.Todo;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.EntityManagerFactory;
|
|
||||||
import javax.persistence.Persistence;
|
|
||||||
import javax.persistence.Query;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Main {
|
|
||||||
private static final String PERSISTENCE_UNIT_NAME = "todos";
|
|
||||||
private static EntityManagerFactory factory;
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
|
|
||||||
EntityManager em = factory.createEntityManager();
|
|
||||||
// read the existing entries and write to console
|
|
||||||
Query q = em.createQuery("select t from Todo t");
|
|
||||||
List<Todo> todoList = q.getResultList();
|
|
||||||
for (Todo todo : todoList) {
|
|
||||||
System.out.println(todo);
|
|
||||||
}
|
|
||||||
System.out.println("Size: " + todoList.size());
|
|
||||||
|
|
||||||
// create new todo
|
|
||||||
em.getTransaction().begin();
|
|
||||||
Todo todo = new Todo();
|
|
||||||
todo.setSummary("This is a test");
|
|
||||||
todo.setDescription("This is a test");
|
|
||||||
em.persist(todo);
|
|
||||||
em.getTransaction().commit();
|
|
||||||
|
|
||||||
em.close();
|
|
||||||
}
|
|
||||||
}
|
|
24
src/main/java/com/example/farsite/model/AbstractModel.java
Normal file
24
src/main/java/com/example/farsite/model/AbstractModel.java
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package com.example.farsite.model;
|
||||||
|
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
//import org.springframework.data.annotation.CreatedDate;
|
||||||
|
//import org.springframework.data.annotation.LastModifiedDate;
|
||||||
|
//import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||||
|
|
||||||
|
import com.example.farsite.util.SerialVersionUID;
|
||||||
|
//import org.eclipse.persistence.descriptors.changetracking.ChangeTracker;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@MappedSuperclass
|
||||||
|
//EntityListeners(AuditingEntityListener.class)
|
||||||
|
public abstract class AbstractModel <T extends Serializable> implements Model<T> { //, ChangeTracker {
|
||||||
|
private static final long serialVersionUID = SerialVersionUID.compute(AbstractModel.class);
|
||||||
|
|
||||||
|
//@Getter @CreatedDate Date createdDate;
|
||||||
|
//@Getter @LastModifiedDate Date modifiedDate;
|
||||||
|
}
|
49
src/main/java/com/example/farsite/model/Address.java
Normal file
49
src/main/java/com/example/farsite/model/Address.java
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package com.example.farsite.model;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
|
||||||
|
import com.example.farsite.util.SerialVersionUID;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.eclipse.persistence.annotations.Cache;
|
||||||
|
import org.eclipse.persistence.annotations.ReturnInsert;
|
||||||
|
|
||||||
|
import static javax.persistence.FetchType.LAZY;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Entity
|
||||||
|
@Cache(
|
||||||
|
refreshOnlyIfNewer = true
|
||||||
|
)
|
||||||
|
public class Address extends AbstractModel<Long> {
|
||||||
|
private static final long serialVersionUID = SerialVersionUID.compute(Address.class);
|
||||||
|
|
||||||
|
// PRIMARY KEY
|
||||||
|
// @Id @GeneratedValue(strategy=GenerationType.IDENTITY) //@ReturnInsert(returnOnly=true)
|
||||||
|
// @Column(unique=true, nullable=false)
|
||||||
|
@Id @GeneratedValue(generator = "flake-seq")
|
||||||
|
@Column(unique = true, nullable = false)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
// FIELDS
|
||||||
|
private String city;
|
||||||
|
private String country;
|
||||||
|
@Basic(fetch=LAZY)
|
||||||
|
private String province;
|
||||||
|
private String postalCode;
|
||||||
|
private String street;
|
||||||
|
|
||||||
|
// OPTIMISTIC CONCURRENCY CONTROL
|
||||||
|
@Version
|
||||||
|
private long version;
|
||||||
|
|
||||||
|
public Address() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address(String city, String country, String province, String postalCode, String street) {
|
||||||
|
this.city = city;
|
||||||
|
this.country = country;
|
||||||
|
this.province = province;
|
||||||
|
this.postalCode = postalCode;
|
||||||
|
this.street = street;
|
||||||
|
}
|
||||||
|
}
|
127
src/main/java/com/example/farsite/model/Employee.java
Normal file
127
src/main/java/com/example/farsite/model/Employee.java
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
package com.example.farsite.model;
|
||||||
|
|
||||||
|
import com.example.farsite.util.SerialVersionUID;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.eclipse.persistence.annotations.Cache;
|
||||||
|
import org.eclipse.persistence.annotations.CacheType;
|
||||||
|
import org.eclipse.persistence.annotations.ChangeTracking;
|
||||||
|
import org.eclipse.persistence.annotations.PrivateOwned;
|
||||||
|
import org.eclipse.persistence.config.HintValues;
|
||||||
|
import org.eclipse.persistence.config.QueryHints;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.eclipse.persistence.annotations.CacheCoordinationType.INVALIDATE_CHANGED_OBJECTS;
|
||||||
|
import static org.eclipse.persistence.annotations.ChangeTrackingType.OBJECT;
|
||||||
|
import static org.eclipse.persistence.config.CacheIsolationType.SHARED;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Entity
|
||||||
|
@SecondaryTable(name = "SALARY")
|
||||||
|
@NamedQueries({
|
||||||
|
@NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employee e ORDER BY e.id"),
|
||||||
|
@NamedQuery(name = "Employee.findByName", query = "SELECT e FROM Employee e WHERE e.firstName LIKE :firstName AND e.lastName LIKE :lastName"),
|
||||||
|
@NamedQuery(name = "Employee.count", query = "SELECT COUNT(e) FROM Employee e"),
|
||||||
|
@NamedQuery(name = "Employee.countByName", query = "SELECT COUNT(e) FROM Employee e WHERE e.firstName LIKE :firstName AND e.lastName LIKE :lastName"),
|
||||||
|
// Query used in {@link IdInPaging}
|
||||||
|
@NamedQuery(name = "Employee.idsIn", query = "SELECT e FROM Employee e WHERE e.id IN :IDS ORDER BY e.id",
|
||||||
|
hints = { @QueryHint(name = QueryHints.QUERY_RESULTS_CACHE, value = HintValues.TRUE) }) })
|
||||||
|
@Cache (type= CacheType.WEAK
|
||||||
|
,isolation=SHARED
|
||||||
|
,expiry=600000
|
||||||
|
,alwaysRefresh=true
|
||||||
|
,disableHits=true
|
||||||
|
,coordinationType=INVALIDATE_CHANGED_OBJECTS
|
||||||
|
)
|
||||||
|
//@ChangeTracking(OBJECT)
|
||||||
|
public class Employee extends AbstractModel<Long> {
|
||||||
|
private static final long serialVersionUID = SerialVersionUID.compute(AbstractModel.class);
|
||||||
|
|
||||||
|
// PRIMARY KEY
|
||||||
|
@Id @GeneratedValue(generator = "flake-seq")
|
||||||
|
@Column(unique = true, nullable = false)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
// FIELDS
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
|
||||||
|
/* NOTE:
|
||||||
|
* Gender mapped using Basic with an ObjectTypeConverter to map between
|
||||||
|
* single char code value in database to enum. JPA only supports mapping to
|
||||||
|
* the full name of the enum or its ordinal value. */
|
||||||
|
@Basic @Column(name = "GENDER") @Convert(converter = GenderConverter.class)
|
||||||
|
private Gender gender = Gender.Male;
|
||||||
|
|
||||||
|
@Column(table = "SALARY")
|
||||||
|
private double salary;
|
||||||
|
|
||||||
|
// OPTIMISTIC CONCURRENCY CONTROL
|
||||||
|
@Version
|
||||||
|
private Long version;
|
||||||
|
|
||||||
|
// RELATIONS
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "MANAGER_ID")
|
||||||
|
private Employee manager;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "manager")
|
||||||
|
private List<Employee> managedEmployees = new ArrayList<Employee>();
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "owner", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
|
@PrivateOwned
|
||||||
|
private List<PhoneNumber> phoneNumbers = new ArrayList<PhoneNumber>();
|
||||||
|
|
||||||
|
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
|
||||||
|
@JoinColumn(name = "ADDRESS_ID")
|
||||||
|
private Address address;
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
@AttributeOverrides({ @AttributeOverride(name = "startDate", column = @Column(name = "START_DATE")),
|
||||||
|
@AttributeOverride(name = "endDate", column = @Column(name = "END_DATE")) })
|
||||||
|
private EmploymentPeriod period;
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
@CollectionTable(name = "RESPONS")
|
||||||
|
private List<String> responsibilities = new ArrayList<String>();
|
||||||
|
|
||||||
|
public Employee addManagedEmployee(Employee employee) {
|
||||||
|
getManagedEmployees().add(employee);
|
||||||
|
employee.setManager(this);
|
||||||
|
return employee;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Employee removeManagedEmployee(Employee employee) {
|
||||||
|
getManagedEmployees().remove(employee);
|
||||||
|
employee.setManager(null);
|
||||||
|
return employee;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PhoneNumber addPhoneNumber(PhoneNumber phoneNumber) {
|
||||||
|
getPhoneNumbers().add(phoneNumber);
|
||||||
|
phoneNumber.setOwner(this);
|
||||||
|
return phoneNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PhoneNumber addPhoneNumber(String type, String number) {
|
||||||
|
PhoneNumber phoneNumber = new PhoneNumber(type, number);
|
||||||
|
return addPhoneNumber(phoneNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PhoneNumber removePhoneNumber(PhoneNumber phoneNumber) {
|
||||||
|
getPhoneNumbers().remove(phoneNumber);
|
||||||
|
phoneNumber.setOwner(null);
|
||||||
|
return phoneNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addResponsibility(String responsibility) {
|
||||||
|
getResponsibilities().add(responsibility);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeResponsibility(String responsibility) {
|
||||||
|
getResponsibilities().remove(responsibility);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.example.farsite.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import static javax.persistence.TemporalType.DATE;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the period of time an employee has worked for the company. A null
|
||||||
|
* endDate indicates that the employee is current.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Embeddable
|
||||||
|
public class EmploymentPeriod {
|
||||||
|
|
||||||
|
@Temporal(DATE)
|
||||||
|
private Calendar startDate;
|
||||||
|
@Temporal(DATE)
|
||||||
|
private Calendar endDate;
|
||||||
|
|
||||||
|
public void setStartDate(int year, int month, int date) {
|
||||||
|
if (this.startDate == null) {
|
||||||
|
setStartDate(Calendar.getInstance());
|
||||||
|
}
|
||||||
|
getStartDate().set(year, month, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndDate(int year, int month, int date) {
|
||||||
|
if (this.endDate == null) {
|
||||||
|
setEndDate(Calendar.getInstance());
|
||||||
|
}
|
||||||
|
getEndDate().set(year, month, date);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,19 +0,0 @@
|
||||||
package com.example.farsite.model;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Data
|
|
||||||
public class Family {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.TABLE)
|
|
||||||
private int id;
|
|
||||||
private String description;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "family")
|
|
||||||
private final List<Person> members = new ArrayList<Person>();
|
|
||||||
}
|
|
5
src/main/java/com/example/farsite/model/Gender.java
Normal file
5
src/main/java/com/example/farsite/model/Gender.java
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
package com.example.farsite.model;
|
||||||
|
|
||||||
|
public enum Gender {
|
||||||
|
Female, Male, ;
|
||||||
|
}
|
36
src/main/java/com/example/farsite/model/GenderConverter.java
Normal file
36
src/main/java/com/example/farsite/model/GenderConverter.java
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package com.example.farsite.model;
|
||||||
|
|
||||||
|
import javax.persistence.AttributeConverter;
|
||||||
|
import javax.persistence.Converter;
|
||||||
|
|
||||||
|
@Converter(autoApply = true)
|
||||||
|
public class GenderConverter implements AttributeConverter<Gender, String> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String convertToDatabaseColumn(Gender gender) {
|
||||||
|
switch (gender) {
|
||||||
|
case Male:
|
||||||
|
return "M";
|
||||||
|
|
||||||
|
case Female:
|
||||||
|
return "F";
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Invalid gender: " + gender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Gender convertToEntityAttribute(String gender) {
|
||||||
|
switch (gender) {
|
||||||
|
case "M":
|
||||||
|
return Gender.Male;
|
||||||
|
|
||||||
|
case "F":
|
||||||
|
return Gender.Female;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Invalid gender code: " + gender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +0,0 @@
|
||||||
package com.example.farsite.model;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.GenerationType;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
public class Job {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.TABLE)
|
|
||||||
private int id;
|
|
||||||
private double salery;
|
|
||||||
private String jobDescr;
|
|
||||||
}
|
|
9
src/main/java/com/example/farsite/model/Model.java
Normal file
9
src/main/java/com/example/farsite/model/Model.java
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package com.example.farsite.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public interface Model<T extends Serializable> {
|
||||||
|
//Date getCreatedDate();
|
||||||
|
//Date getModifiedDate();
|
||||||
|
}
|
|
@ -1,32 +0,0 @@
|
||||||
package com.example.farsite.model;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.GenerationType;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import javax.persistence.Transient;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Data
|
|
||||||
public class Person {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.TABLE)
|
|
||||||
private String id;
|
|
||||||
private String firstName;
|
|
||||||
private String lastName;
|
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
private Family family;
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
private String nonsenseField = "";
|
|
||||||
|
|
||||||
@OneToMany
|
|
||||||
private List<Job> jobList = new ArrayList<Job>();
|
|
||||||
}
|
|
59
src/main/java/com/example/farsite/model/PhoneNumber.java
Normal file
59
src/main/java/com/example/farsite/model/PhoneNumber.java
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package com.example.farsite.model;
|
||||||
|
|
||||||
|
import com.example.farsite.util.SerialVersionUID;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.IdClass;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Data @ToString(exclude="owner") @EqualsAndHashCode(exclude="owner")
|
||||||
|
@Entity
|
||||||
|
@Table(name = "PHONE")
|
||||||
|
@IdClass(PhoneNumber.ID.class)
|
||||||
|
public class PhoneNumber extends AbstractModel<Long> {
|
||||||
|
private static final long serialVersionUID = SerialVersionUID.compute(PhoneNumber.class);
|
||||||
|
|
||||||
|
@Id @Column(name = "EMP_ID", updatable = false, insertable = false)
|
||||||
|
private Long id;
|
||||||
|
@Id @Column(updatable = false)
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
private String number;
|
||||||
|
|
||||||
|
@ManyToOne @JoinColumn(name = "EMP_ID")
|
||||||
|
private Employee owner;
|
||||||
|
|
||||||
|
public PhoneNumber() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public PhoneNumber(String type, String number) {
|
||||||
|
this();
|
||||||
|
setType(type);
|
||||||
|
setNumber(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setOwner(Employee employee) {
|
||||||
|
this.owner = employee;
|
||||||
|
if (employee != null) {
|
||||||
|
this.id = employee.getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class ID implements Serializable {
|
||||||
|
private static final long serialVersionUID = SerialVersionUID.compute(PhoneNumber.ID.class);
|
||||||
|
|
||||||
|
public Long id;
|
||||||
|
public String type;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,18 +0,0 @@
|
||||||
package com.example.farsite.model;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.GenerationType;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Data
|
|
||||||
public class Todo {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
||||||
private Long id;
|
|
||||||
private String summary;
|
|
||||||
private String description;
|
|
||||||
}
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.example.farsite.util;
|
||||||
|
|
||||||
|
import org.eclipse.persistence.platform.database.PostgreSQLPlatform;
|
||||||
|
import org.eclipse.persistence.queries.ValueReadQuery;
|
||||||
|
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
|
||||||
|
public class CockroachDBPlatform extends PostgreSQLPlatform {
|
||||||
|
|
||||||
|
public CockroachDBPlatform() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsIdentity() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsSequenceObjects()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBuildCallWithReturning()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldPrintAliasForUpdate() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCockroachDB() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.example.farsite.util;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import org.eclipse.persistence.config.SessionCustomizer;
|
||||||
|
import org.eclipse.persistence.internal.sessions.AbstractSession;
|
||||||
|
import org.eclipse.persistence.sessions.Session;
|
||||||
|
import org.eclipse.persistence.tools.profiler.PerformanceProfiler;
|
||||||
|
|
||||||
|
public class CrDBSessionCustomizer implements SessionCustomizer {
|
||||||
|
|
||||||
|
public void customize(Session session) throws Exception {
|
||||||
|
|
||||||
|
// Enable concurrent processing of result sets and concurrent loading of load groups.
|
||||||
|
((AbstractSession)session).setIsConcurrent(true);
|
||||||
|
|
||||||
|
// Add sequence generators.
|
||||||
|
Lists.newArrayList(
|
||||||
|
new UUIDSequence("uuid-seq"),
|
||||||
|
new PSRNSequence("psrn-seq"),
|
||||||
|
new FlakeSequence("flake-seq"))
|
||||||
|
.forEach(sequence -> {session.getLogin().addSequence(sequence);});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
74
src/main/java/com/example/farsite/util/FlakeSequence.java
Normal file
74
src/main/java/com/example/farsite/util/FlakeSequence.java
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
package com.example.farsite.util;
|
||||||
|
|
||||||
|
import com.github.rholder.fauxflake.DefaultIdGenerator;
|
||||||
|
import com.github.rholder.fauxflake.api.IdGenerator;
|
||||||
|
import com.github.rholder.fauxflake.provider.SystemTimeProvider;
|
||||||
|
import com.github.rholder.fauxflake.provider.twitter.SnowflakeEncodingProvider;
|
||||||
|
import org.eclipse.persistence.internal.databaseaccess.Accessor;
|
||||||
|
import org.eclipse.persistence.internal.sessions.AbstractSession;
|
||||||
|
import org.eclipse.persistence.sequencing.Sequence;
|
||||||
|
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FlakeSequence is a decentralized, k-ordered unique ID generator that produces 64bit integers (Long).
|
||||||
|
*
|
||||||
|
* This is configured to mimic Twitter's Snowflake pattern.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class FlakeSequence extends Sequence {
|
||||||
|
IdGenerator idGenerator;
|
||||||
|
|
||||||
|
public FlakeSequence(String name) {
|
||||||
|
super(name);
|
||||||
|
long mid = Randomness.randomIntSecure(1024); // TODO(gburd): use a hash of the hostname?
|
||||||
|
idGenerator = new DefaultIdGenerator(new SystemTimeProvider(), new SnowflakeEncodingProvider(mid));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getGeneratedValue(Accessor accessor, AbstractSession writeSession, String seqName) {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
return idGenerator.generateId(10).asLong();
|
||||||
|
}
|
||||||
|
catch (InterruptedException e) {
|
||||||
|
// We waited more than 10ms to generate an Id, try again. This could be due to NTP
|
||||||
|
// drift, leap seconds, GC pause, who knows.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector getGeneratedVector(Accessor accessor, AbstractSession writeSession, String seqName, int size) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnect() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisconnect() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldAcquireValueAfterInsert() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldAlwaysOverrideExistingValue(String seqName, Object existingValue) {
|
||||||
|
return ((String) existingValue).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldUseTransaction() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldUsePreallocation() {
|
||||||
|
// NOTE: never pre-allocate, that would defeat the time-ordered nature of these IDs
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.example.farsite.util;
|
||||||
|
|
||||||
|
import org.eclipse.persistence.internal.databaseaccess.Accessor;
|
||||||
|
import org.eclipse.persistence.internal.queries.DatabaseQueryMechanism;
|
||||||
|
import org.eclipse.persistence.queries.Call;
|
||||||
|
import org.eclipse.persistence.queries.DatabaseQuery;
|
||||||
|
|
||||||
|
public class GeneratedIdentityValue implements Call {
|
||||||
|
/**
|
||||||
|
* INTERNAL:
|
||||||
|
* Return the appropriate mechanism,
|
||||||
|
* with the call set as necessary.
|
||||||
|
*
|
||||||
|
* @param query
|
||||||
|
*/
|
||||||
|
@Override public DatabaseQueryMechanism buildNewQueryMechanism(DatabaseQuery query) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INTERNAL:
|
||||||
|
* Return the appropriate mechanism,
|
||||||
|
* with the call added as necessary.
|
||||||
|
*
|
||||||
|
* @param query
|
||||||
|
* @param mechanism
|
||||||
|
*/
|
||||||
|
@Override public DatabaseQueryMechanism buildQueryMechanism(DatabaseQuery query, DatabaseQueryMechanism mechanism) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INTERNAL:
|
||||||
|
* Return a clone of the call.
|
||||||
|
*/
|
||||||
|
@Override public Object clone() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INTERNAL:
|
||||||
|
* Return a string appropriate for the session log.
|
||||||
|
*
|
||||||
|
* @param accessor
|
||||||
|
*/
|
||||||
|
@Override public String getLogString(Accessor accessor) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INTERNAL:
|
||||||
|
* Return whether the call is finished returning
|
||||||
|
* all of its results (e.g. a call that returns a cursor
|
||||||
|
* will answer false).
|
||||||
|
*/
|
||||||
|
@Override public boolean isFinished() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The return type is one of, NoReturn, ReturnOneRow or ReturnManyRows.
|
||||||
|
*/
|
||||||
|
@Override public boolean isNothingReturned() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The return type is one of, NoReturn, ReturnOneRow or ReturnManyRows.
|
||||||
|
*/
|
||||||
|
@Override public boolean isOneRowReturned() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
1439
src/main/java/com/example/farsite/util/MersenneTwisterFast.java
Normal file
1439
src/main/java/com/example/farsite/util/MersenneTwisterFast.java
Normal file
File diff suppressed because it is too large
Load diff
50
src/main/java/com/example/farsite/util/PSRNSequence.java
Normal file
50
src/main/java/com/example/farsite/util/PSRNSequence.java
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
package com.example.farsite.util;
|
||||||
|
|
||||||
|
import org.eclipse.persistence.internal.databaseaccess.Accessor;
|
||||||
|
import org.eclipse.persistence.internal.sessions.AbstractSession;
|
||||||
|
import org.eclipse.persistence.sequencing.Sequence;
|
||||||
|
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
public class PSRNSequence extends Sequence {
|
||||||
|
|
||||||
|
public PSRNSequence(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getGeneratedValue(Accessor accessor, AbstractSession writeSession, String seqName) {
|
||||||
|
return Randomness.randomHexStringSecure(36);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector getGeneratedVector(Accessor accessor, AbstractSession writeSession, String seqName, int size) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnect() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisconnect() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldAcquireValueAfterInsert() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldAlwaysOverrideExistingValue(String seqName, Object existingValue) {
|
||||||
|
return ((String) existingValue).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldUseTransaction() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldUsePreallocation() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
50
src/main/java/com/example/farsite/util/Password.java
Normal file
50
src/main/java/com/example/farsite/util/Password.java
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
//http://stackoverflow.com/a/11038230/366692
|
||||||
|
package com.example.farsite.util;
|
||||||
|
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.SecretKeyFactory;
|
||||||
|
import javax.crypto.spec.PBEKeySpec;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
|
public class Password {
|
||||||
|
// The higher the number of iterations the more
|
||||||
|
// expensive computing the hash is for us and
|
||||||
|
// also for an attacker.
|
||||||
|
private static final int iterations = 20*1000;
|
||||||
|
private static final int saltLen = 32;
|
||||||
|
private static final int desiredKeyLen = 256;
|
||||||
|
|
||||||
|
/** Computes a salted PBKDF2 hash of given plaintext password
|
||||||
|
suitable for storing in a database.
|
||||||
|
Empty passwords are not supported. */
|
||||||
|
public static String getSaltedHash(String password) throws Exception {
|
||||||
|
byte[] salt = SecureRandom.getInstance("SHA1PRNG").generateSeed(saltLen);
|
||||||
|
// store the salt with the password
|
||||||
|
return Base64.encodeBase64String(salt) + "$" + hash(password, salt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Checks whether given plaintext password corresponds
|
||||||
|
to a stored salted hash of the password. */
|
||||||
|
public static boolean check(String password, String stored) throws Exception{
|
||||||
|
String[] saltAndPass = stored.split("\\$");
|
||||||
|
if (saltAndPass.length != 2) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"The stored password have the form 'salt$hash'");
|
||||||
|
}
|
||||||
|
String hashOfInput = hash(password, Base64.decodeBase64(saltAndPass[0]));
|
||||||
|
return hashOfInput.equals(saltAndPass[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// using PBKDF2 from Sun, an alternative is https://github.com/wg/scrypt
|
||||||
|
// cf. http://www.unlimitednovelty.com/2012/03/dont-use-bcrypt.html
|
||||||
|
private static String hash(String password, byte[] salt) throws Exception {
|
||||||
|
if (password == null || password.length() == 0)
|
||||||
|
throw new IllegalArgumentException("Empty passwords are not supported.");
|
||||||
|
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
|
||||||
|
SecretKey key = f.generateSecret(new PBEKeySpec(
|
||||||
|
password.toCharArray(), salt, iterations, desiredKeyLen)
|
||||||
|
);
|
||||||
|
return Base64.encodeBase64String(key.getEncoded());
|
||||||
|
}
|
||||||
|
}
|
190
src/main/java/com/example/farsite/util/Randomness.java
Normal file
190
src/main/java/com/example/farsite/util/Randomness.java
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
package com.example.farsite.util;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public final class Randomness {
|
||||||
|
private static final int NUM_SEEDS = 16;
|
||||||
|
private static final SecureRandom SEED_PROVIDER = new SecureRandom();
|
||||||
|
private static final Pattern DB_OBJECT_ID_PATTERN = Pattern.compile("[0-9a-f]{24}", Pattern.CASE_INSENSITIVE);
|
||||||
|
private static final String BASE64_CHAR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
private static final String OBJECT_ID_CHAR = "0123456789abcdef";
|
||||||
|
private static final int[] BASE64_NUM = new int[256]; //maps base64 characters to 0-63, others to 0.
|
||||||
|
|
||||||
|
static {
|
||||||
|
for(int i = 0; i < 64; ++i) {
|
||||||
|
BASE64_NUM[BASE64_CHAR.charAt(i)] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ThreadLocal<ReseedingSecureRandom> SECURE_RANDOM = new ThreadLocal<ReseedingSecureRandom>() {
|
||||||
|
@Override
|
||||||
|
protected ReseedingSecureRandom initialValue() {
|
||||||
|
return new ReseedingSecureRandom();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Use the MersenneTwisterFast implementation for its performance and long period. The implementation is
|
||||||
|
// not thread-safe so we keep an instance in thread-local storage.
|
||||||
|
private static final ThreadLocal<MersenneTwisterFast> MERSENNE_TWISTER = new ThreadLocal<MersenneTwisterFast>() {
|
||||||
|
@Override
|
||||||
|
protected MersenneTwisterFast initialValue() {
|
||||||
|
int[] seedInts = new int[NUM_SEEDS];
|
||||||
|
for (int i = 0; i < NUM_SEEDS; i++) {
|
||||||
|
seedInts[i] = SEED_PROVIDER.nextInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MersenneTwisterFast(seedInts);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private Randomness() {}
|
||||||
|
|
||||||
|
/** Unsecure! */
|
||||||
|
public static MersenneTwisterFast getMersenneTwister() {
|
||||||
|
return MERSENNE_TWISTER.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int randomIntSecure(int n) {
|
||||||
|
if (n < 1) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: This is completely different from how java.util.Random#nextInt(int) does it
|
||||||
|
return Math.abs(SECURE_RANDOM.get().nextInt()) % n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[] randomIntsSecure(int count) {
|
||||||
|
int[] ints = new int[count];
|
||||||
|
for (int i = 0; i < ints.length; ++i) {
|
||||||
|
ints[i] = SECURE_RANDOM.get().nextInt();
|
||||||
|
}
|
||||||
|
return ints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[] randomIntsUnsecure(int count) {
|
||||||
|
MersenneTwisterFast mt = getMersenneTwister();
|
||||||
|
int[] ints = new int[count];
|
||||||
|
for (int i = 0; i < ints.length; ++i) {
|
||||||
|
ints[i] = mt.nextInt();
|
||||||
|
}
|
||||||
|
return ints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] randomBytesSecure(int size /* in bytes */) {
|
||||||
|
byte[] bytes = new byte[size];
|
||||||
|
SECURE_RANDOM.get().nextBytes(bytes);
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] randomBytesUnsecure(int size /* in bytes */) {
|
||||||
|
byte[] bytes = new byte[size];
|
||||||
|
getMersenneTwister().nextBytes(bytes);
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String randomHexStringSecure(int lengthBytes) {
|
||||||
|
StringBuilder str = new StringBuilder();
|
||||||
|
ReseedingSecureRandom sr = SECURE_RANDOM.get();
|
||||||
|
for (int i = 0; i < lengthBytes; i++) {
|
||||||
|
str.append(Integer.toHexString(sr.nextInt(16)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return str.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isValidDBObjectId(String stringId) {
|
||||||
|
return stringId != null && DB_OBJECT_ID_PATTERN.matcher(stringId).matches()
|
||||||
|
&& stringId.toLowerCase().equals(stringId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toValidDBObjectId(String stringId) {
|
||||||
|
if (isValidDBObjectId(stringId)) {
|
||||||
|
return stringId;
|
||||||
|
}
|
||||||
|
if (stringId.length() < 24) {
|
||||||
|
throw new AssertionError("Can't convert to valid DBObjectId " + stringId);
|
||||||
|
}
|
||||||
|
StringBuilder hexString = new StringBuilder();
|
||||||
|
for (int i = 0; i < 24; ++i) {
|
||||||
|
byte bt = (byte) stringId.charAt(i);
|
||||||
|
String hs = Integer.toHexString(bt & 0x0F).toLowerCase();
|
||||||
|
hexString.append(hs);
|
||||||
|
}
|
||||||
|
return hexString.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String treeNodeId() {
|
||||||
|
return treeNodeId('\u0000');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String treeNodeId(char prefix) {
|
||||||
|
return treeNodeId(prefix, getMersenneTwister());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String treeNodeId(char prefix, MersenneTwisterFast twister) {
|
||||||
|
final int prefixLength = prefix == '\u0000' ? 0 : 1;
|
||||||
|
final int numChars = prefixLength + 16; // 16 * 6 is 96 bits of entropy
|
||||||
|
char[] chars = new char[numChars];
|
||||||
|
if (prefixLength == 1) {
|
||||||
|
chars[0] = prefix;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
chars[prefixLength + i] = BASE64_CHAR.charAt(twister.nextInt(64));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new String(chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Not secure! */
|
||||||
|
public static String alphaString(int length) {
|
||||||
|
MersenneTwisterFast mt = getMersenneTwister();
|
||||||
|
char[] chars = new char[length];
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
chars[i] = BASE64_CHAR.charAt(mt.nextInt(52));
|
||||||
|
}
|
||||||
|
return new String(chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String alphaNumericStringSecure(int length) {
|
||||||
|
ReseedingSecureRandom sr = SECURE_RANDOM.get();
|
||||||
|
char[] chars = new char[length];
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
chars[i] = BASE64_CHAR.charAt(sr.nextInt(62));
|
||||||
|
}
|
||||||
|
return new String(chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String elementId() {
|
||||||
|
MersenneTwisterFast mt = getMersenneTwister();
|
||||||
|
char[] chars = new char[24];
|
||||||
|
for (int i = 0; i < 24; ++i) {
|
||||||
|
chars[i] = OBJECT_ID_CHAR.charAt(mt.nextInt(16));
|
||||||
|
}
|
||||||
|
return new String(chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String alphaNumericString(int length) {
|
||||||
|
MersenneTwisterFast mt = getMersenneTwister();
|
||||||
|
char[] chars = new char[length];
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
chars[i] = BASE64_CHAR.charAt(mt.nextInt(62));
|
||||||
|
}
|
||||||
|
return new String(chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a feature id without the ordinal */
|
||||||
|
public static String featureId() {
|
||||||
|
return "F" + alphaNumericString(14);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static char toBase64Char(int position) {
|
||||||
|
return BASE64_CHAR.charAt(position % 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int fromBase64Char(char character) {
|
||||||
|
return BASE64_NUM[character];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.example.farsite.util;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
final class ReseedingSecureRandom {
|
||||||
|
/** How frequently does reseeding happen. This is not strict */
|
||||||
|
private static final int RESEED_AT = 100000;
|
||||||
|
|
||||||
|
/** Atomic integer that keeps track of number of calls */
|
||||||
|
private final AtomicInteger count_ = new AtomicInteger(0);
|
||||||
|
/** Secure random */
|
||||||
|
private volatile SecureRandom secureRandom_;
|
||||||
|
|
||||||
|
ReseedingSecureRandom() {
|
||||||
|
secureRandom_ = new SecureRandom();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nextBytes(byte[] bytes) {
|
||||||
|
getSecureRandom().nextBytes(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
int nextInt() {
|
||||||
|
return getSecureRandom().nextInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
int nextInt(int n) {
|
||||||
|
return getSecureRandom().nextInt(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SecureRandom getSecureRandom() {
|
||||||
|
int currentCount = count_.incrementAndGet();
|
||||||
|
if ((currentCount % RESEED_AT) == 0) {
|
||||||
|
// Reset to 0, next caller should not come into this "if" and might use the old secure random which is fine
|
||||||
|
count_.set(0);
|
||||||
|
secureRandom_ = new SecureRandom();
|
||||||
|
}
|
||||||
|
|
||||||
|
return secureRandom_;
|
||||||
|
}
|
||||||
|
}
|
49
src/main/java/com/example/farsite/util/SamplePopulation.java
Normal file
49
src/main/java/com/example/farsite/util/SamplePopulation.java
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package com.example.farsite.util;
|
||||||
|
|
||||||
|
import com.example.farsite.model.Address;
|
||||||
|
import com.example.farsite.model.Employee;
|
||||||
|
import com.example.farsite.model.Gender;
|
||||||
|
import com.github.javafaker.Faker;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Examples illustrating the use of JPA with the employee domain
|
||||||
|
* com.example.farsite.model.
|
||||||
|
*
|
||||||
|
* @see com.example.farsite.jpa.model.ExampleTest
|
||||||
|
*/
|
||||||
|
public class SamplePopulation {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(SamplePopulation.class);
|
||||||
|
|
||||||
|
Faker fake = new Faker();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the specified number of random sample employees.
|
||||||
|
*/
|
||||||
|
public void createNewEmployees(EntityManager em, int quantity) {
|
||||||
|
for (int index = 0; index < quantity; index++) {
|
||||||
|
em.persist(createRandomEmployee());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Employee createRandomEmployee() {
|
||||||
|
Random r = new Random();
|
||||||
|
|
||||||
|
Employee emp = new Employee();
|
||||||
|
emp.setGender(Gender.values()[r.nextInt(2)]);
|
||||||
|
emp.setFirstName(fake.name().firstName());
|
||||||
|
emp.setLastName(fake.name().lastName());
|
||||||
|
emp.addPhoneNumber("HOME", fake.phoneNumber().phoneNumber().toString());
|
||||||
|
emp.addPhoneNumber("WORK", fake.phoneNumber().phoneNumber().toString());
|
||||||
|
emp.addPhoneNumber("MOBILE", fake.phoneNumber().cellPhone().toString());
|
||||||
|
|
||||||
|
emp.setAddress(new Address(fake.address().city(), fake.address().country(), "", fake.address().zipCode(), fake.address().streetAddress()));
|
||||||
|
|
||||||
|
return emp;
|
||||||
|
}
|
||||||
|
}
|
104
src/main/java/com/example/farsite/util/SerialVersionUID.java
Normal file
104
src/main/java/com/example/farsite/util/SerialVersionUID.java
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
package com.example.farsite.util;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SerialVersionUID {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute a UID for the serialization version of a class.
|
||||||
|
*
|
||||||
|
* The Java object serialization standard defines an algorithm for computing the default serialVersionUID of a
|
||||||
|
* class: http://docs.oracle.com/javase/6/docs/platform/serialization/spec/class.html#4100. This method computes a
|
||||||
|
* serialVersionUID value model classes. For example, the com.example.model.User class should specify the following:
|
||||||
|
*
|
||||||
|
* <code><pre>
|
||||||
|
* private static final long serialVersionUID = SerialVersionUID.computeUID(User.class);
|
||||||
|
* </pre></code>
|
||||||
|
*
|
||||||
|
* Java provides a way to access and possibly compute a default value for serialVersionUID using
|
||||||
|
* java.io.ObjectStreamClass. If a class has no serialVersionID, the
|
||||||
|
* {@link java.io.ObjectStreamClass#getSerialVersionUID()} computes a default value according to the algorithm
|
||||||
|
* defined by the object serialization standard. However, we do not use this method because there is no clean way to
|
||||||
|
* access the private method computeDefaultSUID that performs the computation.
|
||||||
|
*
|
||||||
|
* Therefore, this method is based on, but different from the implementation of
|
||||||
|
* java.io.ObjectStreamClass#computeDefaultSIUD(Class<?>). This implementation does not factor various elements of
|
||||||
|
* the default computation into the resulting hash because the goal is to characterize versions of the class which
|
||||||
|
* are compatible for serialization and deserialization of their fields even if method signatures change. We don't
|
||||||
|
* want the addition of a method or a constructor to change the computed value. Therefore, this method uses only
|
||||||
|
* some of the internal logic of the default algorithm: it implements steps 1, 4, 8 and 9 of the standard algorithm
|
||||||
|
* and omits steps 2, 3, 5, 6 and 8.
|
||||||
|
*
|
||||||
|
* Like the standard algorithm, this implementation writes various elements of the class definition to a
|
||||||
|
* DataOutputStream and then computes a SHA-1 digest of the stream and returns a hash based on the digest. Unlike
|
||||||
|
* the standard algorithm, this implementation does not include interface, method and constructor signatures.
|
||||||
|
*
|
||||||
|
* @param clazz
|
||||||
|
* The class
|
||||||
|
* @return A version UID.
|
||||||
|
*/
|
||||||
|
public static long compute(final Class<?> clazz) {
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dataOut = new DataOutputStream(bytesOut);
|
||||||
|
|
||||||
|
// #1
|
||||||
|
dataOut.writeUTF(clazz.getName());
|
||||||
|
|
||||||
|
// #4
|
||||||
|
List<Field> sorted = Arrays.asList(clazz.getDeclaredFields());
|
||||||
|
sorted.sort(new Comparator<Field>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(Field field1, Field field2) {
|
||||||
|
return field1.getName().compareTo(field2.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
for (final Field field : sorted) {
|
||||||
|
int mods = field.getModifiers() &
|
||||||
|
(Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED |
|
||||||
|
Modifier.STATIC | Modifier.FINAL | Modifier.VOLATILE |
|
||||||
|
Modifier.TRANSIENT);
|
||||||
|
if (((mods & Modifier.PRIVATE) == 0) ||
|
||||||
|
((mods & (Modifier.STATIC | Modifier.TRANSIENT)) == 0))
|
||||||
|
// Don't include private static or
|
||||||
|
// private transient fields
|
||||||
|
{
|
||||||
|
dataOut.writeUTF(field.getName());
|
||||||
|
dataOut.writeInt(mods);
|
||||||
|
dataOut.writeUTF(field.getType().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dataOut.flush();
|
||||||
|
|
||||||
|
// #8
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA");
|
||||||
|
byte[] hashBytes = md.digest(bytesOut.toByteArray());
|
||||||
|
|
||||||
|
// #9
|
||||||
|
long hash = 0L;
|
||||||
|
for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
|
||||||
|
hash = (hash << 8) | (hashBytes[i] & 0xFF);
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
throw new InternalError(ex);
|
||||||
|
}
|
||||||
|
catch (NoSuchAlgorithmException ex) {
|
||||||
|
throw new SecurityException(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
55
src/main/java/com/example/farsite/util/UUIDSequence.java
Normal file
55
src/main/java/com/example/farsite/util/UUIDSequence.java
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
package com.example.farsite.util;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.eclipse.persistence.config.SessionCustomizer;
|
||||||
|
import org.eclipse.persistence.internal.databaseaccess.Accessor;
|
||||||
|
import org.eclipse.persistence.internal.sessions.AbstractSession;
|
||||||
|
import org.eclipse.persistence.sequencing.Sequence;
|
||||||
|
import org.eclipse.persistence.sessions.Session;
|
||||||
|
|
||||||
|
public class UUIDSequence extends Sequence {
|
||||||
|
|
||||||
|
public UUIDSequence(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getGeneratedValue(Accessor accessor, AbstractSession writeSession, String seqName) {
|
||||||
|
return UUID.randomUUID().toString().toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector getGeneratedVector(Accessor accessor, AbstractSession writeSession, String seqName, int size) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnect() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisconnect() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldAcquireValueAfterInsert() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldAlwaysOverrideExistingValue(String seqName, Object existingValue) {
|
||||||
|
return ((String) existingValue).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldUseTransaction() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldUsePreallocation() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
66
src/main/resources/META-INF/persistence.xml
Normal file
66
src/main/resources/META-INF/persistence.xml
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
|
||||||
|
<!-- https://jcp.org/aboutJava/communityprocess/final/jsr338/index.html -->
|
||||||
|
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
|
||||||
|
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
|
||||||
|
version="2.1">
|
||||||
|
|
||||||
|
<persistence-unit name="employee" transaction-type="RESOURCE_LOCAL">
|
||||||
|
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||||
|
<class>com.example.farsite.model.Address</class>
|
||||||
|
<class>com.example.farsite.model.Employee</class>
|
||||||
|
<class>com.example.farsite.model.EmploymentPeriod</class>
|
||||||
|
<class>com.example.farsite.model.Gender</class>
|
||||||
|
<class>com.example.farsite.model.GenderConverter</class>
|
||||||
|
<class>com.example.farsite.model.PhoneNumber</class>
|
||||||
|
<properties>
|
||||||
|
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
|
||||||
|
<property name="eclipselink.session.customizer" value="com.example.farsite.util.CrDBSessionCustomizer"/>
|
||||||
|
|
||||||
|
<!-- EclipseLink should create the database schema automatically -->
|
||||||
|
<property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
|
||||||
|
<property name="eclipselink.ddl-generation.output-mode" value="database"/>
|
||||||
|
<property name="javax.persistence.schema-generation.database.action" value="create"/>
|
||||||
|
<property name="eclipselink.target-database" value="com.example.farsite.util.CockroachDBPlatform"/>
|
||||||
|
|
||||||
|
<property name="eclipselink.logging.logger" value="JavaLogger"/>
|
||||||
|
<property name="eclipselink.logging.timestamp" value="false"/>
|
||||||
|
<property name="eclipselink.logging.thread" value="false"/>
|
||||||
|
<property name="eclipselink.logging.session" value="false"/>
|
||||||
|
<property name="eclipselink.logging.exceptions" value="false"/>
|
||||||
|
<property name="eclipselink.logging.connection" value="false"/>
|
||||||
|
<property name="eclipselink.logging.level.metadata" value="WARNING"/>
|
||||||
|
<property name="eclipselink.logging.parameters" value="true"/>
|
||||||
|
|
||||||
|
<property name="eclipselink.profiler" value="org.eclipse.persistence.tools.profiler.PerformanceProfiler"/>
|
||||||
|
|
||||||
|
<!-- Optimization - statement caching -->
|
||||||
|
<property name="eclipselink.jdbc.cache-statements" value="true"/>
|
||||||
|
<!-- Optimization - batch writing -->
|
||||||
|
<property name="eclipselink.jdbc.batch-writing" value="JDBC"/>
|
||||||
|
<property name="eclipselink.jdbc.batch-writing.size" value="1000"/>
|
||||||
|
<!-- Optimization - disable caching for batch insert (caching only improves reads, so only adds overhead for inserts) -->
|
||||||
|
<property name="eclipselink.cache.shared.default" value="false"/>
|
||||||
|
<!-- Except for XXX which is shared by orders
|
||||||
|
<property name="eclipselink.cache.shared.Customer" value="true"/> TODO(gburd): ? -->
|
||||||
|
<!-- Optimization - turn logging off
|
||||||
|
<property name="eclipselink.logging.level" value="off" /> -->
|
||||||
|
<property name="eclipselink.logging.level" value="FINE"/>
|
||||||
|
<!-- Optimization - close EntityManager on commit, to avoid cost of resume -->
|
||||||
|
<property name="eclipselink.persistence-context.close-on-commit" value="true"/>
|
||||||
|
<!-- Optimization - avoid auto flush cost on query execution -->
|
||||||
|
<property name="eclipselink.persistence-context.flush-mode" value="commit"/>
|
||||||
|
<!-- Optimization - avoid cost of persist on commit -->
|
||||||
|
<property name="eclipselink.persistence-context.persist-on-commit" value="false"/>
|
||||||
|
<!-- Optimization - -->
|
||||||
|
<property name="eclipselink.jdbc.bind-parameters" value="true"/>
|
||||||
|
<!-- Optimization - create indexes for all foreign key fields -->
|
||||||
|
<property name="eclipselink.ddl-generation.index-foreign-keys" value="true"/>
|
||||||
|
<!-- Optimization - enable query caching -->
|
||||||
|
<property name="eclipselink.cache.query-results" value="true"/>
|
||||||
|
<!-- <property name="eclipselink.cache.database-event-listener" value="DCN"/> -->
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
</persistence>
|
|
@ -1,107 +0,0 @@
|
||||||
package com.example.farsite.model;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.EntityManagerFactory;
|
|
||||||
import javax.persistence.Persistence;
|
|
||||||
import javax.persistence.Query;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class JpaTest {
|
|
||||||
|
|
||||||
private static final String PERSISTENCE_UNIT_NAME = "people";
|
|
||||||
private EntityManagerFactory factory;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
|
|
||||||
EntityManager em = factory.createEntityManager();
|
|
||||||
|
|
||||||
// Begin a new local transaction so that we can persist a new entity
|
|
||||||
em.getTransaction().begin();
|
|
||||||
|
|
||||||
// read the existing entries
|
|
||||||
Query q = em.createQuery("select m from Person m");
|
|
||||||
// Persons should be empty
|
|
||||||
|
|
||||||
// do we have entries?
|
|
||||||
boolean createNewEntries = (q.getResultList().size() == 0);
|
|
||||||
|
|
||||||
// No, so lets create new entries
|
|
||||||
if (createNewEntries) {
|
|
||||||
assertTrue(q.getResultList().size() == 0);
|
|
||||||
Family family = new Family();
|
|
||||||
family.setDescription("Family for the Knopfs");
|
|
||||||
em.persist(family);
|
|
||||||
for (int i = 0; i < 40; i++) {
|
|
||||||
Person person = new Person();
|
|
||||||
person.setFirstName("Jim_" + i);
|
|
||||||
person.setLastName("Knopf_" + i);
|
|
||||||
em.persist(person);
|
|
||||||
// now persists the family person relationship
|
|
||||||
family.getMembers().add(person);
|
|
||||||
em.persist(person);
|
|
||||||
em.persist(family);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commit the transaction, which will cause the entity to
|
|
||||||
// be stored in the database
|
|
||||||
em.getTransaction().commit();
|
|
||||||
|
|
||||||
// It is always good practice to close the EntityManager so that
|
|
||||||
// resources are conserved.
|
|
||||||
em.close();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void checkAvailablePeople() {
|
|
||||||
|
|
||||||
// now lets check the database and see if the created entries are there
|
|
||||||
// create a fresh, new EntityManager
|
|
||||||
EntityManager em = factory.createEntityManager();
|
|
||||||
|
|
||||||
// Perform a simple query for all the Message entities
|
|
||||||
Query q = em.createQuery("select m from Person m");
|
|
||||||
|
|
||||||
// We should have 40 Persons in the database
|
|
||||||
assertTrue(q.getResultList().size() == 40);
|
|
||||||
|
|
||||||
em.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void checkFamily() {
|
|
||||||
EntityManager em = factory.createEntityManager();
|
|
||||||
// Go through each of the entities and print out each of their
|
|
||||||
// messages, as well as the date on which it was created
|
|
||||||
Query q = em.createQuery("select f from Family f");
|
|
||||||
|
|
||||||
// We should have one family with 40 persons
|
|
||||||
assertTrue(q.getResultList().size() == 1);
|
|
||||||
assertTrue(((Family) q.getSingleResult()).getMembers().size() == 40);
|
|
||||||
em.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = javax.persistence.NoResultException.class)
|
|
||||||
public void deletePerson() {
|
|
||||||
EntityManager em = factory.createEntityManager();
|
|
||||||
// Begin a new local transaction so that we can persist a new entity
|
|
||||||
em.getTransaction().begin();
|
|
||||||
Query q = em
|
|
||||||
.createQuery("SELECT p FROM Person p WHERE p.firstName = :firstName AND p.lastName = :lastName");
|
|
||||||
q.setParameter("firstName", "Jim_1");
|
|
||||||
q.setParameter("lastName", "Knopf_!");
|
|
||||||
Person user = (Person) q.getSingleResult();
|
|
||||||
em.remove(user);
|
|
||||||
em.getTransaction().commit();
|
|
||||||
Person person = (Person) q.getSingleResult();
|
|
||||||
// Begin a new local transaction so that we can persist a new entity
|
|
||||||
|
|
||||||
em.close();
|
|
||||||
}
|
|
||||||
}
|
|
38
src/test/java/com/example/farsite/test/ConfigTest.java
Normal file
38
src/test/java/com/example/farsite/test/ConfigTest.java
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package com.example.farsite.test;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ConfigTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bootstrap() {
|
||||||
|
EntityManager em = getEmf().createEntityManager();
|
||||||
|
|
||||||
|
em.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EntityManagerFactory emf;
|
||||||
|
|
||||||
|
public static EntityManagerFactory getEmf() {
|
||||||
|
return emf;
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void createEMF() {
|
||||||
|
emf = PersistenceTesting.createEMF(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void closeEMF() {
|
||||||
|
if (emf != null && emf.isOpen()) {
|
||||||
|
emf.close();
|
||||||
|
}
|
||||||
|
emf = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
src/test/java/com/example/farsite/test/ExampleTest.java
Normal file
12
src/test/java/com/example/farsite/test/ExampleTest.java
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package com.example.farsite.test;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ExampleTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMain() throws Exception {
|
||||||
|
Main.main(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
108
src/test/java/com/example/farsite/test/Main.java
Normal file
108
src/test/java/com/example/farsite/test/Main.java
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
package com.example.farsite.test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
|
import com.example.farsite.model.Employee;
|
||||||
|
import com.example.farsite.model.Gender;
|
||||||
|
import com.example.farsite.util.SamplePopulation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Examples illustrating the use of JPA with the employee domain
|
||||||
|
* com.example.farsite.jpa.model.
|
||||||
|
*
|
||||||
|
* @see ExampleTest
|
||||||
|
*/
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
EntityManagerFactory emf = PersistenceTesting.createEMF(true);
|
||||||
|
Main example = new Main();
|
||||||
|
|
||||||
|
try {
|
||||||
|
EntityManager em = emf.createEntityManager();
|
||||||
|
|
||||||
|
em.getTransaction().begin();
|
||||||
|
new SamplePopulation().createNewEmployees(em, 1000);
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.clear();
|
||||||
|
|
||||||
|
// Add employee with 555 area code to satisfy a test query
|
||||||
|
em.getTransaction().begin();
|
||||||
|
Employee e = new Employee();
|
||||||
|
e.setFirstName("John");
|
||||||
|
e.setLastName("Doe");
|
||||||
|
e.setGender(Gender.Male);
|
||||||
|
e.addPhoneNumber("HOME", "555-5552222");
|
||||||
|
em.persist(e);
|
||||||
|
Long id = e.getId();
|
||||||
|
|
||||||
|
em.getTransaction().commit();
|
||||||
|
em.clear();
|
||||||
|
|
||||||
|
example.queryAllEmployees(em);
|
||||||
|
em.clear();
|
||||||
|
|
||||||
|
example.queryEmployeeLikeAreaCode55(em);
|
||||||
|
em.clear();
|
||||||
|
|
||||||
|
example.modifyEmployee(em, id);
|
||||||
|
em.clear();
|
||||||
|
|
||||||
|
example.deleteEmployee(em, id);
|
||||||
|
em.clear();
|
||||||
|
|
||||||
|
em.close();
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
emf.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void queryAllEmployees(EntityManager em) {
|
||||||
|
List<Employee> results = em.createQuery("SELECT e FROM Employee e", Employee.class).getResultList();
|
||||||
|
|
||||||
|
System.out.println("Query All Results: " + results.size());
|
||||||
|
|
||||||
|
results.forEach(e -> System.out.println("\t>" + e));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void queryEmployeeLikeAreaCode55(EntityManager em) {
|
||||||
|
System.out.println("\n\n --- Query Employee.phoneNumbers.areaCode LIKE '55%' ---");
|
||||||
|
|
||||||
|
TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e JOIN e.phoneNumbers phones WHERE phones.number LIKE '55%'", Employee.class);
|
||||||
|
List<Employee> emps = query.getResultList();
|
||||||
|
|
||||||
|
emps.forEach(e -> System.out.println("> " + e));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void modifyEmployee(EntityManager em, Long id) {
|
||||||
|
System.out.println("\n\n --- Modify Employee ---");
|
||||||
|
em.getTransaction().begin();
|
||||||
|
|
||||||
|
Employee emp = em.find(Employee.class, id);
|
||||||
|
emp.setSalary(1);
|
||||||
|
|
||||||
|
TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID AND e.firstName = :FNAME", Employee.class);
|
||||||
|
query.setParameter("ID", id);
|
||||||
|
query.setParameter("FNAME", emp.getFirstName());
|
||||||
|
emp = query.getSingleResult();
|
||||||
|
|
||||||
|
em.getTransaction().commit();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteEmployee(EntityManager em, Long id) {
|
||||||
|
em.getTransaction().begin();
|
||||||
|
|
||||||
|
em.remove(em.find(Employee.class, id));
|
||||||
|
em.flush();
|
||||||
|
|
||||||
|
//em.getTransaction().rollback();
|
||||||
|
em.getTransaction().commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.example.farsite.test;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.Persistence;
|
||||||
|
|
||||||
|
import org.eclipse.persistence.config.PersistenceUnitProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persistence testing helper which creates an EMF providing testing overrides
|
||||||
|
* to use direct JDBC instead of a data source
|
||||||
|
*/
|
||||||
|
public class PersistenceTesting {
|
||||||
|
|
||||||
|
public static EntityManagerFactory createEMF(boolean replaceTables) {
|
||||||
|
Map<String, Object> props = new HashMap<String, Object>();
|
||||||
|
|
||||||
|
// Ensure the persistence.xml provided data source are ignored for Java
|
||||||
|
// SE testing
|
||||||
|
props.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, "");
|
||||||
|
props.put(PersistenceUnitProperties.JTA_DATASOURCE, "");
|
||||||
|
props.put(PersistenceUnitProperties.TRANSACTION_TYPE, "RESOURCE_LOCAL");
|
||||||
|
|
||||||
|
// Configure the use of embedded derby for the tests allowing system
|
||||||
|
// properties of the same name to override
|
||||||
|
if (true) {
|
||||||
|
setProperty(props, PersistenceUnitProperties.JDBC_DRIVER, "org.postgresql.Driver");
|
||||||
|
setProperty(props, PersistenceUnitProperties.JDBC_URL, "jdbc:postgresql://127.0.0.1:26257/farsite");
|
||||||
|
setProperty(props, PersistenceUnitProperties.JDBC_USER, "root");
|
||||||
|
setProperty(props, PersistenceUnitProperties.JDBC_PASSWORD, "");
|
||||||
|
} else {
|
||||||
|
setProperty(props, PersistenceUnitProperties.JDBC_DRIVER, "org.postgresql.Driver");
|
||||||
|
setProperty(props, PersistenceUnitProperties.JDBC_URL, "jdbc:postgresql://127.0.0.1:5432/farsite");
|
||||||
|
setProperty(props, PersistenceUnitProperties.JDBC_USER, "postgres");
|
||||||
|
setProperty(props, PersistenceUnitProperties.JDBC_PASSWORD, "postgres");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure weaving is used
|
||||||
|
props.put(PersistenceUnitProperties.WEAVING, "false"); // TODO(gburd): true, -javaagent:toplink-essentials-agent.jar
|
||||||
|
|
||||||
|
if (replaceTables) {
|
||||||
|
props.put(PersistenceUnitProperties.DDL_GENERATION, PersistenceUnitProperties.DROP_AND_CREATE);
|
||||||
|
props.put(PersistenceUnitProperties.DDL_GENERATION_MODE, PersistenceUnitProperties.DDL_DATABASE_GENERATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Persistence.createEntityManagerFactory("employee", props);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the system property value if it exists, otherwise use the default
|
||||||
|
* value.
|
||||||
|
*/
|
||||||
|
private static void setProperty(Map<String, Object> props, String key, String defaultValue) {
|
||||||
|
String value = defaultValue;
|
||||||
|
if (System.getProperties().containsKey(key)) {
|
||||||
|
value = System.getProperty(key);
|
||||||
|
}
|
||||||
|
props.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue