net.massbank.validator.RecordValidator.java Source code

Java tutorial

Introduction

Here is the source code for net.massbank.validator.RecordValidator.java

Source

package net.massbank.validator;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.logging.Logger;
import java.util.Map;
import java.util.TreeMap;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import massbank.MassBankEnv;
import massbank.admin.DatabaseAccess;
import massbank.admin.FileUtil;
import massbank.FileUpload;
import massbank.GetConfig;

import org.apache.commons.cli.*;

// <%@ include file="../jsp/Common.jsp"%>

public class RecordValidator {

    /**  */
    private final static SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd_HHmmss_SSS");

    /**  */
    private final static String NEW_LINE = System.getProperty("line.separator");

    /** ??ZIP */
    private final static String UPLOAD_RECDATA_ZIP = "recdata.zip";

    /** zip? */
    private final static String ZIP_EXTENSION = ".zip";

    /** ??MSBK */
    private final static String UPLOAD_RECDATA_MSBK = "*.msbk";

    /** msbk? */
    private final static String MSBK_EXTENSION = ".msbk";

    /** ?? */
    private final static String RECDATA_DIR_NAME = "recdata";

    /** ? */
    private final static String REC_EXTENSION = ".txt";

    /**  */
    private final static String DEFAULT_VALUE = "N/A";

    /** OK */
    private final static String STATUS_OK = "ok";

    /**  */
    private final static String STATUS_WARN = "warn";

    /**  */
    private final static String STATUS_ERR = "error";

    /**
     * HTML
     * 
     * @param msg
     *            
     * @return 
     */
    private static String msgInfo(String msg) {
        StringBuilder sb = new StringBuilder("<i>info</i> : <span class=\"msgFont\">");
        sb.append(msg);
        sb.append("</span><br>");
        return sb.toString();
    }

    /**
     * HTML
     * 
     * @param msg
     *            
     * @return 
     */
    private static String msgWarn(String msg) {
        StringBuilder sb = new StringBuilder("<i>warn</i> : ");
        sb.append(msg);
        sb.append("</span><br>");
        return sb.toString();
    }

    /**
     * HTML
     * 
     * @param msg
     *            
     * @return 
     */
    private static String msgErr(String msg) {
        StringBuilder sb = new StringBuilder("<i>error</i> : ");
        sb.append(msg);
        sb.append("</span><br>");
        return sb.toString();
    }

    /**
     * ??
     * 
     * @param db
     *            DB
     * @param op
     *            PrintWriter?
     * @param dataPath
     *            ?
     * @param registPath
     *            
     * @param ver
     *            ?
     * @return ??Map<??, ?>
     * @throws IOException
     *             
     */
    private static TreeMap<String, String> validationRecord(DatabaseAccess dbx, PrintStream op, String dataPath,
            String registPath, int ver) throws IOException {

        if (ver == 1) {
            op.println(msgInfo("check record format version is [version 1]."));
        }

        final String[] dataList = (new File(dataPath)).list();
        TreeMap<String, String> validationMap = new TreeMap<String, String>();

        if (dataList.length == 0) {
            op.println(msgWarn("no file for validation."));
            return validationMap;
        }

        // ----------------------------------------------------
        // ???
        // ----------------------------------------------------
        String[] requiredList = new String[] { // Ver.2
                "ACCESSION: ", "RECORD_TITLE: ", "DATE: ", "AUTHORS: ", "LICENSE: ", "CH$NAME: ",
                "CH$COMPOUND_CLASS: ", "CH$FORMULA: ", "CH$EXACT_MASS: ", "CH$SMILES: ", "CH$IUPAC: ",
                "AC$INSTRUMENT: ", "AC$INSTRUMENT_TYPE: ", "AC$MASS_SPECTROMETRY: MS_TYPE ",
                "AC$MASS_SPECTROMETRY: ION_MODE ", "PK$NUM_PEAK: ", "PK$PEAK: " };
        if (ver == 1) { // Ver.1
            requiredList = new String[] { "ACCESSION: ", "RECORD_TITLE: ", "DATE: ", "AUTHORS: ", "COPYRIGHT: ",
                    "CH$NAME: ", "CH$COMPOUND_CLASS: ", "CH$FORMULA: ", "CH$EXACT_MASS: ", "CH$SMILES: ",
                    "CH$IUPAC: ", "AC$INSTRUMENT: ", "AC$INSTRUMENT_TYPE: ", "AC$ANALYTICAL_CONDITION: MODE ",
                    "PK$NUM_PEAK: ", "PK$PEAK: " };
        }
        for (int i = 0; i < dataList.length; i++) {
            String name = dataList[i];
            String status = "";
            StringBuilder detailsErr = new StringBuilder();
            StringBuilder detailsWarn = new StringBuilder();

            // ????
            File file = new File(dataPath + name);
            if (file.isDirectory()) {
                // ??
                status = STATUS_ERR;
                detailsErr.append("[" + name + "] is directory.");
                validationMap.put(name, status + "\t" + detailsErr.toString());
                continue;
            } else if (file.isHidden()) {
                // ???
                status = STATUS_ERR;
                detailsErr.append("[" + name + "] is hidden.");
                validationMap.put(name, status + "\t" + detailsErr.toString());
                continue;
            } else if (name.lastIndexOf(REC_EXTENSION) == -1) {
                // ????
                status = STATUS_ERR;
                detailsErr.append("file extension of [" + name + "] is not [" + REC_EXTENSION + "].");
                validationMap.put(name, status + "\t" + detailsErr.toString());
                continue;
            }

            // ??
            boolean isEndTagRead = false;
            boolean isInvalidInfo = false;
            boolean isDoubleByte = false;
            ArrayList<String> fileContents = new ArrayList<String>();
            boolean existLicense = false; // LICENSE?Ver.1
            ArrayList<String> workChName = new ArrayList<String>(); // RECORD_TITLE??CH$NAME??Ver.1?
            String workAcInstrumentType = ""; // RECORD_TITLE??AC$INSTRUMENT_TYPE??Ver.1?
            String workAcMsType = ""; // RECORD_TITLE??AC$MASS_SPECTROMETRY:
            // MS_TYPE??Ver.2
            String line = "";
            BufferedReader br = null;
            try {
                br = new BufferedReader(new FileReader(file));
                while ((line = br.readLine()) != null) {
                    if (isEndTagRead) {
                        if (!line.equals("")) {
                            isInvalidInfo = true;
                        }
                    }

                    // 
                    if (line.startsWith("//")) {
                        isEndTagRead = true;
                    }
                    fileContents.add(line);

                    // LICENSE?Ver.1
                    if (line.startsWith("LICENSE: ")) {
                        existLicense = true;
                    }
                    // CH$NAME?Ver.1?
                    else if (line.startsWith("CH$NAME: ")) {
                        workChName.add(line.trim().replaceAll("CH\\$NAME: ", ""));
                    }
                    // AC$INSTRUMENT_TYPE?Ver.1?
                    else if (line.startsWith("AC$INSTRUMENT_TYPE: ")) {
                        workAcInstrumentType = line.trim().replaceAll("AC\\$INSTRUMENT_TYPE: ", "");
                    }
                    // AC$MASS_SPECTROMETRY: MS_TYPE?Ver.2
                    else if (ver != 1 && line.startsWith("AC$MASS_SPECTROMETRY: MS_TYPE ")) {
                        workAcMsType = line.trim().replaceAll("AC\\$MASS_SPECTROMETRY: MS_TYPE ", "");
                    }

                    // ?
                    if (!isDoubleByte) {
                        byte[] bytes = line.getBytes("MS932");
                        if (bytes.length != line.length()) {
                            isDoubleByte = true;
                        }
                    }
                }
            } catch (IOException e) {
                Logger.getLogger("global").severe("file read failed." + NEW_LINE + "    " + file.getPath());
                e.printStackTrace();
                op.println(msgErr("server error."));
                validationMap.clear();
                return validationMap;
            } finally {
                try {
                    if (br != null) {
                        br.close();
                    }
                } catch (IOException e) {
                }
            }
            if (isInvalidInfo) {
                // ?????
                if (status.equals(""))
                    status = STATUS_WARN;
                detailsWarn.append("invalid after the end tag [//].");
            }
            if (isDoubleByte) {
                // ?????
                if (status.equals(""))
                    status = STATUS_ERR;
                detailsErr.append("double-byte character included.");
            }
            if (ver == 1 && existLicense) {
                // LICENSE???Ver.1
                if (status.equals(""))
                    status = STATUS_ERR;
                detailsErr.append("[LICENSE: ] tag can not be used in record format  [version 1].");
            }

            // ----------------------------------------------------
            // ????
            // ----------------------------------------------------
            boolean isNameCheck = false;
            int peakNum = -1;
            for (int j = 0; j < requiredList.length; j++) {
                String requiredStr = requiredList[j];
                ArrayList<String> valStrs = new ArrayList<String>(); // 
                boolean findRequired = false; // 
                boolean findValue = false; // 
                boolean isPeakMode = false; // 
                for (int k = 0; k < fileContents.size(); k++) {
                    String lineStr = fileContents.get(k);

                    // ????RELATED_RECORD??????
                    if (lineStr.startsWith("//")) { // Ver.1?
                        break;
                    } else if (ver == 1 && lineStr.startsWith("RELATED_RECORD:")) { // Ver.1
                        break;
                    }
                    // ?????
                    else if (isPeakMode) {
                        findRequired = true;
                        if (!lineStr.trim().equals("")) {
                            valStrs.add(lineStr);
                        }
                    }
                    // ??????
                    else if (lineStr.indexOf(requiredStr) != -1) {
                        // 
                        findRequired = true;
                        if (requiredStr.equals("PK$PEAK: ")) {
                            isPeakMode = true;
                            findValue = true;
                            valStrs.add(lineStr.replace(requiredStr, ""));
                        } else {
                            // 
                            String tmpVal = lineStr.replace(requiredStr, "");
                            if (!tmpVal.trim().equals("")) {
                                findValue = true;
                                valStrs.add(tmpVal);
                            }
                            break;
                        }
                    }
                }
                if (!findRequired) {
                    // ??????
                    status = STATUS_ERR;
                    detailsErr.append("no required item [" + requiredStr + "].");
                } else {
                    if (!findValue) {
                        // ?????
                        status = STATUS_ERR;
                        detailsErr.append("no value of required item [" + requiredStr + "].");
                    } else {
                        // ???

                        // ----------------------------------------------------
                        // ??
                        // ----------------------------------------------------
                        String val = (valStrs.size() > 0) ? valStrs.get(0) : "";
                        // ACESSIONVer.1?
                        if (requiredStr.equals("ACCESSION: ")) {
                            if (!val.equals(name.replace(REC_EXTENSION, ""))) {
                                status = STATUS_ERR;
                                detailsErr.append("value of required item [" + requiredStr
                                        + "] not correspond to file name.");
                            }
                            if (val.length() != 8) {
                                status = STATUS_ERR;
                                detailsErr.append(
                                        "value of required item [" + requiredStr + "] is 8 digits necessary.");
                            }
                        }
                        // RECORD_TITLEVer.1?
                        else if (requiredStr.equals("RECORD_TITLE: ")) {
                            if (!val.equals(DEFAULT_VALUE)) {
                                if (val.indexOf(";") != -1) {
                                    String[] recTitle = val.split(";");
                                    if (!workChName.contains(recTitle[0].trim())) {
                                        if (status.equals(""))
                                            status = STATUS_WARN;
                                        detailsWarn.append("value of required item [" + requiredStr
                                                + "], compound name is not included in the [CH$NAME].");
                                    }
                                    if (!workAcInstrumentType.equals(recTitle[1].trim())) {
                                        if (status.equals(""))
                                            status = STATUS_WARN;
                                        detailsWarn.append("value of required item [" + requiredStr
                                                + "], instrument type is different from [AC$INSTRUMENT_TYPE].");
                                    }
                                    if (ver != 1 && !workAcMsType.equals(recTitle[2].trim())) { // Ver.2
                                        if (status.equals(""))
                                            status = STATUS_WARN;
                                        detailsWarn.append("value of required item [" + requiredStr
                                                + "], ms type is different from [AC$MASS_SPECTROMETRY: MS_TYPE].");
                                    }
                                } else {
                                    if (status.equals(""))
                                        status = STATUS_WARN;
                                    detailsWarn.append("value of required item [" + requiredStr
                                            + "] is not record title format.");

                                    if (!workChName.contains(val)) {
                                        detailsWarn.append("value of required item [" + requiredStr
                                                + "], compound name is not included in the [CH$NAME].");
                                    }
                                    if (!workAcInstrumentType.equals(DEFAULT_VALUE)) {
                                        detailsWarn.append("value of required item [" + requiredStr
                                                + "], instrument type is different from [AC$INSTRUMENT_TYPE].");
                                    }
                                    if (ver != 1 && !workAcMsType.equals(DEFAULT_VALUE)) { // Ver.2
                                        detailsWarn.append("value of required item [" + requiredStr
                                                + "], ms type is different from [AC$MASS_SPECTROMETRY: MS_TYPE].");
                                    }
                                }
                            } else {
                                if (!workAcInstrumentType.equals(DEFAULT_VALUE)) {
                                    if (status.equals(""))
                                        status = STATUS_WARN;
                                    detailsWarn.append("value of required item [" + requiredStr
                                            + "], instrument type is different from [AC$INSTRUMENT_TYPE].");
                                }
                                if (ver != 1 && !workAcMsType.equals(DEFAULT_VALUE)) { // Ver.2
                                    if (status.equals(""))
                                        status = STATUS_WARN;
                                    detailsWarn.append("value of required item [" + requiredStr
                                            + "], ms type is different from [AC$MASS_SPECTROMETRY: MS_TYPE].");
                                }
                            }
                        }
                        // DATEVer.1?
                        else if (requiredStr.equals("DATE: ") && !val.equals(DEFAULT_VALUE)) {
                            val = val.replace(".", "/");
                            val = val.replace("-", "/");
                            try {
                                DateFormat.getDateInstance(DateFormat.SHORT, Locale.JAPAN).parse(val);
                            } catch (ParseException e) {
                                if (status.equals(""))
                                    status = STATUS_WARN;
                                detailsWarn
                                        .append("value of required item [" + requiredStr + "] is not date format.");
                            }
                        }
                        // CH$COMPOUND_CLASSVer.1?
                        else if (requiredStr.equals("CH$COMPOUND_CLASS: ") && !val.equals(DEFAULT_VALUE)) {
                            if (!val.startsWith("Natural Product") && !val.startsWith("Non-Natural Product")) {

                                if (status.equals(""))
                                    status = STATUS_WARN;
                                detailsWarn.append("value of required item [" + requiredStr
                                        + "] is not compound class format.");
                            }
                        }
                        // CH$EXACT_MASSVer.1?
                        else if (requiredStr.equals("CH$EXACT_MASS: ") && !val.equals(DEFAULT_VALUE)) {
                            try {
                                Double.parseDouble(val);
                            } catch (NumberFormatException e) {
                                if (status.equals(""))
                                    status = STATUS_WARN;
                                detailsWarn.append("value of required item [" + requiredStr + "] is not numeric.");
                            }
                        }
                        // AC$INSTRUMENT_TYPEVer.1?
                        else if (requiredStr.equals("AC$INSTRUMENT_TYPE: ") && !val.equals(DEFAULT_VALUE)) {
                            if (val.trim().indexOf(" ") != -1) {
                                if (status.equals(""))
                                    status = STATUS_WARN;
                                detailsWarn
                                        .append("value of required item [" + requiredStr + "] is space included.");
                            }
                            if (val.trim().indexOf(" ") != -1) {
                                if (status.equals(""))
                                    status = STATUS_WARN;
                                detailsWarn
                                        .append("value of required item [" + requiredStr + "] is space included.");
                            }
                        }
                        // AC$MASS_SPECTROMETRY: MS_TYPEVer.2
                        else if (ver != 1 && requiredStr.equals("AC$MASS_SPECTROMETRY: MS_TYPE ")
                                && !val.equals(DEFAULT_VALUE)) {
                            boolean isMsType = true;
                            if (val.startsWith("MS")) {
                                val = val.replace("MS", "");
                                if (!val.equals("")) {
                                    try {
                                        Integer.parseInt(val);
                                    } catch (NumberFormatException e) {
                                        isMsType = false;
                                    }
                                }
                            } else {
                                isMsType = false;
                            }
                            if (!isMsType) {
                                if (status.equals(""))
                                    status = STATUS_WARN;
                                detailsWarn.append("value of required item [" + requiredStr + "] is not \"MSn\".");
                            }
                        }
                        // AC$MASS_SPECTROMETRY:
                        // ION_MODEVer.2?AC$ANALYTICAL_CONDITION: MODEVer.1
                        else if ((ver != 1 && requiredStr.equals("AC$MASS_SPECTROMETRY: ION_MODE ")
                                && !val.equals(DEFAULT_VALUE))
                                || (ver == 1 && requiredStr.equals("AC$ANALYTICAL_CONDITION: MODE ")
                                        && !val.equals(DEFAULT_VALUE))) {
                            if (!val.equals("POSITIVE") && !val.equals("NEGATIVE")) {
                                if (status.equals(""))
                                    status = STATUS_WARN;
                                detailsWarn.append("value of required item [" + requiredStr
                                        + "] is not \"POSITIVE\" or \"NEGATIVE\".");
                            }
                        }
                        // PK$NUM_PEAKVer.1?
                        else if (requiredStr.equals("PK$NUM_PEAK: ") && !val.equals(DEFAULT_VALUE)) {
                            try {
                                peakNum = Integer.parseInt(val);
                            } catch (NumberFormatException e) {
                                status = STATUS_ERR;
                                detailsErr.append("value of required item [" + requiredStr + "] is not numeric.");
                            }
                        }
                        // PK$PEAK:Ver.1?
                        else if (requiredStr.equals("PK$PEAK: ")) {
                            if (valStrs.size() == 0 || !valStrs.get(0).startsWith("m/z int. rel.int.")) {
                                status = STATUS_ERR;
                                detailsErr.append(
                                        "value of required item [PK$PEAK: ] , the first line is not \"PK$PEAK: m/z int. rel.int.\".");
                            } else {
                                boolean isNa = false;
                                String peak = "";
                                String mz = "";
                                String intensity = "";
                                boolean mzDuplication = false;
                                boolean mzNotNumeric = false;
                                boolean intensityNotNumeric = false;
                                boolean invalidFormat = false;
                                HashSet<String> mzSet = new HashSet<String>();
                                for (int l = 0; l < valStrs.size(); l++) {
                                    peak = valStrs.get(l).trim();
                                    // N/A
                                    if (peak.indexOf(DEFAULT_VALUE) != -1) {
                                        isNa = true;
                                        break;
                                    }
                                    if (l == 0) {
                                        continue;
                                    } // m/z int. rel.int.??????????

                                    if (peak.indexOf(" ") != -1) {
                                        mz = peak.split(" ")[0];
                                        if (!mzSet.add(mz)) {
                                            mzDuplication = true;
                                        }
                                        try {
                                            Double.parseDouble(mz);
                                        } catch (NumberFormatException e) {
                                            mzNotNumeric = true;
                                        }
                                        intensity = peak.split(" ")[1];
                                        try {
                                            Double.parseDouble(intensity);
                                        } catch (NumberFormatException e) {
                                            intensityNotNumeric = true;
                                        }
                                    } else {
                                        invalidFormat = true;
                                    }
                                    if (mzDuplication && mzNotNumeric && intensityNotNumeric && invalidFormat) {
                                        break;
                                    }
                                }
                                if (isNa) {// PK$PEAK:?N/A??
                                    if (peakNum != -1) { // PK$NUM_PEAK:N/A??
                                        if (status.equals(""))
                                            status = STATUS_WARN;
                                        detailsWarn
                                                .append("value of required item [PK$NUM_PEAK: ] is mismatch or \""
                                                        + DEFAULT_VALUE + "\".");
                                    }
                                    if (valStrs.size() - 1 > 0) { // PK$PEAK:????????
                                        if (status.equals(""))
                                            status = STATUS_WARN;
                                        detailsWarn.append(
                                                "value of required item [PK$NUM_PEAK: ] is invalid peak information exists.");
                                    }
                                } else {
                                    if (mzDuplication) {
                                        status = STATUS_ERR;
                                        detailsErr.append(
                                                "mz value of required item [" + requiredStr + "] is duplication.");
                                    }
                                    if (mzNotNumeric) {
                                        status = STATUS_ERR;
                                        detailsErr.append(
                                                "mz value of required item [" + requiredStr + "] is not numeric.");
                                    }
                                    if (intensityNotNumeric) {
                                        status = STATUS_ERR;
                                        detailsErr.append("intensity value of required item [" + requiredStr
                                                + "] is not numeric.");
                                    }
                                    if (invalidFormat) {
                                        status = STATUS_ERR;
                                        detailsErr.append(
                                                "value of required item [" + requiredStr + "] is not peak format.");
                                    }
                                    if (peakNum != 0 && valStrs.size() - 1 == 0) { // ?????N/A????PK$NUM_PEAK:?0???????
                                        if (status.equals(""))
                                            status = STATUS_WARN;
                                        detailsWarn.append(
                                                "value of required item [PK$PEAK: ] is no value.  at that time, please add \""
                                                        + DEFAULT_VALUE + "\". ");
                                    }
                                    if (peakNum != valStrs.size() - 1) {
                                        if (status.equals(""))
                                            status = STATUS_WARN;
                                        detailsWarn
                                                .append("value of required item [PK$NUM_PEAK: ] is mismatch or \""
                                                        + DEFAULT_VALUE + "\".");
                                    }
                                }
                            }
                        }
                    }
                }
            }
            String details = detailsErr.toString() + detailsWarn.toString();
            if (status.equals("")) {
                status = STATUS_OK;
                details = " ";
            }
            validationMap.put(name, status + "\t" + details);
        }

        //      // ----------------------------------------------------
        //      // ????
        //      // ----------------------------------------------------
        //      // ?ID?DB
        //      HashSet<String> regIdList = new HashSet<String>();
        //      String[] sqls = { "SELECT ID FROM SPECTRUM ORDER BY ID",
        //            "SELECT ID FROM RECORD ORDER BY ID",
        //            "SELECT ID FROM PEAK GROUP BY ID ORDER BY ID",
        //            "SELECT ID FROM CH_NAME ID ORDER BY ID",
        //            "SELECT ID FROM CH_LINK ID ORDER BY ID",
        //            "SELECT ID FROM TREE WHERE ID IS NOT NULL AND ID<>'' ORDER BY ID" };
        //      for (int i = 0; i < sqls.length; i++) {
        //         String execSql = sqls[i];
        //         ResultSet rs = null;
        //         try {
        //            rs = db.executeQuery(execSql);
        //            while (rs.next()) {
        //               String idStr = rs.getString("ID");
        //               regIdList.add(idStr);
        //            }
        //         } catch (SQLException e) {
        //            Logger.getLogger("global").severe("    sql : " + execSql);
        //            e.printStackTrace();
        //            op.println(msgErr("database access error."));
        //            return new TreeMap<String, String>();
        //         } finally {
        //            try {
        //               if (rs != null) {
        //                  rs.close();
        //               }
        //            } catch (SQLException e) {
        //            }
        //         }
        //      }
        //      // ?ID?
        //      final String[] recFileList = (new File(registPath)).list();
        //      for (int i = 0; i < recFileList.length; i++) {
        //         String name = recFileList[i];
        //         File file = new File(registPath + File.separator + name);
        //         if (!file.isFile() || file.isHidden()
        //               || name.lastIndexOf(REC_EXTENSION) == -1) {
        //            continue;
        //         }
        //         String idStr = name.replace(REC_EXTENSION, "");
        //         regIdList.add(idStr);
        //      }

        //      // ??
        //      for (Map.Entry<String, String> e : validationMap.entrySet()) {
        //         String statusStr = e.getValue().split("\t")[0];
        //         if (statusStr.equals(STATUS_ERR)) {
        //            continue;
        //         }
        //         String nameStr = e.getKey();
        //         String idStr = e.getKey().replace(REC_EXTENSION, "");
        //         String detailsStr = e.getValue().split("\t")[1];
        //         if (regIdList.contains(idStr)) {
        //            statusStr = STATUS_WARN;
        //            detailsStr += "id ["
        //                  + idStr + "] of file name ["
        //                  + nameStr
        //                  + "] already registered.";
        //            validationMap.put(nameStr, statusStr + "\t" + detailsStr);
        //         }
        //      }

        return validationMap;
    }

    /**
     * ???
     * 
     * @param op
     *            PrintWriter?
     * @param resultMap
     *            ??
     * @return ?
     * @throws IOException
     */
    private static boolean dispResult(PrintStream op, TreeMap<String, String> resultMap) throws IOException {

        // ----------------------------------------------------
        // 
        // ----------------------------------------------------
        NumberFormat nf = NumberFormat.getNumberInstance();
        int okCnt = 0;
        int warnCnt = 0;
        int errCnt = 0;
        for (Map.Entry<String, String> e : resultMap.entrySet()) {
            String statusStr = e.getValue().split("\t")[0];
            if (statusStr.equals(STATUS_OK)) {
                okCnt++;
            } else if (statusStr.equals(STATUS_WARN)) {
                warnCnt++;
            } else if (statusStr.equals(STATUS_ERR)) {
                errCnt++;
            }
        }
        op.println(nf.format(okCnt) + " ok");
        op.println(nf.format(warnCnt) + " warn");
        op.println(nf.format(errCnt) + " error / " + nf.format(resultMap.size()) + " files");
        op.println("Status");
        op.println("Details");

        // ----------------------------------------------------
        // 
        // ----------------------------------------------------
        for (Map.Entry<String, String> e : resultMap.entrySet()) {
            String nameStr = e.getKey();
            String statusStr = e.getValue().split("\t")[0];
            String detailsStr = e.getValue().split("\t")[1].trim();
            op.println(nameStr + " ");
            op.println(statusStr + "");
            op.println(detailsStr + "");
        }

        return true;
    }

    public static void printHelp(Options lvOptions) {
        HelpFormatter lvFormater = new HelpFormatter();
        lvFormater.printHelp("Programm_Name", lvOptions);
    }

    public static void main(String[] args) {
        RequestDummy request;

        PrintStream out = System.out;

        Options lvOptions = new Options();
        lvOptions.addOption("h", "help", false, "show this help.");
        lvOptions.addOption("r", "recdata", true,
                "points to the recdata directory containing massbank records. Reads all *.txt files in there.");

        CommandLineParser lvParser = new BasicParser();
        CommandLine lvCmd = null;
        try {
            lvCmd = lvParser.parse(lvOptions, args);
            if (lvCmd.hasOption('h')) {
                printHelp(lvOptions);
                return;
            }
        } catch (org.apache.commons.cli.ParseException pvException) {
            System.out.println(pvException.getMessage());
        }

        String recDataPath = lvCmd.getOptionValue("recdata");

        // ---------------------------------------------
        // ????
        // ---------------------------------------------

        final String baseUrl = MassBankEnv.get(MassBankEnv.KEY_BASE_URL);
        final String dbRootPath = "./";
        final String dbHostName = MassBankEnv.get(MassBankEnv.KEY_DB_HOST_NAME);
        final String tomcatTmpPath = ".";
        final String tmpPath = (new File(tomcatTmpPath + sdf.format(new Date()))).getPath() + File.separator;
        GetConfig conf = new GetConfig(baseUrl);
        int recVersion = 2;
        String selDbName = "";
        Object up = null; // Was: file Upload
        boolean isResult = true;
        String upFileName = "";
        boolean upResult = false;
        DatabaseAccess db = null;

        try {
            // ----------------------------------------------------
            // ???
            // ----------------------------------------------------
            // if (FileUpload.isMultipartContent(request)) {
            // (new File(tmpPath)).mkdir();
            // String os = System.getProperty("os.name");
            // if (os.indexOf("Windows") == -1) {
            // isResult = FileUtil.changeMode("777", tmpPath);
            // if (!isResult) {
            // out.println(msgErr("[" + tmpPath
            // + "]  chmod failed."));
            // return;
            // }
            // }
            // up = new FileUpload(request, tmpPath);
            // }

            // ----------------------------------------------------
            // ?DB????
            // ----------------------------------------------------
            List<String> dbNameList = Arrays.asList(conf.getDbName());
            ArrayList<String> dbNames = new ArrayList<String>();
            dbNames.add("");
            File[] dbDirs = (new File(dbRootPath)).listFiles();
            if (dbDirs != null) {
                for (File dbDir : dbDirs) {
                    if (dbDir.isDirectory()) {
                        int pos = dbDir.getName().lastIndexOf("\\");
                        String dbDirName = dbDir.getName().substring(pos + 1);
                        pos = dbDirName.lastIndexOf("/");
                        dbDirName = dbDirName.substring(pos + 1);
                        if (dbNameList.contains(dbDirName)) {
                            // DB???massbank.conf???DB????
                            dbNames.add(dbDirName);
                        }
                    }
                }
            }
            if (dbDirs == null || dbNames.size() == 0) {
                out.println(msgErr("[" + dbRootPath + "] directory not exist."));
                return;
            }
            Collections.sort(dbNames);

            // ----------------------------------------------------
            // ?
            // ----------------------------------------------------
            // if (FileUpload.isMultipartContent(request)) {
            // HashMap<String, String[]> reqParamMap = new HashMap<String,
            // String[]>();
            // reqParamMap = up.getRequestParam();
            // if (reqParamMap != null) {
            // for (Map.Entry<String, String[]> req : reqParamMap
            // .entrySet()) {
            // if (req.getKey().equals("ver")) {
            // try {
            // recVersion = Integer
            // .parseInt(req.getValue()[0]);
            // } catch (NumberFormatException nfe) {
            // }
            // } else if (req.getKey().equals("db")) {
            // selDbName = req.getValue()[0];
            // }
            // }
            // }
            // } else {
            // if (request.getParameter("ver") != null) {
            // try {
            // recVersion = Integer.parseInt(request
            // .getParameter("ver"));
            // } catch (NumberFormatException nfe) {
            // }
            // }
            // selDbName = request.getParameter("db");
            // }
            // if (selDbName == null || selDbName.equals("")
            // || !dbNames.contains(selDbName)) {
            // selDbName = dbNames.get(0);
            // }

            // ---------------------------------------------
            // 
            // ---------------------------------------------
            out.println("Database: ");
            for (int i = 0; i < dbNames.size(); i++) {
                String dbName = dbNames.get(i);
                out.print("dbName");
                if (dbName.equals(selDbName)) {
                    out.print(" selected");
                }
                if (i == 0) {
                    out.println("------------------");
                } else {
                    out.println(dbName);
                }
            }
            out.println("Record Version : ");
            out.println(recVersion);

            out.println("Record Archive :");

            // ---------------------------------------------
            // 
            // ---------------------------------------------
            //         HashMap<String, Boolean> upFileMap = up.doUpload();
            //         if (upFileMap != null) {
            //            for (Map.Entry<String, Boolean> e : upFileMap.entrySet()) {
            //               upFileName = e.getKey();
            //               upResult = e.getValue();
            //               break;
            //            }
            //            if (upFileName.equals("")) {
            //               out.println(msgErr("please select file."));
            //               isResult = false;
            //            } else if (!upResult) {
            //               out.println(msgErr("[" + upFileName
            //                     + "] upload failed."));
            //               isResult = false;
            //            } else if (!upFileName.endsWith(ZIP_EXTENSION)
            //                  && !upFileName.endsWith(MSBK_EXTENSION)) {
            //               out.println(msgErr("please select ["
            //                     + UPLOAD_RECDATA_ZIP
            //                     + "] or ["
            //                     + UPLOAD_RECDATA_MSBK + "]."));
            //               up.deleteFile(upFileName);
            //               isResult = false;
            //            }
            //         } else {
            //            out.println(msgErr("server error."));
            //            isResult = false;
            //         }
            //         up.deleteFileItem();
            //         if (!isResult) {
            //            return;
            //         }

            // ---------------------------------------------
            // ???
            // ---------------------------------------------
            //         final String upFilePath = (new File(tmpPath + File.separator
            //               + upFileName)).getPath();
            //         isResult = FileUtil.unZip(upFilePath, tmpPath);
            //         if (!isResult) {
            //            out.println(msgErr("["
            //                  + upFileName
            //                  + "]  extraction failed. possibility of time-out."));
            //            return;
            //         }

            // ---------------------------------------------
            // ??
            // ---------------------------------------------
            final String recPath = (new File(dbRootPath + File.separator + selDbName)).getPath();
            File tmpRecDir = new File(recDataPath);
            if (!tmpRecDir.isDirectory()) {
                tmpRecDir.mkdirs();
            }

            // ---------------------------------------------
            // ???
            // ---------------------------------------------
            // data?
            //         final String recDataPath = (new File(tmpPath + File.separator
            //               + RECDATA_DIR_NAME)).getPath()
            //               + File.separator;
            //
            //         if (!(new File(recDataPath)).isDirectory()) {
            //            if (upFileName.endsWith(ZIP_EXTENSION)) {
            //               out.println(msgErr("["
            //                     + RECDATA_DIR_NAME
            //                     + "]  directory is not included in the up-loading file."));
            //            } else if (upFileName.endsWith(MSBK_EXTENSION)) {
            //               out.println(msgErr("The uploaded file is not record data."));
            //            }
            //            return;
            //         }

            // ---------------------------------------------
            // DB
            // ---------------------------------------------
            //         db = new DatabaseAccess(dbHostName, selDbName);
            //         isResult = db.open();
            //         if (!isResult) {
            //            db.close();
            //            out.println(msgErr("not connect to database."));
            //            return;
            //         }

            // ---------------------------------------------
            // ??
            // ---------------------------------------------
            TreeMap<String, String> resultMap = validationRecord(db, out, recDataPath, recPath, recVersion);
            if (resultMap.size() == 0) {
                return;
            }

            // ---------------------------------------------
            // ?
            // ---------------------------------------------
            isResult = dispResult(out, resultMap);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (db != null) {
                db.close();
            }
            File tmpDir = new File(tmpPath);
            if (tmpDir.exists()) {
                FileUtil.removeDir(tmpDir.getPath());
            }
        }

    }

    /**
     * ??
     * 
     * @param db
     *            DB
     * @param op
     *            PrintWriter?
     * @param dataPath
     *            ?
     * @param registPath
     *            
     * @param ver
     *            ?
     * @return ??Map<??, ?>
     * @throws IOException
     *             
     */
    private static TreeMap<String, String> validationRecordOnline(DatabaseAccess db, PrintStream op,
            String dataPath, String registPath, int ver) throws IOException {

        op.println(msgInfo("validation archive is [" + UPLOAD_RECDATA_ZIP + "] or [" + UPLOAD_RECDATA_MSBK + "]."));
        if (ver == 1) {
            op.println(msgInfo("check record format version is [version 1]."));
        }

        final String[] dataList = (new File(dataPath)).list();
        TreeMap<String, String> validationMap = new TreeMap<String, String>();

        if (dataList.length == 0) {
            op.println(msgWarn("no file for validation."));
            return validationMap;
        }

        // ----------------------------------------------------
        // ???
        // ----------------------------------------------------
        String[] requiredList = new String[] { // Ver.2
                "ACCESSION: ", "RECORD_TITLE: ", "DATE: ", "AUTHORS: ", "LICENSE: ", "CH$NAME: ",
                "CH$COMPOUND_CLASS: ", "CH$FORMULA: ", "CH$EXACT_MASS: ", "CH$SMILES: ", "CH$IUPAC: ",
                "AC$INSTRUMENT: ", "AC$INSTRUMENT_TYPE: ", "AC$MASS_SPECTROMETRY: MS_TYPE ",
                "AC$MASS_SPECTROMETRY: ION_MODE ", "PK$NUM_PEAK: ", "PK$PEAK: " };
        if (ver == 1) { // Ver.1
            requiredList = new String[] { "ACCESSION: ", "RECORD_TITLE: ", "DATE: ", "AUTHORS: ", "COPYRIGHT: ",
                    "CH$NAME: ", "CH$COMPOUND_CLASS: ", "CH$FORMULA: ", "CH$EXACT_MASS: ", "CH$SMILES: ",
                    "CH$IUPAC: ", "AC$INSTRUMENT: ", "AC$INSTRUMENT_TYPE: ", "AC$ANALYTICAL_CONDITION: MODE ",
                    "PK$NUM_PEAK: ", "PK$PEAK: " };
        }
        for (int i = 0; i < dataList.length; i++) {
            String name = dataList[i];
            String status = "";
            StringBuilder detailsErr = new StringBuilder();
            StringBuilder detailsWarn = new StringBuilder();

            // ????
            File file = new File(dataPath + name);
            if (file.isDirectory()) {
                // ??
                status = STATUS_ERR;
                detailsErr.append("[" + name + "] is directory.");
                validationMap.put(name, status + "\t" + detailsErr.toString());
                continue;
            } else if (file.isHidden()) {
                // ???
                status = STATUS_ERR;
                detailsErr.append("[" + name + "] is hidden.");
                validationMap.put(name, status + "\t" + detailsErr.toString());
                continue;
            } else if (name.lastIndexOf(REC_EXTENSION) == -1) {
                // ????
                status = STATUS_ERR;
                detailsErr.append("file extension of [" + name + "] is not [" + REC_EXTENSION + "].");
                validationMap.put(name, status + "\t" + detailsErr.toString());
                continue;
            }

            // ??
            boolean isEndTagRead = false;
            boolean isInvalidInfo = false;
            boolean isDoubleByte = false;
            ArrayList<String> fileContents = new ArrayList<String>();
            boolean existLicense = false; // LICENSE?Ver.1
            ArrayList<String> workChName = new ArrayList<String>(); // RECORD_TITLE??CH$NAME??Ver.1?
            String workAcInstrumentType = ""; // RECORD_TITLE??AC$INSTRUMENT_TYPE??Ver.1?
            String workAcMsType = ""; // RECORD_TITLE??AC$MASS_SPECTROMETRY:
            // MS_TYPE??Ver.2
            String line = "";
            BufferedReader br = null;
            try {
                br = new BufferedReader(new FileReader(file));
                while ((line = br.readLine()) != null) {
                    if (isEndTagRead) {
                        if (!line.equals("")) {
                            isInvalidInfo = true;
                        }
                    }

                    // 
                    if (line.startsWith("//")) {
                        isEndTagRead = true;
                    }
                    fileContents.add(line);

                    // LICENSE?Ver.1
                    if (line.startsWith("LICENSE: ")) {
                        existLicense = true;
                    }
                    // CH$NAME?Ver.1?
                    else if (line.startsWith("CH$NAME: ")) {
                        workChName.add(line.trim().replaceAll("CH\\$NAME: ", ""));
                    }
                    // AC$INSTRUMENT_TYPE?Ver.1?
                    else if (line.startsWith("AC$INSTRUMENT_TYPE: ")) {
                        workAcInstrumentType = line.trim().replaceAll("AC\\$INSTRUMENT_TYPE: ", "");
                    }
                    // AC$MASS_SPECTROMETRY: MS_TYPE?Ver.2
                    else if (ver != 1 && line.startsWith("AC$MASS_SPECTROMETRY: MS_TYPE ")) {
                        workAcMsType = line.trim().replaceAll("AC\\$MASS_SPECTROMETRY: MS_TYPE ", "");
                    }

                    // ?
                    if (!isDoubleByte) {
                        byte[] bytes = line.getBytes("MS932");
                        if (bytes.length != line.length()) {
                            isDoubleByte = true;
                        }
                    }
                }
            } catch (IOException e) {
                Logger.getLogger("global").severe("file read failed." + NEW_LINE + "    " + file.getPath());
                e.printStackTrace();
                op.println(msgErr("server error."));
                validationMap.clear();
                return validationMap;
            } finally {
                try {
                    if (br != null) {
                        br.close();
                    }
                } catch (IOException e) {
                }
            }
            if (isInvalidInfo) {
                // ?????
                if (status.equals(""))
                    status = STATUS_WARN;
                detailsWarn.append("invalid after the end tag [//].");
            }
            if (isDoubleByte) {
                // ?????
                if (status.equals(""))
                    status = STATUS_ERR;
                detailsErr.append("double-byte character included.");
            }
            if (ver == 1 && existLicense) {
                // LICENSE???Ver.1
                if (status.equals(""))
                    status = STATUS_ERR;
                detailsErr.append("[LICENSE: ] tag can not be used in record format  [version 1].");
            }

            // ----------------------------------------------------
            // ????
            // ----------------------------------------------------
            boolean isNameCheck = false;
            int peakNum = -1;
            for (int j = 0; j < requiredList.length; j++) {
                String requiredStr = requiredList[j];
                ArrayList<String> valStrs = new ArrayList<String>(); // 
                boolean findRequired = false; // 
                boolean findValue = false; // 
                boolean isPeakMode = false; // 
                for (int k = 0; k < fileContents.size(); k++) {
                    String lineStr = fileContents.get(k);

                    // ????RELATED_RECORD??????
                    if (lineStr.startsWith("//")) { // Ver.1?
                        break;
                    } else if (ver == 1 && lineStr.startsWith("RELATED_RECORD:")) { // Ver.1
                        break;
                    }
                    // ?????
                    else if (isPeakMode) {
                        findRequired = true;
                        if (!lineStr.trim().equals("")) {
                            valStrs.add(lineStr);
                        }
                    }
                    // ??????
                    else if (lineStr.indexOf(requiredStr) != -1) {
                        // 
                        findRequired = true;
                        if (requiredStr.equals("PK$PEAK: ")) {
                            isPeakMode = true;
                            findValue = true;
                            valStrs.add(lineStr.replace(requiredStr, ""));
                        } else {
                            // 
                            String tmpVal = lineStr.replace(requiredStr, "");
                            if (!tmpVal.trim().equals("")) {
                                findValue = true;
                                valStrs.add(tmpVal);
                            }
                            break;
                        }
                    }
                }
                if (!findRequired) {
                    // ??????
                    status = STATUS_ERR;
                    detailsErr.append("no required item [" + requiredStr + "].");
                } else {
                    if (!findValue) {
                        // ?????
                        status = STATUS_ERR;
                        detailsErr.append("no value of required item [" + requiredStr + "].");
                    } else {
                        // ???

                        // ----------------------------------------------------
                        // ??
                        // ----------------------------------------------------
                        String val = (valStrs.size() > 0) ? valStrs.get(0) : "";
                        // ACESSIONVer.1?
                        if (requiredStr.equals("ACCESSION: ")) {
                            if (!val.equals(name.replace(REC_EXTENSION, ""))) {
                                status = STATUS_ERR;
                                detailsErr.append("value of required item [" + requiredStr
                                        + "] not correspond to file name.");
                            }
                            if (val.length() != 8) {
                                status = STATUS_ERR;
                                detailsErr.append(
                                        "value of required item [" + requiredStr + "] is 8 digits necessary.");
                            }
                        }
                        // RECORD_TITLEVer.1?
                        else if (requiredStr.equals("RECORD_TITLE: ")) {
                            if (!val.equals(DEFAULT_VALUE)) {
                                if (val.indexOf(";") != -1) {
                                    String[] recTitle = val.split(";");
                                    if (!workChName.contains(recTitle[0].trim())) {
                                        if (status.equals(""))
                                            status = STATUS_WARN;
                                        detailsWarn.append("value of required item [" + requiredStr
                                                + "], compound name is not included in the [CH$NAME].");
                                    }
                                    if (!workAcInstrumentType.equals(recTitle[1].trim())) {
                                        if (status.equals(""))
                                            status = STATUS_WARN;
                                        detailsWarn.append("value of required item [" + requiredStr
                                                + "], instrument type is different from [AC$INSTRUMENT_TYPE].");
                                    }
                                    if (ver != 1 && !workAcMsType.equals(recTitle[2].trim())) { // Ver.2
                                        if (status.equals(""))
                                            status = STATUS_WARN;
                                        detailsWarn.append("value of required item [" + requiredStr
                                                + "], ms type is different from [AC$MASS_SPECTROMETRY: MS_TYPE].");
                                    }
                                } else {
                                    if (status.equals(""))
                                        status = STATUS_WARN;
                                    detailsWarn.append("value of required item [" + requiredStr
                                            + "] is not record title format.");

                                    if (!workChName.contains(val)) {
                                        detailsWarn.append("value of required item [" + requiredStr
                                                + "], compound name is not included in the [CH$NAME].");
                                    }
                                    if (!workAcInstrumentType.equals(DEFAULT_VALUE)) {
                                        detailsWarn.append("value of required item [" + requiredStr
                                                + "], instrument type is different from [AC$INSTRUMENT_TYPE].");
                                    }
                                    if (ver != 1 && !workAcMsType.equals(DEFAULT_VALUE)) { // Ver.2
                                        detailsWarn.append("value of required item [" + requiredStr
                                                + "], ms type is different from [AC$MASS_SPECTROMETRY: MS_TYPE].");
                                    }
                                }
                            } else {
                                if (!workAcInstrumentType.equals(DEFAULT_VALUE)) {
                                    if (status.equals(""))
                                        status = STATUS_WARN;
                                    detailsWarn.append("value of required item [" + requiredStr
                                            + "], instrument type is different from [AC$INSTRUMENT_TYPE].");
                                }
                                if (ver != 1 && !workAcMsType.equals(DEFAULT_VALUE)) { // Ver.2
                                    if (status.equals(""))
                                        status = STATUS_WARN;
                                    detailsWarn.append("value of required item [" + requiredStr
                                            + "], ms type is different from [AC$MASS_SPECTROMETRY: MS_TYPE].");
                                }
                            }
                        }
                        // DATEVer.1?
                        else if (requiredStr.equals("DATE: ") && !val.equals(DEFAULT_VALUE)) {
                            val = val.replace(".", "/");
                            val = val.replace("-", "/");
                            try {
                                DateFormat.getDateInstance(DateFormat.SHORT, Locale.JAPAN).parse(val);
                            } catch (ParseException e) {
                                if (status.equals(""))
                                    status = STATUS_WARN;
                                detailsWarn
                                        .append("value of required item [" + requiredStr + "] is not date format.");
                            }
                        }
                        // CH$COMPOUND_CLASSVer.1?
                        else if (requiredStr.equals("CH$COMPOUND_CLASS: ") && !val.equals(DEFAULT_VALUE)) {
                            if (!val.startsWith("Natural Product") && !val.startsWith("Non-Natural Product")) {

                                if (status.equals(""))
                                    status = STATUS_WARN;
                                detailsWarn.append("value of required item [" + requiredStr
                                        + "] is not compound class format.");
                            }
                        }
                        // CH$EXACT_MASSVer.1?
                        else if (requiredStr.equals("CH$EXACT_MASS: ") && !val.equals(DEFAULT_VALUE)) {
                            try {
                                Double.parseDouble(val);
                            } catch (NumberFormatException e) {
                                if (status.equals(""))
                                    status = STATUS_WARN;
                                detailsWarn.append("value of required item [" + requiredStr + "] is not numeric.");
                            }
                        }
                        // AC$INSTRUMENT_TYPEVer.1?
                        else if (requiredStr.equals("AC$INSTRUMENT_TYPE: ") && !val.equals(DEFAULT_VALUE)) {
                            if (val.trim().indexOf(" ") != -1) {
                                if (status.equals(""))
                                    status = STATUS_WARN;
                                detailsWarn
                                        .append("value of required item [" + requiredStr + "] is space included.");
                            }
                            if (val.trim().indexOf(" ") != -1) {
                                if (status.equals(""))
                                    status = STATUS_WARN;
                                detailsWarn
                                        .append("value of required item [" + requiredStr + "] is space included.");
                            }
                        }
                        // AC$MASS_SPECTROMETRY: MS_TYPEVer.2
                        else if (ver != 1 && requiredStr.equals("AC$MASS_SPECTROMETRY: MS_TYPE ")
                                && !val.equals(DEFAULT_VALUE)) {
                            boolean isMsType = true;
                            if (val.startsWith("MS")) {
                                val = val.replace("MS", "");
                                if (!val.equals("")) {
                                    try {
                                        Integer.parseInt(val);
                                    } catch (NumberFormatException e) {
                                        isMsType = false;
                                    }
                                }
                            } else {
                                isMsType = false;
                            }
                            if (!isMsType) {
                                if (status.equals(""))
                                    status = STATUS_WARN;
                                detailsWarn.append("value of required item [" + requiredStr + "] is not \"MSn\".");
                            }
                        }
                        // AC$MASS_SPECTROMETRY:
                        // ION_MODEVer.2?AC$ANALYTICAL_CONDITION: MODEVer.1
                        else if ((ver != 1 && requiredStr.equals("AC$MASS_SPECTROMETRY: ION_MODE ")
                                && !val.equals(DEFAULT_VALUE))
                                || (ver == 1 && requiredStr.equals("AC$ANALYTICAL_CONDITION: MODE ")
                                        && !val.equals(DEFAULT_VALUE))) {
                            if (!val.equals("POSITIVE") && !val.equals("NEGATIVE")) {
                                if (status.equals(""))
                                    status = STATUS_WARN;
                                detailsWarn.append("value of required item [" + requiredStr
                                        + "] is not \"POSITIVE\" or \"NEGATIVE\".");
                            }
                        }
                        // PK$NUM_PEAKVer.1?
                        else if (requiredStr.equals("PK$NUM_PEAK: ") && !val.equals(DEFAULT_VALUE)) {
                            try {
                                peakNum = Integer.parseInt(val);
                            } catch (NumberFormatException e) {
                                status = STATUS_ERR;
                                detailsErr.append("value of required item [" + requiredStr + "] is not numeric.");
                            }
                        }
                        // PK$PEAK:Ver.1?
                        else if (requiredStr.equals("PK$PEAK: ")) {
                            if (valStrs.size() == 0 || !valStrs.get(0).startsWith("m/z int. rel.int.")) {
                                status = STATUS_ERR;
                                detailsErr.append(
                                        "value of required item [PK$PEAK: ] , the first line is not \"PK$PEAK: m/z int. rel.int.\".");
                            } else {
                                boolean isNa = false;
                                String peak = "";
                                String mz = "";
                                String intensity = "";
                                boolean mzDuplication = false;
                                boolean mzNotNumeric = false;
                                boolean intensityNotNumeric = false;
                                boolean invalidFormat = false;
                                HashSet<String> mzSet = new HashSet<String>();
                                for (int l = 0; l < valStrs.size(); l++) {
                                    peak = valStrs.get(l).trim();
                                    // N/A
                                    if (peak.indexOf(DEFAULT_VALUE) != -1) {
                                        isNa = true;
                                        break;
                                    }
                                    if (l == 0) {
                                        continue;
                                    } // m/z int. rel.int.??????????

                                    if (peak.indexOf(" ") != -1) {
                                        mz = peak.split(" ")[0];
                                        if (!mzSet.add(mz)) {
                                            mzDuplication = true;
                                        }
                                        try {
                                            Double.parseDouble(mz);
                                        } catch (NumberFormatException e) {
                                            mzNotNumeric = true;
                                        }
                                        intensity = peak.split(" ")[1];
                                        try {
                                            Double.parseDouble(intensity);
                                        } catch (NumberFormatException e) {
                                            intensityNotNumeric = true;
                                        }
                                    } else {
                                        invalidFormat = true;
                                    }
                                    if (mzDuplication && mzNotNumeric && intensityNotNumeric && invalidFormat) {
                                        break;
                                    }
                                }
                                if (isNa) {// PK$PEAK:?N/A??
                                    if (peakNum != -1) { // PK$NUM_PEAK:N/A??
                                        if (status.equals(""))
                                            status = STATUS_WARN;
                                        detailsWarn
                                                .append("value of required item [PK$NUM_PEAK: ] is mismatch or \""
                                                        + DEFAULT_VALUE + "\".");
                                    }
                                    if (valStrs.size() - 1 > 0) { // PK$PEAK:????????
                                        if (status.equals(""))
                                            status = STATUS_WARN;
                                        detailsWarn.append(
                                                "value of required item [PK$NUM_PEAK: ] is invalid peak information exists.");
                                    }
                                } else {
                                    if (mzDuplication) {
                                        status = STATUS_ERR;
                                        detailsErr.append(
                                                "mz value of required item [" + requiredStr + "] is duplication.");
                                    }
                                    if (mzNotNumeric) {
                                        status = STATUS_ERR;
                                        detailsErr.append(
                                                "mz value of required item [" + requiredStr + "] is not numeric.");
                                    }
                                    if (intensityNotNumeric) {
                                        status = STATUS_ERR;
                                        detailsErr.append("intensity value of required item [" + requiredStr
                                                + "] is not numeric.");
                                    }
                                    if (invalidFormat) {
                                        status = STATUS_ERR;
                                        detailsErr.append(
                                                "value of required item [" + requiredStr + "] is not peak format.");
                                    }
                                    if (peakNum != 0 && valStrs.size() - 1 == 0) { // ?????N/A????PK$NUM_PEAK:?0???????
                                        if (status.equals(""))
                                            status = STATUS_WARN;
                                        detailsWarn.append(
                                                "value of required item [PK$PEAK: ] is no value.  at that time, please add \""
                                                        + DEFAULT_VALUE + "\". ");
                                    }
                                    if (peakNum != valStrs.size() - 1) {
                                        if (status.equals(""))
                                            status = STATUS_WARN;
                                        detailsWarn
                                                .append("value of required item [PK$NUM_PEAK: ] is mismatch or \""
                                                        + DEFAULT_VALUE + "\".");
                                    }
                                }
                            }
                        }
                    }
                }
            }
            String details = detailsErr.toString() + detailsWarn.toString();
            if (status.equals("")) {
                status = STATUS_OK;
                details = " ";
            }
            validationMap.put(name, status + "\t" + details);
        }

        // ----------------------------------------------------
        // ????
        // ----------------------------------------------------
        // ?ID?DB
        HashSet<String> regIdList = new HashSet<String>();
        String[] sqls = { "SELECT ID FROM SPECTRUM ORDER BY ID", "SELECT ID FROM RECORD ORDER BY ID",
                "SELECT ID FROM PEAK GROUP BY ID ORDER BY ID", "SELECT ID FROM CH_NAME ID ORDER BY ID",
                "SELECT ID FROM CH_LINK ID ORDER BY ID",
                "SELECT ID FROM TREE WHERE ID IS NOT NULL AND ID<>'' ORDER BY ID" };
        for (int i = 0; i < sqls.length; i++) {
            String execSql = sqls[i];
            ResultSet rs = null;
            try {
                rs = db.executeQuery(execSql);
                while (rs.next()) {
                    String idStr = rs.getString("ID");
                    regIdList.add(idStr);
                }
            } catch (SQLException e) {
                Logger.getLogger("global").severe("    sql : " + execSql);
                e.printStackTrace();
                op.println(msgErr("database access error."));
                return new TreeMap<String, String>();
            } finally {
                try {
                    if (rs != null) {
                        rs.close();
                    }
                } catch (SQLException e) {
                }
            }
        }
        // ?ID?
        final String[] recFileList = (new File(registPath)).list();
        for (int i = 0; i < recFileList.length; i++) {
            String name = recFileList[i];
            File file = new File(registPath + File.separator + name);
            if (!file.isFile() || file.isHidden() || name.lastIndexOf(REC_EXTENSION) == -1) {
                continue;
            }
            String idStr = name.replace(REC_EXTENSION, "");
            regIdList.add(idStr);
        }

        // ??
        for (Map.Entry<String, String> e : validationMap.entrySet()) {
            String statusStr = e.getValue().split("\t")[0];
            if (statusStr.equals(STATUS_ERR)) {
                continue;
            }
            String nameStr = e.getKey();
            String idStr = e.getKey().replace(REC_EXTENSION, "");
            String detailsStr = e.getValue().split("\t")[1];
            if (regIdList.contains(idStr)) {
                statusStr = STATUS_WARN;
                detailsStr += "id [" + idStr + "] of file name [" + nameStr + "] already registered.";
                validationMap.put(nameStr, statusStr + "\t" + detailsStr);
            }
        }

        return validationMap;
    }

}