「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

42
Grails-1.1を斬る! +Grails-1.1からのチーム開発~ 第0.9回 名古屋Grails/Groovy勉強会「もうやっこでいこみゃ~か!」 def speaker = new Cast(name:”T.Yamamoto”,version:”GRN-0.9-2009-03-19”)

Transcript of 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

Page 1: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

Grails-1.1を斬る!~+Grails-1.1からのチーム開発~

第0.9回 名古屋Grails/Groovy勉強会「もうやっこでいこみゃ~か!」

def speaker = new Cast(name:”T.Yamamoto”,version:”GRN-0.9-2009-03-19”)

Page 2: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

自己紹介名前:山本 剛 (やまもとつよし)所属:ニューキャスト

「Grails徹底入門」9-11章、書きました。

ブログhttp://xmldo.blogspot.com/http://d.hatena.ne.jp/mottsnite/

Page 3: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

おさらい

Page 4: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

Grailsとは?よく聞く説明では、「Groovyで実装されたRuby on Rails」!?  合ってるようで間違いJava+Groovyで実装された、CoC、DRYの概念を取り入れた(‘RoR’にインスパイアされた)、Webアプリケーション開発環境。基礎はJavaでの開発で信頼されたSpring,Hibernate等を使用している。そして、それらをシンプルに利用できる環境。

Grails, 開発プラットフォーム (DGG2引用)

Page 5: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

Grailsの構成図GrailsGrailsGrails Groovy

Spring Hibernate SiteMeshGroovy

基礎部分はJava(+Groovy)基礎部分はJava(+Groovy)基礎部分はJava(+Groovy)基礎部分はJava(+Groovy)JVMJVMJVMJVM

Hibernate:ORマッピング Spring: DIコンテナ・多機能なラッパーフレームワーク SiteMesh:レイアウトフレームワーク Jetty: サーブレットコンテナ HSQLDB:ピュアJavaなデータベース

Page 6: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

デモgrails create-app democd demograils create-domain-class Bookgrails create-controller Bookgrails run-app--止める--grails install-plugin acegi--プラグインインストールは前より早くなった!!

Page 7: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

GRAILS-1.1

Page 8: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

Grails-1.1リリースAnt+IvyとMavenビルドのサポートスタンドアロンGORMプラグインの新機能:グローバルプラグイン、他動推移的なプラグイン解決、ローカルリポジトリー対応、他Springネームスペースサポート劇的に向上したパフォーマンステストフレームワークMVCレイヤーとGORM等のGrailsコアへの多くの新機能と改善

Groovyは最新の1.6に更新

Page 9: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

長くなるので、一気に紹介!

Page 10: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

GORMイベント - イベントbeforeInsert,beforeUpdate,beforeDeleteに、さらにafterInsert, afterUpdate and afterDeleteが追加された。他に、 基本型(String,Integer)、 Enum でのコレクション。読み取りのみのオブジェクト取得。ソートのデフォルト値の設定。バッチフェッチ。ダイナミックファインダの向上。joinTable!generatorの指定

GORMスタンドアロンでGORMが使用可能!  Spring MVCでのサンプル、GRAILS_HOME/samples/petclinic-mvcを参照applicationContext.xmlにデータソースと、<gorm:sessionFactory/>の定義

<gorm:sessionFactory base-package="org.grails.samples" data-source-ref="dataSource" message-source-ref="messageSource">

<property name="hibernateProperties"><util:map>

<entry key="hibernate.hbm2ddl.auto" value="update"/>

</util:map></property>

</gorm:sessionFactory>

import

grail

s.pers

istenc

e.Enti

ty

@Entit

y

class

Person

{

String

name

...

}

Person

.groov

y

def book = Book.read(1)

static hasMany = [name:Str

ing]

static mapping = { sort "name" books sort:"title"}

static mapping = {batchSize 15

}

static mapping = {id generator:"org.hibernate.id.enhanced.SequenceStyleGenerator",

params:[sequence_name:'item_id_seq',initial_value:1000,increment_size:1]}

Page 11: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

GSP(Groovy Server Pages)GSPでのJSPタグライブラリのサポート

テンプレートネームスペース

Server Side Includes - <g:include>タグで別のコントローラ、アクションを呼び出せる。

パフォーマンスの改善

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

JSPタグを使う!<fmt:formatNumber value="${10}" pattern=".00"/>

メソッドのように使う!${fmt.formatNumber(value:10, pattern:".00")}

_tableRow.gspの中身<tr> <td class="prop">${label}</td> <td class="value">${value}</td></tr>ネームスペースtmpl+”_”を無くしたファイル名で呼び出す。<tmpl:tableRow label="one" value="two" />

<g:include controller="book" action="list"/>

コントローラあるいはタグライブラリでは、メソッドとして呼出も可能!def content = include(controller:"book", action:"list")

Page 12: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

データバインディングサブセットプロパティ

コレクション型への対応

今までは、以下の方法で全プロパティがバインドされました。person.properties = params

サブセットプロパティの対応で、指定した項目のみバインド!person.properties["firstName","lastName"] = params

同じ方法でアクセスも可能!person.properties["firstName","lastName"].each { println it }

<g:textField name="books[0].title" value="the Stand" /><g:textField name="books[1].title" value="the Shining" /><g:textField name="books[2].title" value="Red Madder" />自動的に収集してまとめてくれます。

Page 13: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

コントローラ関連RESTfulマッピングの指定方法の向上  "/books"(resource:"book") の指定で、  GET, PUT, POST, DELETEを自動的に、 アクション"show", "save", "update", "delete"に設定多重サブミット対策フォームに、<g:form useToken="true">を指定すると、コントローラ内で、withFormを使用してフォームの多重サブミットを判別できるようになった。

リクエストのフォワード

エラーハンドルの宣言 UrlMappingsにエラーハンドルの宣言が可能に。

withForm { // 正常なリクエスト}.invalidToken { // ダブルクリックしたな?}

forward controller:"home", action:"index"

"500"(controller:"errors", exception:IllegalArgumentException)

Page 14: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

Scaffoldingダイナミックスカッフォルディングとテンプレートダイナミックスカッフォルディング時のテンプレートは、grails install-templates コマンドでインストールされたテンプレートを使用するようになった。ダイナミックなのに微調整できる!スカッフォルドでのM-to-M対応!

Page 15: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

その他Maven統合Ant + Ivy統合 - Grailsが生成するAntのbuild.xmlとivy.xmlで、Grailsがインストールされていない環境(CIサーバ等)でもビルド可能。Log4j DSLEnvironment(環境) 、Metadata(メタ情報) API

非インタラクティブモード BeanBuilderでSpringネームスペースに対応テストフレームワーク - Testingプラグインは、本体に統合!Encrypted Data Sources - データソースパスワードの暗号化

grails.util.En

vironment.DEVE

LOPMENT

def metadata =

grails.util.M

etadata.curren

t

println metada

ta.application

Name

Page 16: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

まだまだ有ります。ここからは、

チーム開発に便利!?な・・

Page 17: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

BuildConfig.groovyプロジェクトのビルドに関連する情報をカスタマイズできる定義ファイルGrails-1.0.x系では、Grailsのコンパイルされたクラスなどは、$USER_HOME/.grails/<バージョン>/以下に固定されていましたが、Grails-1.1からは指定変更可能になりました。

ファイルの設置場所 $PROJECT_HOME/grails-app/conf/BuildConfig.groovy中はこんな感じ↓

grails.project.plugins.dir="work_tmp/plugins"grails.project.work.dir="work_tmp/work"grails.plugin.location."feeds"="./plugins/feeds-1.4"

Page 18: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

BuildConfig定義できる内容※主な項目のみgrails.project.work.dir プロジェクトの作業ディレクトリ (このディレクトリ以下に classes,resources,plugins等が配置される) デフォルト:$USER_HOME/.grails/<バージョン>/projects/<プロジェクト名>/ 作業ディレクトリ以下を個別に指定も可能grails.project.plugins.dir プラグインのディレクトリ。 grails-1.0.xでの、$PROJECT_HOME/plugins デフォルト:$USER_HOME/.grails/<バージョン>/projects/<プロジェクト名>/pluginsgrails.project.test.reports.dir テストリポート書きだし先。grails.project.class.dir クラスの書きだし先。

Page 19: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

何でBuildConfigで設定変える必要があるの?個人的な意見・・・。grails.project.class.dirのように、コンパイルクラスを置く場所はよいとして、Grails-1.1からプラグインの場所が変わってしまったので、Grails-1.0.xを使っていたユーザには、プラグインのディレクトリが近くにいないのは・・・・。で、 grails.project.plugins.dirで場所を変更すると、プラグインの場所が近くで管理できるのでわかりやすい。ビルドサーバなどでの事情もあるし!変な所にファイル置かれても・・じゃあ、変えられればOKでしょ!

管理できるのは良いこと!

Page 20: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

プラグイン個別のパス指定プラグインを個別に指定することもできます。

プラグイン開発に便利!

grails.plugin.location."ext"="./plugins/ext-0.1"grails.plugin.location."form-maker"="./plugins/form-maker-0.1"grails.plugin.location."rhino"="./plugins/rhino-0.1.1"grails.plugin.location."waku-script"="./plugins/waku-script-0.2-SNAPSHOT"grails.plugin.location."yui"="./plugins/yui-2.6.0"grails.plugin.location."resources"="./plugins/resources-0.1"grails.plugin.location."taggin"="/works/experiment/grails-taggin/trunk"

Page 21: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

どの辺がチーム開発?で、ここで強引にプラグインの話!

Page 22: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

Grailsプラグインとは?自分のプロジェクトに便利な拡張機能を追加できる

公式プラグインも有ります!ユーザ認証機能とか、メールとか、

コマンド install-pluginで簡単に追加できるそもそもGrails自身がプラグインの集合体!通常のGrailsプロジェクトと構造が同じ!~GrailsPlugin.groovyファイルの有無

詳しくは!

Page 23: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

ん?プラグインで機能分けすると、開発を分担できそうだ!

メインプロジェクト

プラグインA (プロジェクトの一部の機能)

グラフ機能プラグイン (今後も再利用できそうな機能)

ユーザ認証プラグイン (公式のプラグイン+カスタマイズ)

プラグインB (プロジェクトの一部の機能)

インストール

インストール

インストール

インストール

この辺がチーム開発!+再利用性!

Page 24: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

前から有るのに、何故いまさら主張するの?Grails-1.0.xでは、プラグインはプロジェクトのディレクトリにインストールされて、チーム開発で使うと、結構それぞれがプラグインの内容をさわってしまって・・・・結局、後でまとめ直したりと・・・プロジェクトによってプラグインの派生ができてしまったりで、便利のようで実は管理しにくかったのです。

Page 25: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

そこで!

Page 26: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

Grails-1.1からの、プラグインの新機能グローバルプラグイン複数のプラグインリポジトリ他動的なプラグイン自動解決 (Automatic Transitive Plugin Resolution)プラグインでのモジュール式アプリケーション開発プラグインスコープと環境定義

Page 27: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

グローバルプラグイン"-global"オプションを指定することによって、プラグインはグローバルプラグインとして管理されます。インストールされたプラグインは、同じ場所に保管されて、一度インストールすれば、同じバージョンのGrailsで他のアプリケーション開発するときは再度インストールすることなく使用することができます。

grails install-plugin acegi -global

Page 28: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

グローバルは、必ず毎回とりこまれる有る意味便利だけど・・

・・・物によっては不便!? orz

Page 29: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

そんなあなたにこんな新機能!プラグインでのモジュール式アプリケーション開発他動的なプラグイン自動解決 (Automatic Transitive Plugin Resolution)複数のプラグインリポジトリ

Page 30: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

プラグインでのモジュール式アプリケーション開発Grails-1.1からプラグインは基本的にapplication.propertiesにメタ情報で管理されます。

プラグインの追加削除、バージョン変更は、プロジェクトのapplication.propertiesの内容を変更するだけでよいのです。これで、他のチームメンバーへのプラグイン変更通知も楽々。

app.version=0.1plugins.acegi=0.5.1app.servlet.version=2.4app.grails.version=1.1-SNAPSHOTplugins.hibernate=1.1-beta3app.name=relationsample plugins

.プラグイン名=バージョン

Page 31: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

しかも!

Page 32: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

他動的なプラグイン自動解決他動的なプラグイン自動解決 (※仮翻訳) (Automatic Transitive Plugin Resolution)

application.propertiesの情報を元に、自動的にバージョン確認して、インストール、アンインストールを行ってくれます。

間違った操作を防げます!

Page 33: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

これって、プラグインリポジトリの

プラグインにしか対応していないぢゃん!

Page 34: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

複数のプラグインリポジトリGrails-1.1から独自のプラグインリポジトリを設定することができるようになりました。設定方法USER_HOME/.grails/settings.groovy 又は、grails-app/conf/BuildConfig.groovyに情報定義。例えば、チームのプラグインリポジトリに使用するSvnのUrlが、"http://127.0.0.1/gp"だとしたら

grails.plugin.repos.discovery.local="http://127.0.0.1/gp" grails.plugin.repos.distribution.local="http://127.0.0.1/gp"

grails.plugin.repos.discovery.リポジトリ名称="リポジトリへのHttpベースのURL"grails.plugin.repos.distribution.リポジトリ名称="リポジトリへのHttpベースのURL"

Page 35: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

複数のプラグインリポジトリ独自のプラグインリポジトリ設定をすることによって、プラグイン関連のコマンドlist-plugins,install-pluginで設定したプラグインリポジトリも同時に参照してくれます。個別に参照する場合は、以下のように設定したリポジトリ名称を指定します。grails list-plugins -repository=リポジトリ名称

Page 36: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

独自のプラグインリポジトリにプラグインをリリース

プラグインプロジェクトディレクトリでrelease-pluginに-repository=対象リポジトリ名称を指定して実行。

以下の内容を行ってくれます。1. プラグインのパッケージング2. プラグインリポジトリへのプラグインの追加(grails-プラグイン名の階層に、tags trunkを追加)

3. プラグインのバージョンを自動でタグ切り4. プラグインリポジトリにある、プラグイン管理用の.plugin-meta/plugins-list.xmlを更新

grails release-plugin -repository=リポジトリ名称

Page 37: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

チーム用のプラグインリポジトリ!

Page 38: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

いろいろGRAILS-1.1は便利です。

Page 39: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

元々

メインプロジェクト

プラグインA (プロジェクトの一部の機能)

グラフ機能プラグイン (今後も再利用できそうな機能)

ユーザ認証プラグイン (公式のプラグイン+カスタマイズ)

プラグインB (プロジェクトの一部の機能)

インストール

インストール

インストール

インストール

Page 40: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

これから!Grails公式プラグイン

チーム用プラグインリポジトリ

メインプロジェクト

使用するプラグインの情報を

定義 プラグインA (プロジェクトの一部の機能)

グラフ機能プラグイン (今後も再利用できそうな機能)

ユーザ認証プラグイン (公式のプラグイン+カスタマイズ)

プラグインB (プロジェクトの一部の機能)

チーム用リポジトリ

独自プラグインリポジトリで管理

チームメンバー

チェックアウト

プラグイン自動解決

プラグイン自動解決

Page 41: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

まとめapplication.propertiesにプラグイン情報を保持するため、チームメンバー間でのプラグインバージョン管理が楽に!BuildConfig.groovyで、開発時のビルド場所や、プラグイン情報をまとめやすくなった。見えないゴミ減る!プラグイン開発時のソース分けが以前より楽に!

開発プロジェクト内容の切り分けをプラグイン別にし、 チーム用プラグインリポジトリを活用することで、開発した内容をプラグインとしての再利用が期待できる!

Page 42: 「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」

つづく.......