GradleからPostgreSQL Studioを起動する方法

## はじめに

### PostgreSQL Studioとは

http://www.postgresqlstudio.org

PostgreSQL Studioは、PostgreSQLをブラウザから操作出来るwebアプリケーションです。
詳しい操作については[こちら](http://www.postgresqlstudio.org/about/features/)をご覧ください。

この方法は2013−10−09現在にて確認できたものです。

## プロジェクトをclone

以下のコマンドを実行して、プロジェクトをcloneします。

```bash
$ git clone https://bitbucket.org/openscg/pgstudio.git pgstudio
$ cd pgstudio
```
### build-wrapper.xmlを追加

プロジェクトの **build.xml**には様々なtargetがありますが、 **target name="clean"**がGradleの **clean**タスクと重複してしまうため、
以下のファイルを追加して、回避します。

```build-wrapper.xml
<project default="">
    <include file="build.xml" as="original" />
</project>
```
こうすることで、build.xmlのtargetをGradleから **"original.${target名}"**でタスクとして実行できるようになります。

### Gradleのプロジェクトを準備する

Gradle 1.7から[Build Setup Plugin](http://gradle.monochromeroad.com/docs/userguide/build_setup_plugin.html)により **setupBuild**タスクが使えるようになりました。
今回の場合、既にsrcディレクトリがありますので **--type=basic**で準備します。
以下のコマンドを実行すると、 **gradle wrapper**に関するファイルと **build.gradle**等が作成されます。

```bash
$ gradle setupBuild --type=basic
```

### build.gradleの設定

**build.gradle**を以下の内容に書き換えます。

```build.gradle
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'jetty'

repositories {
    mavenCentral()
}

def ivyDependenciesResolver = {
    new XmlParser().parse(file("ivy.xml")).dependencies.dependency.findAll { 
        it.@name != 'gcodemirror' 
    }.collect { 
        "${it.@org + ':' + it.@name + ':' + it.@rev}" 
    }
}

dependencies {
    compile ivyDependenciesResolver()

    compile fileTree(dir: 'libs', include: '*.jar')

    providedRuntime 'net.sf.advanced-gwt:advanced-gwt:2.0.8'
    providedRuntime 'commons-codec:commons-codec:1.8'
    providedRuntime 'org.apache.commons:commons-lang3:3.1'
    providedRuntime 'com.google.gwt:gwt-servlet:2.5.1'
    providedRuntime 'org.json:json:20090211'
    providedRuntime 'com.googlecode.json-simple:json-simple:1.1.1'
    providedRuntime 'org.postgresql:postgresql:9.2-1003-jdbc4'
    providedRuntime 'com.smartgwt:smartgwt:2.4'
    providedRuntime 'com.smartgwt:smartgwt-skins:2.4'
    providedRuntime 'javax.validation:validation-api:1.0.0.GA'

}

sourceSets {
    main {
        java {
            srcDir 'src'
        }
    }
}

task DownloadGCodeMirrorTask(type: DownloadTask) {
    sourceUrl = 'https://gcodemirror.googlecode.com/files/gcodemirror-0.9.jar'
    target = file("libs")
}

class DownloadTask extends DefaultTask {

    @Input
    String sourceUrl

    @OutputDirectory
    File target

    @TaskAction
    void douwnload() {
        ant.get(src: sourceUrl, dest: target)
    }

}

ant.importBuild 'build-wrapper.xml'

task compileGwt(dependsOn: 'classes', type: JavaExec) {
    ext.buildDir = "${buildDir}/gwt"
    ext.extraDir = "${buildDir}/extra"

    inputs.source sourceSets.main.java.srcDirs
    inputs.dir sourceSets.main.output.resourcesDir
    outputs.dir buildDir

    outputs.upToDateSpec = new org.gradle.api.specs.AndSpec()

    doFirst {
        file(buildDir).mkdirs()
    }

    main = 'com.google.gwt.dev.Compiler'

    classpath {
        [
                sourceSets.main.java.srcDirs,           // Java source
                sourceSets.main.output.resourcesDir,    // Generated resources
                sourceSets.main.output.classesDir,      // Generated classes
                sourceSets.main.compileClasspath,       // Deps
        ]
    }

    jvmArgs = ['-Xmx384M']

    args = [
            ant.properties['gwt.module.name'],
            '-extra', extraDir,
    ]

}

jar {
    baseName = ant.properties['file.name']
    extension = 'jar'
    destinationDir = file("lib")
}

webAppDirName = 'war'

war {

    from('war') {
        exclude "**/WEB-INF/**"
    }

    exclude "**/${ant.properties['server.resources.name']}/**"
    exclude "**/deploy/**"

    classpath -= configurations.compile
    classpath -= files(sourceSets.main.output.classesDir)
    classpath configurations.providedRuntime
    classpath fileTree('lib')
    classpath fileTree(dir: 'libs', include: '*.jar')

    webXml = file('war/WEB-INF/web.xml')
    baseName = ant.properties['file.name']
    extension = 'war'

}

jar.dependsOn compileGwt

war.dependsOn jar

clean.dependsOn 'original.clean'

```

### gcodemirror.jarのダウンロード

gcodemirror.jarは、maven centralには存在せず、以下のプロジェクトにあります。
http://code.google.com/p/gcodemirror/
手動で管理するのが許される時代はもう終わりました。
そこで、以下のコマンドを実行して **libs**ディレクトリで管理します。

```bash
$ gradle DownloadGCodeMirrorTask
```

Gradleでタスクを実行する際は省略出来るので、[ここを参考に](http://gradle.monochromeroad.com/docs/userguide/tutorial_gradle_command_line.html#N10DC5)して適宜省略してください。

### jettyRunWarを実行

以下のコマンドを実行します。

```bash
$ gradle jettyRunWar
```
以下の表示がされるまでしばらくお待ちください。

```bash
> Building > :jettyRunWar > Running at http://localhost:8080/pgstudio
```

表示されたら、ブラウザから[http://localhost:8080/pgstudio/](http://localhost:8080/pgstudio/)へアクセスしてください。

ログイン画面が表示されたら成功です。

### 最後に

私はGoogle Web Toolkitの作法がまだよく分かっていないため、上記のようなbuild.gradleになってしまいました。
また、 **JettyRun**タスクでは失敗するのでそこも修正課題です。
コメント等で教えていただければ幸いです。