Skip to content

Commit

Permalink
GORM to JPA Generator (#16)
Browse files Browse the repository at this point in the history
* GORM to JPA importer code

* resolved code violations

* documentation

* exclude the example files from the check
  • Loading branch information
musketyr committed Jul 26, 2021
1 parent f285b93 commit 2e2b8b6
Show file tree
Hide file tree
Showing 21 changed files with 1,479 additions and 20 deletions.
1 change: 1 addition & 0 deletions .asciidoctorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:root-dir: {asciidoctorconfigdir}
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,14 @@ config {

allprojects {
repositories {
jcenter()
mavenCentral()
maven { url "https://dl.bintray.com/agorapulse/libs" }
maven { url "https://repo.grails.org/artifactory/core" }
maven { url "https://repo.spring.io/release" }
}

license {
exclude '**/*.json'
exclude '**/*.groovy.txt'
exclude '***.yml'
}
}
Expand Down
1 change: 1 addition & 0 deletions docs/guide/src/docs/asciidoc/.asciidoctorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:includedir: {asciidoctorconfigdir}
70 changes: 69 additions & 1 deletion docs/guide/src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,74 @@ which will automatically load the configuration once the JAR is on classpath.
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.agorapulse.micronaut.grails.example.GrailsConfig
----

== Integration Tests

If you want to take advantage of additional features provided by `MicronautGrailsApp` such additional package scanning inside integration tests then you need to use a following extension of the standard testing library:

[source,indent=0,role="primary",subs='verbatim,attributes']
.Gradle
----
compile 'com.agorapulse:micronaut-grails-integration-test:{project-version}'
----

Once the library is on the classpath, use `@MicronautGrailsIntegration` instead of `@Inegration` annotation to achieve the similar result:

[source,groovy]
----
include::{root-dir}/examples/micronaut-grails-example/src/test/groovy/micronaut/grails/example/IntegrationSpec.groovy[tags=body]
----

== GORM to Micronaut Data JPA Generator

There is an experimental generator for the JPA entities from GORM domain classes. You can use either from integration test or using Grails Console plugin

[source,groovy,indent=0,options="nowrap"]
.Integration Test Usage
----
include::{root-dir}/examples/micronaut-grails-example/src/test/groovy/micronaut/grails/example/GeneratorSpec.groovy[tags=body]
----


[source,groovy,indent=0,options="nowrap"]
.Grails Console Usage
----
ctx.micronautJpaGenerator.generate(new File('/path/to/generated/sources'))
----

The current generator supports

* Constraints
* Column mappings
* One-to-One, One-to-Many and Many-to-One relationships
* Join Tables
* Unique and regular indices

Please, let us know if there is any feature missing!

=== Generated Entities Example

For an `User` entity such as this one

[source, groovy]
.GORM Entity
----
include::{root-dir}/examples/micronaut-grails-example/grails-app/domain/micronaut/grails/example/User.groovy[tag=body]
----

The following files are generated

[source, groovy]
.Micronaut Data JPA Entity
----
include::{root-dir}/examples/micronaut-grails-example/src/test/resources/micronaut/grails/example/GeneratorSpec/User.groovy.txt[]
----

[source, groovy]
.Micronaut Data Repository
----
include::{root-dir}/examples/micronaut-grails-example/src/test/resources/micronaut/grails/example/GeneratorSpec/UserRepository.groovy.txt[]
----

== Troubleshooting

=== Dumping Configuration Properties
Expand All @@ -149,7 +217,7 @@ for (source in sources) {
println "$source.name:"
for (name in source) {
def value = source.get(name)
println " $name (${value?.getClass()}): ${String.valueOf(value)}"
println " $name (${value?.getClass()}): ${String.valueOf(value)}"
}
}
----
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2020 Vladimir Orany.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// tag::body[]
package micronaut.grails.example

import grails.compiler.GrailsCompileStatic

@GrailsCompileStatic
class User {

String userName
String password
String email

static constraints = {
userName blank: false, unique: true
password size: 5..10, blank: false
email email: true, blank: true
}

}
// end::body[]
21 changes: 6 additions & 15 deletions examples/micronaut-grails-example/micronaut-grails-example.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ buildscript {
}
dependencies {
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
classpath "gradle.plugin.com.github.erdi.webdriver-binaries:webdriver-binaries-gradle-plugin:2.0"
classpath "org.grails.plugins:hibernate5:7.0.4"
classpath "com.bertramlabs.plugins:asset-pipeline-gradle:3.2.4"
}
Expand All @@ -39,7 +38,6 @@ apply plugin:"eclipse"
apply plugin:"idea"
apply plugin:"war"
apply plugin:"org.grails.grails-web"
apply plugin:"com.github.erdi.webdriver-binaries"
apply plugin:"com.bertramlabs.asset-pipeline"
apply plugin:"org.grails.grails-gsp"

Expand Down Expand Up @@ -98,6 +96,10 @@ dependencies {
runtime "org.apache.tomcat:tomcat-jdbc"
runtime "javax.xml.bind:jaxb-api:2.3.1"
runtime "com.bertramlabs.plugins:asset-pipeline-grails:3.2.4"

testCompile project(':micronaut-grails-integration-test')
testCompile project(':micronaut-grails-jpa-generator')

testCompile "io.micronaut:micronaut-inject-groovy"
testCompile "org.grails:grails-gorm-testing-support"
testCompile "org.mockito:mockito-core"
Expand All @@ -108,6 +110,8 @@ dependencies {
testCompile "org.seleniumhq.selenium:selenium-support:3.14.0"
testRuntime "org.seleniumhq.selenium:selenium-chrome-driver:3.14.0"
testRuntime "org.seleniumhq.selenium:selenium-firefox-driver:3.14.0"

testCompile 'com.agorapulse.testing:fixt:0.2.1.1'
}

bootRun {
Expand All @@ -128,19 +132,6 @@ tasks.withType(GroovyCompile) {
}
}

webdriverBinaries {
chromedriver '2.45.0'
geckodriver '0.24.0'
}

tasks.withType(Test) {
systemProperty "geb.env", System.getProperty('geb.env')
systemProperty "geb.build.reportsDir", reporting.file("geb/integrationTest")
systemProperty "webdriver.chrome.driver", System.getProperty('webdriver.chrome.driver')
systemProperty "webdriver.gecko.driver", System.getProperty('webdriver.gecko.driver')
}


assets {
minifyJs = true
minifyCss = true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2020 Vladimir Orany.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package micronaut.grails.example

// tag::body[]
import com.agorapulse.micronaut.grails.jpa.generator.MicronautJpaGenerator
import com.agorapulse.micronaut.grails.test.MicronautGrailsIntegration
import com.agorapulse.testing.fixt.Fixt
import org.springframework.beans.factory.annotation.Autowired
import spock.lang.Specification

@MicronautGrailsIntegration
class GeneratorSpec extends Specification {

Fixt fixt = Fixt.create(GeneratorSpec)

@Autowired MicronautJpaGenerator generator

void 'generate domains'() {
given:
File root = initRootDirectory()
when:
int generated = generator.generate(root)
then:
noExceptionThrown()

generated == 1

when:
File entityFile = new File(root, 'micronaut/grails/example/User.groovy')
File repositoryFile = new File(root, 'micronaut/grails/example/UserRepository.groovy')
then:
entityFile.exists()
entityFile.text.trim() == fixt.readText('User.groovy.txt').trim()

repositoryFile.exists()
repositoryFile.text.trim() == fixt.readText('UserRepository.groovy.txt').trim()
}

private static File initRootDirectory() {
File root = new File(System.getProperty('java.io.tmpdir'), 'micronaut-data-model')

if (root.exists()) {
root.deleteDir()
}

root.mkdirs()

return root
}

}
// end::body[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* Copyright 2020 Vladimir Orany.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package micronaut.grails.example

// tag::body[]
import com.agorapulse.micronaut.grails.jpa.generator.MicronautJpaGenerator
import com.agorapulse.micronaut.grails.test.MicronautGrailsIntegration
import org.springframework.beans.factory.annotation.Autowired
import spock.lang.Specification

@MicronautGrailsIntegration
class IntegrationSpec extends Specification {

@Autowired MicronautJpaGenerator generator

void 'application started'() {
when:
new URL("http:https://localhost:$serverPort").text
then:
noExceptionThrown()
}

}
// end::body[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package micronaut.grails.example

import groovy.transform.CompileStatic
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id
import javax.persistence.Table
import javax.persistence.UniqueConstraint
import javax.persistence.Version
import javax.validation.constraints.Email
import javax.validation.constraints.NotBlank
import javax.validation.constraints.NotNull
import javax.validation.constraints.Size

@Entity
@CompileStatic
@Table(
uniqueConstraints = [
@UniqueConstraint(columnNames = ['user_name'])
]
)
class User {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
Long id

@Version
Long version

@NotNull
@Email
@Size(max = 255)
String email

@NotNull
@Size(min = 5, max = 10)
@NotBlank
@Size(min = 5, max = 10)
String password

@NotNull
@NotBlank
@Size(max = 255)
String userName

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package micronaut.grails.example

import io.micronaut.data.annotation.Repository
import io.micronaut.data.repository.CrudRepository

@Repository
interface UserRepository extends CrudRepository<User, Long> {

}
2 changes: 1 addition & 1 deletion gradle/LICENSE_HEADER
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
SPDX-License-Identifier: Apache-2.0

Copyright ${copyrightYear} ${author}.
Copyright 2020 ${author}.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
Loading

0 comments on commit 2e2b8b6

Please sign in to comment.