/*
 * Copyright (c) 2007 NTT DATA Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package jp.terasoluna.batch.functionsample.sample005;

import jp.terasoluna.fw.batch.core.AbstractCollector;
import jp.terasoluna.fw.batch.core.CollectedDataHandler;
import jp.terasoluna.fw.batch.core.CollectorResult;
import jp.terasoluna.fw.batch.core.JobStatus;
import jp.terasoluna.fw.batch.openapi.JobContext;
import jp.terasoluna.fw.batch.openapi.ReturnCode;
import jp.terasoluna.fw.file.dao.FileException;
import jp.terasoluna.fw.file.dao.FileLineIterator;
import jp.terasoluna.fw.file.dao.FileQueryDAO;
import jp.terasoluna.batch.functionsample.common.ZandakaData;

/**
 * ファイルコレクタークラス。
 * ２つの入力ファイルを「顧客コード」でマージする。
 */
public class Sample005FileCollector extends AbstractCollector {

    /**
     * ファイルアクセス用DAO。
     * Springによりインスタンス生成され設定される。
     */
    private FileQueryDAO fileDao = null;

    /**
     * 結果クラス。
     * Springによりインスタンス生成され設定される。
     */
    private Object resultClass = null;

    /**
     * ファイル名1。
     * Springによりインスタンス生成され設定される。
     */
    private String fileName1 = null;
    
    /**
     * ファイル名2。
     * Springによりインスタンス生成され設定される。
     */
    private String fileName2 = null;
    
         
    @Override
    protected CollectorResult doCollect(JobContext jobContext,
        CollectedDataHandler handler, JobStatus jobStatus) {
    
        // 処理済行のカウント
        int collected = 0;

        //ファイル行オブジェクトを保持するイテレータを取得する
        FileLineIterator fileLineIterator = fileDao.execute(fileName1,
            resultClass.getClass());

        FileLineIterator fileLineIterator2 = fileDao.execute(fileName2,
            resultClass.getClass());
       
        
        try {
            
            ZandakaData zandaka1 = new ZandakaData();
            ZandakaData zandaka2 = new ZandakaData();

            if(fileLineIterator.hasNext()){
        	zandaka1 = (ZandakaData)fileLineIterator.next();
            }
            
            if(fileLineIterator2.hasNext()){
        	zandaka2 = (ZandakaData)fileLineIterator2.next();
            }
            
            //マージ    
            while (fileLineIterator.hasNext() 
        	    && fileLineIterator2.hasNext()) {
     
                ZandakaData mergeZandaka = new ZandakaData();
                
        	//顧客コードを辞書的に比較する
        	int compareTo = zandaka1.getKokyakucd().compareTo(
        		zandaka2.getKokyakucd());
        	
        	//顧客コードが等しい
        	if(compareTo == 0){

        	    //残高を足す
        	    mergeZandaka.setKokyakucd(zandaka1.getKokyakucd());
        	    mergeZandaka.setZandaka(zandaka1.getZandaka() 
        		    + zandaka2.getZandaka());
        	    zandaka1 = (ZandakaData)fileLineIterator.next();
        	    zandaka2 = (ZandakaData)fileLineIterator2.next();

        	//1つめの顧客コードが2つめより小さい
        	}else if(compareTo < 0){
        	    mergeZandaka = zandaka1;
        	    zandaka1 = (ZandakaData)fileLineIterator.next();

        	//1つめの顧客コードが2つめより大きい
        	}else{
        	    mergeZandaka = zandaka2;
        	    zandaka2 = (ZandakaData)fileLineIterator2.next();
        	}
        	
        	handler.handle(mergeZandaka, collected++);
        	jobStatus.incrementCollected();

            }

            //残データの処理
            while(fileLineIterator.hasNext()){
        	zandaka1 = (ZandakaData)fileLineIterator.next();
        	handler.handle(zandaka1, collected++);
        	jobStatus.incrementCollected();
            }
            while(fileLineIterator2.hasNext()){
        	zandaka2 = (ZandakaData)fileLineIterator2.next();
        	handler.handle(zandaka2, collected++);
        	jobStatus.incrementCollected();
            }
            
            //コレクター結果オブジェクトを返却する
            CollectorResult result 
            	= new CollectorResult(ReturnCode.NORMAL_END, collected);
            return result;
            
        } catch (FileException e) {
            throw e;
        } finally {
            fileLineIterator.closeFile();
            fileLineIterator2.closeFile();
        }
    }

    /**
     * FileQueryDAOを設定する。
     * @param fileDao FileQueryDAO
     */
    public void setFileDao(FileQueryDAO fileDao) {
        this.fileDao = fileDao;
    }

    /**
     * ファイル名1を設定する。
     * @param fileName1 ファイル名
     */
    public void setFileName1(String fileName1) {
        this.fileName1 = fileName1;
    }

    /**
     * ファイル名2を設定する。
     * @param fileName2 ファイル名
     */
    public void setFileName2(String fileName2) {
        this.fileName2 = fileName2;
    }

    /**
     * 結果クラスを設定する。
     * @param resultClass 結果クラス
     */
    public void setResultClass(Object resultClass) {
        this.resultClass = resultClass;
    }

}
