既存のURLのソースを解析してRSS2.0文書を生成してみる
::::::::::::::
AbsolutePathObtainer.java
::::::::::::::
import java.util.*;
import java.util.regex.*;
import java.io.*;
import java.net.*;
/**
* $Id: RSSGenerator.html,v 1.1 2009/06/22 16:11:53 kishi Exp kishi $
* @author KISHI Yasuhiro
* 絶対URLに変換する
*/
public class AbsolutePathObtainer {
/** 相対パスから絶対パスに変更する
* @param currentUrl 処理しているURL
* @param path リンク先のパス
* @return 絶対パス
*/
static public String getAbsolutePath( URL currentUrl, String path ) {
if ( path.toLowerCase().startsWith( "http:" )
|| path.toLowerCase().startsWith( "https:" )
|| path.toLowerCase().startsWith( "ftp:" )
|| path.toLowerCase().startsWith( "mailto:" )
) {
/* do nothing */
} else if ( path.startsWith( "/" ) ) {
/* / でスタートするのは、ホスト内の絶対パス表記であるので、プロトコルとホスト名を頭に付ける */
path = currentUrl.getProtocol() + "://" + currentUrl.getHost() + path;
} else if ( path.startsWith( "./" ) ) {
// 先頭の "./" を削除する
path = path.replaceAll( "^./", "" );
path = getDirName( currentUrl ) + path;
} else if ( path.startsWith( "../" ) ) {
path = getParentPath( currentUrl, path );
} else {
path = getDirName( currentUrl ) + path;
}
return path;
}
/** URLからディレクトリ名を得る
* @param url URL
* @return ディレクトリ名
*/
static private String getDirName( URL url ) {
String dirName = null;
Pattern p;
Matcher m;
p = Pattern.compile( "^(.+/).*$" );
m = p.matcher( url.toString() );
if ( m.find() ) {
dirName = m.group( 1 );
}
// System.err.println( " *** DEBUG *** in getDirName :");
// System.err.println( "\t" + "urlString = " + urlString + " dirName = " + dirName
// + " プロトコル = " + url.getProtocol() );
if ( dirName.equals( url.getProtocol() + "://" ) ) {
dirName = url.toString() + "/";
}
return dirName;
}
/** 上位の相対パスを処理する
@param url 処理しているURL
@param relativePath ../などが先頭に付いたパス
@return ../などを削除して書き直したもの
*/
static private String getParentPath( URL url, String relativePath ) {
Pattern p;
Matcher m;
String parentPath = null;
String tempPath = url.getProtocol() + "://" + url.getHost() + url.getPath();
int count = 0;
while ( relativePath.startsWith( "../" ) ) {
//==========================================================================
// 末尾のディレクトリ名あるいはディレクトリ名+"/"+ファイル名を削除
//==========================================================================
p = Pattern.compile( "(.+/).+/.*$" );
m = p.matcher( tempPath );
if ( m.find() ) {
tempPath = m.group( 1 );
}
//==========================================================================
// 相対パスの先頭の"../"を削除する
//==========================================================================
p = Pattern.compile( "^\\.\\./(.*)$" );
m = p.matcher( relativePath );
if ( m.find() ) {
relativePath = m.group( 1 );
}
}
return tempPath + relativePath;
}
/**
* テストコード
*/
public static void main( String[] args ) throws Exception {
URL baseURL = new URL( "http://www.abc.co.jp/xxx/yyy/" );
System.out.println( AbsolutePathObtainer.getAbsolutePath( baseURL, "../../test.jpg" ) );
System.out.println( AbsolutePathObtainer.getAbsolutePath( baseURL, "../test.jpg" ) );
System.out.println( AbsolutePathObtainer.getAbsolutePath( baseURL, "./test.jpg" ) );
System.out.println( AbsolutePathObtainer.getAbsolutePath( baseURL, "test.jpg" ) );
System.out.println( AbsolutePathObtainer.getAbsolutePath( baseURL, "/test.jpg" ) );
System.out.println( AbsolutePathObtainer.getAbsolutePath( baseURL, "http://www.abc.co.jp/OPQ/test.jpg" ) );
}
}
::::::::::::::
ArticleExtractor.java
::::::::::::::
import java.util.*;
import java.util.regex.*;
import java.io.*;
import java.net.*;
/**
* $Id: RSSGenerator.html,v 1.1 2009/06/22 16:11:53 kishi Exp kishi $
* @author KISHI Yasuhiro
*/
public class ArticleExtractor {
/**
* @param in 処理対象文字列
* @return 取り出した結果
*/
public static String extractPre( String in ) {
String result = "";
// 先頭がIMGでそれ以降に初めて出現したSRC属性の値を求める
// ただしシングルクォートあるいはダブルクォートで挟み込まれてなくてはいけない
Pattern p = Pattern.compile( "<PRE>(.*?)</PRE>",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL );
Matcher m = p.matcher( in );
if ( m.find() ) {
result = m.group( 1 );
}
return result.trim();
}
/**
* @param in 処理対象文字列
* @return 取り出した結果
*/
public static String extractTitle( String in ) {
String result = "";
// 先頭がIMGでそれ以降に初めて出現したSRC属性の値を求める
// ただしシングルクォートあるいはダブルクォートで挟み込まれてなくてはいけない
Pattern p = Pattern.compile( "<TITLE>(.*?)</TITLE>",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL );
Matcher m = p.matcher( in );
if ( m.find() ) {
result = m.group( 1 );
}
return result.trim();
}
/**
* テストコード
*/
public static void main( String[] args ) throws Exception {
String str = "...............<pre>.............\n\n";
str += "ああああああああああああああああああああああああああああああああ</pre>";
str += "<title>\n";
str += "タイトル</title>\n\n";
System.out.println( "PRE: " + ArticleExtractor.extractPre( str ) );
System.out.println( "TITLE: " + ArticleExtractor.extractTitle( str ) );
}
}
::::::::::::::
ContentObtainer.java
::::::::::::::
import java.net.*;
import java.io.*;
import java.util.*;
/**
* $Id: RSSGenerator.html,v 1.1 2009/06/22 16:11:53 kishi Exp kishi $
*/
public class ContentObtainer {
public String getResponseBodyAsString( String urlString, String encoding ) throws Exception {
StringBuilder sb = new StringBuilder();
URL url;
try {
url = new URL( urlString );
HttpURLConnection connection = ( HttpURLConnection ) url.openConnection();
//---------------------------------------------------------------
// ユーザ・エージェントの設定
//---------------------------------------------------------------
String userAgent = RagUtil.sha1Digest( new Date().toString() + "128-256-384-512-640-768" );
if ( ( url.hashCode() + userAgent.hashCode() ) % 2 == 0 ) {
userAgent = userAgent.toUpperCase();
}
connection.setRequestProperty( "User-Agent", userAgent );
// System.err.println( "User-Agent: " + userAgent );
//---------------------------------------------------------------
// HTTP応答コードの取得
//---------------------------------------------------------------
int responseCode = connection.getResponseCode();
System.out.println( urlString + ": 応答コード=" + responseCode + "\n" );
BufferedReader reader = new BufferedReader( new InputStreamReader(
connection.getInputStream(), encoding ) );
String line;
while ( ( line = reader.readLine() ) != null ) {
sb.append( line + "\n" );
}
reader.close();
} catch ( Exception e ) {
throw e;
}
return sb.toString();
}
}
::::::::::::::
CreateXMLTest.java
::::::::::::::
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.w3c.dom.*;
import java.io.*;
import java.util.*;
import java.text.*;
/**
* $Id: RSSGenerator.html,v 1.1 2009/06/22 16:11:53 kishi Exp kishi $
* DOMを使ってXML文書を作成するモックアッププログラム
*/
public class CreateXMLTest {
public static void main( String[] args ) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
DOMImplementation domImpl = builder.getDOMImplementation();
//-------------------------------------
// ルート要素名をrssにする
//-------------------------------------
Document document = domImpl.createDocument( "", "rss", null );
//-------------------------------------
// ルート要素を取得
//-------------------------------------
Element rss = document.getDocumentElement();
//-------------------------------------
// 属性としてversionを付与
//-------------------------------------
rss.setAttribute( "version", "2.0" );
/**
* 以下の方法でも可
* Attr attr = document.createAttribute( "version" );
* attr.setValue( "2.0" );
* rss.setAttributeNode( attr );
**/
//-------------------------------------
// ルート配下にchannel要素を追加
//-------------------------------------
Element channel = document.createElement( "chanell" );
//-------------------------------------
// channel配下にそれぞれの要素を追加
//-------------------------------------
createChannel( document, channel );
rss.appendChild( channel );
//-------------------------------------
// DOMツリーをXMLに変換
//-------------------------------------
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
DOMSource source = new DOMSource( document );
/**
File newXML = new File("newXML.xml");
FileOutputStream os = new FileOutputStream(newXML);
**/
StreamResult result = new StreamResult( System.out ); // ファイル出力の場合は、FileOutputStreamを引き渡す
transformer.transform( source, result );
}
private static void createChannel( Document document, Element channel ) {
addOn( document, channel, "title", "私のブログでやんす!" );
addOn( document, channel, "link", "http://www.xxx.yyy.zzz.jp/" );
addOn( document, channel, "description", "DOMでRSS2.0文書を生成してみます" );
addOn( document, channel, "language", "ja" );
addOn( document, channel, "webmaster", "mimetype@content-type.jp" );
addOn( document, channel, "lastBuildDate", getFormattedDate() );
addOn( document, channel, "generator", "AS-IS-TO-BE" );
addOn( document, channel, "docs", "http://blogs.law.harvard.edu/tech/rss" );
createItems( document, channel );
}
private static void createItems( Document document, Element channel ) {
Element item1 = document.createElement( "item" );
addOn( document, item1, "title", "ブッシュ大統領の支持率、最低の29%に下落" );
addOn( document, item1, "link", "http://www.xxx.yyy.zzz.jp/item1" );
addOn( document, item1, "description", "米紙ウォール・ストリート・ジャーナル(電子版)は12日、世論調査機関ハリス・インタラクティブの調査結果として、ブッシュ大統領の支持率が2001年の政権発足後、最低の29%に下落したと報じた。不支持は71%だった。 支持率は1月の調査の43%、4月の35%から急落。主要な世論調査でブッシュ大統領の支持率が3割を切ったのは初めて。調査は5〜8日、全国の1003人を対象に電話で行われた。 「危険水域」とされる2割台に突入したことで、11月に中間選挙を控えた与党・共和党はさらに危機感を強めるとみられる。" );
addOn( document, item1, "category", "政治" );
addOn( document, item1, "comment", "http://www.asahi.com/international/update/0514/001.html" );
addOn( document, item1, "guid", "http://www.doblog.com/weblog/myblog/7160/2553728#2553728" );
addOn( document, item1, "pubDate", getFormattedDate() );
channel.appendChild( item1 );
Element item2 = document.createElement( "item" );
addOn( document, item2, "title", "地デジ受信機1千万台、BSデジタル放送の2倍の早さ" );
addOn( document, item2, "link", "http://www.xxx.yyy.zzz.jp/item2" );
addOn( document, item2, "description", "NHKは11日、地上デジタル放送の受信機が、4月末現在で、1000万台を突破し、1049万台に達したことを明らかにした。 1000万台の突破は2003年12月の地上デジタル放送開始以来、880日での達成で、1735日かかったBSデジタル放送の2倍近い速さ。 受信可能世帯は、6月末で全世帯の68%にあたる3220万世帯に達する見通しで、年末には84%にまで拡大する。" );
addOn( document, item2, "category", "エンタメ" );
addOn( document, item2, "comment", "http://www.yomiuri.co.jp/entertainment/news/20060511it12.htm" );
addOn( document, item2, "guid", "http://www.doblog.com/weblog/myblog/7160/12553728#12553728" );
addOn( document, item2, "pubDate", getFormattedDate() );
channel.appendChild( item2 );
}
private static void addOn( Document document, Element parent, String elementName, String value ) {
Element element = document.createElement( elementName );
element.appendChild( document.createTextNode( value ) );
parent.appendChild( element );
}
private static String getFormattedDate() {
//
// Sat, 13 May 2006 19:18:00 +0900 みたいなRFC822タイムゾーンがついた形式で日付時刻を返す
//
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat( "EEE, d MMM yyyy HH:mm:ss Z", Locale.US );
String value = formatter.format( date );
return value;
}
}
::::::::::::::
DownloaderRunnable.java
::::::::::::::
import java.net.*;
import java.io.*;
import java.util.*;
/**
* $Id: RSSGenerator.html,v 1.1 2009/06/22 16:11:53 kishi Exp kishi $
*/
public class DownloaderRunnable implements Runnable {
private String target;
private long size;
public DownloaderRunnable( String target ) {
this.target = target;
}
public void run() {
ImageDownloader downloader = new ImageDownloader( target );
size = downloader.download();
}
public long getSize() {
return size;
}
}
::::::::::::::
HrefURLObtainer.java
::::::::::::::
import java.util.*;
import java.util.regex.*;
import java.io.*;
import java.net.*;
/**
* $Id: RSSGenerator.html,v 1.1 2009/06/22 16:11:53 kishi Exp kishi $
* @author KISHI Yasuhiro
* 正規表現を使って、リンク先のURLを抽出する
*/
public class HrefURLObtainer {
/**
* @param in 処理対象文字列
* @return 取り出した結果のリスト
*/
public static List obtain( String in ) {
List result = new LinkedList();
// 先頭がAでそれ以降に初めて出現したHREF属性の値を求める
// ただしシングルクォートあるいはダブルクォートで挟み込まれてなくてはいけない
Pattern p = Pattern.compile( "<A.*?\\s+?HREF=(\"|\')(.*?)(\"|\')(.*?>)",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL );
Matcher m = p.matcher( in );
while ( m.find() ) {
result.add( m.group( 2 ) );
}
return result;
}
/**
* ユニークなURLのセットを返す
*/
public static java.util.Set getUniqueURLs( String baseURLPath , String in ) throws Exception {
List urlList = HrefURLObtainer.obtain( in );
return UniquePathObtainer.getUniqueURLs( baseURLPath , urlList );
}
/**
* テストコード
*/
public static void main( String[] args ) throws Exception {
if ( args.length != 2 ) {
System.out.println( "Usage: java -cp . HrefURLObtainer [url] [encoding]" );
System.exit( 1 );
}
String urlAsString = args[ 0 ];
String encoding = args[ 1 ];
/******************************************************************************/
/* 接続タイムアウトの設定; 設定された時間でコネクトできない場合はタイムアウト */
/******************************************************************************/
System.setProperty ( "sun.net.client.defaultConnectTimeout", "10000" );
/**********************************************************************************/
/* 読み取りタイムアウトの設定; 設定された時間で読み取りできない場合はタイムアウト */
/**********************************************************************************/
System.setProperty ( "sun.net.client.defaultReadTimeout", "10000" );
// String urlAsString = "http://asistobe851.hp.infoseek.co.jp/public_tec/";
// String encoding = "Shift_JIS";
WebClientEmulator browser = new WebClientEmulator( urlAsString, encoding );
// System.out.println( browser.getResponseBodyAsString());
java.util.Set urlSet = HrefURLObtainer.getUniqueURLs( urlAsString , browser.getResponseBodyAsString() );
Iterator iterator = urlSet.iterator();
int i = 0;
while ( iterator.hasNext() ) {
String url = ( String ) iterator.next();
if ( url.endsWith( ".html" ) ) {
System.out.printf( "%3d: %s\n", ++i, url );
}
}
}
}
::::::::::::::
ImageDownloadManager.java
::::::::::::::
import java.net.*;
import java.io.*;
import java.util.*;
/**
* $Id: RSSGenerator.html,v 1.1 2009/06/22 16:11:53 kishi Exp kishi $
*/
public class ImageDownloadManager {
public static void download( java.util.Set urlSet ) {
Iterator iterator = urlSet.iterator();
while ( iterator.hasNext() ) {
String target = ( String ) iterator.next();
System.out.println( target );
DownloaderRunnable runnable = new DownloaderRunnable( target );
Thread thread = new Thread( runnable );
thread.start();
try {
thread.join();
} catch ( Exception e ) {
e.printStackTrace();
}
}
System.out.println( "ImageDownloadManager: 完了しました!" );
}
}
::::::::::::::
ImageDownloader.java
::::::::::::::
import java.io.*;
import java.net.*;
/**
* $Id: RSSGenerator.html,v 1.1 2009/06/22 16:11:53 kishi Exp kishi $
*/
public class ImageDownloader {
private String urlString;
private BufferedOutputStream bos;
private OutputStream out = null ;
private long iSize = 0;
public ImageDownloader( String urlString, OutputStream out ) {
this.urlString = urlString;
this.out = out;
}
/**
* 空読みする場合
*/
public ImageDownloader( String urlString ) {
this.urlString = urlString;
}
public long download() {
try {
//-------------------------------------------------
// URL の作成
//-------------------------------------------------
URL url = new URL( urlString );
// コネクトして、HttpURLConnection の作成
HttpURLConnection connection = ( HttpURLConnection ) url.openConnection();
connection.setRequestMethod( "GET" );
//---------------------------------------------------------------
// HTTP応答コードの取得
//---------------------------------------------------------------
int responseCode = connection.getResponseCode();
System.out.println( "\t応答コード=" + responseCode );
if ( out != null ) {
// 出力ストリーム
bos = new BufferedOutputStream( out );
}
// 入力ストリーム
BufferedInputStream bis = new BufferedInputStream( connection.getInputStream() );
int size = bis.available();
byte[] buf = new byte[ size ];
int len = 0;
while ( ( len = bis.read( buf ) ) > 0 ) {
if ( out != null ) {
bos.write( buf, 0, len );
}
// 読み込んだサイズを加算
iSize += len;
}
bis.close();
if ( out != null ) {
bos.close();
}
System.out.println( "\t画像ファイルサイズ=" + iSize + "\n" );
} catch ( Exception e ) {
e.printStackTrace();
}
return iSize;
}
static public void main( String[] args ) {
if ( args.length != 1 ) {
System.err.println( "Usage: java -cp . ImageDownloader [URL]" );
System.exit( 1 );
}
String targetUrl = args[ 0 ];
ImageDownloader downloader = new ImageDownloader( targetUrl, System.out );
downloader.download();
}
}
::::::::::::::
ImageURLObtainer.java
::::::::::::::
import java.util.*;
import java.util.regex.*;
import java.io.*;
import java.net.*;
/**
* $Id: RSSGenerator.html,v 1.1 2009/06/22 16:11:53 kishi Exp kishi $
* @author KISHI Yasuhiro
* 正規表現を使って、画像URLを抽出する
*/
public class ImageURLObtainer {
/**
* @param in 処理対象文字列
* @return 取り出した結果のリスト
*/
public static List obtain( String in ) {
List result = new LinkedList();
// 先頭がIMGでそれ以降に初めて出現したSRC属性の値を求める
// ただしシングルクォートあるいはダブルクォートで挟み込まれてなくてはいけない
Pattern p = Pattern.compile( "<IMG.*?\\s+?SRC=(\"|\')(.*?)(\"|\')(.*?>)",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL );
Matcher m = p.matcher( in );
while ( m.find() ) {
result.add( m.group( 2 ) );
}
return result;
}
/**
* ユニークなURLのセットを返す
*/
public static java.util.Set getUniqueURLs( String baseURLPath , String in ) throws Exception {
List urlList = ImageURLObtainer.obtain( in );
return UniquePathObtainer.getUniqueURLs( baseURLPath , urlList );
}
/**
* テストコード
*/
public static void main( String[] args ) throws Exception {
String str = "...............<img src=\"AAA.jpg\">.................";
str += "<img src=\"test.gif\" alt=\"aaa\">";
str += "<img width='1000' src=\"test2.gif\" alt=\"aaa\">\n";
str += "<img width='333' src='/test3.ping' alt=\"aaa\">\n";
str += "<img width='999' src='/test3.ping' alt=\"aaa\">\n";
List result = ImageURLObtainer.obtain( str );
Iterator iterator = result.iterator();
while ( iterator.hasNext() ) {
System.out.println( iterator.next() );
}
java.util.Set urlSet = ImageURLObtainer.getUniqueURLs( "http://www.mysite.jp/AAA/" , str );
iterator = urlSet.iterator();
while ( iterator.hasNext() ) {
System.out.println( iterator.next() );
}
}
}
::::::::::::::
RSSGenerator.java
::::::::::::::
import java.util.*;
import java.util.regex.*;
import java.io.*;
import java.net.*;
/**
* $Id: RSSGenerator.html,v 1.1 2009/06/22 16:11:53 kishi Exp kishi $
* @author KISHI Yasuhiro
* 正規表現を使って、リンク先のURLを抽出する
*/
public class RSSGenerator {
/**
* テストコード
*/
public static void main( String[] args ) throws Exception {
/**
if ( args.length != 2 ) {
System.out.println( "Usage: java -cp . RSSGenerator [url] [encoding]" );
System.exit( 1 );
}
String urlAsString = args[ 0 ];
String encoding = args[ 1 ];
**/
/******************************************************************************/
/* 接続タイムアウトの設定; 設定された時間でコネクトできない場合はタイムアウト */
/******************************************************************************/
System.setProperty ( "sun.net.client.defaultConnectTimeout", "10000" );
/**********************************************************************************/
/* 読み取りタイムアウトの設定; 設定された時間で読み取りできない場合はタイムアウト */
/**********************************************************************************/
System.setProperty ( "sun.net.client.defaultReadTimeout", "10000" );
String urlAsString = "http://asistobe851.hp.infoseek.co.jp/public_tec/";
String encoding = "Shift_JIS";
WebClientEmulator browser = new WebClientEmulator( urlAsString, encoding );
// System.out.println( browser.getResponseBodyAsString());
// 対象URLからリンク先を取得する
java.util.Set urlSet = HrefURLObtainer.getUniqueURLs( urlAsString , browser.getResponseBodyAsString() );
Iterator iterator = urlSet.iterator();
int i = 0;
RSSWriter writer = new RSSWriter();
while ( iterator.hasNext() ) {
String url = ( String ) iterator.next();
if ( url.endsWith( ".html" ) ) {
System.out.printf( "%3d: %s\n", ++i, url );
String title = "";
String link = url;
String description = "";
String category = "開発言語"; // 固定
browser = new WebClientEmulator( url, "Shift_JIS" );
String content = browser.getResponseBodyAsString();
title = ArticleExtractor.extractTitle( content );
description = ArticleExtractor.extractPre( content );
writer.createItem( title, link, description, category );
}
}
writer.transform();
}
}
::::::::::::::
RSSWriter.java
::::::::::::::
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.w3c.dom.*;
import java.io.*;
import java.util.*;
import java.text.*;
/**
* $Id: RSSGenerator.html,v 1.1 2009/06/22 16:11:53 kishi Exp kishi $
* DOMを使ってRSS2.0文書を生成する
*/
public class RSSWriter {
private Document document = null;
private Element channel = null;
public RSSWriter() throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
DOMImplementation domImpl = builder.getDOMImplementation();
//-------------------------------------
// ルート要素名をrssにする
//-------------------------------------
document = domImpl.createDocument( "", "rss", null );
//-------------------------------------
// ルート要素を取得
//-------------------------------------
Element rss = document.getDocumentElement();
//-------------------------------------
// 属性としてversionを付与
//-------------------------------------
rss.setAttribute( "version", "2.0" );
//-------------------------------------
// channel部分の生成
//-------------------------------------
createChannel();
rss.appendChild( channel );
}
public void transform() throws Exception {
//-------------------------------------
// DOMツリーをXMLに変換
//-------------------------------------
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
DOMSource source = new DOMSource( document );
File indexXML = new File( "index.xml" );
FileOutputStream os = new FileOutputStream( indexXML );
StreamResult result = new StreamResult( os ); // ファイル出力の場合は、FileOutputStreamを引き渡す
transformer.transform( source, result );
}
private void createChannel( ) {
//-------------------------------------
// ルート配下にchannel要素を追加
//-------------------------------------
channel = document.createElement( "chanell" );
//-------------------------------------
// channel配下にそれぞれの要素を追加
//-------------------------------------
addOn( channel, "title", "AS-IS-TO-BEのチャネル" );
addOn( channel, "link", "http://asistobe851.hp.infoseek.co.jp/public_tec/" );
addOn( channel, "description", "Trivia often comes to be helpful" );
addOn( channel, "language", "ja" );
addOn( channel, "webmaster", "appaloosa_909@yahoo.co.jp" );
addOn( channel, "lastBuildDate", getFormattedDate() );
addOn( channel, "generator", "AS-IS-TO-BE" );
addOn( channel, "docs", "http://blogs.law.harvard.edu/tech/rss" );
}
public void createItem( String title, String link, String description, String category ) {
Element item = document.createElement( "item" );
addOn( item, "title", title );
addOn( item, "link", link );
addOn( item, "description", description );
addOn( item, "category", category );
addOn( item, "comment", "unsupported" ); // サポートしない
addOn( item, "guid", link ); // とりあえずlinkを同じ値をセット
addOn( item, "pubDate", getFormattedDate() );
channel.appendChild( item );
}
private void addOn( Element parent, String elementName, String value ) {
Element element = document.createElement( elementName );
element.appendChild( document.createTextNode( value ) );
parent.appendChild( element );
}
private String getFormattedDate() {
//
// Sat, 13 May 2006 19:18:00 +0900 みたいなRFC822タイムゾーンがついた形式で日付時刻を返す
//
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat( "EEE, d MMM yyyy HH:mm:ss Z", Locale.US );
String value = formatter.format( date );
return value;
}
/**
* 単体テスト
*/
public static void main( String[] args ) throws Exception {
RSSWriter writer = new RSSWriter();
writer.createItem(
"ブッシュ大統領の支持率、最低の29%に下落",
"http://unknown.jp/",
"米紙ウォール・ストリート・ジャーナル(電子版)は12日、世論調査機関ハリス・インタラクティブの調査結果として、ブッシュ大統領の支持率が2001年の政権発足後、最低の29%に下落したと報じた。不支持は71%だった。 支持率は1月の調査の43%、4月の35%から急落。主要な世論調査でブッシュ大統領の支持率が3割を切ったのは初めて。調査は5〜8日、全国の1003人を対象に電話で行われた。 「危険水域」とされる2割台に突入したことで、11月に中間選挙を控えた与党・共和党はさらに危機感を強めるとみられる。",
"政治"
);
writer.transform();
}
}
::::::::::::::
RagUtil.java
::::::::::::::
/**
* $Id: RSSGenerator.html,v 1.1 2009/06/22 16:11:53 kishi Exp kishi $
* @author KISHI Yasuhiro
*/
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;
import java.security.MessageDigest;
public class RagUtil {
/** 文字列からSHA1ハッシュ値を求めて16進で表示する
@param str 入力文字列
@return ハッシュ値
*/
static public String sha1Digest( String str ) {
StringBuffer result = new StringBuffer( "" );
try {
MessageDigest md = MessageDigest.getInstance( "SHA1" ); /* MD5のときは"MD5"とすればいいですよ! */
md.update( str.getBytes() );
byte[] digest = md.digest();
for ( int i = 0; i < digest.length; i++ ) {
if ( ( digest[ i ] & 0x0ff ) / 16 == 0 ) {
result.append( "0" );
}
result.append( Integer.toHexString( digest[ i ] & 0x0ff ) );
}
} catch ( Exception e ) {}
return result.toString();
}
}
::::::::::::::
UniquePathObtainer.java
::::::::::::::
import java.util.*;
import java.util.regex.*;
import java.io.*;
import java.net.*;
/**
* $Id: RSSGenerator.html,v 1.1 2009/06/22 16:11:53 kishi Exp kishi $
* @author KISHI Yasuhiro
* 正規表現を使って、画像URLを抽出する
*/
public class UniquePathObtainer {
/**
* ユニークなURLのセットを返す
*/
protected static java.util.Set getUniqueURLs( String baseURLPath , List urlList ) throws Exception {
Iterator iterator = urlList.iterator();
java.util.Set urlSet = new java.util.TreeSet();
while ( iterator.hasNext() ) {
String target = ( String ) iterator.next();
//-------------------------------------------------------
// 絶対パスに変換
//-------------------------------------------------------
String absPath = AbsolutePathObtainer.getAbsolutePath( new URL( baseURLPath ), target );
//-------------------------------------------------------
// Setに格納して重複を取り除く
//-------------------------------------------------------
urlSet.add( absPath );
}
return urlSet;
}
}
::::::::::::::
WebClientEmulator.java
::::::::::::::
import java.net.*;
import java.io.*;
import java.util.*;
/**
* $Id: RSSGenerator.html,v 1.1 2009/06/22 16:11:53 kishi Exp kishi $
*/
public class WebClientEmulator {
private String resBody = null;
/**
* コンストラクタ
*/
public WebClientEmulator( String urlAsString, String encoding ) {
Iterator iterator;
long elapsedTime, start, end;
start = System.currentTimeMillis();
long totalImageSize = 0;
try {
//-------------------------------------------------------
// 対象URLのレスポンスボディを取得
//-------------------------------------------------------
ContentObtainer obtainer = new ContentObtainer();
resBody = obtainer.getResponseBodyAsString( urlAsString, encoding );
//------------------------------------------------------------------------------
// IMGタグ内に含まれるURL(絶対PATHにしてユニークにしたもの)を取り出す
//------------------------------------------------------------------------------
java.util.Set urlSet = ImageURLObtainer.getUniqueURLs( urlAsString , resBody );
//-------------------------------------------------------
// IMGのURLだけコンテンツダウンロードする(複数スレッドで同時実行)
//-------------------------------------------------------
ImageDownloadManager.download( urlSet );
} catch ( Exception e ) {
e.printStackTrace();
}
end = System.currentTimeMillis();
elapsedTime = ( end - start ) ;
System.out.println( "\n経過時間: " + elapsedTime + " msec" );
}
/**
* レスポンスボディを返す
*/
public String getResponseBodyAsString() {
return resBody;
}
public static void main( String[] args ) {
if ( args.length != 2 ) {
System.out.println( "Usage: java -cp . WebClientEmulator [url] [encoding]" );
System.exit( 1 );
}
/******************************************************************************/
/* 接続タイムアウトの設定; 設定された時間でコネクトできない場合はタイムアウト */
/******************************************************************************/
System.setProperty ( "sun.net.client.defaultConnectTimeout", "10000" );
/**********************************************************************************/
/* 読み取りタイムアウトの設定; 設定された時間で読み取りできない場合はタイムアウト */
/**********************************************************************************/
System.setProperty ( "sun.net.client.defaultReadTimeout", "10000" );
String urlAsString = args[ 0 ];
String encoding = args[ 1 ];
WebClientEmulator browser = new WebClientEmulator( urlAsString, encoding );
}
}