com.svi.uzabase.logic.ValidationProcess.java Source code

Java tutorial

Introduction

Here is the source code for com.svi.uzabase.logic.ValidationProcess.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.svi.uzabase.logic;

import com.softcorporation.suggester.BasicSuggester;
import com.softcorporation.suggester.dictionary.BasicDictionary;
import com.softcorporation.suggester.tools.SpellCheck;
import com.softcorporation.suggester.util.Constants;
import com.softcorporation.suggester.util.SpellCheckConfiguration;
import com.softcorporation.suggester.util.SuggesterException;
import com.svi.uzabase.frames.MainFrame;
import com.svi.uzabase.objects.FS;
import com.svi.uzabase.objects.Field;
import com.svi.uzabase.objects.SchemaFields;
import com.svi.uzabase.objects.XMLHolder;
import java.io.BufferedReader;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import static java.lang.String.format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import static javax.management.Query.value;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.validator.routines.EmailValidator;
import org.apache.commons.validator.routines.UrlValidator;
import org.apache.poi.EncryptedDocumentException;
import org.jsoup.Jsoup;
import org.jsoup.parser.Parser;

/**
 *
 * @author Daniel
 */
public class ValidationProcess implements Callable<Map<String, List<?>>> {

    private final String inputStr;
    private final MainFrame mf;
    ArrayList<String> xmlHolder = new ArrayList<>();
    List<String> companyList = new ArrayList<>();
    List<String> cityList = new ArrayList<>();
    List<String> provinceList = new ArrayList<>();
    List<String> nationalityList = new ArrayList<>();
    List<SchemaFields> schemaFieldsList = new ArrayList<>();
    AtomicInteger total;
    AtomicInteger progress;
    List<FS> fsData = new ArrayList<>();

    ValidationProcess(MainFrame mf, String inputStr, ArrayList<String> xmlHolder, List<String> companyList,
            List<String> cityList, List<String> provinceList, List<SchemaFields> schemaFieldsList,
            List<String> nationalityList) {
        this.inputStr = inputStr;
        this.mf = mf;
        this.xmlHolder = xmlHolder;
        this.companyList = companyList;
        this.cityList = cityList;
        this.provinceList = provinceList;
        this.schemaFieldsList = schemaFieldsList;
        this.nationalityList = nationalityList;
    }

    private Map<String, List<?>> getLists() {
        Map<String, List<?>> map = new HashMap();
        map.put("xmlHolder", extractXML());
        map.put("fsData", extractFSErrors());
        return map;
    }

    private List<XMLHolder> extractXML() {
        System.out.println("in extracting xml");
        BufferedReader brInput;
        String sCurrentLineInput;
        String[] fieldNo;
        String[] splitter;
        String toValidate;
        String str;
        List<XMLHolder> xmlBatchHolder = new ArrayList<>();
        XMLHolder xmlFileHolder;
        Field xmlField;
        org.jsoup.nodes.Document doc;
        progress = new AtomicInteger(0);
        total = new AtomicInteger(xmlHolder.size());
        mf.setJprogressValues(total, progress);
        for (String xmlPath : xmlHolder) {
            mf.loader("Extracting XML: ", false);
            xmlFileHolder = new XMLHolder();
            xmlFileHolder.setFileName(xmlPath);
            try {
                brInput = new BufferedReader(new FileReader(xmlPath));
                while ((sCurrentLineInput = brInput.readLine()) != null) {
                    str = sCurrentLineInput;
                    if (str.contains("field no=\"")) {
                        xmlField = new Field();
                        sCurrentLineInput = brInput.readLine();
                        fieldNo = str.split("\"");
                        str = sCurrentLineInput;
                        doc = Jsoup.parse(str, "", Parser.xmlParser());
                        toValidate = doc.select("value").text();
                        if (fieldNo.length < 1) {
                            xmlField.setFieldNo(0);
                        } else {
                            xmlField.setFieldNo(Integer.parseInt(fieldNo[1]));
                        }
                        xmlField.setValue(toValidate);
                        if (!toValidate.isEmpty()) {
                            xmlFileHolder.add(xmlField);
                        }
                    }
                }
                brInput.close();
                xmlBatchHolder.add(xmlFileHolder);
            } catch (FileNotFoundException ex) {
                Logger.getLogger(ValidationProcess.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(ValidationProcess.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        //Set field name based on the schema
        for (XMLHolder h : xmlBatchHolder) {
            for (Field f : h) {
                for (SchemaFields s : schemaFieldsList) {
                    if (f.getFieldNo() == s.getFieldNo()) {
                        f.setFieldName(s.getFieldName());
                        break;
                    }
                }
            }
        }
        //Set field types for validation
        FS fs;
        for (XMLHolder h : xmlBatchHolder) {
            fs = new FS();
            fs.setFileName(h.getFileName());
            for (Field f : h) {
                if (f.getFieldName().toLowerCase().contains("nationality")) {
                    f.setType("nationality");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldName().toLowerCase().contains("company name")) {
                    f.setType("corporation");
                } else if (f.getFieldName().toLowerCase().contains("position")) {
                    f.setType("position");
                } else if (f.getFieldName().toLowerCase().contains("directors/officers")
                        && f.getFieldName().toLowerCase().contains("name")) {
                    f.setType("name");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldName().toLowerCase().contains("directors/officers")
                        && f.getFieldName().toLowerCase().contains("tin")) {
                    f.setType("tin");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldName().toLowerCase().contains("directors/officers")
                        && f.getFieldName().toLowerCase().contains("stockholder")) {
                    f.setType("stockholder");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldName().toLowerCase().contains("directors/officers")
                        && !f.getFieldName().toLowerCase().contains("how many")) {
                    splitter = f.getFieldName().split(":", 2);
                    if (splitter[1].trim().equals("Board") || splitter[1].trim().equals("Officer")) {
                        f.setType("board");
                    } else {
                        f.setType("none");
                    }
                    f.setColumnHeader(f.getFieldName());
                    //                } else if (f.getFieldName().equalsIgnoreCase("address")) {
                } else if (f.getFieldNo() == 31) {
                    f.setType("city");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldNo() == 32) {
                    f.setType("province");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldName().toLowerCase().contains("phone number")) {
                    f.setType("tel");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldName().toLowerCase().contains("fax number")) {
                    f.setType("fax");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldName().toLowerCase().contains("contact person")) {
                    f.setType("person");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldName().toLowerCase().contains("e-mail address")) {
                    f.setType("email");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldName().toLowerCase().contains("website/url address")) {
                    f.setType("website");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldName().toLowerCase().contains("tin/passport no.")) {
                    f.setType("tin");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldName().toLowerCase().contains("% ownership")) {
                    f.setType("ownership");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldName().toLowerCase().contains("share type")) {
                    f.setType("shareType");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldNo() == 1) {
                    f.setType("sec");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldNo() == 1207) {
                    f.setType("tin");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldNo() == 7) {
                    if (!f.getValue().equals("*N/A")) {
                        fs.setTotalAssets(Double.parseDouble(f.getValue().replaceAll(",", "")));
                    }
                    f.setType("assets");
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldNo() == 9) {
                    f.setType("liabilities");
                    if (!f.getValue().equals("*N/A")) {
                        fs.setTotalLiabilities(Double.parseDouble(f.getValue().replaceAll(",", "")));
                    }
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldNo() == 11) {
                    f.setType("balanceSheet");
                    if (!f.getValue().equals("*N/A")) {
                        fs.setTotalShareholderEquity(Double.parseDouble(f.getValue().replaceAll(",", "")));
                    }
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldNo() == 3) {
                    f.setType("grossc");
                    if (!f.getValue().equals("*N/A")) {
                        fs.setGrossRevenue(Double.parseDouble(f.getValue().replaceAll(",", "")));
                    }
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldNo() == 4) {
                    f.setType("gross");
                    if (!f.getValue().equals("*N/A")) {
                        fs.setGrossRevenueP(Double.parseDouble(f.getValue().replaceAll(",", "")));
                    }
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldNo() == 5) {
                    f.setType("netIncome");
                    if (!f.getValue().equals("*N/A")) {
                        fs.setNetIncome(Double.parseDouble(f.getValue().replaceAll(",", "")));
                    }
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldNo() == 6) {
                    f.setType("netIncomeP");
                    if (!f.getValue().equals("*N/A")) {
                        fs.setNetIncomeP(Double.parseDouble(f.getValue().replaceAll(",", "")));
                    }
                    f.setColumnHeader(f.getFieldName());
                } else if (f.getFieldNo() == 1201) {
                    f.setType("purpose");
                } else if (f.getFieldNo() == 1206) {
                    f.setType("periodCovered");
                } else if (f.getFieldNo() == 1209) {
                    f.setType("fiscalYear");
                } else {
                    f.setType("none");
                }
            }
            fsData.add(fs);
        }

        List<String> foundDupAlready = new ArrayList<>();
        String tempFoundDup = "";
        int dupCtr = 0;
        for (XMLHolder h : xmlBatchHolder) {
            for (Field f1 : h) {
                if (f1.getValue().equals("*N/A")) {
                    //skip if value is *N/A
                    continue;
                }
                for (Field f2 : h) {
                    if (f2.getValue().equals("*N/A")) {
                        //skip if value is *N/A
                        continue;
                    }
                    if (f1.getValue().equals(f2.getValue()) && !f1.getFieldName().toLowerCase().contains("company")
                            && !f2.getFieldName().toLowerCase().contains("company")
                            && f1.getFieldName().toLowerCase().contains("name")
                            && f2.getFieldName().toLowerCase().contains("name")
                            //Check if board or stockholder only
                            && ((f1.getFieldName().toLowerCase().contains("directors/officers")
                                    && f2.getFieldName().toLowerCase().contains("directors/officers"))
                                    || ((f1.getFieldName().toLowerCase().contains("name")
                                            && !f1.getFieldName().toLowerCase().contains("directors/officers"))
                                            && (f2.getFieldName().toLowerCase().contains("name") && !f2
                                                    .getFieldName().toLowerCase().contains("directors/officers"))))
                            //end of condition to check
                            && !f1.getValue().isEmpty() && !tempFoundDup.equals(f2.getValue())) {
                        dupCtr++;
                        if (dupCtr == 2 && foundDupAlready.indexOf(f1.getValue()) < 0) {
                            if (f2.getFieldName().toLowerCase().contains("former")
                                    || f2.getFieldName().toLowerCase().contains("building")) {
                                continue;
                            }
                            System.out.println("2 " + f2.getValue() + f2.getFieldName());
                            foundDupAlready.add(f2.getValue());
                            tempFoundDup = f2.getValue();
                            f2.add("Duplicate entry");
                        }
                    }
                }
                dupCtr = 0;
            }
        }
        List<Field> dupeHolder = new ArrayList<>();
        for (XMLHolder z : xmlBatchHolder) {
            for (Field f1 : z) {
                for (String s : f1) {
                    if (s.equals("Duplicate entry")) {
                        dupeHolder.add(f1);
                    }
                }
            }
        }
        for (XMLHolder z : xmlBatchHolder) {
            for (Field f1 : z) {
                for (Field fd : dupeHolder) {
                    if (fd.getFieldNo() != f1.getFieldNo() && fd.getValue().equals(f1.getValue())) {
                        f1.add("Duplicate entry");
                    }
                }
            }
        }

        return validateData(xmlBatchHolder);
    }

    private List<XMLHolder> validateData(List<XMLHolder> xmlBatchHolder) {
        try {
            int totalCounter = 0;
            //Initialize dictionary
            String dictFileName = "file://./dic/english.jar";
            String configFile = "file://./classes/spellCheck.config";
            BasicDictionary dictionary = new BasicDictionary(dictFileName);
            SpellCheckConfiguration configuration = new SpellCheckConfiguration(configFile);
            BasicSuggester suggester = new BasicSuggester(configuration);
            suggester.attach(dictionary);

            // create SpellCheck object based on configuration and specify Suggester
            SpellCheck spellCheck = new SpellCheck(configuration);
            spellCheck.setSuggester(suggester);
            //set for jprogress bar
            for (XMLHolder h : xmlBatchHolder) {
                totalCounter += h.size();

            }
            progress = new AtomicInteger(0);
            total = new AtomicInteger(totalCounter);
            mf.setJprogressValues(total, progress);
            //validation process begins here
            String[] invalidWords = { "corporation", "inc.", "city", "corp.", "st.", "co.", "ltd." };
            String[] invalidBoardWords = { "other", "oth" };
            String[] validWords = { "loc", "to", "ext", "local" };
            String[] invalidCharacters = { ",", "/", "\\", "[", "]", "\"", ":", "^", "{", "}", "%", "+", "#", "(",
                    ")" };
            String[] splitter;
            String tempURL;
            SimpleDateFormat sdf = new SimpleDateFormat("YYYY/MM/DD");
            SimpleDateFormat fiscalYear = new SimpleDateFormat("MM/DD");
            sdf.setLenient(false);
            Set<String> officerList = new HashSet<>();
            List<Double> percentOwnership = new ArrayList<>();
            UrlValidator urlValidator = new UrlValidator();
            Date date = null;
            for (XMLHolder h : xmlBatchHolder) {
                for (Field f : h) {
                    mf.loader("Validating fields: ", false);
                    if (!f.getType().equals("none") && !f.getValue().equals("*N/A")) {
                        switch (f.getType()) {
                        case "city":
                            if (f.getValue().isEmpty() || f.getValue().equals("")) {
                                f.add("Address is empty");
                            } else {
                                if (hasWhiteSpaceTrailing(f.getValue())) {
                                    f.add("has trailing white space ");
                                }
                                if (cityList.indexOf(f.getValue()) < 0) {
                                    f.add("City not found on list!");
                                }
                            }

                            break;
                        case "province":
                            if (f.getValue().isEmpty() || f.getValue().equals("")) {
                                f.add("Address is empty");
                            } else {
                                if (hasWhiteSpaceTrailing(f.getValue())) {
                                    f.add("has trailing white space ");
                                }
                                if (provinceList.indexOf(f.getValue()) < 0) {
                                    f.add("Province not found on list!");
                                }
                            }

                            break;
                        case "tel":
                            if (!f.getValue().isEmpty() || !f.getValue().equals("")) {
                                //                                    if (f.getValue().matches("[a-z A-Z]+")) {
                                if (f.getValue().matches(".*[a-zA-Z]+.*")) {
                                    for (String s : validWords) {
                                        if (!f.getValue().contains(s)) {
                                            f.add("Invalid telephone number");
                                        }
                                    }
                                }

                                if (f.getValue().replace(" ", "").replace("-", "").length() < 7
                                        || f.getValue().replace(" ", "").replace("-", "").length() > 8) {
                                    f.add("Invalid telephone number length");
                                }

                                if (hasWhiteSpaceTrailing(f.getValue())) {
                                    f.add("has trailing white space ");
                                }
                                if (StringUtils.countMatches(f.getValue(), "-") > 2) {
                                    f.add("Invalid telephone number");
                                }

                                for (String c : invalidCharacters) {
                                    if (f.getValue().contains(c)) {
                                        f.add("Contains invalid character [ " + c + " ]");
                                        break;
                                    }
                                }
                            }
                            break;
                        case "fax":
                            if (!f.getValue().isEmpty() || !f.getValue().equals("")) {
                                //                                    if (f.getValue().matches("[a-z A-Z]+")) {
                                if (f.getValue().matches(".*[a-zA-Z]+.*")) {
                                    for (String s : validWords) {
                                        if (!f.getValue().contains(s)) {
                                            f.add("Invalid fax number");
                                        }
                                    }
                                }
                                if (f.getValue().replace(" ", "").length() < 6) {
                                    f.add("Invalid fax number");
                                }
                                if (StringUtils.countMatches(f.getValue(), "-") > 1) {
                                    f.add("Invalid fax number");
                                }
                                if (hasWhiteSpaceTrailing(f.getValue())) {
                                    f.add("has trailing white space ");
                                }
                                for (String c : invalidCharacters) {
                                    if (f.getValue().contains(c)) {
                                        f.add("Contains invalid character [ " + c + " ]");
                                        break;
                                    }
                                }
                            }
                            break;
                        case "person":
                            if (!f.getValue().isEmpty() || !f.getValue().equals("")) {
                                if (!f.getValue().matches("[a-zA-Z\\.,\\- ()]+")) {
                                    f.add("Invalid name");
                                }
                                if (f.getValue().matches("[a-z ]+")) {
                                    f.add("All small caps");
                                }
                                if (f.getValue().matches("\\w+")) {
                                    f.add("Only one word");
                                }
                                if (f.getValue().replace(" ", "").length() > 30) {
                                    f.add("More than 30 characters.");
                                }
                                if (f.getValue().replace(" ", "").length() < 2) {
                                    f.add("Invalid name.");
                                }
                                if (hasWhiteSpaceTrailing(f.getValue())) {
                                    f.add("has trailing white space ");
                                }
                            }
                            break;
                        case "email":
                            if (!f.getValue().isEmpty() || !f.getValue().equals("")) {
                                if (!EmailValidator.getInstance(true).isValid(f.getValue())) {
                                    f.add("Invalid email");
                                }
                            }
                            break;
                        case "website":
                            if (!f.getValue().isEmpty() || !f.getValue().equals("")) {
                                if (!f.getValue().contains("http")) {
                                    tempURL = "http://" + f.getValue();
                                } else {
                                    tempURL = f.getValue();
                                }
                                if (!urlValidator.isValid(tempURL)) {
                                    f.add("Invalid website");
                                }
                                if (hasWhiteSpaceTrailing(f.getValue())) {
                                    f.add("has trailing white space ");
                                }
                            }
                            break;
                        case "name":
                            officerList.add(f.getValue());
                            if (!f.getValue().isEmpty() || !f.getValue().equals("")) {
                                if (!f.getValue().matches("[a-zA-Z\\.,\\-() ]+")) {
                                    f.add("Invalid name");
                                }
                                if (f.getValue().replace(" ", "").length() > 30) {
                                    f.add("More than 50 characters.");
                                }
                                if (f.getValue().matches("[a-z ]+")) {
                                    f.add("All small caps");
                                }
                                if (f.getValue().matches("\\w+")) {
                                    f.add("Only one word");
                                }
                                if (f.getValue().replace(" ", "").length() < 2) {
                                    f.add("Invalid name.");
                                }
                                if (hasWhiteSpaceTrailing(f.getValue())) {
                                    f.add("has trailing white space ");
                                }
                                for (String s : invalidWords) {
                                    if (f.getValue().contains(s)) {
                                        f.add("Contains invalid word: " + s);
                                        break;
                                    }
                                }
                            }
                            break;
                        case "stockholder":
                            officerList.add(f.getValue());
                            if (!f.getValue().isEmpty() || !f.getValue().equals("")) {
                                if (!f.getValue().matches("[a-zA-Z\\.,\\-() ]+")) {
                                    f.add("Invalid name");
                                }
                                if (f.getValue().replace(" ", "").length() > 30) {
                                    f.add("More than 50 characters.");
                                }
                                if (f.getValue().matches("[a-z ]+")) {
                                    f.add("All small caps");
                                }
                                if (f.getValue().matches("\\w+")) {
                                    f.add("Only one word");
                                }
                                if (f.getValue().replace(" ", "").length() < 2) {
                                    f.add("Invalid name.");
                                }
                                if (hasWhiteSpaceTrailing(f.getValue())) {
                                    f.add("has trailing white space ");
                                }
                                for (String s : invalidWords) {
                                    if (f.getValue().contains(s)) {
                                        f.add("Contains invalid word: " + s);
                                        break;
                                    }
                                }
                            }
                            break;
                        case "board":
                            if (!f.getValue().isEmpty() || !f.getValue().equals("")) {
                                if (!f.getValue().matches("[a-zA-Z\\.,\\-() ]+")) {
                                    f.add("Invalid position");
                                }
                                for (String c : invalidCharacters) {
                                    if (f.getValue().contains(c)) {
                                        f.add("Contains invalid character [ " + c + " ]");
                                        break;
                                    }
                                }
                                for (String c : invalidBoardWords) {
                                    if (f.getValue().contains(c)) {
                                        f.add("Contains invalid word [ " + c + " ]");
                                        break;
                                    }
                                }

                                if (f.getValue().equalsIgnoreCase("N") || f.getValue().equalsIgnoreCase("Y")) {
                                    f.add("is letter " + f.getValue() + " only");
                                }
                                if (Character.isLowerCase(f.getValue().charAt(0))) {
                                    f.add("starts with a lower case letter");
                                }

                                spellCheck.setText(f.getValue(), Constants.DOC_TYPE_TEXT, "en");
                                spellCheck.check();
                                if (spellCheck.hasMisspelt()) {
                                    f.add("word is misspelled.");
                                }

                            }
                            break;
                        case "corporation":
                            if (companyList.indexOf(f.getValue().toUpperCase()) < 0) {
                                f.add("Company name not found on table.");
                            }
                            break;
                        case "sec":
                            if (StringUtils.countMatches(f.getValue(), "-") > 1) {
                                f.add("Invalid SEC number");
                            }
                            if (f.getValue().replace(" ", "").length() > 9) {
                                f.add("SEC number more than 9 digits.");
                            }
                            if (hasWhiteSpaceTrailing(f.getValue())) {
                                f.add("SEC has trailing white space.");
                            }
                            for (String c : invalidCharacters) {
                                if (f.getValue().contains(c)) {
                                    f.add("Contains invalid character [ " + c + " ]");
                                    break;
                                }
                            }
                            break;
                        case "tin":
                            if (f.getValue().isEmpty() || f.getValue().equals("")) {
                                f.add("TIN is empty");
                            }
                            if (hasWhiteSpaceTrailing(f.getValue())) {
                                f.add("TIN has trailing white space.");
                            }
                            if (!f.getValue().matches("[0-9]+")) {
                                f.add("invalid TIN number");
                            }
                            if (f.getValue().replace(" ", "").replace("-", "").length() > 12
                                    || f.getValue().replace(" ", "").replace("-", "").length() < 9) {
                                f.add("TIN number invalid length.");
                            }
                            if (StringUtils.countMatches(f.getValue(), "-") > 1) {
                                f.add("Invalid TIN number");
                            }
                            for (String c : invalidCharacters) {
                                if (f.getValue().contains(c)) {
                                    f.add("Contains invalid character [ " + c + " ]");
                                    break;
                                }
                            }
                            break;
                        case "nationality":
                            if (!f.getValue().isEmpty() || !f.getValue().equals("")) {
                                if (nationalityList.indexOf(f.getValue()) < 0) {
                                    f.add("nationality is misspelled.");
                                }
                            }
                            break;
                        case "purpose":
                            splitter = f.getValue().split(" ");
                            for (int i = 0; i < splitter.length; i++) {
                                spellCheck.setText(splitter[i], Constants.DOC_TYPE_TEXT, "en");
                                spellCheck.check();
                                if (spellCheck.hasMisspelt()) {
                                    f.add("word is misspelled. ( " + spellCheck.getMisspelt() + " )");
                                }
                            }
                            break;
                        case "periodCovered":
                            try {
                                date = sdf.parse(f.getValue());
                                if (!f.getValue().equals(sdf.format(date))) {
                                    f.add("Invalid date format");
                                }
                            } catch (ParseException ex) {
                                f.add("Invalid date format");
                            }
                            break;
                        case "fiscalYear":
                            try {
                                date = fiscalYear.parse(f.getValue());
                                if (!f.getValue().equals(sdf.format(date))) {
                                    f.add("Invalid date format");
                                }
                            } catch (ParseException ex) {
                                f.add("Invalid date format");
                            }
                            break;
                        case "position":
                            if (f.getValue().contains("\\d+")) {
                                f.add("Invalid position/designation");
                            }
                            if (f.getValue().replace(" ", "").length() > 10
                                    || f.getValue().replace(" ", "").length() < 3) {
                                f.add("More than 30 characters.");
                            }
                            break;
                        case "shareType":
                            if (f.getValue().toLowerCase().contains("total")) {
                                f.add("Share type contains total.");
                            }

                            if (f.getValue().replace(" ", "").length() > 20) {
                                f.add("Share type More than 20 characters.");
                            }
                            break;
                        case "ownership":
                            percentOwnership.add(Double.parseDouble(f.getValue()));
                            if (Double.parseDouble(f.getValue()) > 100) {
                                f.add("Percent ownership more than 100%");
                            }
                            break;
                        default:
                            break;
                        }
                    } else if (f.getType().equals("tin") && f.getValue().equals("*N/A")) {
                        f.add("TIN is N/A");
                    }
                }
            }

        } catch (EncryptedDocumentException | SuggesterException ex) {
            Logger.getLogger(ValidationProcess.class.getName()).log(Level.SEVERE, null, ex);
        }
        return xmlBatchHolder;
    }

    private List<FS> extractFSErrors() {
        for (FS f : fsData) {
            if ((f.getTotalAssets() - f.getTotalLiabilities() - f.getTotalShareholderEquity()) != 0) {
                f.add("Total Assets not equal to Total Liabilities and Shareholder Equity\t"
                        + (f.getTotalAssets() - f.getTotalLiabilities() - f.getTotalShareholderEquity()));
            }
            if (((f.getGrossRevenue() / f.getGrossRevenueP()) * 100 > 500)) {

                f.add("Year-on-year turnover rate is higher than 500%\t"
                        + ((f.getGrossRevenue() / f.getGrossRevenueP()) * 100));
            } else if (((f.getGrossRevenueP() / f.getGrossRevenue()) * 100 > 500)) {

                f.add("Year-on-year turnover rate is higher than 500%\t"
                        + ((f.getGrossRevenueP() / f.getGrossRevenue()) * 100));
            }

            if (((f.getGrossRevenue() / f.getGrossRevenueP()) * 100 < 0.002)) {

                f.add("Year-on-year turnover rate is higher than 500%\t"
                        + ((f.getGrossRevenue() / f.getGrossRevenueP()) * 100));
            } else if (((f.getGrossRevenueP() / f.getGrossRevenue()) * 100 < 0.002)) {

                f.add("Year-on-year turnover rate is higher than 500%\t"
                        + ((f.getGrossRevenueP() / f.getGrossRevenue()) * 100));
            }

            if ((((f.getNetIncome() / f.getGrossRevenue()) * 100) > 1000)) {

                f.add("Net Profit Margin higher than 1000%\t" + (((f.getNetIncome() / f.getGrossRevenue()) * 100)));
            } else if ((((f.getNetIncomeP() / f.getGrossRevenueP()) * 100) > 1000)) {
                f.add("Net Profit Margin higher than 1000%\t"
                        + (((f.getNetIncomeP() / f.getGrossRevenueP()) * 100)));
            }

        }
        return fsData;
    }

    private boolean hasWhiteSpaceTrailing(String str) {
        if (Character.isWhitespace(str.charAt(str.length() - 1))) {
            return true;
        }
        return false;
    }

    private static String toAlphabetic(int i) {
        if (i < 0) {
            return "-" + toAlphabetic(-i - 1);
        }
        int quot = i / 26;
        int rem = i % 26;
        char letter = (char) ((int) 'A' + rem);
        if (quot == 0) {
            return "" + letter;
        } else {
            return toAlphabetic(quot - 1) + letter;
        }
    }

    @Override
    public Map<String, List<?>> call() throws Exception {
        return getLists();
    }
}