仕事のやり方って

久しぶりの

思うところシリーズ。

銀の弾丸

開発プロセスアジャイル銀の弾丸にならないように、仕事のやり方にも、人それぞれのやり方があって然るべきで、これが万人にとってBestなんていうやり方は無いと思ってます。
逆にあるなら教えて欲しい。

なのに、自分の仕事のやり方がイチバン!完璧!みたいな人が、そのやり方を別の人(後輩とか)に教えるという名目で押し付けてくるのが、ひっじょーにうっとおしい!!

先輩として

あなたはそのやり方で上手いことここまでこれたのかもしれませんが、そのやり方が万人に適用できると思ったら、それはちょっと違うんじゃないかなと。
確かにあなた以外の人でも上手いこといく"場合"はあるかもしれないけど、それはそれ。
その方法を本当にイィと思って自分の仕事のやり方に適用するなら、とてもありがたい話しだと思うけど。
押し付けるのは、ダメ!絶対!

先輩なんだったら、その辺りも含めて指導するべきなんじゃないかな。

若い芽を摘むなよ

私は新人でもない、ちょうどひねくれたくらいの若輩者なので、ホイホイとは聞き入れないタチ悪い時期やけど、「先輩の言う事は絶対!先輩万歳!」みたいな風に思ってる新人だったら、たとえそのやり方がクソおかしくても信じてやっちゃうんだから。
そんな事して、無理やり新人を巨人の星みたいに矯正しないでねっと。
先輩なら若い芽を摘むなよ。

と、最近思うのでした。
おしまい。

独自の Jenkins の設定(グローバルな設定)をした〜い

Jenkins プラグイン開発ネタの第二弾。

今回は、Jenkins 管理画面で独自の項目を設定したい場合の拡張についてやってみようず。

管理画面の設定情報

Jenkins プラグインを「mvn -cpu hpi:create」で作った時に最初にひな形として定義されているサンプルでも、管理画面に独自の設定(使用する言語の設定)をしているが、このサンプルでは、Descriptor にその情報を保持している。
これでは、この Descriptor のエンクロージングクラスからしか使うことが出来ない(はず)出来る*1
なので、他の独自 Builder やら、独自 Parameter やら、他の独自拡張クラスから、参照することが出来ない(はず)。

そこで、jenkins.model.GlobalConfiguration クラスを使用する。
管理画面の独自設定項目については、このクラスを拡張して定義してあげることで、その他の独自拡張クラスから、設定された値を参照することができる。

Java

こんな感じ。

package com.sample.jenkins;

@Extension
public class ExtensionConfiguration extends GlobalConfiguration {

    public ExtensionConfiguration() {
        load();
    }

    @Override
    public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
        req.bindJSON(this, json);
        return true;
    }
}

View は

これに該当する View ファイルは、こんな感じ。

package com.sample.jenkins.ExtensionConfiguration

def f=namespace(lib.FormTagLib)

f.section(title:"Sample") {
    f.entry(title:_("Value"), field:"value", description:_("Please enter sample value")) {
        f.textbox(default: "xxx")
    }
}


一点注意が必要なのが、通常 View となるファイルは、「.jelly」となるが、この GlobalConfiguration を拡張したクラスに対する View ファイルは、「.groovy」となる点だ。
定義する内容自体は、「.jelly」とさほど変わらないが、若干書き方も違うので、注意が必要。

上記の View は .groovy で書いているが、他の View 同様に .jelly でもOK。
id:kiy0taka さんありがとうございます!

あとは

用意した独自の Config クラスに、自身のインスタンスを取得する Factory メソッドを用意すれば OK。
設定情報を参照したい場合は、Factory メソッドで取得した Config クラスから参照する。

public static ExtensionConfiguration get() {
    return GlobalConfiguration.all().get(ExtensionConfiguration.class);
}

こんな感じで

GlobalConfiguration を拡張した、独自の設定用 Config クラスを用意すれば、他に定義した複数の Builder や Parameter から参照できる。
みなさんも、独自の設定情報を定義したくなったら試してみては :-P

*1:id:kiy0taka さんのコメントにある通り、Jenkins.getInstance().getDescriptor(HelloWorldBuilder.class) と辿れば参照できる

doCheckXxxx と doFillXxxxItems

Jenkins 使ってますか?

便利ですよねー。私が始めて触ったのは前のプロジェクトで、その頃はまだ Hudson おじさんでした。
今ではJenkins を使っていなかったら、そのプロジェクトは大丈夫かしら?と心配になります。

Jenkinsプラグイン作ってますか?

このJenkinsの良いところとして、さまざまなプラグインがあり、それらを組み合わせて使う事で、より Jenkins は賢くなり、Jenkins で出来る事が増えます。
そして、Jenkins が Java で実装されているということで、そのプラグインJava で(簡単に)作る事が出来ます。

とゆーことで、Jenkins プラグインを作成する際に、私が得た(躓いた)知識を幾つかに分けて紹介します。
もし間違っていましたら、ご指摘頂けると助かります。

doCheckXxxx と doFillXxxxItems について

Jenkins プラグインでは、設定画面などの入力項目に対して、特定の命名規則に沿ったメソッドを用意してあげると、Jenkins がそのメソッドを勝手に呼び出してくれるものがあります。
それが doCheckXxxx と doFillXxxxItems です(他にもあるのかしら(・3・)?)。
それぞれ具体的に見ていきます。

doCheckXxxx

Jenkins のプラグインを作成する中で、設定画面等に独自の入力項目を用意したくなる場合があります。

これらの中でテキストボックスに対して入力チェック*1を行いたい場合、その対象のテキストボックスのプロパティ名に対応するチェックメソッドを用意してあげると、そのテキストボックスに対する入力があった場合に、用意したチェックメソッドを Jenkins が呼び出してくれます*2

こんな感じ。

jelly のサンプル

(src/main/resources/com/sample/jenkins/plugin/SampleBuilder/config.jelly)

<f:entry title="Free word" field="word">
  <f:textbox />
</f:entry>
Java のサンプル

(src/main/java/com/sample/jenkins/plugin/SampleBuilder$DescriptorImpl)

public FormValidation doCheckWord(@QueryParameter String value) {
    if (value.length() == 0) {
        return FormValidation.error("条件は必須です。");
    }
    return FormValidation.ok();
}

大事なのは、 で指定した field 属性と同じ名前(キャメルケース)で、チェックメソッドを用意するということ。
今回の例でいえば、 の field 属性は「word」なので、チェックメソッドは、「doCheckWord」となります。

もっと詳しい解説はこちらのサイトとかを見てみて下さい(丸投げ)より詳しく解説されてます( ̄▽ ̄)。

doFillXxxxItems

同じく入力項目としてプルダウンを用意して、今度はその選択候補を設定してくれるのがこのメソッド(命名規則)。

こんな感じ。

jelly のサンプル
<f:entry title="Pulldown" field="person">
  <f:select />
</f:entry>
Java のサンプル
public ListBoxModel doFillPersonItems() {
    ListBoxModel items = new ListBoxModel();
    for (Person person : persons) {
        items.add(person.getName(), person.getId());
    }
    return items;
}

これも大事なのは、 で指定した field 属性と同じ名前(キャメルケース)で、チェックメソッドを定義するということ。
今回の例でいえば、 の field 属性は「person」なので、チェックメソッドは、「doFillPersonItems」となります。

Java で何かしら処理した値を出したいような場合には、これを使えば良いと思います。

逆に、「はい」「いいえ」みたいなものをプルダウンにしたいのなら、別にこの方法でなくても良いと思います。jelly ファイルにベタに書いたのでも個人的には問題無いんちゃうかな〜(そもそも「はい」「いいえ」はプルダウンじゃなくて、ラジオとかチェックボックスだろ、という声が聞こえてきますが〜(・ω・`))。

とまぁ

こんな感じでこれから色々と私が躓いたところで、皆さんが躓かないように、紹介していけたらと思います(・ω・)ノ

*1:例えば、必須チェックとか、有効性チェックとか

*2:ちなみに、このチェックメソッドは、テキストボックス以外に対しても行うこと事も出来ますが、その場合、チェックメソッドの呼び出しを明示的に指定する必要があります。詳しくは後日

Evernote の検索構文

いや〜遅くなりましたが久しぶりの Evernote ネタ。

前回は

ノートの取得に関するサンプルを書きました。
今回はもう少し複雑なノートの検索について、Evernote に用意されている検索構文について、紹介していきます。

検索構文

Evernote には独自の検索構文が用意されており、それらを組み合わせて使うことで、より高度なノートの検索を行うことが出来ます。
検索構文については、本家のサイトにより詳細に書かれているので、詳しい解説はしません。
よく使うであろう検索構文について、軽く解説だけしておきます。


■notebook:[notebook name]
・ノートブックの名前を指定して検索します。
・この条件は、検索条件の先頭でなければいけません。

■any:[word]
・この式が条件の先頭にあった場合、これ以降の任意の検索項目のいずれかに一致するノートを対象とする

リテラル項目の一致
・大文字/小文字は区別されない
ワイルドカードは末尾しか有効にならない(e.g. Ever*)
・「-word」とした場合、否定を表す

■tag:[tag name]
・tag:cooking -> "cooking" というタグを含む任意のノートを対象とする
・tag:cook* -> "cook" で始まるタグを含む任意のノートを対象とする
・-tag:cook* -> "cook" で始まるタグを含まない任意のノートを対象とする
・tag:* -> 少なくとも 1 つのタグを含む任意のノートを対象とする
・-tag:* -> タグを含んでいない任意のノートを対象とする

■intitle:[literal]
・intitle:chicken -> "chicken" という単語をタイトルに含む任意のノートを対象とする
・-intitle:chicken -> "chicken" という単語をタイトルに含んでいない任意のノートを対象とする

■created:[datetime]
・created:20070704 -> 2007/07/04 以降に作成されたノートを対象とする
・created:20070704T090000 -> 2007/07/04 9:00 以降に作成されたノートを対象とする
・created:20070704T150000 -> 2007/07/04 15:00 以降に作成されたノートを対象とする
・-created:20070704 -> 2007/07/04 より前に作成されたノートを対象とする
・created:day-1 -> 昨日または今日作成されたノートを対象とする
・-created:day -> 今日より前に作成されたノートを対象とする
・created:day-1 -created:day -> 昨日作成されたノートを対象とする
・created:day-30 -> 過去30日以内に作成されたノートを対象とする
・created:week -> カレンダー上の今週中(日曜〜土曜)に作成されたノートを対象とする
・-created:month -> 今月より前に作成されたノートを対象とする
・created:year-1 -> 昨年または今年作成されたノートを対象とする

■updated:[datetime]
・フォーマットについては、上記 created の指定内容と同じ。

■resource:[MIME type string]
・resource:image/gif -> 少なくとも 1 つの image/gif リソースを含むノートを対象とする
・resource:audio/* -> 少なくとも 1 つの audio リソースを含むノートを対象とする
・-resource:image/* -> イメージを含まないノートを対象とする

■author:[string]
・author:robert* -> author 属性に "robert" を含むノートを対象とする
・-author:* -> author 属性が設定されていないノートを対象とする

■source:[string]
・source:web.clip -> Evernote Web Clipper を使用している Web ページからクリップしたノートを対象とする
・source:mail.clip -> ローカルなメールクライアントからクリップしたノートを対象とする

■日付および時刻引数
<現在日時が [2007年10月31日(日) 13:30:56] の場合>
・day -> 2007/10/31 00:00:00
・day-1 -> 2007/10/30 00:00:00
・day-14 -> 2007/10/17 00:00:00
・week -> 2007/10/28(日) 00:00:00(現在日時の週の頭の日曜)
・week-2 -> 2007/10/14(日) 00:00:00(現在日時の週の 2 週間前の日曜)
・month -> 2007/10/1 00:00:00(現在日時の月初)
・month-1 -> 2007/9/1 00:00:00(現在日時の前の月の月初)
・year -> 2007/1/1 00:00:00(現在日時の元旦)
・year-3 -> 2004/1/1 00:00:00(現在日時の 3 年前の元旦)

■組み合わせ条件
・chicken tag:cooking created:year
単語 "chicken" を含み、タグ "cooking" を持つノートのうち、今年作成されたものを対象とする
・any: "San Francisco" tag:SFO
単語 "San Francisco" をテキストに含んでいるか、またはタグ "SFO" を含んだノートを対象とする

こんな感じ

とま〜こんな感じで結構柔軟な検索条件を指定することが可能なんです。
あとはコードを見たほうが早いと思いますので、例のごとく GitHub にコードを晒しました。参考になれば幸いです。
evernote-api-example

もう

これで最後かな〜。ノートの登録とかは GitHub に上げてるコードを見てもらえれば分かるかな(不親切)。
何か要望があれば考えます〜。では〜( ^q^)ノ

2年9ヶ月お世話になったプロジェクトを離任しました

ちょっと時間が経ってしまいましたが、2010年7月から参画させていただいていたプロジェクトを、2013年3月末をもって離任(退室)いたしました!
個人的には、このプロジェクトでかなり色々な刺激を受けましたので、退職エントリならぬ退室エントリを書いておこうと思います。

2010年7月〜(不安と期待)

このプロジェクトへの参画が決まったのが同年6月の最終週に突然上司に言われたことを覚えています。ちなみに東京の案件です。
そのときは大阪の自社でお勉強していたので、そこから東京のウィークリーマンションを探して、出張申請書いて、荷物を詰め詰めして、ドタバタで東京に行ったことが懐かしいです。
本来は、プロジェクトに参画するにあたり、間に入っている某会社さん(以後、M社とします)の「面接」を受けなければいけないのですが、昔M社さんと一緒に似たような案件をやったことがあったということと、もう一人一緒に参画した社員の方の推薦もあり、「面接」を受けることなく、このプロジェクトに参画することが出来ました。
この人(仮にNさんとします)には本当に感謝しています。今では周りから、私のNさんに対する「当たりが強い!」と言われるほど、恩を仇で返している感は否めませんが、この件については(も)本当に感謝しています。

参画してからは、これまで経験してこなかった共通部品の設計・実装を行ってきました。
ここでは、時を同じくして参画したM社の方(仮にKさんとします)や、Tさん、Mさんにとても色々教えていただきました。
当たり前なのかもしれませんが、「メソッド名の付け方」や「引数の順番」、「テストの重要さ」など、これまで全く意識してこなかった部分について、他の会社であるにも関わらず優しく教えていただきました。
また、これは私の個人的な意見ですが、M社の方々にはとても可愛がってもらった印象があります。仕事の合間でも気を使って雑談をして下さったり、Kさんには結婚式の二次会にも呼んでいただきました。正直、かなり嬉しかったです!お陰でたくさん泣きましたww自分の事のように(ToT )wwww

2011年4月〜(アジャイルスクラムと私)

ここからは、新たに開発するフロントシステムの開発メンバとして参画させていただきました。
ここでは、『チーム』として、Scrum を使った開発を初めて経験させてもらいました。正直、私はかなり扱い辛い人間だったと思います。若いくせに偉そうだし、態度はデカイし、髭は濃いしで、チームのメンバの方にはとてもご迷惑をお掛けしたと思っております。この場を借りてお詫び致しますm(_ _)m
この開発は今もなお続いているのですが、2012年7月をもって一次リリースは終わりました。この一次リリースのタイミングで殆どのメンバとは解散してしまいました。
個人的には一次リリース後に「アジャイルラクティス」や「アジャイルサムライ」などを読んでいると、あぁ〜チームのみんなに迷惑を掛けたなぁ〜と、本当に反省します。
別に過去の WF の案件で大成功を収めたわけでもないのに、アジャイルというものにとても懐疑的だったのを反省します。

アジャイルプラクティス 達人プログラマに学ぶ現場開発者の習慣

アジャイルプラクティス 達人プログラマに学ぶ現場開発者の習慣

アジャイルサムライ−達人開発者への道−

アジャイルサムライ−達人開発者への道−

私はこれまで、あるシステムの途中から開発に参画したことはあっても、一から参画したことはありませんでした。
今回、このシステムでは、最初のイテレーションから開発に参画させていただくことが出来たのは本当に良い経験になりました。

また、開発当初は、進め方など分からない点が多々あったのですが、Nさんや、Hさんにはとてもお世話になりました。
特にHさんとは同じ兎年ということもあり、公私共に仲良くさせて頂きました。本当に感謝です。(今日も荷物ありがとうございました >_<)

2012年8月〜(ドキュメントのジレンマ)

で、本当は、2012年7月で大阪に帰阪するつもりだったのですが、諸般の都合により、やっぱり東京に残る!と決めたので、同システムの二次開発以降もお手伝いさせていただくことになりました。
一次開発の時には、主に実装がメインだったのですが、二次開発以降は、M社さんにお願いして、分析(いわゆる詳細設計)もやらせていただくことが出来ました。
これまたあまり詳細設計などはしてこなかったので、とても良い経験にもなりました。モンスターカスタマーへの対応なども経験できたので、(今となっては)良い経験が出来たと思いますww
もう一人のTさんにも大変お世話になりました。詳細設計の経験が殆ど無い私に、このような機会を与えて下ったのは本当に感謝しています。

そして離任

もろもろの個人的な事情があり、かなり急ではありましたが、2013年3月をもって長かったこのプロジェクトを離任(退室)しました。
離任に際し、Tさんには本当にご迷惑をお掛けしました。超個人的な事情にも関わらず、もろもろ調整してくださったのは忘れません。
自分の毛で布は織りませんが、何かしらで恩返ししたいと思ってます!いつか!必ず!!

最後に

とま〜ぐだぐだと書いてしまいましたが、一番言いたかったのは皆さんに「感謝」です。
こんな偉そうで太太しい若輩者とこんなにも長い間面倒を見てくださった皆さんに本当に「感謝」しています。
このプロジェクトに入って、皆さんと出会って、一緒に仕事をして、本当に良い経験が出来たと思っております。この経験がなければ、恐らく東京に出てくるなんてことは無かったと思います。大袈裟ではなく本当にこの経験は自分のターニングポイントになったと感じています。

私にとって、この2年9ヶ月は、本当に楽しかったです。最後は簡単な挨拶しか出来ませんでしたが、この場を借りてお礼申し上げます。

「ありがとうございましたぃッ」

また是非飲みに行きましょう。今度また皆さんと会う時には、この現場で培った技術や姿勢をちゃんと活かして、「成長したね」と言われるよう、これまで以上に精進して参ります!!
本当にありがとうございました\(^o^)/

ノートの取得

前回は

ユーザ認証を行い、ノートブックの取得についてサンプルコードを交えながら簡単ですが紹介しました。
今回は、ノートの取得について、紹介していきます。

ノートの一覧を取得する

まずは簡単な、ノートの一覧を取得するコードを紹介します。
ここで指すノートの一覧とは、対象のユーザが作成した全てのノートを指します。
そのため、あるノートブック "A" と "B" それぞれに 10 件のノートが存在していた場合、このコードでは、20 件全てのノートを取得することが出来ます。

// UserStore を取得
UserStore.Client userStore = userStoreFactory.create();

// NoteStore を取得
NoteStore.Client noteStore = noteStoreFactory.create(user, userStore);

// ノート一覧を取得する
NoteFilter filter = new NoteFilter();
filter.setOrder(NoteSortOrder.CREATED.getValue());

NoteList notes;
try {
    notes = noteStore.findNotes(user.getDeveloperToken(), filter, 0, 1000);
} catch (EDAMUserException | EDAMSystemException
        | EDAMNotFoundException | TException e) {
    throw new EvernoteException(e);
}
return notes.getNotes();

このように、全件取得するからといって、(例えば findAll のような)便利な API は公開されておらず、基本的に NoteFilter というクラスを使って、ノートを検索することになります。
そして、今回の例でいえば、NoteFilter にソート順(作成日の昇順)しか指定していないので、ユーザが持つノート全てを取得する、ということになります。

デフォルトノートブックに含まれるノートの一覧を取得する

次に、デフォルトノートブックに含まれているノートの一覧だけを取得する場合のコードを見てみましょう。

// UserStore を取得
UserStore.Client userStore = userStoreFactory.create();

// NoteStore を取得
NoteStore.Client noteStore = noteStoreFactory.create(user, userStore);

// デフォルトノートブックを取得
Notebook notebook;
try {
    notebook = noteStore.getDefaultNotebook(user.getDeveloperToken());
} catch (EDAMUserException | EDAMSystemException | TException e) {
    throw new EvernoteException(e);
}

// ノート一覧を取得する
NoteFilter filter = new NoteFilter();
filter.setNotebookGuid(notebook.getGuid());
filter.setOrder(NoteSortOrder.CREATED.getValue());

NoteList notes;
try {
    notes = noteStore.findNotes(user.getDeveloperToken(), filter, 0, 1000);
} catch (EDAMUserException | EDAMSystemException
        | EDAMNotFoundException | TException e) {
    throw new EvernoteException(e);
}
return notes.getNotes();

このように、違いは NoteFilter に対象となるノートブックの GUID を指定しているだけ。
もし、別のノートブックのノート一覧を取得したい場合、そのノートブックの GUID さえ指定すれば取得できます。
ね?簡単でしょ?
え?そりゃそうだろ?失礼しました。

今日は終わり

今回は簡単なノートの全件取得だけです。次回以降に、もう少し凝った検索についてご紹介したいと思います。

ちなみに

今回紹介したコードも懲りずに GitHub に晒していますので、参考になれば幸いです。
ご指摘等あればコメントいただけると助かります。
GitHub: ノート一覧の取得と、そのテスト

ノートブックの取得

準備

前回はかなりかる〜く、Evernote でいうところのノートブックとノートを EvernoteAPI ではどう取得するのかを説明しました。
といっても説明はしていないか。さわりのコードを軽く見せただけでした。失礼しました。

そこで今回からは、実際の EvernoteAPI の使い方を少しずつご紹介していけたらと思います。

と、その前に EvernoteAPI を触るにあたって色々と準備があります。
準備については、こちらのサイトを見てください(笑)

簡単に説明すると、以下のような流れ。

  1. Evernoteへの認証時に使用する API キーの取得
  2. Evernote SDK の入手
  3. Sandbox 環境(開発環境)の作成
  4. 取得した API キーを本番でも使えるようにアクティベートする

でも、1 つ目と 4 つ目については、認証方法に OAuth 認証を選択したときだけ必要になります。
認証方法にディベロッパトーク*1を用いる方法を選択した場合は不要です。
(確かそうだったはず、うろ覚えですいません。自分が以前 EvernoteAPI と戯れていたときは、ディベロッパトークンは無かったので(^^;;)

ということは、認証方法にディベロッパトークンを用いた場合、Evernote SDK と Sandbox 環境を用意すれば OK。
あとは、その Sandbox 環境用のディベロッパトークンを発行すれば、すぐにでも API を使えます。

UserStoreとNoteStore

それでは実際にコードを見ていこう、っとその前に EvernoteAPI を触る上で、コアとなる概念を軽く触れておきます。それはUserStoreNoteStore
前回チラっと触れたこのUserStoreNoteStoreは、それぞれ以下の感じ。

UserStore

Evernote ユーザアカウント自体を管理するサービス(API)

NoteStore

ユーザの Evernote アカウントの内容を管理するサービス(API)

まぁクラス名の通りっちゃ〜通りですね。
では実際にそれぞれの情報を取得するためのコードを見てみましょう。

UserStore を取得

THttpClient userStoreTrans;
try {
    userStoreTrans = new THttpClient("https://sandbox.evernote.com/edam/user");
} catch (TTransportException e) {
    throw new EvernoteException(e);
}
TBinaryProtocol userStoreProtocol = new TBinaryProtocol(userStoreTrans);

UserStore.Client userStore =  new UserStore.Client(userStoreProtocol);

NoteStore を取得

String noteStoreUrl;
try {
    noteStoreUrl = userStore.getNoteStoreUrl(developerToken);
} catch (EDAMUserException | EDAMSystemException | TException e) {
    throw new EvernoteException(e);
}

THttpClient noteStoreTrans;
try {
    noteStoreTrans = new THttpClient(noteStoreUrl);
} catch (TTransportException e) {
    throw new EvernoteException(e);
}
TBinaryProtocol noteStoreProt = new TBinaryProtocol(noteStoreTrans);

NoteStore.Client noteStore = new NoteStore.Client(noteStoreProt);

上記の通り、とっても似ています。とゆーかほぼ同じ。
なので、この辺りの処理は、実際に何かアプリを作るときにはリファクタリングの余地ありって感じですね。
ちなみに、この二つのクラスを扱う場合、それぞれインナークラスの Client を介して使用する必要があるので、注意が必要。

そして、この取得した NoteStore を使って実際にノートを取ったり、ノートを作成したりする訳です。
今回は、まずノートブックを取得する処理について、コードを見てみましょう。

デフォルトノートブックを取得する

Notebook defaultNotebook;
try {
    defaultNotebook = noteStore.getDefaultNotebook(developerToken);
} catch (EDAMUserException | EDAMSystemException | TException e) {
    throw new EvernoteException(e);
}

指定した名前のノートブックを取得する

// ノートブックの一覧を取得(1)
List<Notebook> notebooks;
try {
    notebooks = noteStore.listNotebooks(developerToken);
} catch (EDAMUserException | EDAMSystemException | TException e) {
    throw new EvernoteException(e);
}

// ノートブック名が一致するものを取得(2)
Notebook result = null;
for (Notebook notebook : notebooks) {
    if (notebook.getName().equals(notebookName)) {
        result = notebook;
        break;
    }
}

こちらは少し残念な感じですね。
ノートブックを取得する系の API は、デフォルトを取得か、一覧で取得か、GUID*2 で取得かしか用意されていません。
そのため、ノートブックの名前で取得したい場合は、まず一覧で取得して(1)、その中から該当する名前のノートブックを比較する(2)必要があります。

この他、ノートブックに関連する API としては、更新(update)、削除(expunge)などがあります。

今日は終わり

今回はここまで。
次回は取得したノートブックを基に、ノートを取得するところのコードを見てみようと思います。

ちなみに

今回お見せしたコードは全て GitHub に晒していますので、参考になれば幸いです。
ご指摘等あればコメントいただけると助かります。
GitHub: evernote-api-exampleノートブックの取得と、そのテスト

*1:http://dev.evernote.com/intl/jp/documentation/cloud/chapters/Authentication.php#devtoken

*2:Evernote 内で扱う様々なオブジェクトを一意に識別するID。Global Unique ID の略。