package org.itscool.commons.dao;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import org.itscool.commons.bean.BeanUtil;

/**
 * RecordMapクラスはFieldMapインスタンスを管理するクラスです<BR>
 * このクラスはJavaBeanとテーブル情報の関連をFieldMapインスタンスの配列
 * で管理しています。
 * @author KANO
 * @since jdk1.4.1
 * @version 1.00A 2004/11/1
 */
//public class RecordMap implements Cloneable {
public class RecordMap {
    /**
     * JavaBeansのクラス名
     */
    private String className;
    /**
     * JavaBeansに対応するテーブル名
     */
    private String tableName;
    /**
     * JavaBeansのプロパティに対応したフィールド情報のリスト
     * キー：テーブル名.フィールド名で保持します
     */
    private HashMap fields = new HashMap();
    
    /**
     * RecordMapインスタンスの登録内容を取得します
     * @return String RecordMapインスタンスの登録内容を返します
     */
    public String toString(){
        String line = System.getProperty("line.separator");
        String tab = "  ";
        
        StringBuffer sb = new StringBuffer();
        sb.append("TABLE[").append(tableName).append("] ");
        sb.append("CLASS[").append(className).append("] ");
        sb.append(line);
        Set keySet = fields.keySet();
        Iterator it = keySet.iterator();
        while(it.hasNext()){
            String key = (String)it.next();
            FieldMap fieldMap = (FieldMap)fields.get(key);
            sb.append(tab).append("KEY[").append(key).append("] ");
            sb.append("COLUM[").append(fieldMap.getColumName()).append("] ");
            sb.append("PROPERTY[").append(fieldMap.getPropertyName()).append("] ");
            sb.append(line);
        }
        return sb.toString();
    }
    
    /**
     * 指定されたクラス名とテーブル名でRecordMapインスタンス
     * を初期化します
     * @param className クラス名
     * @param tableName テーブル名
     */
    public RecordMap(String className, String tableName){
        this.tableName = tableName;
        this.className = className;
    }
    
    /**
     * パッケージ名付のクラスからクラス名のみを取得します
     * @return パッケージ名付のクラスからクラス名のみ取得します
     */
    public String getClassOnlyName(){
        int classOnlyNameIndex = className.lastIndexOf(".") + 1;
        String classOnlyName = className.substring(classOnlyNameIndex, className.length());
        return classOnlyName;
    }
    
    /**
     * このクラスにセットされたJavaBeansのクラス名を取得します
     * @return クラス名
     */
    public String getClassName(){
        return className;
    }
    
    /**
     * RecordMapインスタンスのクラス名をセットします
     * @param className このテーブルに関連するクラス名
     */
    public void setClassName(String className){
        this.className = className;
    }
    
    /**
     * このクラスにセットされたテーブル名を取得します
     * @return テーブル名
     */
    public String getTableName(){
        return tableName;
    }
    
    /**
     * FieldMapインスタンスを追加します
     * @param field FieldMapインスタンス
     */
    public void addField(FieldMap field){
        //fields.add(field);
        fields.put(tableName + "." + field.getColumName(), field);
        //fields.put(field.getPropertyName(), field);
    }
    
    /**
     * このクラスに登録されている全てのFieldMapインスタンスを取得します
     * @return このクラスに登録されている全てのFieldMapインスタンスを
     * 返却します
     */
    public HashMap getFields(){
        return fields;
    }
    
    /**
     * このクラスに登録されているFieldMapインスタンスを"テーブル名.フィールド名"
     * で指定したコードから取得します
     * @return "テーブル名.フィールド名"で指定したFieldMapインスタンスを返します
     */
    public FieldMap getField(String tableDotFieldName){
        FieldMap field = (FieldMap)fields.get(tableDotFieldName.toUpperCase());
        return field;
    }
    
    /**
     * 引数に指定したカラム名からフィールド情報を取得します
     * @param argFieldName テーブルのカラム名
     * @return FieldMap フィールド情報を返します
     */
    public FieldMap getFieldByFieldName(String argFieldName){
        String fieldName = argFieldName.toUpperCase();
        Set keySet = fields.keySet();
        Iterator it = keySet.iterator();
        while(it.hasNext()){
            String key = (String)it.next();
            FieldMap fieldMap = (FieldMap)fields.get(key);
            if(fieldMap.getColumName().equals(fieldName)){
                return fieldMap;
            }
        }
        return null;
    }
    
    
    /**
     * 引数に指定したプロパティ名からフィールド情報を取得します
     * @param argFieldName テーブルのカラム名
     * @return FieldMap フィールド情報を返します
     */
    public FieldMap getFieldByPropertyName(String propertyName){
        Set keySet = fields.keySet();
        Iterator it = keySet.iterator();
        while(it.hasNext()){
            String key = (String)it.next();
            FieldMap fieldMap = (FieldMap)fields.get(key);
            if(fieldMap.getPropertyName().equals(propertyName)){
                return fieldMap;
            }
        }
        return null;
    }
    
    /**
     * RecordMapインスタンスにテーブル名をセットします
     * @param tableName テーブル名
     */
    public void setTableName(String tableName) {
        this.tableName = tableName;
    }
    
    public static boolean isEquals(Object obj1, Object obj2, RecordMap recordMap){
        HashMap fieldMap = recordMap.getFields();
        Set keySet = fieldMap.keySet();
        Iterator it = keySet.iterator();
        while(it.hasNext()){
            Object key = it.next();
            FieldMap field = (FieldMap)fieldMap.get(key);
            if( !field.isPrimaryKey() ){
                continue;
            }
            String propertyName = field.getPropertyName();
            Object property1 = BeanUtil.getProperty(obj1, propertyName);
            Object property2 = BeanUtil.getProperty(obj2, propertyName);
            if( !property1.equals(property2) ){
                return false;
            }
        }
        return true;
    }
}
