nu.mine.kino.assertionutils.TextAssertionLogic.java Source code

Java tutorial

Introduction

Here is the source code for nu.mine.kino.assertionutils.TextAssertionLogic.java

Source

/******************************************************************************
 * Copyright (c) 2014 Masatomi KINO and others. 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * Contributors:
 *      Masatomi KINO - initial API and implementation
 * $Id$
 ******************************************************************************/
//?: 2016/07/19

package nu.mine.kino.assertionutils;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Scanner;

import org.apache.commons.lang3.StringUtils;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.spi.Parameters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * ???????
 * 
 * <ul>
 * <li>???????????????</li>
 * <li>??? ???????????</li>
 * <li>???????????????????????????
 * ?????????????????????</li>
 * </ul>
 * 
 * @author Masatomi KINO
 * @version $Revision$
 */
public class TextAssertionLogic extends DefaultAssertionLogic {
    private static final Logger slogger = LoggerFactory.getLogger("forStackTrace");

    private static final Logger logger = LoggerFactory.getLogger(TextAssertionLogic.class);

    private Charset enc1;

    private Charset enc2;

    public TextAssertionLogic(Parameters params) throws AssertionError {
        super(params);
        enc1 = createCharset(params, 1);
        enc2 = createCharset(params, 2);
        logger.info("    encode: " + enc1.displayName());
        logger.info(" encode: " + enc2.displayName());
    }

    private Charset createCharset(Parameters params, int index) {
        String encoding = getEncoding(params, index);
        if (StringUtils.isEmpty(encoding)) {
            return Charset.defaultCharset();
        }
        return Charset.forName(encoding);
    }

    @Override
    public void executeAssertion(Path expected, Path actual) throws AssertionError {

        LINE_SEPARATOR eSeparator = getLineSeparator(expected, enc1);
        LINE_SEPARATOR aSeparator = getLineSeparator(actual, enc2);

        // ?null??????
        // ?????????????????????
        if (eSeparator != null && aSeparator != null) {
            assertThat("?", aSeparator, is(eSeparator));
        }
        logger.debug("?{}??", aSeparator);

        List<String> expectedLines = readText(expected, enc1);
        List<String> actualLines = readText(actual, enc2);

        assertThat("?", actualLines.size(), is(expectedLines.size()));
        for (int i = 0; i < actualLines.size(); i++) {
            String actualLine = actualLines.get(i);
            String expectedLine = expectedLines.get(i);
            executeTextAssertion(expectedLine, actualLine);
        }

        LINE_SEPARATOR eLastLineSepa = getLastStrAndIsLineSeparator(expected, enc1);
        LINE_SEPARATOR aLastLineSepa = getLastStrAndIsLineSeparator(actual, enc2);

        // ?NULL?????assert????
        // NULL??NULL???true????
        if (eLastLineSepa == null || aLastLineSepa == null) {
            assertThat("??", aLastLineSepa, is(eLastLineSepa));
        }

    }

    /**
     * ?????? ??????NULL????????enum?
     * 
     * @param path
     * @param enc
     * @return
     */
    private LINE_SEPARATOR getLastStrAndIsLineSeparator(Path path, Charset enc) {
        byte[] bytes = readBinary(path);
        String target = new String(bytes, enc);

        if (target.endsWith("\r\n")) {
            return LINE_SEPARATOR.CRLF;
        } else if (target.endsWith("\r")) {
            return LINE_SEPARATOR.CR;
        }
        if (target.endsWith("\n")) {
            return LINE_SEPARATOR.LF;
        }
        return null;
    }

    /**
     * ??????NULL:
     * 
     * @param path
     * @param charsetName
     * @return
     */
    private LINE_SEPARATOR getLineSeparator(Path path, Charset charsetName) {
        String LINE_SEPARATOR_PATTERN = "\r\n|[\n\r\u2028\u2029\u0085]";
        try (Scanner scan = new Scanner(path, charsetName.name())) {
            String lineSeparator = scan.findWithinHorizon(LINE_SEPARATOR_PATTERN, 0);
            if (StringUtils.isEmpty(lineSeparator)) {
                return null;
            }
            if (lineSeparator.contains("\r")) {
                if (lineSeparator.contains("\r\n")) {
                    return LINE_SEPARATOR.CRLF;
                } else {
                    return LINE_SEPARATOR.CR;
                }
            } else if (lineSeparator.contains("\n")) {
                return LINE_SEPARATOR.LF;
            }
        } catch (IOException e) {
            slogger.error("??????: {},({})", path, e.getMessage());
            slogger.error("", e);
            String message = "java.nio.charset.MalformedInputException: Input length = xx? \n???????"
                    + "????????????????????"
                    + "?????";
            slogger.error(message);
            fail(e.getMessage());
        }
        return null;
    }

    private List<String> readText(Path path, Charset enc) {
        List<String> lines = null;
        try {
            lines = Files.readAllLines(path, enc);
        } catch (IOException e) {
            slogger.error("??????: {},({})", path, e.getMessage());
            slogger.error("", e);
            String message = "java.nio.charset.MalformedInputException: Input length = xx? \n???????"
                    + "????????????????????"
                    + "?????";
            slogger.error(message);
            fail(e.getMessage());
        }
        return lines;
    }

    private byte[] readBinary(Path path) {
        try {
            return Files.readAllBytes(path);
        } catch (IOException e) {
            slogger.error("??????: {},({})", path, e.getMessage());
            slogger.error("", e);
            fail(e.getMessage());
        }
        return new byte[0];
    }

    public void executeTextAssertion(String expectedLine, String actualLine) {
        String message = "??: ";
        assertThat(message, actualLine, is(expectedLine));
    }

    /**
     * ??????? -1???????????
     * 
     * @param index
     * @return
     * @throws CmdLineException
     */
    private String getEncoding(Parameters params, int index) {
        // String auto = "JISAutoDetect";
        String auto = null;

        try {
            return params.getParameter(index);
        } catch (CmdLineException e) {
            if (index == 1) {
                return auto;
            }
            try {
                return params.getParameter(index - 1);
            } catch (CmdLineException e1) {
                return auto;
            }
        }
    }

    enum LINE_SEPARATOR {
        CR, CRLF, LF;
    }

}