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.util; 020import java.io.PrintStream; 021import java.util.regex.Pattern; 022 023/** 024 * Helpers for emitting strings that may contain XML-reserved characters 025 * inside log payloads, optionally wrapping them in {@code CDATA} blocks. 026 */ 027public class LogUtil { 028 /** Utility class; instances carry no state. */ 029 public LogUtil() {} 030 /** Regex matching XML-reserved characters that force CDATA escaping. */ 031 public static final Pattern xmlReservedPattern = Pattern.compile("&|<|>"); 032 033 /** 034 * Writes {@code s} to {@code p}, wrapping it in {@code <![CDATA[...]]>} when 035 * the string contains XML-reserved characters. 036 * 037 * @param p destination stream 038 * @param indent prefix used when the value is dumped on a single line 039 * @param s value to emit 040 */ 041 public static void dump (PrintStream p, String indent, String s) { 042 try { 043 boolean expanded = s.length() > 60; 044 if (needsCDATA(s)) { 045 if (expanded) { 046 p.println("<![CDATA["); 047 p.println(s); 048 p.println("]]>"); 049 } else { 050 p.print(indent + "<![CDATA["); 051 p.print(s); 052 p.println("]]>"); 053 } 054 } else 055 p.print(s); 056 } catch (Exception e) { 057 p.println(e.getMessage()); 058 } 059 } 060 061 /** 062 * Indicates whether {@code s} contains any XML-reserved characters and therefore 063 * needs {@code CDATA} escaping when embedded in XML output. 064 * 065 * @param s value to inspect 066 * @return {@code true} if any of {@code &}, {@code <}, or {@code >} is present 067 */ 068 public static boolean needsCDATA(String s) { 069 return xmlReservedPattern.matcher(s).find(); 070 } 071}