mike-neckのブログ

Java or Groovy or Swift or Golang

IntelliJ IDEA - gradle - javaee のテンプレートにpersistence.xmlを出力するタスクを追加した

題名の通り。

まあ、使わないと思うけど…

このリポジトリをクローンしてから、build.gradleに次のようなDSLを追加して、gradle idea rD persistenceXmlを起動すれば、IntelliJ IDEAプロジェクトができて、persistence.xmlも勝手に作成される。

task rmDummy(type: RemovingDummyTask)

task persistenceXml(type: JpaPersistenceXml) {
    baseJdbcUrl project.baseJdbcUrl
    jdbcUser jdbcUser
    jdbcPassword jdbcPassword
    jdbcProperties 'eclipselink.ddl-generation': 'create-or-extend-tables'
}

設定できるのは次のプロパティ。

configuration type description default
version String jpa version 2.1
unitName String persistence unit name javaee
transactionType String type of transaction JTA
providerName String name of JPA provider eclipse
jdbcDriver String a name of fully qualified class name of JDBC Driver org.h2.Driver
baseJdbcUrl String a base name of database url jdbc:h2:tcp://localhost:9092/~/h2
jdbcUser String user name of database null
jdbcPassword String password of the user null
jdbcProperties Map jpa's property key and value [:]

なお、調べるのが面倒だったので、対応しているJPAライブラリーはeclipse linkだけです。あと、対応しているtransaction-typeはJTAだけです。

persistenceXmlタスクのベースになっているのはbuildSrc/src/main/groovy/JpaPersistenceXml.groovyです。

class JpaPersistenceXml extends DefaultTask {

    static final String PROJECT_NAME = 'project-name'

    final String fileName = 'persistence.xml'

    final String xmlFileDir = 'jpa/src/main/resources/META-INF'

    final String xmlns = 'http://xmlns.jcp.org/xml/ns/persistence'

    String _version = '2.1'

    String _unitName = 'javaee'

    String _transactionType = 'JTA'

    final Map<String, String> _providers = [eclipse: 'org.eclipse.persistence.jpa.PersistenceProvider']

    String _providerName = 'eclipse'

    String _jdbcDriver = 'org.h2.Driver'

    String _baseJdbcUrl = 'jdbc:h2:tcp://localhost:9092/~/h2'

    String _jdbcUser

    String _jdbcPassword

    Map _jdbcProperties = [:]

    @TaskAction
    void generate() {
        File xmlFile = file("${xmlFileDir}/${fileName}")
        def projectName = file(PROJECT_NAME).text
        def w = new StringWriter()
        w << '<?xml version="1.0" encoding="UTF-8"?>\n'
        def b = new MarkupBuilder(w)
        b.persistence(xmlns: xmlns, version: _version) {
            'persistence-unit'(name: _unitName, 'transaction-type': _transactionType) {
                provider _providers[_providerName]
                if (_transactionType == 'JTA') {
                    'jta-data-source' "jdbc/${projectName}"
                }
                'properties' {
                    property(name: 'javax.persistence.jdbc.driver', value: _jdbcDriver)
                    property(name: 'javax.persistence.jdbc.url', value: "${_baseJdbcUrl}/${projectName}")
                    if (_jdbcUser) {
                        property (name: 'javax.persistence.jdbc.user', value: _jdbcUser)
                    }
                    if (_jdbcPassword) {
                        property (name: 'javax.persistence.jdbc.password', value: _jdbcPassword)
                    }
                    _jdbcProperties.each {
                        property(name: it.key, value: it.value)
                    }
                }
            }
        }
        xmlFile.write(w.toString())
    }

    private File file(String fileName) {
        getProject().file(fileName)
    }

    JpaPersistenceXml version(String v) {
        this._version  = v
        return this
    }

    // DSL用の公開しているメソッドは省略
}

おわり