hjow.hgtable.util.DataUtil.java Source code

Java tutorial

Introduction

Here is the source code for hjow.hgtable.util.DataUtil.java

Source

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

package hjow.hgtable.util;

import hjow.hgtable.Main;
import hjow.hgtable.Manager;
import hjow.hgtable.tableset.Column;
import hjow.hgtable.tableset.DefaultTableSet;
import hjow.hgtable.tableset.Record;
import hjow.hgtable.tableset.TableSet;

import java.io.File;
import java.io.FileNotFoundException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;

import org.apache.commons.codec.binary.Base64;

/**
 * <p>??  ? ?  ? ?  ?.</p>
 * 
 * @author HJOW
 *
 */
public class DataUtil {
    /**
     * <p>?   . null ? true  ?,  ?? ? true  ?.</p>
     * 
     * @param ob :  ?
     * @return ? 
     */
    public static boolean isEmpty(Object ob) {
        if (ob == null)
            return true;
        if (ob instanceof String) {
            if (((String) ob).trim().equals(""))
                return true;
            else if (((String) ob).trim().equals("null"))
                return true;
            else
                return false;
        } else if (ob instanceof List<?>) {
            return ((List<?>) ob).isEmpty();
        } else if (ob instanceof Map<?, ?>) {
            return ((Map<?, ?>) ob).isEmpty();
        } else if (String.valueOf(ob).trim().equals("null"))
            return true;
        else if (String.valueOf(ob).trim().equals(""))
            return true;
        else
            return isEmpty(String.valueOf(ob));
    }

    /**
     * <p>?? ?    . ?  ? true  ?.</p>
     * 
     * @param obs : ?
     * @return   
     */
    public static boolean isEmpties(Object... obs) {
        for (Object o : obs) {
            if (isNotEmpty(o)) {
                return false;
            }
        }
        return true;
    }

    /**
     * <p>?   . null ? false  ?,  ?? ? false  ?.</p>
     * 
     * @param ob :  ?
     * @return ? 
     */
    public static boolean isNotEmpty(Object ob) {
        return !isEmpty(ob);
    }

    /**
     * <p>?? ?   ?  . ?   ? ? true  ?.</p>
     * 
     * @param obs : ?
     * @return   ? 
     */
    public static boolean isNotEmpties(Object... obs) {
        for (Object o : obs) {
            if (isEmpty(o)) {
                return false;
            }
        }
        return true;
    }

    /**
     * <p> ?   ?   .</p>
     * 
     * @param ob :  ?
     * @return :    
     */
    public static boolean isInteger(Object ob) {
        if (ob instanceof BigInteger)
            return true;
        if (ob instanceof Integer)
            return true;
        if (ob instanceof Long)
            return true;
        if (ob instanceof String) {
            try {
                Long.parseLong((String) ob);
                return true;
            } catch (NumberFormatException e) {
                return false;
            }
        } else
            return false;
    }

    /**
     * <p> ?   ?   .</p>
     * 
     * @param ob :  ?
     * @return :    
     */
    public static boolean isFloat(Object ob) {
        if (ob instanceof BigDecimal)
            return true;
        if (ob instanceof Float)
            return true;
        if (ob instanceof Double)
            return true;
        if (ob instanceof String) {
            try {
                Double.parseDouble((String) ob);
                return true;
            } catch (NumberFormatException e) {
                return false;
            }
        } else
            return false;
    }

    /**
     * <p> ? , ?  ?  .</p>
     * 
     * @param ob :  ?
     * @return ? ?? 
     */
    public static boolean isNumber(Object ob) {
        return isInteger(ob) || isFloat(ob);
    }

    /**
     * <p>? boolean  . ? y/n ?   ?  true, false   ? ?.</p>
     * 
     * @param ob : ?
     * @return 
     * @throws InvalidInputException :   ??  ?   
     */
    public static boolean parseBoolean(Object ob) throws InvalidInputException {
        if (ob == null)
            return false;
        if (isEmpty(ob))
            return false;
        if (ob instanceof String) {
            String target = ((String) ob).trim();
            if (target.equalsIgnoreCase("t") || target.equalsIgnoreCase("true") || target.equalsIgnoreCase("y")
                    || target.equalsIgnoreCase("yes"))
                return true;
            else
                return false;
        } else if (ob instanceof Integer) {
            if (((Integer) ob).intValue() == 0)
                return false;
            else
                return true;
        } else if (ob instanceof BigInteger) {
            if (((Integer) ob).intValue() == 0)
                return false;
            else
                return true;
        } else if (ob instanceof Boolean) {
            return ((Boolean) ob).booleanValue();
        }
        throw new InvalidInputException(Manager.applyStringTable("Invalid inputs") + " : " + String.valueOf(ob));
    }

    /**
     * <p>?  ? .</p>
     * 
     * @param newList :  ?,   ?  . ?? ? ?   ? ?? ?.
     * @return  ?
     */
    public static <T> List<T> arrayToList(T[] obj, List<T> newList) {
        if (obj == null)
            return null;
        List<T> lists = newList;
        for (int i = 0; i < obj.length; i++) {
            lists.add(obj[i]);
        }
        return lists;
    }

    /**
     * <p> ?    . ? ?  ??  ?  .</p>
     * 
     * @param one : 
     * @param two : ?  
     * @return ? 
     */
    private static <T> List<T> mergeList(List<T> one, List<T> two) {
        if (one == null)
            return two;
        if (two == null)
            return one;
        if (one.size() <= 0)
            return two;
        if (two.size() <= 0)
            return one;

        List<T> newList = new Vector<T>();

        boolean isEquals = true;
        for (int i = 0; i < one.size(); i++) {
            newList.add(one.get(i));
        }
        for (int i = 0; i < two.size(); i++) {
            isEquals = true;
            for (int j = 0; j < newList.size(); j++) {
                if (!(two.get(i).equals(newList.get(j)))) {
                    isEquals = false;
                }
            }
            if (!isEquals) {
                newList.add(two.get(i));
            }
        }
        return newList;
    }

    /**
     * <p> ?    . ? ?  ??  ?  .</p>
     * <p>? ? equals(others)   ?, ?  ?? ?    .</p>
     * 
     * @param lists : 
     * @return ?  
     */
    public static <T> List<T> merge(List<T>... lists) {
        List<List<T>> targets = new Vector<List<T>>();
        for (List<T> othersList : lists) {
            targets.add(othersList);
        }

        List<T> results = new Vector<T>();
        for (int i = 0; i < targets.size(); i++) {
            results = mergeList(results, targets.get(i));
        }

        return results;
    }

    /**
     * <p> ? \  . (?)</p>
     * 
     * @param isDoubleQuote : ? ? true ? ? ? \  ?,  ? ?  ? \  .
     * @param target : ? ?
     * @return \ ? ?
     */
    public static String castQuote(boolean isDoubleQuote, String target) {
        if (isDoubleQuote) {
            return target.replace("\"", "\\" + "\"");
        } else {
            return target.replace("'", "\'");
        }
    }

    /**
     * <p>\ ? ?  ??  ? . (? )</p>
     * 
     * @param isDoubleQuote : ? ? true ? \ ? ??  ?? ? , false ? ? ?  ??  .
     * @param target : ? ?
     * @return \  ? ?
     */
    public static String reCastQuote(boolean isDoubleQuote, String target) {
        /*
        if(isDoubleQuote)
        {
           return target.replace("\\" + "\"", "\"");
        }
        else
        {
           return target.replace("\'", "'");
        }
        */
        char[] chars = target.toCharArray();
        StringBuffer results = new StringBuffer("");
        boolean useDefault = true;
        for (int i = 0; i < chars.length; i++) {
            useDefault = true;
            if (isDoubleQuote) {
                if (i >= 3) {
                    useDefault = false;
                    if ((chars[i - 2] == '\\') && chars[i - 1] == '\\' && chars[i] == '"') {
                        results = results.append(String.valueOf('"'));
                    } else if ((chars[i - 2] != '\\') && chars[i - 1] == '\\' && chars[i] == '"') {
                        results = results.append(String.valueOf('"'));
                    } else if (chars[i - 1] == '\\' && chars[i] == '\\') {
                        results = results.append(String.valueOf('\\'));
                    } else if (chars[i] == '\\') {
                        continue;
                    } else {
                        useDefault = true;
                    }
                } else if (i >= 2) {
                    useDefault = false;
                    if (chars[i - 1] == '\\' && chars[i] == '"') {
                        results = results.append(String.valueOf('"'));
                    } else if (chars[i - 1] == '\\' && chars[i] == '\\') {
                        results = results.append(String.valueOf('\\'));
                    } else if (chars[i] == '\\') {
                        continue;
                    } else
                        useDefault = true;
                } else {
                    useDefault = true;
                }
            } else {
                if (i >= 3) {
                    useDefault = false;
                    if ((chars[i - 2] == '\\') && chars[i - 1] == '\\' && chars[i] == '\'') {
                        results = results.append(String.valueOf('\''));
                    } else if ((chars[i - 2] != '\\') && chars[i - 1] == '\\' && chars[i] == '\'') {
                        results = results.append(String.valueOf('\''));
                    } else if (chars[i - 1] == '\\' && chars[i] == '\\') {
                        results = results.append(String.valueOf('\\'));
                    } else if (chars[i] == '\\') {
                        continue;
                    } else {
                        useDefault = true;
                    }
                } else if (i >= 2) {
                    useDefault = false;
                    if (chars[i - 1] == '\\' && chars[i] == '\'') {
                        results = results.append(String.valueOf('\''));
                    } else if (chars[i - 1] == '\\' && chars[i] == '\\') {
                        results = results.append(String.valueOf('\\'));
                    } else if (chars[i] == '\\') {
                        continue;
                    } else
                        useDefault = true;
                } else {
                    useDefault = true;
                }
            }

            if (useDefault) {
                results = results.append(chars[i]);
            }
        }
        return results.toString();
    }

    /**
     * <p>? ?  .  ? ? ? .</p>
     * 
     * @param contents : ? ?
     * @param needDouble : true  ? 
     * @return  ?? ?
     */
    public static String putQuote(String contents, boolean needDouble) {
        if (needDouble)
            return "\"" + castQuote(true, contents) + "\"";
        else
            return "'" + castQuote(false, contents) + "'";
    }

    /**
     * <p>? ?  ,  ? ? ? . ? ?   ?? ?? .</p>
     * 
     * @param contents : ? ?
     * @return  ? ? ?
     */
    public static String removeQuote(String contents) {
        String target = contents.trim();
        if (target.startsWith("\"") && target.endsWith("\"")) {
            target = target.substring(1, target.length() - 1);
            target = reCastQuote(true, target);
        } else if (target.startsWith("'") && target.endsWith("'")) {
            target = target.substring(1, target.length() - 1);
            target = reCastQuote(false, target);
        }
        return target;
    }

    /**
     * <p> ?, ,  ? \ .   ?   ?,  ? ??  \n?,  ?? \t  ?.</p>
     * 
     * @param isDoubleQuote : ? ? true ? ? ? \  ?,  ? ?  ? \  .
     * @param target : ? ?
     * @return \ ? ?
     */
    public static String castTotal(boolean isDoubleQuote, String target) {
        return castQuote(isDoubleQuote, target.replace("\n", "\\n").replace("\t", "\\t"));
    }

    /**
     * <p>\n, \t, \"   \  . \n?  ?  ?, \t   ?.</p>
     * 
     * @param isDoubleQuote : ? ? true ? \ ? ??  ?? ? , false ? ? ?  ??  .
     * @param target : ? ?
     * @return \  ? ?
     */
    public static String reCastTotal(boolean isDoubleQuote, String target) {
        // return reCastQuote(isDoubleQuote, target.replace("\\n", "\n").replace("\\t", "\t"));

        char[] chars = target.toCharArray();
        StringBuffer results = new StringBuffer("");
        boolean useDefault = true;
        for (int i = 0; i < chars.length; i++) {
            useDefault = true;
            if (isDoubleQuote) {
                if (i >= 3) {
                    useDefault = false;
                    if ((chars[i - 2] == '\\') && chars[i - 1] == '\\' && chars[i] == '"') {
                        results = results.append(String.valueOf('"'));
                    } else if ((chars[i - 2] != '\\') && chars[i - 1] == '\\' && chars[i] == '"') {
                        results = results.append(String.valueOf('"'));
                    } else if ((chars[i - 2] == '\\') && chars[i - 1] == '\\' && chars[i] == 'n') {
                        results = results.append(String.valueOf('n'));
                    } else if ((chars[i - 2] != '\\') && chars[i - 1] == '\\' && chars[i] == 'n') {
                        results = results.append(String.valueOf('\n'));
                    } else if ((chars[i - 2] == '\\') && chars[i - 1] == '\\' && chars[i] == 't') {
                        results = results.append(String.valueOf('t'));
                    } else if ((chars[i - 2] != '\\') && chars[i - 1] == '\\' && chars[i] == 't') {
                        results = results.append(String.valueOf('\t'));
                    } else if (chars[i - 1] == '\\' && chars[i] == '\\') {
                        results = results.append(String.valueOf('\\'));
                    } else if (chars[i] == '\\') {
                        continue;
                    } else {
                        useDefault = true;
                    }
                } else if (i >= 2) {
                    useDefault = false;
                    if (chars[i - 1] == '\\' && chars[i] == '"') {
                        results = results.append(String.valueOf('"'));
                    } else if (chars[i - 1] == '\\' && chars[i] == '\\') {
                        results = results.append(String.valueOf('\\'));
                    } else if (chars[i - 1] == '\\' && chars[i] == 'n') {
                        results = results.append(String.valueOf('\n'));
                    } else if (chars[i - 1] == '\\' && chars[i] == 't') {
                        results = results.append(String.valueOf('\t'));
                    } else if (chars[i] == '\\') {
                        continue;
                    } else
                        useDefault = true;
                } else {
                    useDefault = true;
                }
            } else {
                if (i >= 3) {
                    useDefault = false;
                    if ((chars[i - 2] == '\\') && chars[i - 1] == '\\' && chars[i] == '\'') {
                        results = results.append(String.valueOf("\\'"));
                    } else if ((chars[i - 2] != '\\') && chars[i - 1] == '\\' && chars[i] == '\'') {
                        results = results.append(String.valueOf('\''));
                    } else if ((chars[i - 2] == '\\') && chars[i - 1] == '\\' && chars[i] == 'n') {
                        results = results.append(String.valueOf('n'));
                    } else if ((chars[i - 2] != '\\') && chars[i - 1] == '\\' && chars[i] == 'n') {
                        results = results.append(String.valueOf('\n'));
                    } else if ((chars[i - 2] == '\\') && chars[i - 1] == '\\' && chars[i] == 't') {
                        results = results.append(String.valueOf('t'));
                    } else if ((chars[i - 2] != '\\') && chars[i - 1] == '\\' && chars[i] == 't') {
                        results = results.append(String.valueOf('\t'));
                    } else if (chars[i - 1] == '\\' && chars[i] == '\\') {
                        results = results.append(String.valueOf('\\'));
                    } else if (chars[i] == '\\') {
                        continue;
                    } else {
                        useDefault = true;
                    }
                } else if (i >= 2) {
                    useDefault = false;
                    if (chars[i - 1] == '\\' && chars[i] == '\'') {
                        results = results.append(String.valueOf('\''));
                    } else if (chars[i - 1] == '\\' && chars[i] == '\\') {
                        results = results.append(String.valueOf('\\'));
                    } else if (chars[i - 1] == '\\' && chars[i] == 'n') {
                        results = results.append(String.valueOf('\n'));
                    } else if (chars[i - 1] == '\\' && chars[i] == 't') {
                        results = results.append(String.valueOf('\t'));
                    } else if (chars[i] == '\\') {
                        continue;
                    } else
                        useDefault = true;
                } else {
                    useDefault = true;
                }
            }

            if (useDefault) {
                results = results.append(chars[i]);
            }
        }
        return results.toString();
    }

    /**
     * <p>HGF ?? ? ?  .</p>
     * 
     * @param hgf : HGF ?
     * @return ?  ?
     */
    public static TableSet toTableSet(String hgf) {
        TableSet tableSet = new DefaultTableSet();

        StringTokenizer lineToken = new StringTokenizer(hgf, "\n");
        String lines;

        String data = "";
        String selectedColumn = null;
        char inQuote = ' ';
        Column newColumn;

        while (lineToken.hasMoreTokens()) {
            lines = lineToken.nextToken().trim(); //  

            if (lines.startsWith("#"))
                continue; // #  ? --> #   ?  ?
            if (lines.startsWith("@")) // @   ? ? ?? 
            {
                String name = lines.substring(1);
                if (name.startsWith("\"")) {
                    name = DataUtil.reCastTotal(true, name.substring(1, name.length() - 1));
                } else if (name.startsWith("'")) {
                    name = DataUtil.reCastTotal(false, name.substring(1, name.length() - 1));
                }

                tableSet.setName(name);
            } else if (lines.startsWith("%")) // %   ?  , :;:  
            {
                String columns = lines.substring(1).trim();
                char[] columnsChar = columns.toCharArray();

                for (int i = 0; i < columnsChar.length; i++) {
                    if (inQuote == '"') //  ?  
                    {
                        if (columnsChar[i] == '"') //  
                        {
                            inQuote = ' '; //   
                            if (i == columnsChar.length - 1) //  ?? 
                            {
                                if (selectedColumn != null) //  ?? ??  -->  ??   
                                {
                                    newColumn = new Column();
                                    newColumn.setName(selectedColumn);
                                    newColumn.setType(DataUtil.reCastTotal(true, data));
                                    tableSet.getColumns().add(newColumn);
                                    data = "";
                                    selectedColumn = null;
                                }
                            }
                        } else //  ? ? 
                        {
                            data = data + String.valueOf(columnsChar[i]);
                        }
                    } else //  ?  
                    {
                        if (columnsChar[i] == ' ')
                            continue; // ? ?
                        else if (columnsChar[i] == '"') //   
                        {
                            inQuote = '"'; //   
                            data = "";
                        } else if (columnsChar[i] == ':') // :  , ?  ??  ? ?
                        {
                            selectedColumn = DataUtil.reCastTotal(true, data);
                            data = "";
                        } else if (columnsChar[i] == ';') // ;  , ??  ?? ?  ?? ??     
                        {
                            if (selectedColumn != null) {
                                newColumn = new Column();
                                newColumn.setName(selectedColumn);
                                newColumn.setType(DataUtil.reCastTotal(true, data));
                                tableSet.getColumns().add(newColumn);
                                data = "";
                                selectedColumn = null;
                            }
                        } else //  ? ? 
                        {
                            data = data + String.valueOf(columnsChar[i]);
                        }
                    }
                }
            } else if (lines.startsWith("$")) // $   ? ,  ? ? , ;  
            {
                String recordData = lines.substring(1).trim();
                char[] recordChar = recordData.toCharArray();

                data = "";
                List<String> recordDatas = new Vector<String>();
                List<String> columnNames = new Vector<String>();
                List<Integer> typeDatas = new Vector<Integer>();

                for (int i = 0; i < recordChar.length; i++) {
                    if (inQuote == '"') //  ?  
                    {
                        if (recordChar[i] == '"') {
                            inQuote = ' ';
                            if (i == recordChar.length - 1) //  ?? 
                            {
                                recordDatas.add(DataUtil.reCastTotal(true, data));
                                data = "";
                            }
                        } else {
                            data = data + String.valueOf(recordChar[i]);
                        }
                    } else //  ?  
                    {
                        if (recordChar[i] == ' ')
                            continue; // ? ?
                        else if (recordChar[i] == '"') {
                            inQuote = '"';
                            data = "";
                        } else if (recordChar[i] == ';') {
                            recordDatas.add(DataUtil.reCastTotal(true, data));
                            data = "";
                        } else {
                            data = data + String.valueOf(recordChar[i]);
                        }
                    }
                }

                Record newRecord = new Record();

                List<Object> newRecordData = new Vector<Object>();

                for (int i = 0; i < recordDatas.size(); i++) {
                    newRecordData.add(recordDatas.get(i));
                }

                newRecord.setDatas(newRecordData);

                for (int i = 0; i < tableSet.getColumns().size(); i++) {
                    columnNames.add(tableSet.getColumn(i).getName());
                    typeDatas.add(new Integer(tableSet.getColumn(i).getType()));
                }

                newRecord.setColumnName(columnNames);
                newRecord.setTypes(typeDatas);

                try {
                    tableSet.addData(newRecord);
                } catch (InvalidInputException e) {
                    Main.logError(e, Manager.applyStringTable("On HGF to TableSet") + "...\n" + hgf);
                    return null;
                }
            }
        }

        return tableSet;
    }

    /**
     * <p>? ? ? ?.</p>
     * 
     * @param file : ? ?
     * @return ?  ?
     * @throws Exception ?  . ? ? ? 
     */
    public static TableSet fromFile(File file) throws Exception {
        if (file == null)
            throw new FileNotFoundException(Manager.applyStringTable("On fromFile,") + " " + String.valueOf(file)
                    + " " + Manager.applyStringTable("is null"));

        String allPath = file.getAbsolutePath();
        if (allPath.endsWith(".xls") || allPath.endsWith(".xlsx") || allPath.endsWith(".XLS")
                || allPath.endsWith(".XLSX") || allPath.endsWith(".Xls") || allPath.endsWith(".Xlsx")) {
            // return new DefaultTableSet(Manager.applyStringTable("NOW_READING"), file);
            return XLSXUtil.toTableSet(Manager.applyStringTable("NOW_READING"), file);
        } else if (allPath.endsWith(".json") || allPath.endsWith(".JSON") || allPath.endsWith(".Json")) {
            return JSONUtil.toTableSet(StreamUtil.readText(file, Manager.getOption("file_charset")));
        } else if (allPath.endsWith(".hgf") || allPath.endsWith(".HGF") || allPath.endsWith(".Hgf")) {
            return toTableSet(StreamUtil.readText(file, Manager.getOption("file_charset")));
        } else {
            return toTableSet(StreamUtil.readText(file, Manager.getOption("file_charset")));
        }
    }

    /**
     * <p>, ?  ?? ? ? . ?? ? ? ?? .</p>
     * 
     * @param t : , ?  ?
     * @return ? 
     */
    public static String stackTrace(Throwable t) {
        StringBuffer results = new StringBuffer("");
        results = results.append(t.getClass().getName() + ": " + t.getMessage() + "\n");
        StackTraceElement[] traces = t.getStackTrace();
        for (StackTraceElement e : traces) {
            results = results.append("\tat " + String.valueOf(e) + "\n");
        }
        return results.toString();
    }

    /**
     * <p>??  ? ??     ? .</p>
     * 
     * @param target : ?? ?
     * @return    ? ?
     */
    public static String remove65279(String target) {
        char[] targetChar = target.toCharArray();

        List<Character> resultChars = new Vector<Character>();
        for (int i = 0; i < targetChar.length; i++) {
            if (((int) targetChar[i]) != 65279)
                resultChars.add(new Character(targetChar[i]));
        }

        char[] newChar = new char[resultChars.size()];
        for (int i = 0; i < newChar.length; i++) {
            newChar[i] = resultChars.get(i);
        }
        return new String(newChar);
    }

    /**
     * <p>?  ? . ?   ? ?  .</p>
     * 
     * @param delim : ?
     * @param contents : ?? ?
     * @return  ? 
     */
    public static List<TextBlock> getBlocks(char delim, String contents) {
        return getBlocks(delim, contents, true);
    }

    /**
     * <p>?  ? . ?   ? ?  .</p>
     * <p>? </p>
     * 
     * @param delim : ?
     * @param contents : ?? ?
     * @return  ? 
     */
    public static List<TextBlock> getBlocks(char delim, String contents, boolean alsoDelimWithNewLine) {
        List<TextBlock> blocks = new Vector<TextBlock>();

        // TODO : ? 

        StringBuffer newBlock = new StringBuffer("");
        int newBlockStartPos = -1;
        char beforeChar = ' ';
        char quotes = ' ';
        boolean casted = false;
        boolean commented = false;
        for (int i = 0; i < contents.length(); i++) {
            char ch = contents.charAt(i);

            if (commented) {
                if (beforeChar == '*' && ch != '/') {
                    newBlock = newBlock.append("*");
                    beforeChar = ' ';
                }

                if (ch == '*') {
                    beforeChar = ch;
                } else if (beforeChar == '*' && ch == '/') {
                    beforeChar = ' ';
                    commented = false;

                    if (DataUtil.isNotEmpty(newBlock.toString())) {
                        blocks.add(new TextBlock(newBlockStartPos, i + 1, "/*" + newBlock.toString() + "*/"));
                        newBlock = new StringBuffer("");
                        newBlockStartPos = i;
                        casted = false;
                    }
                    continue;
                } else {
                    newBlock = newBlock.append(String.valueOf(ch));
                }
            } else {
                if (quotes == ' ') {
                    if (beforeChar == '/' && ch != '*') {
                        if (DataUtil.isEmpty(newBlock.toString())) {
                            newBlockStartPos = i;
                        }
                        newBlock = newBlock.append("/");
                        beforeChar = ' ';
                    }

                    if (ch == '"') {
                        if (casted) {
                            if (DataUtil.isEmpty(newBlock.toString())) {
                                newBlockStartPos = i;
                            }
                            newBlock = newBlock.append("\"");
                            casted = false;
                        } else {
                            quotes = '"';
                        }
                    } else if (beforeChar == '/' && ch == '*') {
                        beforeChar = ' ';
                        commented = true;

                        if (DataUtil.isNotEmpty(newBlock.toString())) {
                            blocks.add(new TextBlock(newBlockStartPos, (i - 1), newBlock.toString()));
                        }
                        newBlock = new StringBuffer("");
                        newBlockStartPos = (i - 1);
                        casted = false;

                        continue;
                    } else if (ch == '\'') {
                        if (casted) {
                            if (DataUtil.isEmpty(newBlock.toString())) {
                                newBlockStartPos = i;
                            }
                            newBlock = newBlock.append("'");
                            casted = false;
                        } else {
                            quotes = '\'';
                        }
                    } else if (ch == '\\') {
                        if (casted) {
                            if (DataUtil.isEmpty(newBlock.toString())) {
                                newBlockStartPos = i;
                            }
                            newBlock = newBlock.append(String.valueOf(ch));
                            casted = false;
                        } else {
                            casted = true;
                        }
                    } else if (ch == delim || (alsoDelimWithNewLine && ch == '\n')
                            || (delim == ' ' && ch == '\t')) {
                        if (DataUtil.isNotEmpty(newBlock.toString())) {
                            blocks.add(new TextBlock(newBlockStartPos, i, newBlock.toString()));
                            newBlock = new StringBuffer("");
                            newBlockStartPos = i;
                            casted = false;
                        }
                    } else if (ch == '*' || ch == '/') {
                        beforeChar = ch;
                    } else {
                        if ((!commented) && DataUtil.isEmpty(newBlock.toString())) {
                            newBlockStartPos = i;
                        }
                        newBlock = newBlock.append(String.valueOf(ch));
                    }
                } else if (quotes == '"') {
                    if (ch == '"') {
                        if (casted) {
                            if ((!commented) && DataUtil.isEmpty(newBlock.toString())) {
                                newBlockStartPos = i;
                            }
                            newBlock = newBlock.append("\"");
                            casted = false;
                        } else {
                            quotes = ' ';
                            if (DataUtil.isNotEmpty(newBlock.toString())) {
                                blocks.add(
                                        new TextBlock(newBlockStartPos, i, reCastQuote(true, newBlock.toString())));
                                newBlock = new StringBuffer("");
                                newBlockStartPos = i;
                                casted = false;
                            }
                        }
                    } else if (ch == '\\') {
                        if (casted) {
                            if ((!commented) && DataUtil.isEmpty(newBlock.toString())) {
                                newBlockStartPos = i;
                            }
                            newBlock = newBlock.append(String.valueOf(ch));
                            casted = false;
                        } else {
                            casted = true;
                        }
                    } else {
                        if ((!commented) && DataUtil.isEmpty(newBlock.toString())) {
                            newBlockStartPos = i;
                        }
                        newBlock = newBlock.append(String.valueOf(ch));
                    }
                } else if (quotes == '\'') {
                    if (ch == '\'') {
                        if (casted) {
                            if ((!commented) && DataUtil.isEmpty(newBlock.toString())) {
                                newBlockStartPos = i;
                            }
                            newBlock = newBlock.append("'");
                            casted = false;
                        } else {
                            quotes = ' ';
                            if (DataUtil.isNotEmpty(newBlock.toString())) {
                                blocks.add(new TextBlock(newBlockStartPos, i,
                                        reCastQuote(false, newBlock.toString())));
                                newBlock = new StringBuffer("");
                                newBlockStartPos = i;
                                casted = false;
                            }
                        }
                    } else if (ch == '\\') {
                        if (casted) {
                            if ((!commented) && DataUtil.isEmpty(newBlock.toString())) {
                                newBlockStartPos = i;
                            }
                            newBlock = newBlock.append(String.valueOf(ch));
                            casted = false;
                        } else {
                            casted = true;
                        }
                    } else {
                        if ((!commented) && DataUtil.isEmpty(newBlock.toString())) {
                            newBlockStartPos = i;
                        }
                        newBlock = newBlock.append(String.valueOf(ch));
                    }
                }
            }

            beforeChar = ch;
        }

        if (DataUtil.isNotEmpty(newBlock.toString())) {
            blocks.add(new TextBlock(newBlockStartPos, contents.length() - 1, newBlock.toString()));
            newBlock = new StringBuffer("");
            casted = false;
        }

        return blocks;
    }

    /**
     * <p>??   ? .</p>
     * 
     * @param values : ??   (byte )
     * @return  ? ?
     */
    public static String toByteUnit(long values) {
        double calcs = 0.0;

        if (values == 0)
            return "0";
        if (values == 1)
            return "1 byte";
        if (values < 1024)
            return String.valueOf(values) + " bytes";

        calcs = values / 1024.0;
        if (calcs < 1024.0)
            return String.format("%.3f KB", calcs);

        calcs = calcs / 1024.0;
        if (calcs < 1024.0)
            return String.format("%.3f MB", calcs);

        calcs = calcs / 1024.0;
        if (calcs < 1024.0)
            return String.format("%.3f GB", calcs);

        calcs = calcs / 1024.0;
        if (calcs < 1024.0)
            return String.format("%.3f TB", calcs);

        calcs = calcs / 1024.0;
        if (calcs < 1024.0)
            return String.format("%.3f PB", calcs);

        calcs = calcs / 1024.0;
        if (calcs < 1024.0)
            return String.format("%.3f EB", calcs);

        calcs = calcs / 1024.0;
        if (calcs < 1024.0)
            return String.format("%.3f ZB", calcs);

        calcs = calcs / 1024.0;
        if (calcs < 1024.0)
            return String.format("%.3f YB", calcs);

        return String.format("%.3f YB", calcs);
    }

    /**
     * <p>?  ? 0 ?.</p>
     * 
     * @param bytes : ? 
     */
    public static void emptyByteArray(byte[] bytes) {
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = 0;
        }
    }

    /**
     * <p> ?  Date ? .</p>
     * 
     * @return  ?
     */
    public static Date currentDate() {
        Date date = new Date(System.currentTimeMillis());
        return date;
    }

    /**
     * <p>?  ??  ? .</p>
     * 
     * @param one :  ?
     * @param two :   ?
     * @return   
     */
    public static Date subtract(Date one, Date two) {
        long oneLong = one.getTime();
        long twoLong = two.getTime();

        if (oneLong > twoLong)
            return new Date(oneLong - twoLong);
        else
            return new Date(twoLong - oneLong);
    }

    /**
     * <p> ??  ?   ??  . finds   ? -1 ? .</p>
     * 
     * @param text : ?
     * @param finds : 
     * @return  ? 
     */
    public static int has(String text, String finds) {
        int results = 0;
        String target = text;

        if (finds.equals(""))
            return -1;

        while (text.indexOf(finds) >= 0) {
            results = results + 1;
            target = target.replaceFirst(finds, "");
        }

        return results;
    }

    /**
     * <p>2? 1  ? .</p>
     * 
     * @param original : ?? 
     * @param scale :  ?
     * @return 2? 1 
     */
    public static BigDecimal sqrt(BigDecimal original, int scale) {
        BigDecimal temp = new BigDecimal(String.valueOf(original));

        BigDecimal results = new BigDecimal("1.0");
        results.setScale(scale + 2);

        int loops = 0;

        while (true) {
            if (loops >= 1) {
                temp = new BigDecimal(String.valueOf(results));
            }

            temp.setScale(scale + 2, BigDecimal.ROUND_FLOOR);
            results = original.divide(temp, scale + 2, BigDecimal.ROUND_FLOOR).add(temp)
                    .divide(new BigDecimal("2.0"), scale + 2, BigDecimal.ROUND_FLOOR);
            if (temp.equals(results))
                break;

            loops++;
        }

        return results.setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * <p>??  . null?  -1?,  ? ?  ?   ?  ? ? .</p>
     * 
     * @param val : ?
     * @param original : 
     * @return   
     */
    public static int parseIntWithoutError(String val, int original) {
        if (val == null)
            return -1;
        try {
            return Integer.parseInt(val.trim());
        } catch (NumberFormatException e) {
            return original;
        }
    }

    /**
     * <p> ?? ?? ? ?? ? .</p>
     * 
     * @param original : ? ?
     * @param lines    : ??  
     * @param startsAt :  ?
     * @param appendies : ? ? ?
     * @return 
     */
    public static String appendLines(String original, int[] lines, int startsAt, String appendies) {
        String[] lineTexts = original.split("\n");
        StringBuffer results = new StringBuffer("");

        for (int l = 0; l < lineTexts.length; l++) {
            char[] lineChars = lineTexts[l].toCharArray();
            List<Character> newChars = new Vector<Character>();
            boolean worked = false;

            boolean exists = false;
            for (int lineNum : lines) {
                if (lineNum == l) {
                    exists = true;
                    break;
                }
            }

            if (!exists)
                continue;

            int charNums = 0;
            for (int i = 0; i < lineChars.length; i++) {
                if (charNums == startsAt) {
                    char[] appendiesChars = appendies.toCharArray();
                    for (int c = 0; c < appendiesChars.length; c++) {
                        newChars.add(appendiesChars[c]);
                        charNums++;
                    }
                }
                newChars.add(lineChars[i]);
                charNums++;
                worked = true;
            }

            while (!worked) {
                if (charNums == startsAt) {
                    char[] appendiesChars = appendies.toCharArray();
                    for (int c = 0; c < appendiesChars.length; c++) {
                        newChars.add(appendiesChars[c]);
                    }
                } else
                    newChars.add(' ');
                charNums++;
            }

            char[] newLineChars = new char[newChars.size()];
            for (int i = 0; i < newChars.size(); i++) {
                newLineChars[i] = newChars.get(i);
            }

            results = results.append(new String(newLineChars)).append("\n");
        }

        return results.toString().trim();
    }

    public static String toString(Date date, String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(date);
    }

    public static Date toDate(String dateVal, String format) throws ParseException {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.parse(dateVal);
    }

    /**
     * <p>BASE64 ? ? ?? ?.</p>
     * 
     * @param bytes : ? ??
     * @return BASE64 ?? ?
     */
    public static String base64(byte[] bytes) {
        return new String(Base64.encodeBase64(bytes));
    }

    /**
     * <p>BASE64 ? ?? ?? ?  .</p>
     * 
     * @param data : ?? ?
     * @return : ? ??
     */
    public static byte[] base64(String data) {
        return Base64.decodeBase64(data.getBytes());
    }
}