001/*
002 * jPOS Project [http://jpos.org]
003 * Copyright (C) 2000-2026 jPOS Software SRL
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.jpos.log;
020
021import java.io.ByteArrayOutputStream;
022import java.io.PrintStream;
023
024/**
025 * Strategy that renders an object of type {@code T} into a target log format
026 * (XML, JSON, plain text, or Markdown).
027 *
028 * @param <T> the concrete type rendered by this strategy
029 */
030public interface LogRenderer<T> {
031    /**
032     * Renders the given object to the print stream with the specified indentation.
033     * @param obj the object to render
034     * @param ps the output stream
035     * @param indent indentation prefix
036     */
037    void render (T obj, PrintStream ps, String indent);
038    /**
039     * Returns the class this renderer handles.
040     * @return the handled class
041     */
042    Class<?> clazz();
043    /**
044     * Returns the log event type this renderer handles.
045     * @return the handled event type
046     */
047    Type type();
048
049    /**
050     * Renders the given object to the print stream with no indentation.
051     * @param obj the object to render
052     * @param ps the output stream
053     */
054    default void render (T obj, PrintStream ps) {
055        render (obj, ps, "");
056    }
057
058    /**
059     * Renders the given object to a string with the specified indentation.
060     * @param obj the object to render
061     * @param indent indentation prefix
062     * @return rendered string
063     */
064    default String render (T obj, String indent) {
065        ByteArrayOutputStream baos = new ByteArrayOutputStream();
066        PrintStream ps = new PrintStream(baos);
067        render (obj, ps, indent);
068        return baos.toString();
069    }
070
071    /**
072     * Renders the given object to a string with no indentation.
073     * @param obj the object to render
074     * @return rendered string
075     */
076    default String render (T obj) {
077        return render (obj, "");
078    }
079
080    /**
081     * Prepends {@code indent} to each line of {@code s}.
082     * @param indent the indentation string
083     * @param s the multi-line string to indent
084     * @return the indented string
085     */
086    default String indent (String indent, String s) {
087        if (s == null || s.isEmpty() || indent==null || indent.isEmpty()) {
088            return s;
089        }
090        String[] lines = s.split("\n", -1);  // Preserve trailing empty strings
091        StringBuilder indentedString = new StringBuilder();
092        for (int i = 0; i < lines.length; i++) {
093            indentedString.append(indent).append(lines[i]);
094            if (i < lines.length - 1) {
095                indentedString.append("\n");
096            }
097        }
098        return indentedString.toString();
099    }
100
101
102    /** Supported log output format types. */
103    enum Type {
104        /** Renders to XML output. */
105        XML,
106        /** Renders to JSON output. */
107        JSON,
108        /** Renders to plain text. */
109        TXT,
110        /** Renders to Markdown. */
111        MARKDOWN
112    }
113}