コードを張ってみる
前のエントリで書いていたやつのコード。
う〜ん。微妙かな、、、、。
でも、インナークラス(State に相当)作って、無名クラス(各々の状態)作りまくるよりはましな気もする。
/** * はてブ ホットエントリ パース用のクラス */ public class HotEntryBookMarkParserCallback extends HTMLEditorKit.ParserCallback { //データ用のフィールドがあるけど、省略 //現在の状態 private State state = State.DIV_ENTRY_BODY_OR_PAGER; /** * HTMLをパースしていく上での状態と状態ごとの処理の定義。 * 状態の命名は、どういったデータを探しているかを名前にしている */ enum State { /** * 初期状態。 * * ブックマークのエントリのデータ群、 * もしくは、ページャー(次のページへのリンク) * を探す。 * * ブックマークのエントリは一ページに複数回出現する。 */ DIV_ENTRY_BODY_OR_PAGER { public State handleTag(HTML.Tag tag, MutableAttributeSet attr, HotEntryBookMarkParserCallback call) { //ブックマークのエントリの基点となるタグ //DIVで、クラスがentry-body if (tag.equals(HTML.Tag.DIV) && "entry-body".equals(attr .getAttribute(HTML.Attribute.CLASS))) { //次は、エントリのURLを探します。 return A_LINK; } else { //ページャー(次のページへのリンク)の確認 //構造は持っていないので、一発で終わり if (tag.equals(HTML.Tag.A) && "pager-prev".equals(attr .getAttribute(HTML.Attribute.CLASS))) { call.beforeLink = (String) attr .getAttribute(HTML.Attribute.HREF); } return this; } } }, /** * URLを探している状態 */ A_LINK { public State handleTag(HTML.Tag tag, MutableAttributeSet attr, HotEntryBookMarkParserCallback call) { // Aタグが見つかったらデータ抜いて終了 if (tag.equals(HTML.Tag.A)) { call.tmpLink = (String) attr.getAttribute(HTML.Attribute.HREF); //次は、Aタグのコンテンツがタイトルなのでそれを取りにいく return TITLE; } else { //見つからなければ続行 return this; } } }, /** * タイトルを探している状態 */ TITLE { //タイトルは、タグではなくコンテンツ? public State handleText(char[] data, HotEntryBookMarkParserCallback call) { call.tmpTitle = new String(data); //次は、はてブのこのエントリに対する詳細ページの取得 return A_DOMAIN_DITAIL_LINK; } }, /** * はてぶの詳細ページを探している状態。 * Aタグとclassがdomain のものを探す */ A_DOMAIN_DITAIL_LINK { public State handleTag(HTML.Tag tag, MutableAttributeSet attr, HotEntryBookMarkParserCallback call) { if (tag.equals(HTML.Tag.A) && "domain".equals(attr .getAttribute(HTML.Attribute.CLASS))) { call.tmpDitailLink = (String) attr .getAttribute(HTML.Attribute.HREF); //ここまできたら必要な情報はそろったので、 //データをバックアップして、初期状態へ call.addBookMarkEntryInfo(); return DIV_ENTRY_BODY_OR_PAGER; } else { return this; } } } ; public State handleTag(HTML.Tag tag, MutableAttributeSet attr, HotEntryBookMarkParserCallback call) { throw new IllegalStateException(); } public State handleText(char[] data, HotEntryBookMarkParserCallback call) { return this; } } // ここからが、HTMLEditorKit.ParserCallback のメソッド。 // SAXに似た感じ public void handleStartTag(HTML.Tag tag, MutableAttributeSet attr, int pos) { //ステータスに応じた処理をしてもらって、 //ステータスの更新も勝手にやってもらう。 this.state = state.handleTag(tag, attr, this); } public void handleText(char[] data, int pos) { //同上 this.state = state.handleText(data, this); } public void handleSimpleTag(HTML.Tag tag, MutableAttributeSet attr, int pos) { } public void handleEndTag(Tag t, int pos) { } }