org.openlegacy.terminal.render.DefaultTerminalSnapshotTextRenderer.java Source code

Java tutorial

Introduction

Here is the source code for org.openlegacy.terminal.render.DefaultTerminalSnapshotTextRenderer.java

Source

/*******************************************************************************
 * Copyright (c) 2014 OpenLegacy Inc.
 * 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:
 *     OpenLegacy Inc. - initial API and implementation
 *******************************************************************************/
package org.openlegacy.terminal.render;

import org.apache.commons.lang.CharEncoding;
import org.apache.commons.lang.SystemUtils;
import org.openlegacy.exceptions.OpenLegacyRuntimeException;
import org.openlegacy.terminal.ScreenSize;
import org.openlegacy.terminal.TerminalField;
import org.openlegacy.terminal.TerminalPosition;
import org.openlegacy.terminal.TerminalSendAction;
import org.openlegacy.terminal.TerminalSnapshot;
import org.openlegacy.terminal.utils.FieldsQuery;
import org.openlegacy.terminal.utils.FieldsQuery.EditableFieldsCriteria;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.List;

/**
 * A textual utility which format terminal snapshot in to a preventable text which is very comfort for debugging purposes
 * 
 */
public class DefaultTerminalSnapshotTextRenderer implements TerminalSnapshotTextRenderer {

    private static DefaultTerminalSnapshotTextRenderer instance = new DefaultTerminalSnapshotTextRenderer();

    private boolean hidePasswordFields = true;

    public static DefaultTerminalSnapshotTextRenderer instance() {
        return instance;
    }

    @Override
    public void render(TerminalSnapshot terminalSnapshot, OutputStream outputStream) {
        boolean decorated = true;

        String text = terminalSnapshot.getText();
        String newline = SystemUtils.LINE_SEPARATOR;
        int rows = terminalSnapshot.getSize().getRows();
        StringBuilder out = new StringBuilder();
        if (decorated) {
            generateColumnNumbers(terminalSnapshot, newline, out);
        }
        for (int i = 0; i < rows; i++) {
            int beginIndex = i * terminalSnapshot.getSize().getColumns();
            if (decorated) {
                out.append(i + 1);
                if (decorated) {
                    if ((i + 1) < 10) {
                        out.append(" ");
                    }
                    out.append("|");
                }
            }
            if (decorated) {
                out.append(text.substring(beginIndex, beginIndex + terminalSnapshot.getSize().getColumns()));
                out.append("|");
            }
            out.append(newline);
        }
        if (decorated) {
            out.append("___________________________________________________________________________________");
        }
        if (decorated) {
            out.append(newline);
            generateColumnNumbers(terminalSnapshot, newline, out);
        }

        drawFieldsSeperators(terminalSnapshot, out);
        drawEditableFields(terminalSnapshot, out,
                FieldsQuery.queryFields(terminalSnapshot, EditableFieldsCriteria.instance()));

        try {
            // append new line so snapshot will be rendered from start of line in logs
            outputStream.write(SystemUtils.LINE_SEPARATOR.getBytes());
            outputStream.write(out.toString().getBytes(CharEncoding.UTF_8));
        } catch (IOException e) {
            throw (new OpenLegacyRuntimeException(e));
        }

    }

    @SuppressWarnings("unused")
    private static void drawCursor(TerminalSnapshot terminalSnapshot, StringBuilder out,
            TerminalSendAction terminalSendAction) {
        if (terminalSendAction.getCursorPosition() == null) {
            return;
        }
        int cursorPainterLocation = calculatePositionOnPainter(terminalSendAction.getCursorPosition(),
                terminalSnapshot.getSize());
        if (out.charAt(cursorPainterLocation) == ' ') {
            out.setCharAt(cursorPainterLocation, '#');
        }

    }

    private static void drawFieldsSeperators(TerminalSnapshot terminalSnapshot, StringBuilder out) {
        List<TerminalPosition> attributes = terminalSnapshot.getFieldSeperators();
        for (TerminalPosition position : attributes) {
            if (position.getColumn() > 0) {
                int bufferLocation = calculatePositionOnPainter(position, terminalSnapshot.getSize());
                out.setCharAt(bufferLocation, '^');
            }
        }

    }

    private static void generateColumnNumbers(TerminalSnapshot terminalSnapshot, String newline,
            StringBuilder out) {
        StringBuilder headerLine1 = new StringBuilder("    ");
        StringBuilder headerLine2 = new StringBuilder("    ");
        for (int i = 2; i <= terminalSnapshot.getSize().getColumns(); i++) {
            if (i % 2 == 0) {
                headerLine1.append(i % 10);
                if ((i / 10) > 0) {
                    headerLine2.append(i / 10);
                } else {
                    headerLine2.append(" ");
                }
            } else {
                headerLine1.append(" ");
                if ((i / 10) < 10) {
                    headerLine2.append(" ");
                }
            }

        }
        out.append(headerLine1 + newline);
        out.append(headerLine2 + newline);
        out.append("___________________________________________________________________________________");
        out.append(newline);
    }

    private void drawEditableFields(TerminalSnapshot terminalSnapshot, StringBuilder out,
            Collection<TerminalField> fields) {
        char leftMark;
        char rightMark;
        for (TerminalField terminalField : fields) {
            // +6 - line numbers + |
            int beforeInputBufferLocation = calculatePositionOnPainter(terminalField.getPosition(),
                    terminalSnapshot.getSize()) - 1;
            if (terminalField.isModified()) {
                leftMark = '*';
                rightMark = '*';
            } else {
                leftMark = '[';
                rightMark = ']';
            }
            out.setCharAt(beforeInputBufferLocation, leftMark);
            int afterInputBufferLocation = beforeInputBufferLocation + terminalField.getLength() + 1;
            out.setCharAt(afterInputBufferLocation, rightMark);

            String value = terminalField.getValue();
            for (int i = 0; i < terminalField.getLength(); i++) {
                int inputBufferLocation = beforeInputBufferLocation + 1;
                if (i < value.length()) {
                    char ch = value.charAt(i);
                    if (hidePasswordFields && terminalField.isPassword()) {
                        ch = '*';
                    }
                    out.setCharAt(inputBufferLocation + i, ch);
                } else {
                    out.setCharAt(inputBufferLocation + i, ' ');
                }
            }
        }
    }

    private static int calculatePositionOnPainter(TerminalPosition position, ScreenSize screenSize) {
        int fieldStartBufferLocation = (screenSize.getColumns() + 4 + SystemUtils.LINE_SEPARATOR.length()) // 6- line numbers + |
                // + NL
                // -1 - 0 base, +3 - header
                * (position.getRow() - 1 + 3) + position.getColumn() - 1;
        return fieldStartBufferLocation;
    }

    @Override
    public String getFileFormat() {
        return "txt";
    }

    public void setHidePasswordFields(boolean hidePasswordFields) {
        this.hidePasswordFields = hidePasswordFields;
    }
}