/*
 * $Id: DefaultContentsAnalyzer.java,v 1.6 2006/02/19 09:26:22 akabane Exp $
 * LOGICAL-PARADOX.ORG
 * Copyright (C)2005 satoshi akabane(akabane@logical-paradox.org)
 *
 */
package org.logical_paradox.rss.http.contents;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.swing.text.html.HTMLEditorKit.Parser;

import org.logical_paradox.common.util.StringUtils;
import org.logical_paradox.rss.http.ParserGetter;
import org.logical_paradox.rss.http.RSSHttpResponse;
import org.logical_paradox.rss.http.WebContents;

/**
 * デフォルトコンテンツアナライザ．
 * サイトの詳細までは解析しないタイプのアナライザ．<br>
 * せいぜいサイトタイトルやURLなどをメタデータとして取得する程度．
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.6 $
 */
public class DefaultContentsAnalyzer implements ContentsAnalyzer {
	/** HTMLコンテンツフィルタ */
	private static final ContentsFilter htmlContentsFilter = new HTMLContentsFilter();

	/**
	 * webコンテンツを解析し，結果をメタデータとして返す．
	 * @param response HTTPレスポンスオブジェクト
	 * @param contents HTMLドキュメント
	 * @return メタデータ
	 */
	public WebContents analyze(RSSHttpResponse response, String contents) {
		WebContents wc = new WebContents();

		if(response.getResponseCode() < 0) {
			throw new IllegalStateException("HttpURLConnection object has no content");
		}

		// オリジナルのコンテンツ(HTML)
		wc.setOriginalDocument(contents);
		// URL
		wc.setURL(response.getURL());
		// コンテンツの位置
		wc.setLocation(response.getURL().toString());
		// mimeタイプ
		wc.setContentType(response.getContentType());
		// httpステータスコード
		wc.setResponseCode(response.getResponseCode());
		// URLがrobots.txtを示していた場合はフラグをセット
		if(wc.getLocation().indexOf("robots.txt") >= 0) {
			wc.setRobotsTxtFlg(true);
		} else {
			wc.setRobotsTxtFlg(false);
		}

		// テキスト化されたドキュメント
		wc.setDocument(normalizeDocument(contents));
		// サイト名
		wc.setSitename(getSiteName(contents));
		// ドキュメントタイトル(ない場合は単にURLとする)
		String title = getTitle(contents); 
		wc.setTitle(StringUtils.isEmpty(title) ? wc.getLocation() : title);

		return wc;
	}
	/**
	 * コンテンツを解析して，タグのない単なるテキストに変換する．
	 * @param contents 元のコンテンツ
	 * @return 変換されたコンテンツ
	 */
	protected String normalizeDocument(String contents) {
		return StringUtils.isEmpty(contents) == true ? "" : htmlContentsFilter.filter(contents);
	}
	/**
	 * コンテンツを解析して，サイト名を返す．
	 * @param contents 元のコンテンツ
	 * @return 抽出されたサイト名
	 */
	protected String getSiteName(String contents) {
		// とりあえずタイトルと同じものを返しておく
		return getTitle(contents);
	}
	/**
	 * コンテンツを解析して，ドキュメントタイトルを返す．
	 * @param contents 元のコンテンツ
	 * @return 抽出されたドキュメントタイトル
	 */
	protected String getTitle(String contents) {
		if(StringUtils.isEmpty(contents)) {
			return "";
		}
		Parser parser = new ParserGetter().getParser();
		DocumentTitleCollectionCallback cb = new DocumentTitleCollectionCallback();
		BufferedReader br = new BufferedReader(
								new InputStreamReader(new ByteArrayInputStream(contents.getBytes()))
							);
		try {
			// 解析
			parser.parse(br, cb, true);
			String title = cb.getDocumentTitle(); 
			return StringUtils.isEmpty(title) ? "" : title;
		} catch (IOException e) {
			// もうどうしようもないので適当なものを返しておく
			return "";
		}
	}
}
