All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hcl.domino.util.JNXDumpUtil Maven / Gradle / Ivy

There is a newer version: 1.44.0
Show newest version
/*
 * ==========================================================================
 * Copyright (C) 2019-2022 HCL America, Inc. ( http://www.hcl.com/ )
 *                            All rights reserved.
 * ==========================================================================
 * Licensed under the  Apache License, Version 2.0  (the "License").  You may
 * not use this file except in compliance with the License.  You may obtain a
 * copy of the License at .
 *
 * Unless  required  by applicable  law or  agreed  to  in writing,  software
 * distributed under the License is distributed on an  "AS IS" BASIS, WITHOUT
 * WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the  specific language  governing permissions  and limitations
 * under the License.
 * ==========================================================================
 */
package com.hcl.domino.util;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.io.Writer;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Scanner;

import com.hcl.domino.richtext.records.RichTextRecord;

/**
 * Utility class to dump memory content
 * 
 * @author Karsten Lehmann
 */
public class JNXDumpUtil {

  /**
   * Creates a log file and ensures its content is
   * written to disk when the method is done (e.g. to write something to disk before
   * a crash).
* By default we use the temp directory (system property "java.io.tmpdir"). * By setting the system property "dominojnx.dumpdir", the output directory can be changed. * * @param suffix filename will be "domino-jnxlog-" + suffix + uniquenr + ".txt" * @param content file content * @return created temp file or null in case of errors */ public static Path writeLogFile(final String suffix, final String content) { return AccessController.doPrivileged((PrivilegedAction) () -> { OutputStream fOut = null; Writer fWriter = null; try { String outDirPath = AccessController.doPrivileged((PrivilegedAction) () -> System.getProperty("dominojnx.dumpdir", null)); //$NON-NLS-1$ if (JNXStringUtil.isEmpty(outDirPath)) { outDirPath = AccessController.doPrivileged((PrivilegedAction) () -> System.getProperty("java.io.tmpdir", null)); //$NON-NLS-1$ } Path outDir = Paths.get(outDirPath); Files.createDirectories(outDir); Path dmpFile = Files.createTempFile(outDir, "domino-jnxlog-"+suffix+"-", ".txt"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ fOut = Files.newOutputStream(dmpFile, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); fWriter = new OutputStreamWriter(fOut, StandardCharsets.UTF_8); fWriter.write(content); fWriter.flush(); return dmpFile; } catch (IOException e1) { e1.printStackTrace(); } finally { if (fWriter!=null) { try { fWriter.close(); } catch (IOException e2) { e2.printStackTrace(); } } if (fOut!=null) { try { fOut.close(); } catch (IOException e3) { e3.printStackTrace(); } } } return null; }); } /** * Reads memory content at the specified pointer and produces a String with hex codes and * character data in case the memory contains bytes in ascii range. Calls {@link #dumpAsAscii(ByteBuffer, int, int)} * with cols = 8 and size = buf.remaining(). * * @param buf byte buffer * @return memory dump * @since 1.0.32 */ public static String dumpAsAscii(ByteBuffer buf) { return dumpAsAscii(buf, buf.remaining()); } /** * Reads byte array content and produces a String with hex codes and character data in case the memory contains * bytes in ascii range. Calls {@link #dumpAsAscii(ByteBuffer, int, int)} with cols = 8 and size = data.length. * * @param data byte array * @return memory dump * @since 1.0.32 */ public static String dumpAsAscii(byte[] data) { return dumpAsAscii(ByteBuffer.wrap(data)); } /** * Reads memory content at the specified pointer and produces a String with hex codes and * character data in case the memory contains bytes in ascii range. Calls {@link #dumpAsAscii(ByteBuffer, int, int)} * with cols = 8. * * @param buf byte buffer * @param size number of bytes to read * @return memory dump */ public static String dumpAsAscii(ByteBuffer buf, int size) { return dumpAsAscii(buf, size, 8); } /** * Reads memory content at the specified pointer and produces a String with hex codes and * character data in case the memory contains bytes in ascii range. * * @param buf byte buffer * @param size number of bytes to read * @param cols number of bytes written in on eline * @return memory dump */ public static String dumpAsAscii(ByteBuffer buf, int size, int cols) { StringBuilder sb = new StringBuilder(); int i = 0; size = Math.min(size, buf.limit()); while (i < size) { sb.append("["); //$NON-NLS-1$ for (int c=0; c0) { sb.append(' '); } if ((i+c) < size) { byte b = buf.get(i+c); if (b >=0 && b < 16) { sb.append("0"); //$NON-NLS-1$ } sb.append(Integer.toHexString(b & 0xFF)); } else { sb.append(" "); //$NON-NLS-1$ } } sb.append("]"); //$NON-NLS-1$ sb.append(" "); //$NON-NLS-1$ sb.append("["); //$NON-NLS-1$ for (int c=0; c= 32 && bAsInt<=126) { sb.append((char) (b & 0xFF)); } else { sb.append("."); //$NON-NLS-1$ } } else { sb.append(" "); //$NON-NLS-1$ } } sb.append("]\n"); //$NON-NLS-1$ i += cols; } return sb.toString(); } /** * Reads memory content of two {@link ByteBuffer} objects and produces a String with hex codes and * character data in case the memory contains bytes in ascii range. * * @param headline1 headline for first bytebuffer * @param buf1 first byte buffer * @param headline2 headline for second bytebuffer * @param buf2 second byte buffer * @param size number of bytes to read * @param cols number of bytes written in on eline * @return memory dump */ public static String dumpAsAscii(String headline1, ByteBuffer buf1, String headline2, ByteBuffer buf2, int size, int cols) { String dumpBuf1 = dumpAsAscii(buf1, size, cols); String dumpBuf2 = dumpAsAscii(buf2, size, cols); try (Scanner scannerBuf1 = new Scanner(new StringReader(dumpBuf1)); Scanner scannerBuf2 = new Scanner(new StringReader(dumpBuf2));) { List lines1 = new ArrayList<>(); List lines2 = new ArrayList<>(); int maxLine1Len = 0; int maxLine2Len = 0; while (scannerBuf1.hasNext() || scannerBuf2.hasNext()) { String line1 = scannerBuf1.hasNext() ? scannerBuf1.nextLine() : ""; //$NON-NLS-1$ maxLine1Len = Math.max(maxLine1Len, line1.length()); lines1.add(line1); String line2 = scannerBuf2.hasNext() ? scannerBuf2.nextLine() : ""; //$NON-NLS-1$ maxLine2Len = Math.max(maxLine2Len, line2.length()); lines2.add(line2); } StringBuilder sb = new StringBuilder(); //write header sb.append(headline1.substring(0, Math.min(headline1.length(), maxLine1Len))); if (headline1.length() < maxLine1Len) { sb.append(JNXStringUtil.repeat(' ', maxLine1Len - headline1.length())); } sb.append(" | "); //$NON-NLS-1$ sb.append(headline2.substring(0, Math.min(headline2.length(), maxLine2Len))); if (headline2.length() < maxLine2Len) { sb.append(JNXStringUtil.repeat(' ', maxLine2Len - headline2.length())); } sb.append(" | Different?"); //$NON-NLS-1$ sb.append("\n"); //$NON-NLS-1$ for (int i=0; i> rt) { StringBuilder sb = new StringBuilder(); rt.forEach((record) -> { String txt = dumpAsAscii(record); sb.append(txt); }); return sb.toString(); } /** * Produces a string with richtext record type, hex codes and character data * * @param record richtext record * @return record dump */ public static String dumpAsAscii(RichTextRecord record) { return new StringBuilder() .append(record.getType()) .append(MessageFormat.format(" ({0} bytes total, {1} bytes variable length)", record.getCDRecordLength(), record.getVariableData().capacity())) //$NON-NLS-1$ .append('\n') .append(dumpAsAscii(record.getData())) .append("\n\n") //$NON-NLS-1$ .toString(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy