/*
 * $Id: IPAddressRangeSet.java,v 1.3 2006/01/26 16:27:35 rampil Exp $
 * Copyright (c) 2005 LOGICAL-PARADOX.ORG
 */
package org.logical_paradox.common.net;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.Iterator;

/**
 * IPAddressRangeSet
 * IPアドレス範囲のセットを管理するクラス
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.3 $
 */
public abstract class IPAddressRangeSet {
	/** IPアドレス範囲セットの辞書 */
	protected final HashSet<IPAddress> dic = new HashSet<IPAddress>();

	/**
	 * コンストラクタ
	 */
	public IPAddressRangeSet() {
	}
	/**
	 * コンストラクタ
	 * @param filename IPアドレス範囲セットファイル名
	 * @throws IOException 範囲セットデータのロードに失敗
	 */
	public IPAddressRangeSet(String filename) throws IOException {
		load(filename);
	}
	/**
	 * コンストラクタ
	 * @param in IPアドレス範囲セットデータへの入力ストリーム
	 * @throws IOException 読み込みに失敗
	 */
	public IPAddressRangeSet(InputStream in) throws IOException {
		load(in);
	}

	/**
	 * IPアドレス範囲の一覧をファイルなどからロードする
	 * @param ranges 範囲データ
	 */
	public void setRanges(String[] ranges) throws UnknownHostException {
		for(int i = 0; i < ranges.length; i++) {
			dic.add(getIPAddress(ranges[i].trim()));
		}
	}
	/**
	 * IPアドレス範囲セットをロードする
	 * @param filename IPアドレス範囲セットファイル名
	 * @throws IOException ロードに失敗した
	 */
	public void load(String filename) throws IOException {
		load(new FileInputStream(filename));
	}
	/**
	 * 指定された入力ストリームからIPアドレス範囲セットを取り込む
	 * @param in 入力ストリーム
	 * @throws IOException 入力ストリームからの取り込みに失敗
	 */
	public void load(InputStream in) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(in));

		String line = null;
		try {
			while((line = br.readLine()) != null) {
				dic.add(getIPAddress(line));
			}
		} catch(UnknownHostException ue) {
			throw new IOException(ue.getMessage());
		}
		br.close();
	}

	/**
	 * IPアドレスを作成する(何のクラスを作成するかはサブクラスで実装
	 * @param ips IPアドレス(文字列)
	 * @return IPv4またはIPv6クラス
	 */
	protected abstract IPAddress getIPAddress(String ips) throws UnknownHostException;

	/**
	 * 指定されたIPアドレスに該当するIPアドレス範囲レコードが存在するかどうかを調べる
	 * @param ipa IPアドレス
	 * @return true:含まれている / false:含まれていない
	 */
	public boolean includes(InetAddress ipa) {
		Iterator it = dic.iterator();
		while(it.hasNext()) {
			IPAddress range = (IPAddress)it.next();
			if(range.includes(ipa)) {
				return true;		// あった
			}
		}

		return false;
	}
}

// end of IPAddressRangeSet.java
