twitter sphere of #twitter4j #twtr_hack

87
TwitterSphere of Twitter4J 2012/02/23 @kimukou2628

Upload: kimukou26-kimukou

Post on 28-May-2015

4.273 views

Category:

Technology


3 download

DESCRIPTION

griffon using twitter4j

TRANSCRIPT

Page 1: Twitter sphere of #twitter4j #twtr_hack

TwitterSphere of Twitter4J

2012/02/23@kimukou2628

 

Page 2: Twitter sphere of #twitter4j #twtr_hack

● 今日のソース○ https://bitbucket.org/kimukou_26/twittersphere4j/src

○ にMercurial(HG)で上げてます<練習がてら

● bitbucketには○ githubみたいな

■ 最新レポジトリのソースのzipダウンロード機能○ ないみたいなのでごめんなさい

● Windowsの場合は UTF-8のソースなので○ http://www.asukaze.net/etc/vcs/hg-fixutf8.html

■ を参考にしてダウンロードしてください

● MacのGUIクライアントだと○ MacHg という物があるようです

   

Page 3: Twitter sphere of #twitter4j #twtr_hack

ソース取得後の動かす前の事前設定(1)

● OAuthアプリケーションキーの取得○ アプリの登録を行います○ Twitter にログイン後、下記にアクセス

■ http://twitter.com/apps○ 「create new application」をクリックしてアプリケーションを

登録○ 登録したアプリの詳細をみる。○ My Access Tokenをクリック。

■ consumerKey

■ consumerSecret

■ accessToken

■ accessTokenSecret

○ を取得

  

Page 4: Twitter sphere of #twitter4j #twtr_hack

ソース取得後の動かす前の事前設定(2)

● TwitterSphere4J/griffon-app/resources の中の○ twitter4j.properties_n をコピー○ twitter4j.properties_t を作成

● 取得した情報をtwitter4j.properties_t の方に書込○ その際に # のコメントは外します

 ● 実行手順)

○ Macの場合■ sh runw.sh で実行

○ Winの場合■ runw.bat のJAVA_HOMEを修正、実行

Page 5: Twitter sphere of #twitter4j #twtr_hack

ソース取得後の動かす前の事前設定(3)

● IDEA11を使って実行したい場合○ IDEAインストール

■ startupgroovy で情報まとめられていますので下記参照

■ https://bitbucket.org/kyon_mm/startupgroovy/wiki/Home

 ○ Griffon関係のIDEA上の設定

■ なんらかのgriffonプロジェクトを作ったり動かす時に

■ GRIFFONのパスをModule(UseLibrary)として追加する必要があり<Androidとかも同じ

○ 詳細は下記URLのブログを参照■ http://d.hatena.ne.jp/waman/20111209/1323454481

Page 6: Twitter sphere of #twitter4j #twtr_hack

〜基礎知識編〜

Page 7: Twitter sphere of #twitter4j #twtr_hack

元にしているプログラム

● JavaOne 2009 のGriffonのデモアプリ

● @kazuchikaさんブログに

まとめあり ● http://d.hatena.ne.

jp/ksky/20090613/p1

Page 8: Twitter sphere of #twitter4j #twtr_hack

どんなプログラムなの?

● NASA World Wind○ http://worldwind.arc.nasa.gov/java/index.html

● という地球儀を表示するjavaライブラリ

● を使ってTwitterの呟きを地球儀上に置く

   ● 大元は

○ Twitterのxml,atomをRESTで取得していた○ griffonが0.2の頃のプログラムだからそのままでは動かな

いよ

 

Page 9: Twitter sphere of #twitter4j #twtr_hack

griffonって何?

● codehausさんで作られている

● Groovy製のMVCイメージのGUIフレームワークです(デフォルトSwing拡張)

● pluginでjavafxにも対応は出来ます(groovyFX

○ codehaus さん■ SpringSource=>VMWare って感じの系列

■ jetty(Androidの人なら i-jettyで知っている人多いかな?)も提供

● 詳しく知りたい人は

○ @kiy0taka さんのGマガジンのGriffon連載をぜひ

■ http://grails.jp/g_mag_jp/■ Griffon不定期便〜G*ワークショップ編〜

● http://www.slideshare.net/kiy0taka/griffong

 

Page 10: Twitter sphere of #twitter4j #twtr_hack

griffonの概略イメージ(1)

● Model・・グローバル変数とか記述

● View ・・表示テンプレート(JSPイメージに近い)

● Controller・・実際のアクション処理を書く

● Service ・・抽象化した共通処理書く○ 使っている人が少ないようで挙動が微妙な面も

ModelControllerView

Service

Page 11: Twitter sphere of #twitter4j #twtr_hack

griffonの概略イメージ(2)

● BuildConfig.groovy○ ローカルpluginの参照○ mavenからdllしてくるjar記述

● lib○ mavenから落とせないjar等を入れるところ

● script○ griffonコマンドに割込みする処理を記述します○ 主にant(Builder)を使ってant処理記述○ 今回は下記の処理に記述します

■ eventCompileEnd● コンパイルした後等

● gant ○ antのgroovy拡張です○ http://www.ruimo.

com/publication/groovyconf/gant.pdf○ に解説あります

 

Page 12: Twitter sphere of #twitter4j #twtr_hack

groovyってなに?

● javaにおけるスクリプト拡張、いわゆる簡単に使う為の糊みたいな物です(DSLも勿論かけます)

● GroovyConsole等を使うとjavaライブラリを簡単に試す事が出来ます

○ groovyConsole

  ● 最近だと

○ NTTデータ さん関連の日経記事が載りました■ 2012/2/15

○ http://www.ntts.co.jp/products/grails/index.html

Page 13: Twitter sphere of #twitter4j #twtr_hack

Griffonに日本で一番詳しい方の一人です Jenkinsのコミッターとしても有名です

さん達とお仕事できるかも~

Page 14: Twitter sphere of #twitter4j #twtr_hack

今回一寸だけ楽になった事

● IDEA11で有料版提供されてたGriffonの機能<Grailsは有料版のみ提供○ 無料版 でも提供されるようになった事!○ ステップデバックも多少は出来るようになるよ!

○ IDEA10より使い勝手はあがりました

 ● でもデスクトップGUIアプリって人気無いんです

よねー(griffonの一文字も記述無し

○ InfoQ IntelliJ IDEA 11 - 新機能■ http://www.infoq.com/jp/news/2012/02/idea11

Page 15: Twitter sphere of #twitter4j #twtr_hack

〜デモ〜

Page 16: Twitter sphere of #twitter4j #twtr_hack

〜Twitter(4J)絡みの解説〜

Page 17: Twitter sphere of #twitter4j #twtr_hack

● http://twitter4j.org/ja/api-support.html ● の対応表を後で確認しながら読み返して頂けると

● 理解は深まると思います

○ もしくは

● Twitter API

ポケットリファレンス

(POCKET REFERENCE)

○ 山本 裕介 (著) ● を見比べながら確認してください

Page 18: Twitter sphere of #twitter4j #twtr_hack

トレンド取得def getTrends = { に記述

Twitter API ポケットリファレンス P218

def parser = new JsonParser()jsonText = new URL("http://api.twitter.com/1/trends.json").openStream().textdef obj = parser.parseObject(jsonText)trendNames = obj.trends.collect{it.name}

def trends = twitter.getLocationTrends(locatonID).trends trendNames = trends.collect{it.name}

● トレンド取得コード

● 途中からxmlが廃止されてたみたい

○ 元はxml操作コード

● JSON直接操作 (trends.json) ● Twitter4J書換(trends/:woeid.json 日本トレンド絞込に P225)

Page 19: Twitter sphere of #twitter4j #twtr_hack

statuses/public_timeline.json def getPublicResults() に記述

Twitter API ポケットリファレンス P93

def doc = slurpAPIStream("http://twitter.com/statuses/public_timeline.xml")doc.status.each {

results << [icon: it.user.profile_image_url as String,tweet: it.text as String,user: it.user.screen_name as String

]}

 

XMLをパースする方法の場合(旧コード)

ExpanddoのオブジェクトがList追加されているイメージ

Page 20: Twitter sphere of #twitter4j #twtr_hack

twitter.getPublicTimeline().each{ st->println "getPublicResults:" +st.dump()if(model.japanf){

println "st.place=" + st.place?.dump()f("ja".equals(st.place?.country))returnif(!service.chkLangage(st.text))return

}results << [

icon: st.user.profileImageUrl as String, //Stringに明示的に型変換

tweet: st.text,user: st.user.screenName

]f(st.geoLocation!=null){

results.last().pos=Position.fromDegrees(st.geoLocation.latitude,st.geoLocation.longitude,0)

}//一度検索済みの場合

else if(model.uMap.get(st.user.screenName)?.pos != null){results.last().pos = model.uMap.get(st.user.screenName).pos

}}

Twitter4Jに書換コード(location情報も取れればセット)

eachクロージャの中のreturn分はcontinue扱いです

Page 21: Twitter sphere of #twitter4j #twtr_hack

search.json def getSearchResults(search) { に記述

Twitter API ポケットリファレンス P247

def url = "http://search.twitter.com/search.atom?q=${URLEncoder.encode(search)}&rpp=${model.searchLimit}"//println "url="+urldef doc = service.slurpAPIStream(url)//println "doc="+doc.dump()doc.entry.each {

results << [icon: it.link[1]["@href"] as String,tweet: it.title as String,user: (it.author.uri as String)[19..-1] //19文字目から末尾までという意味

]}

 

XMLをパースする方法の場合(旧コード)

Page 22: Twitter sphere of #twitter4j #twtr_hack

def q = new Query(search);q.setRpp(model.searchLimit); //検索リミット数

//日本語限定の検索(過去7日になる)

if(model.japanf){q.setLang(slocale)q.setLocale(slocale)

}if(twitter==null)twitter = new TwitterFactory().getInstance()def arr = twitter.search(q).getTweets();arr.each{

results << [icon: it.profileImageUrl as String,tweet: it.text,user: it.fromUser

]if(it.geoLocation!=null){

results.last().pos =Position.fromDegrees(it.geoLocation.latitude,it.geoLocation.longitude,0)}//一度検索済みの場合

else if(model.uMap.get(it.fromUser)?.pos != null){results.last().pos = model.uMap.get(it.fromUser).pos

}}

Twitter4Jに書換コード(location情報も取れればセット)

setLangを指定すると直近7日間の検索になってしまうらしい

Page 23: Twitter sphere of #twitter4j #twtr_hack

users/show.jsondef addLocation(def tweet) { に記述

Twitter API ポケットリファレンス P153

def twitterUser = slurpAPIStream("http://twitter.com/statuses/public_timeline.xml$tweet.user") //位置情報をRESTするサービスに問い合わせ

def gnm = service.slurpAPIStream("http://ws.geonames.org/search?maxRows=1&q=${URLEncoder.encode(twitterUser.location as String)}") if (gnm.geoname.size()) {

tweet.pos = Position.fromDegrees(Float.parseFloat(gnm.geoname[0].lat as String),Float.parseFloat(gnm.geoname[0].lng as String),0);

}

 

XMLをパースする方法の場合(旧コード)

Page 24: Twitter sphere of #twitter4j #twtr_hack

Twitter4Jに書換コード

def user =twitter.showUser(tweet.user) //位置情報の取得

tweet.pos = service.getPosition user,model.tweetListPos

//ユーザ座標の記録

def posObj = new Expando()posObj.pos = tweet.posmodel.uMap.put(tweet.user,posObj)

 ● Map等で複数の値を持つオブジェクト等を値にしたい時○ Expando を使うと便利です

■ プログラミングGroovy P206 のコラムに記載があります○ 動的にプロパティ(値,関数)を生成できます

  

def obj = new Expando()obj.name ='ほげほげ'

println "obj.name = ${obj.name}"

showuser呼びまくるとAPIが直ぐ無くなるので状態は保存する

Page 25: Twitter sphere of #twitter4j #twtr_hack

statuses/sample.jsondef getStreamResults(){ に記述

Twitter API ポケットリファレンス P273if(stream == null ){

stream = new TwitterStreamFactory().instancestream.addListener(listener)

}stream.sample()

 statuses/filter.json

def getFilterResults = { に記述Twitter API ポケットリファレンス P273

FilterQuery query = new FilterQuery()query.track([search] as String[])stream.filter(query)

 

Page 26: Twitter sphere of #twitter4j #twtr_hack

StatusListener記述(1)listener = [

onStatus: { st ->if(model.japanf){

println "st.place=" + st.place?.dump()if(st.place !=null && !"ja".equals(st.place?.country))returnif(!service.chkLangage(st.text))return

}model.tweetList << [

icon: st?.user?.profileImageUrl as String,tweet: st?.text,user: st?.user?.screenName

]if(st?.geoLocation!=null){

model.tweetList.last().pos =Position.fromDegrees(st.geoLocation.latitude,st.geoLocation.longitude,0)}//一度User検索済みの場合

else if(model.uMap.get(st?.user?.screenName)?.pos != null){model.tweetList.last().pos = model.uMap.get(st?.user?.screenName).pos

}//model.tweetListPos = 0//model.searching = falseif(model.searching==false)nextTweet()

},

 

Page 27: Twitter sphere of #twitter4j #twtr_hack

StatusListener記述(2)

listener = [〜略〜

//http://twitter4j.org/ja/code-examples.htmlonDeletionNotice:{statusDeletionNotice->

println "Got a status deletion notice id:" + statusDeletionNotice.statusId},onTrackLimitationNotice:{numberOfLimitedStatuses->

println "Got track limitation notice:" + numberOfLimitedStatuses },onScrubGeo:{ userId,upToStatusId ->

println("Got scrub_geo event userId:" + userId + " upToStatusId:" + upToStatusId)},onException: { ex -> ex.printStackTrace() },

//] as UserStreamAdapter] as StatusListener

 

● Streaming処理で使っているリスナー定義です(コールバック処理)

Page 28: Twitter sphere of #twitter4j #twtr_hack

def getAsyncResults = {Twitter API ポケットリファレンス ??

if(asyncTwitter == null ){asyncTwitter = new AsyncTwitterFactory().instanceasyncTwitter.addListener asynclistener

}//asyncTwitter.updateStatus(args[0]);Paging page = new Paging(1,20)asyncTwitter.getHomeTimeline(page)//asyncTwitter.getDirectMessages(page)//asyncTwitter.getMentions(page)

 

自分で定義したプロパティ関数呼んでるイメージ

Page 29: Twitter sphere of #twitter4j #twtr_hack

TwitterAdapter記述 <AsyncTwitter処理で使用

listener = [gotHomeTimeline:{statuses ->

List results = []statuses?.each {st->

if(model.japanf){if(st.place !=null && !"ja".equals(st.place?.country))returnif(!service.chkLangage(st.text))return

}results << [

icon: st?.user?.profileImageUrl as String,tweet: st?.text,user: st?.user?.screenName

]if(st?.geoLocation!=null){

results.last().pos =Position.fromDegrees(st?.geoLocation?.latitude,st?.geoLocation?.longitude,0)}//一度検索済みの場合

else if(model.uMap.get(st.user.screenName)?.pos != null){results.last().pos = model.uMap.get(st.user.screenName).pos

}}edt {

model.tweetListPos = 0model.tweetList = resultsmodel.searching = falseif(model.searching==false)nextTweet()

}},〜略〜

] as TwitterAdapter 

 

Page 30: Twitter sphere of #twitter4j #twtr_hack

Streaming等の停止は・・・

def onSearch = { に記述//streaming 一度止める

//ストリーミング受信if(stream!=null){

stream.cleanUp()stream=null

}//非同期検索

if(asyncTwitter!=null){asyncTwitter.shutdown()asyncTwitter=null

} //GUIと連動している変数は同期を取る

edt {model.tweetListPos = 0model.tweetList?.clear()

}

 

viewの表示と同期を取りたい変数に関してはedt{

//実際の処理} 依存しなくても問題無い非同期処理はdoOutside{

//実際の処理}クロージャの中に記述します

● ModelでBindable、Viewでbind と記述されている変数に関しては edt で書換する方が良いとされています (値が変わると画面の表示状態が連動して動く為)

● http://www.slideshare.net/kiy0taka/griffong のP46に対応表あり

Page 31: Twitter sphere of #twitter4j #twtr_hack

〜今回はまった処〜

Page 32: Twitter sphere of #twitter4j #twtr_hack

griffon plugin編<twitter plugin>(1)

● def twitterと記述するとinstanceが自動DI(インジェクション)されるはずなのにインスタンスがNullでくる事がある

○ if(twitter==null)twitter = new TwitterFactory().getInstance()■ の記述を追記

 

● 「griffon install-plugin twitter」 でPluginをインストール時

● twitter4j.propertiesはinstall時に作るけど、動かす時にclassの位置にコピーしてくれない

■ =>

○ script/_Events.groovyでclassフォルダにコピー処理記述

● twitter-core 、しかも古いのしか標準ではサポートしていないよ

○ =>

○ じゃあローカル参照しますか

■ 公式にはあまり推奨されていないので多少手を入れる必要があり

 

Page 33: Twitter sphere of #twitter4j #twtr_hack

griffon-twitter/dependencies.groovypackage-pluginの時に参照(公式推奨の記述正確にはプラグインの griffon-app/conf/BuildConfig.groovyが変換されたものらしい

//runtime 'org.twitter4j:twitter4j-core:2.2.0'runtime 'org.twitter4j:twitter4j-core:2.2.6-SNAPSHOT'runtime 'org.twitter4j:twitter4j-stream:2.2.6-SNAPSHOT'runtime 'org.twitter4j:twitter4j-async:2.2.6-SNAPSHOT'

 

griffon-twitter/script/_Events.groovyローカル参照でも動かせるようにする時に記述するcompileに変更しておかないとエラーになるので注意!(詳細は次ページ

//compile 'org.twitter4j:twitter4j-core:2.2.0'compile 'org.twitter4j:twitter4j-core:2.2.6-SNAPSHOT'compile 'org.twitter4j:twitter4j-stream:2.2.6-SNAPSHOT'compile 'org.twitter4j:twitter4j-async:2.2.6-SNAPSHOT'

 

griffon plugin編<twitter plugin>(2)

Page 34: Twitter sphere of #twitter4j #twtr_hack

プラグインのローカル参照記述個所

相対パスでOKです

griffon-app/conf/BuildConfig.groovy 末尾追記griffon.plugin.location.'eclipse-support'="../griffon-eclipse-support"griffon.plugin.location.'twitter'="../griffon-twitter"

 プラグイン側の修正

grails pluginと微妙に作りが違うので小手先技が必要

griffon-twitter/script/_Events.groovy//mavenからjarをDL(ダウンロード)してくる記述

eventSetClasspath = { cl ->manager.parseDependencies { 等記述

 //addon のjarコピー記述eventCopyLibsEnd = { jardir ->

def twitterLibDir = "${getPluginDirForName('twitter').file}/addon"ant.copy(todir: jardir, overwrite: true ) { fileset(dir: twitterLibDir, includes: '*.jar')

}

 

Page 35: Twitter sphere of #twitter4j #twtr_hack

addon-jarの正規の挙動的には

● install-plugin 時に○ griffon-app/conf/Builder.groovy

■ root.'TwitterGriffonAddon'.addon=true

○ の追記処理の記述が追加されています

■ griffon-twitter/scripts/_install.groovy に記載あり

● が

○ 相対参照しているときはどうもadd-onは動くような挙動する気がする

○ コントローラ等のEventに対して、DSL記述によりイベント割込を付加するイメージなので、その場合は必要かも

■ 今回はその割込イベント未使用なので記述を有効にしてません

 

○ 使用サンプルの tweetagile は 0.9.4では動きませんでした

■ http://sourceforge.net/projects/tweetagile/develop

 

 

Page 36: Twitter sphere of #twitter4j #twtr_hack

Nasa World Wind 編

● pluginアップデートで処理関数の記述が変更

● デフォルトのフォントが日本語未対応■ =>

○ 日本語呟きが化ける■ =>

○ アプリ側でfontを設定して表示○ IPAフォントを griffon-app/resources にいれて○ script/_Events.groovy でclassフォルダにコピー処理記

● 地表から300km以下になると地表表示が出来ない○ 350km辺りで調整

■ plugin 自体は worldwind-0.6.680.14215.jarを使っていますが最新の1.2でも同じなので公式のそのまま使う

Page 37: Twitter sphere of #twitter4j #twtr_hack

script/_Events.groovyの記述例

○の箇所(antの知識は必要かも

eventCompileEnd = {msg->println "==compile end(${msg})=="growlNotify("eventCompileEnd")

 srcDir ="${basedir}/griffon-app/resources"destDir = "${classesDir}" ant.copy(file:"${srcDir}/twitter4j.properties_t",tofile:"${destDir}/twitter4j.properties",overwrite:true) //ant.copy(file:"${srcDir}/twitter4j.properties_n",tofile:"${destDir}/twitter4j.properties",overwrite:true) destDir = "${basedir}/staging"copySetting(destDir)

 //need TTF & DDL Copy (defaul griffon-app/resources only image file) //○

srcDir ="${basedir}/griffon-app/resources"destDir = "${classesDir}"ant.copy(todir: destDir, overwrite: true ) {

fileset(dir: srcDir, includes: '*.ddl,*.TTF')}

設定は手動でコピーしましょう。な話は結構あります

Page 38: Twitter sphere of #twitter4j #twtr_hack

giffon-app/controllers/twittersphere4j/TwitterSphere4JController.groovy

//コントローラ初期化時に最初に通る関数

void mvcGroupInit(Map args) {if(model.vfont==null)

def fontname="ipag.ttf"InputStream is=getClass().classLoader.getResourceAsStream(fontname)model.vfont = Font.createFont(Font.TRUETYPE_FONT, is).deriveFont(12.0f)is.close()

} //コントローラ終了時(アプリケーション終了時)に必ず通る関数

void mvcGroupDestroy() { //viewが初期化された後に通るイベントプロパティ関数

def onStartupEnd = { 

 giffon-app/views/twittersphere4j/TwitterSphere4JView.groovy

def addTweet(pos, user, tweet, tweetImage) { bean(ga.attributes,insets: [inset, 48 + inset * 2, inset, inset],font:model.vfont, //☆ 追加

Page 39: Twitter sphere of #twitter4j #twtr_hack

StremingAPIで国で絞り込めない

● @jontaniさんに教えて頂いた language_detection で呟き内容の言語判定で対応○ http://d.hatena.ne.

jp/n_shuyo/touch/20111125/language_detection

Page 40: Twitter sphere of #twitter4j #twtr_hack

giffon-app/service/twittersphere4j/TwitterSphere4JService.groovy

def chkLangage = {msg -> //http://code.google.com/p/language-detection/wiki/ProjectHomeJa

def detector = DetectorFactory.create()detector.append(msg)String cn = detector.detect()println "detector.detect()=$cn"if( !"ja".equals(cn) ) return falsereturn true

}

 ● ファイル構成は

○ lib/langdetect.jar

○ setting/profiles

● に配置● script/_Events.groovyに下記にコピー処理記述追記

○ stanging

Page 41: Twitter sphere of #twitter4j #twtr_hack

IDEAでpropertiesのnative2ascill変換のや

り方側が悩んだ

● 結論から言うと下記な形。デフォルトでONになってない

Page 42: Twitter sphere of #twitter4j #twtr_hack

IDEAの操作的にはこんな感じ

Page 43: Twitter sphere of #twitter4j #twtr_hack

一応Springの技術的には

● UTF-8 encoding and Spring message sources○ http://www.cakesolutions.

net/teamblogs/2009/04/02/utf-8-encoding-and-message-sources/■ みたいな話はあって

 ○ org.springframework.context.support.

ResourceBundleMessageSource● =>

○ org.springframework.context.support.ReloadableResourceBundleMessageSource

 ○ に差し替えれば可能な記述はあるのですが・・orz

  

Page 44: Twitter sphere of #twitter4j #twtr_hack

Springとは

● GrailsやGriffon等Groovy系のFWで使われているコアライブ

ラリ群です○ SpringSourceで開発されています

■ 国内ではSeasar人気ですが

● 日本人のひがやすおさんが作られていて● マニュアルが日本人ドキュメントの為

■ 日本人は英語ドキュメント嫌いな人が多いんですよね

~■ だから海外の会社系FWは日本語マニュアル揃えた

りする労力が・・・

 

Page 45: Twitter sphere of #twitter4j #twtr_hack

〜griffonの

 基本オペレーション

 (IDEA)〜

Page 46: Twitter sphere of #twitter4j #twtr_hack

griffonコマンドの発行

● ベースはコマンドライン開発FWなのでコマンドでコンパイル、実行できたりします● IDEA上からのコマンド実行は下記な感じ(「griffon clean」実行例

○ griffon の部分は いらない感じです

Page 47: Twitter sphere of #twitter4j #twtr_hack

よく使うコマンド

● griffon clean○ コンパイル済みのクラスファイル、

直下のstadingフォルダを削除します(エラーが出た場合はjavaプロセスを終了して再実行)

● griffon run-app○ IDEAの実行ボタンと同じ

● griffon install-plugin XXX○ http://griffon.codehaus.org/Plugins

○ http://svn.codehaus.org/griffon/plugins/

○ に公開されているPluginをインストールして機能拡張が出来ます

● griffon interactive○ 継続実行が速くできるという奴ですけど。

■ コマンドライン実行では重宝

○ IDEAでやるとOutOfmemoryがよく出るorz

Page 48: Twitter sphere of #twitter4j #twtr_hack

〜開発時によく困る事〜

Page 49: Twitter sphere of #twitter4j #twtr_hack

認証情報等が入ったファイルの管理

● 認証情報が入った twitter4j.properties って上げちゃうの恐いですよね(下記みたいな呟きが出てしまう

     ● その場合は

○ scripts/_Events.groovy にファイル名変えてコピーの処理を記述

■ DVCS管理用のダミーファイルは用意しておきましょう

○ .hgignore(.gitignore)に除外処理を書いておきましょう

 

Page 50: Twitter sphere of #twitter4j #twtr_hack

script/_Events.groovyの記述例eventCompileEnd = {msg->

println "==compile end(${msg})=="growlNotify("eventCompileEnd")

 //上がキー書いた方、下がキー書いていない方の記述例(認証いらない奴なら下でOK)

srcDir ="${basedir}/griffon-app/resources"destDir = "${classesDir}" ant.copy(file:"${srcDir}/twitter4j.properties_t",tofile:"${destDir}/twitter4j.properties",overwrite:true) //ant.copy(file:"${srcDir}/twitter4j.properties_n",tofile:"${destDir}/twitter4j.properties",overwrite:true) destDir = "${basedir}/staging"copySetting(destDir)

 //need TTF & ddl Copy (defaul griffon-app/resources only image file) srcDir ="${basedir}/griffon-app/resources"destDir = "${classesDir}"ant.copy(todir: destDir, overwrite: true ) {

fileset(dir: srcDir, includes: '*.ddl,*.TTF')}

 

Page 51: Twitter sphere of #twitter4j #twtr_hack

立ち上がらないんだけど?

● プロセスが正常終了しない場合○ GUIが立ち上がっていない状態で、タスクマネージャで、

jqs、javaのプロセスが立ち上がっていたら強制終了しましょう■ エラーが発生したりするとSwingプロセスが残ってしま

う○ mac等

■ ps -aux | grep java 等で確認して kill -9 で■ コンソール実行している場合は command +・ で

Page 52: Twitter sphere of #twitter4j #twtr_hack

変更が反映されない、コンパイルエラーが・・

● griffon clean コマンドを実行します○ 実行の仕方は以下(IDEAから実行するときは 「clean」)

○ cleanコマンドで エラーが出るときはタスクマネージャ等(ps)でjavaプロセスがいないか確認しましょう

Page 53: Twitter sphere of #twitter4j #twtr_hack

ClassNotFoundExceptionが・・

● jarのコピー失敗○ griffon run-app 実行時

○ $HOME/.ivy からjarの存在チェック● 無ければ maven Repo から自動DL

○ $HOME/.ivy =>stanging フォルダ にコピー● のどの段階かでライブラリが破損している(DL失敗)恐れがあります

1. stangingフォルダのjarのサイズが小さくないか

a. 「griffon clean」コマンドを行う

2. $HOME/.ivyの位置にjarが存在するかサイズがおかしくないかa. サイズがおかしい場合=>そのjarを消して再実行b. ダウンロードが動いていないとき

i. BuildConfig.groovy に事前にDL記述を書いて落とす

   

 

Page 54: Twitter sphere of #twitter4j #twtr_hack

griffon-app/conf/BuildConfig.groovy 記述例

language_detection内部でjsonicを使っているのその記述例

griffon.project.dependency.resolution = {

// inherit Griffon' default dependencies

inherits("global") {

}

log "warn" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'

repositories {

griffonPlugins()

griffonHome()

griffonCentral()

// uncomment the below to enable remote dependency resolution

// from public Maven repositories

//mavenLocal()

//mavenCentral()

mavenRepo "http://maven.seasar.org/maven2/" //DL(ダウンロード)元のMavenレポジトリ

}

dependencies {

// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.

// runtime 'mysql:mysql-connector-java:5.1.5' //jarの中の関連参照なら runtime

compile 'net.arnx.jsonic:jsonic:1.2.0' //ソースのコンパイルに必要ならcompile

}

}

 

 

Page 55: Twitter sphere of #twitter4j #twtr_hack

〜知っておくと

  一寸コードが

  読みやすくなる事〜

Page 56: Twitter sphere of #twitter4j #twtr_hack

groovy編(1)

● println "obj=$obj" な形でコンソール出力できます○ うまく表示されない時は ${obj} のように記述

● オブジェクトの中身は dump() コマンドで表示可能です○ println "obj=${obj.dump()}"

● オプジェクとのNullチェックは下記のように書けば不要です○ println "obj=${obj?.dump()}"○ この場合、objがnullならnullと出力されます

● オブジェクトのプロパティにはダイレクトにアクセスできます○ obj.A = "テスト"○ println "obj=${obj.A}"

● 厳密にはこういう話です https://gist.github.com/1041631

  

 

class Hoge { def xxx = 10 def getXxx() { 100 }}def h = new Hoge()assert h.xxx == 100 // getXxxがあればそちら優先

assert h.@xxx == 10 // フィールド値をダイレクトで取得

assert h.getXxx() == 100 // メソッド値をダイレクトで取得

Page 57: Twitter sphere of #twitter4j #twtr_hack

groovy編(2)

● def funcA() { } と書くと関数に見えますが、実はプロパティ扱い(クロージャ変数)です!○ def func(num){}

■ =○ def func = {num -> }○ と同じ意味になります。○ また引数の型の方も省略する書き方も可能です(自動判

 ● void funcB(){ } みたいな書き方は普通の関数

   

 

Page 58: Twitter sphere of #twitter4j #twtr_hack

groovy編(3)

● クロージャってなんじゃらほ?○ { }で囲んだ部分の記述 で表現されるCloureという名前のクラスです

■ http://groovy.codehaus.org/api/groovy/lang/Closure.html○ javascript 等のコールバック関数記述イメージが近いかも

○ 参考資料)■ Groovyでクロージャ内部で設定してもらった値を利用する

■ http://d.hatena.ne.jp/fumokmm/20101008/1286547976

■ 下記は testというクロージャ変数の例

test { println it // => 一つ目の引数

println this // => このクラス println owner // => このクロージャ保有者

println delegate // => このクロージャ移譲先(Objective-Cでいう親クラス参照)

println that // thatで指定された文字列

map.count = 1 // mapも参照できる

map.clos = { that * 3 }}

Page 59: Twitter sphere of #twitter4j #twtr_hack

griffon編・・SwingBuilder編(1)

● Plugin拡張をしていない場合、ViewはSwingBuilderというSwingのDSL拡張で記述○ http://groovy.codehaus.org/Japanese+Swing+Builder

○ http://groovy.codehaus.org/Alphabetical+Widgets+List

■ の記載情報が編集する為の情報のベースになります

 ● 「プログラミングGroovy 」の P139 

から数ページ少し解説があります

 ● IBMの技術資料

○ http://www.ibm.com/developerworks/jp/java/library/j-groovy09299/index.html

● @toby55kij さん SwingBuilderでGroupLayoutを使ってみる。

○ http://www.tobikkiri.org/2009/08/swingbuildergrouplayout.html  

  

Page 60: Twitter sphere of #twitter4j #twtr_hack

griffon編・・SwingBuilder編(2)

● よく使う奴を列挙してみます

 ● レイアウト系

○ hbox { } ・・ 横レイアウト○ vbox { } ・・縦レイアウト○ レイアウト() みたいに記載するとその直後の奴はそのレイ

アウトで配置できます■ borderLayout()■ cardLayout()■ gridBugLayout()

● http://desmontandojava.blogspot.com/2012/02/swingbuilder-series-layouts.html

Page 61: Twitter sphere of #twitter4j #twtr_hack

GUIパーツの記載イメージ

● 下記みたいにmapイメージで書けます○ 変数名:値○ どんな値があるかは、下記みたいに

■ dump()してみるか■ IDEAで候補出してみるか

● http://d.hatena.ne.jp/masanobuimai/20090105#1231168963

■ みたいな方法もあります

progressBar(id:'hoge',maximum: bind { model.tweetList?.size() ?: 1 },value: bind {model.tweetListPos}

)println hoge.dump()

値の連動関連づけですModelクラスの中でBindableと記載がある物が対象になります(今回は全体に付いている)

Page 62: Twitter sphere of #twitter4j #twtr_hack

griffon編・・SwingBuilder編(3)

button(getMessage("view.label.Search"),actionPerformed: controller.onSearch,enabled:bind {!model.searching},margin: new Insets(5, 10, 15, 20)

)

 

● controllerとの関連づけはactionPerformed等に記載します○ 普通のjavaだとListnerが渡されていますが

○ groovyの場合はクロージャを渡します

■ 渡し方の記載例は次ページ

Page 63: Twitter sphere of #twitter4j #twtr_hack

griffon編・・SwingBuilder編(4)

● viewで関連づけるClousure参照の記述例ではまることも・・○ OK例

■ button(id:'DLGBTN1',text:'btn1',

actionPerformed:{controller.&action()}) ● closure代入(既存Closureに対してappend(追記)

■ button(id:'DLGBTN2',text:'btn2',actionPerformed:controller.action)● closure参照

■ button(id:'DLGBTN3',text:'btn3',actionPerformed:controller.&action)● MethodClosure参照

○ NG例■ button(id:'DLGBTN4',text:'btn4',

actionPerformed:{controller.&action})● MethodClosure参照をClosure代入しようとしたから駄目

Page 64: Twitter sphere of #twitter4j #twtr_hack

griffon編・・SwingBuilder編(5)

● 普通のjavaのパーツをSwingBuilder上に設定する場合2パターンの方法があります○ 単純に埋め込み

■ widget

■ http://groovy.codehaus.org/SwingBuilder.widget● widget(new hogehoge())

 ○ SwingBuilderにDSL関連づけする場合

■ registerFactory■ registerBeanFactory

● registerFactory("migLayout", new LayoutFactory(MigLayout))● registerBeanFactory("led", Led)

Page 65: Twitter sphere of #twitter4j #twtr_hack

griffon編(1)

● griffon自体のイメージをつかむには

 ● @waman10da さん Griffon の世界

○ http://www5.ocn.ne.jp/~coast/programming/groovy/griffon.html

 

○ あたりが一番詳しいです。

○ ただかなり高度な内容もありますので(数学知識も必要)

○ わからないところは読み飛ばしてよいかと思います

 

Page 66: Twitter sphere of #twitter4j #twtr_hack

griffon編(2)

● LL言語は基本エディタで開発するのが前提なので

○ =>「最低限以外は自分で書換」 等のお話が多い■ 解らなければ末尾の方に載っけている、自分より詳し

い方々に聞くと良いかも

● serviceクラスをコマンドで作る時○ griffon create-service twittersphere4j.TwitterSphere4JService

○ Controller に def service という形で参照したい時○ Application.groovyに下記の★

記述を追加

'twittersphere4j' {model = 'twittersphere4j.TwitterSphere4JModel'view = 'twittersphere4j.TwitterSphere4JView'controller = 'twittersphere4j.TwitterSphere4JController'service = 'twittersphere4j.TwitterSphere4JService' //★

}

Page 67: Twitter sphere of #twitter4j #twtr_hack

griffon編(3)

● airbag plugin とかの説明そのままだと動かなかったり(汗○ http://griffon.codehaus.org/Airbag+Plugin

■ 実はTwitterSphere4JView.groovyの記述修正が必要だったりとか・・・

 ○ application(title: 'TwitterSphere4J',

■ =>○ mainWindow = application(title: 'TwitterSphere4J',

Page 68: Twitter sphere of #twitter4j #twtr_hack

IDEAを使うと多少楽になるので

● キーマップに慣れましょう○ eclipseと大分違うので混乱はします

○ http://www.jetbrains.com/idea/docs/IntelliJIDEA_ReferenceCard.pdf

 

● @masanobuimai さんブログIDEA周りの話を読みましょう

○ 初めてIntelliJに触れる人へ■ http://d.hatena.ne.jp/masanobuimai/20091017/1255784181

■ http://d.hatena.ne.jp/masanobuimai/20091021/1256129174

 

○ モダンなIntelliJ環境の構築方法 http://d.hatena.ne.jp/masanobuimai/20100726%231280151977

● IDEAに詳しい人に効いてみましょう

Page 69: Twitter sphere of #twitter4j #twtr_hack

〜今後に期待編〜

Page 70: Twitter sphere of #twitter4j #twtr_hack

IDEA11で現状残念な処<use griffon(1)● griffon-app/conf/BuildConfig.groovy

○ griffon.plugin.location.プラグイン名が認識しない・・。

○ 手動で追加も出来ない

Page 71: Twitter sphere of #twitter4j #twtr_hack
Page 72: Twitter sphere of #twitter4j #twtr_hack

IDEA11で現状残念な処<use griffon(2)

● ivy経由で取得したjarがうまく認識しない

○ 従ってIDEAの強力機能 => リアルタイム補完 ×  

 ● maven だと下記の記事参考になるようなんだけど・・

● @yusukeyさんの記事 Mars Phoenix の最後の Tweet を IntelliJ IDEA 8 と Twitter4J を使ってデコードする

○ http://samuraism.jp/diary/2008/11/15/1226684171300.html@masanobuimai さん記事 Scripting IDE for DSL awareness

○ http://d.hatena.ne.jp/masanobuimai/20091021#1256129173

Page 73: Twitter sphere of #twitter4j #twtr_hack

IDEA11で現状残念な処<use griffon(3)

● スレッド周りの処理にブレークポイントを貼っても止まらない事が多い

● 普通のJavaプログラムでもそうなんですが

○ スレッドプログラムでエラー

■ =>

○ 処理中断 でストール な現象になる事が多い

 

● src/main/java がちゃんと認識しない

○ その他の部品等は src/main/java,src/main/groovy とディレクトリを掘ってい

れます

   

Page 74: Twitter sphere of #twitter4j #twtr_hack

IDEAで今後出来たらいいなと思うこと

● Viewのプレビュー表示○ IDEA11でAndroidのレイアウトプレビューが出来るよう

になったのでこちらも期待したいなー

 ● groovyファイル(Controller)の関数表示がツリー

に出てくると楽○ 今は関数名等を検索しないと駄目○ 関数Jumpが今は出来ない ><

 

Page 75: Twitter sphere of #twitter4j #twtr_hack

eclipseではどう?

● griffon-eclipse-support plugin ○ griffonコマンドを実行するたびに.classpath等更新○ 公式のだとWinXP等空白パスあるのでは動きません

■ =>○ 修正してローカル参照で動かしています○ 一応jarのクラスパスは通っているのでエラーは出ないけど・・

 

● groovy eclipse plugin 自体が○ def 等に代入した変数に対して補完きかない○ そもそもブレークポイントでとまらない事が多い

■ Grailsでは止まるので<STS対応されている為か

Page 76: Twitter sphere of #twitter4j #twtr_hack

NetBeansでは?

● NetBeansインストール後手動で下記のPlugin等を追加する必要があり(すみません。最新版で確認する時間ありませんでした)

 ● Netbeans griffon plugin

○ http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=18664

 ● Netbeans gradle plugin

○ http://plugins.netbeans.org/plugin/41776/gradle

Page 77: Twitter sphere of #twitter4j #twtr_hack

〜groovyを勉強するには〜

Page 78: Twitter sphere of #twitter4j #twtr_hack

ネットの情報で学習(お試しレベル

● @fumokmm さんのブログ○ Groovy基礎文法最速マスター

○ http://d.hatena.ne.jp/fumokmm/20100605/1275736594

○ Groovy全般に関して広い知見を学べます

● 日曜プログラマ劇場○ http://www.noids.net/groovy/

 ● 試す実行環境(Javaは別途必要)

○ @bluepapa32 さん GroovyConsole JavaWebStart■ http://d.hatena.ne.jp/bluepapa32/20101228/1293466511

■ gradleの記事が豊富に書かれているブログです

Page 79: Twitter sphere of #twitter4j #twtr_hack

● このインタビューに載っている本を買いましょう○ 青い本とは何でしょう? 日本鼻メガネの会 の公式読本

でしょうか?○ http://theinterviews.jp/inda_re/3039859

 ■ プログラミングGroovyというタイトルです

Page 80: Twitter sphere of #twitter4j #twtr_hack

ネットの情報で学習(少し慣れてきたら

● @uehaj さんの Grな日々○ http://d.hatena.ne.jp/uehaj/

■ 最新技術や情報について記載されていますので中級者~上級者向けかも

● @kazuchika さんの Groovyラボ○ http://d.hatena.ne.jp/ksky/○ JavaOne等の情報も絡めたお話があります

 ● @bikisuke さんの bikisuke in Action

○ http://d.hatena.ne.jp/bikisuke/Spockのお話とかがあります

Page 81: Twitter sphere of #twitter4j #twtr_hack

ネットの情報で学習(少し慣れてきたら

● @nobusueさん nobusueの日記 ○ http://d.hatena.ne.jp/nobusue/

 ● @genzouw さんゲンゾウ用ポストイット

○ http://d.hatena.ne.jp/genzouw/

 ● @kiy0taka さんblog4j 2.0

○ http://d.hatena.ne.jp/kiy0taka/○ Griffon、Jenkinsの情報が豊富です

Page 82: Twitter sphere of #twitter4j #twtr_hack

ネットの情報で学習(少し慣れてきたら

● @tyama さんleftovers... ○ http://d.hatena.ne.jp/mottsnite/○ Grails情報はここが一番充実

 ● @yamadamasaki さんGrails goes on

○ http://grailsgoeson.metabolics.co.jp/○ JGGUG主宰の方です

● @nobeans さん豆無日記

○ http://d.hatena.ne.jp/nobeans/○ GroovyServの開発者の方です

Page 83: Twitter sphere of #twitter4j #twtr_hack

ネットの情報で学習(少し慣れてきたら

● @literalice さんLiteral Ice○ http://monochromeroad.blogspot.com/○ gradleの日本語翻訳をメインでされてます○ http://monochromeroad.com/artifacts/gradle/userguide/userguide.

html

● @irof さん日々常々○ http://d.hatena.ne.jp/irof/○ 全国の勉強会を行脚していらっしゃいます○ すごく知見に富んだ方です

● 海外サイトだと下記が超有名(コミッタさん)○ Groovy Goodnes

■ http://mrhaki.blogspot.com/search/label/Groovy%3AGoodness

Page 84: Twitter sphere of #twitter4j #twtr_hack

● Groovyクラスタ○ 特にJGGUG講師の方はオススメ

 ○ @orange_clover さんまとめ

○ 今すぐフォローすべき

Groovy界のスーパーエンジニア

■ http://d.hatena.ne.jp/orangeclover/20110618/1308355956

  

下記のクラスタをフォローしましょう

Page 85: Twitter sphere of #twitter4j #twtr_hack

● 日本鼻メガネ会クラスタ(#riskrisk #日本鼻メガネの会)

■ Groovyクラスタと重なっている人が多いです■ http://riskrisk.hatenablog.com/entry/2012/02/14/032704

● という組織

■ ただ有能な方々ばかりでお忙しい方々なので

● インタビューズを遣られている方にはそちらで質問しましょう

● inda_re 先生、kyon_mm先生、mike_neck先生あたり

@orange_clover @inda_re @riskrisk @kyon_mm @mike_neck @nobusue@shinyaa31

Page 86: Twitter sphere of #twitter4j #twtr_hack

Groovy系の勉強会に参加しましょう

● JGGUG○ 日本Groovyユーザ会

■ 定期的に■ http://kokucheese.com/main/host/JGGUG■ http://grails.jp/■ #JGGUG ハッシュタグ

 ○ Grailsドキュメント会 (名古屋)

■ Grailsのドキュメント翻訳をされている @tyama さんがメインで開催されています

■ http://kokucheese.com/main/host/+Grails%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88%E4%BC%9A

   

Grailsに関して日本で一番詳しい方の一人

Page 87: Twitter sphere of #twitter4j #twtr_hack

Groovy系の勉強会に参加しましょう

● StartupGroovy○ 2012 /02 / 18

■ 開催まとめ● http://d.hatena.ne.

jp/absj31/20120218/1329636558

○ http://kokucheese.com/event/index/26942/■ 2回目も要望があれば企画されるそうです