コードを張ってみる

前のエントリで書いていたやつのコード。
う〜ん。微妙かな、、、、。


でも、インナークラス(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) {

}
}