/*
 * blanco Framework
 * Copyright (C) 2004-2006 IGA Tosiki
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */
package blanco.valueobjectfactory.task;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;

import javax.xml.transform.TransformerException;

import blanco.resourcebundle.BlancoResourceBundleMeta2Xml;
import blanco.valueobject.BlancoValueObjectMeta2Xml;
import blanco.valueobjectfactory.BlancoValueObjectFactoryConstants;
import blanco.valueobjectfactory.BlancoValueObjectFactoryMeta2Xml;
import blanco.valueobjectfactory.BlancoValueObjectFactoryXml2SourceFile;
import blanco.valueobjectfactory.resourcebundle.BlancoValueObjectFactoryResourceBundle;

/**
 * 「バリューオブジェクトファクトリ定義書」Excel様式から バリューオブジェクトのためのファクトリクラス・ソースコードを生成するためのAntタスク。
 * 
 * このクラスは、Apache Antタスクを実装します。
 * 
 * @author IGA Tosiki
 */
public class BlancoValueObjectFactoryTask extends
        AbstractBlancoValueObjectFactoryTask {
    /**
     * このプロダクトのリソースバンドルへのアクセスオブジェクト。
     */
    private final BlancoValueObjectFactoryResourceBundle fBundle = new BlancoValueObjectFactoryResourceBundle();

    /**
     * 定義書(XLS)からソースコードを自動生成するApache Antタスクのエントリポイントです。
     */
    protected void process() throws IllegalArgumentException {
        System.out.println("- "
                + BlancoValueObjectFactoryConstants.PRODUCT_NAME + " ("
                + BlancoValueObjectFactoryConstants.VERSION + ")");

        try {
            final File fileMetadir = new File(getMetadir());
            if (fileMetadir.exists() == false) {
                throw new IllegalArgumentException(fBundle
                        .getAnttaskErr001(getMetadir()));
            }

            // テンポラリディレクトリを作成。
            new File(getTmpdir()
                    + BlancoValueObjectFactoryConstants.TARGET_SUBDIRECTORY)
                    .mkdirs();

            final HashMap valueObjectMap = new HashMap();
            final HashMap resourceBundleMap = new HashMap();

            {
                // 処理の過程で必要となるValueObjectクラスのテンポラリ。
                new File(getTmpdir()
                        + BlancoValueObjectFactoryConstants.TARGET_SUBDIRECTORY
                        + "/valueobject").mkdirs();

                // 先にバリューオブジェクト定義書を解析します。
                new BlancoValueObjectMeta2Xml()
                        .processDirectory(
                                fileMetadir,
                                getTmpdir()
                                        + BlancoValueObjectFactoryConstants.TARGET_SUBDIRECTORY
                                        + "/valueobject");

                // バリューオブジェクト定義書をメモリ展開
                // ハッシュに記憶しておく
                BlancoValueObjectFactoryXml2SourceFile
                        .processBlancoValueObjectXmlDirectory(
                                new File(
                                        getTmpdir()
                                                + BlancoValueObjectFactoryConstants.TARGET_SUBDIRECTORY
                                                + "/valueobject"),
                                valueObjectMap);
            }

            {
                // 処理の過程で必要となるResourceBundleクラスのテンポラリ。
                new File(getTmpdir()
                        + BlancoValueObjectFactoryConstants.TARGET_SUBDIRECTORY
                        + "/resourcebundle").mkdirs();

                // 先にリソースバンドル定義書を解析します。
                new BlancoResourceBundleMeta2Xml()
                        .processDirectory(
                                fileMetadir,
                                getTmpdir()
                                        + BlancoValueObjectFactoryConstants.TARGET_SUBDIRECTORY
                                        + "/resourcebundle");

                // リソースバンドル定義書をメモリ展開
                // ハッシュに記憶しておく
                BlancoValueObjectFactoryXml2SourceFile
                        .processBlancoResourceBundleXmlDirectory(
                                new File(
                                        getTmpdir()
                                                + BlancoValueObjectFactoryConstants.TARGET_SUBDIRECTORY
                                                + "/resourcebundle"),
                                resourceBundleMap);
            }

            // 指定されたメタディレクトリを処理します。
            new BlancoValueObjectFactoryMeta2Xml()
                    .processDirectory(
                            fileMetadir,
                            getTmpdir()
                                    + BlancoValueObjectFactoryConstants.TARGET_SUBDIRECTORY);

            // XML化された中間ファイルからソースコードを生成
            final File[] fileMeta2 = new File(getTmpdir()
                    + BlancoValueObjectFactoryConstants.TARGET_SUBDIRECTORY)
                    .listFiles();
            for (int index = 0; index < fileMeta2.length; index++) {
                if (fileMeta2[index].getName().endsWith(".xml") == false) {
                    continue;
                }

                new BlancoValueObjectFactoryXml2SourceFile().process(
                        fileMeta2[index], valueObjectMap, resourceBundleMap,
                        new File(getTargetdir()));
            }
        } catch (IOException ex) {
            throw new IllegalArgumentException(ex.toString());
        } catch (TransformerException ex) {
            throw new IllegalArgumentException(ex.toString());
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
            throw ex;
        }
    }
}
