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.function; 020 021import org.jpos.core.Configurable; 022import org.jpos.core.Configuration; 023import org.jpos.core.ConfigurationException; 024 025import java.nio.ByteBuffer; 026 027/** 028 * Mapper for removing newlines from the output of writing LogEvents to a stream. 029 * 030 * Configuration options allow you to optionally combine multiple spaces into a single space and 031 * opting not to add a newline at the end of the data. 032 * 033 * Example: <br> 034 * <pre>{@code 035 * <output-mapper class="org.jpos.util.function.RemoveNewLinesMapper"> 036 * <properties name="combine-spaces" value="true"/> 037 * <properties name="newline-at-end" value="false"/> 038 * </output-mapper> 039 * }</pre><br> 040 * 041 * <b>NB. Do not set combine-spaces to true if you have data where spaces are significant.</b> 042 * 043 * @author Alwyn Schoeman 044 * @since 2.1.4 045 */ 046public class RemoveNewLinesMapper implements ByteArrayMapper, Configurable { 047 /** Creates a mapper with default settings; tweak via {@link #setConfiguration(Configuration)}. */ 048 public RemoveNewLinesMapper() {} 049 boolean combineSpaces = false; 050 boolean newLineAtEnd = true; 051 final byte SPACE = ' '; 052 byte[] NEWLINE_SEPARATORS = System.lineSeparator().getBytes(); 053 054 @Override 055 public byte[] apply(byte[] bytes) { 056 final ByteBuffer buffer = ByteBuffer.allocate(bytes.length); 057 boolean prevSpace = false; 058 for (byte aByte : bytes) { 059 if (aByte == SPACE) { 060 if (combineSpaces) { 061 prevSpace = true; 062 } else { 063 buffer.put(aByte); 064 } 065 } else { 066 if (combineSpaces && prevSpace) { 067 buffer.put(SPACE); 068 prevSpace = false; 069 } 070 if (!isNewLine(aByte)) { 071 buffer.put(aByte); 072 } 073 } 074 } 075 // Solve the mystery of the missing trailing spaces. 076 if (combineSpaces && prevSpace) { 077 buffer.put(SPACE); 078 } 079 if (newLineAtEnd) { 080 buffer.put(NEWLINE_SEPARATORS); 081 } 082 buffer.flip(); 083 byte[] result = new byte[buffer.limit()]; 084 buffer.get(result); 085 return result; 086 } 087 088 @Override 089 public void setConfiguration(Configuration cfg) throws ConfigurationException { 090 combineSpaces = cfg.getBoolean("combine-spaces", false); 091 newLineAtEnd = cfg.getBoolean("newline-at-end", true); 092 } 093 094 private boolean isNewLine(byte aByte) { 095 boolean isNewLine = false; 096 for (byte b : NEWLINE_SEPARATORS) { 097 if (aByte == b) { 098 isNewLine = true; 099 break; 100 } 101 } 102 return isNewLine; 103 } 104}