org.wso2.andes.tools.messagestore.commands.Dump.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.andes.tools.messagestore.commands.Dump.java

Source

/*
 * Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. licenses this file to you 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
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 org.wso2.andes.tools.messagestore.commands;

import org.apache.commons.codec.binary.Hex;
import org.wso2.andes.server.queue.QueueEntryImpl;
import org.wso2.andes.server.queue.QueueEntry;
import org.wso2.andes.server.message.ServerMessage;
import org.wso2.andes.tools.messagestore.MessageStoreTool;
import org.wso2.andes.tools.utils.Console;

import java.io.UnsupportedEncodingException;
import java.util.LinkedList;
import java.util.List;

public class Dump extends Show {
    private static final int LINE_SIZE = 8;
    private static final String DEFAULT_ENCODING = "utf-8";
    private static final boolean SPACE_BYTES = true;
    private static final String BYTE_SPACER = " ";
    private static final String NON_PRINTING_ASCII_CHAR = "?";

    protected boolean _content = true;

    public Dump(MessageStoreTool tool) {
        super(tool);
    }

    public String help() {
        return "Dump selected message content. Default: show=content";
    }

    public String usage() {
        return getCommand()
                + " [show=[all],[msgheaders],[_amqHeaders],[routing],[content]] [id=<msgid e.g. 1,2,4-10>]";
    }

    public String getCommand() {
        return "dump";
    }

    public void execute(String... args) {
        assert args.length > 0;
        assert args[0].equals(getCommand());

        if (args.length >= 2) {
            for (String arg : args) {
                if (arg.startsWith("show=")) {
                    _content = arg.contains("content") || arg.contains("all");
                }
            }

            parseArgs(args);
        }

        performShow();
    }

    protected List<List> createMessageData(java.util.List<Long> msgids, List<QueueEntry> messages,
            boolean showHeaders, boolean showRouting, boolean showMessageHeaders) {

        List<List> display = new LinkedList<List>();

        List<String> hex = new LinkedList<String>();
        List<String> ascii = new LinkedList<String>();
        display.add(hex);
        display.add(ascii);

        for (QueueEntry entry : messages) {
            ServerMessage msg = entry.getMessage();
            if (!includeMsg(msg, msgids)) {
                continue;
            }

            //Add divider between messages
            hex.add(Console.ROW_DIVIDER);
            ascii.add(Console.ROW_DIVIDER);

            // Show general message information
            hex.add(Show.Columns.ID.name());
            ascii.add(msg.getMessageNumber().toString());

            hex.add(Console.ROW_DIVIDER);
            ascii.add(Console.ROW_DIVIDER);

            if (showRouting) {
                addShowInformation(hex, ascii, msg, "Routing Details", true, false, false);
            }
            if (showHeaders) {
                addShowInformation(hex, ascii, msg, "Headers", false, true, false);
            }
            if (showMessageHeaders) {
                addShowInformation(hex, ascii, msg, null, false, false, true);
            }

            // Add Content Body section
            hex.add("Content Body");
            ascii.add("");
            hex.add(Console.ROW_DIVIDER);
            ascii.add(Console.ROW_DIVIDER);

            final int messageSize = (int) msg.getSize();
            if (messageSize != 0) {
                hex.add("Hex");
                hex.add(Console.ROW_DIVIDER);

                ascii.add("ASCII");
                ascii.add(Console.ROW_DIVIDER);

                java.nio.ByteBuffer buf = java.nio.ByteBuffer.allocate(64 * 1024);

                int position = 0;

                while (position < messageSize) {

                    position += msg.getContent(buf, position);
                    buf.flip();
                    //Duplicate so we don't destroy original data :)
                    java.nio.ByteBuffer hexBuffer = buf;

                    java.nio.ByteBuffer charBuffer = hexBuffer.duplicate();

                    Hex hexencoder = new Hex();

                    while (hexBuffer.hasRemaining()) {
                        byte[] line = new byte[LINE_SIZE];

                        int bufsize = hexBuffer.remaining();
                        if (bufsize < LINE_SIZE) {
                            hexBuffer.get(line, 0, bufsize);
                        } else {
                            bufsize = line.length;
                            hexBuffer.get(line);
                        }

                        byte[] encoded = hexencoder.encode(line);

                        try {
                            String encStr = new String(encoded, 0, bufsize * 2, DEFAULT_ENCODING);
                            String hexLine = "";

                            int strLength = encStr.length();
                            for (int c = 0; c < strLength; c++) {
                                hexLine += encStr.charAt(c);

                                if ((c & 1) == 1 && SPACE_BYTES) {
                                    hexLine += BYTE_SPACER;
                                }
                            }

                            hex.add(hexLine);
                        } catch (UnsupportedEncodingException e) {
                            _console.println(e.getMessage());
                            return null;
                        }
                    }

                    while (charBuffer.hasRemaining()) {
                        String asciiLine = "";

                        for (int pos = 0; pos < LINE_SIZE; pos++) {
                            if (charBuffer.hasRemaining()) {
                                byte ch = charBuffer.get();

                                if (isPrintable(ch)) {
                                    asciiLine += (char) ch;
                                } else {
                                    asciiLine += NON_PRINTING_ASCII_CHAR;
                                }

                                if (SPACE_BYTES) {
                                    asciiLine += BYTE_SPACER;
                                }
                            } else {
                                break;
                            }
                        }

                        ascii.add(asciiLine);
                    }
                    buf.clear();
                }
            } else {
                List<String> result = new LinkedList<String>();

                display.add(result);
                result.add("No ContentBodies");
            }
        }

        // if hex is empty then we have no data to display
        if (hex.size() == 0) {
            return null;
        }

        return display;
    }

    private void addShowInformation(List<String> column1, List<String> column2, ServerMessage msg, String title,
            boolean routing, boolean headers, boolean messageHeaders) {
        List<QueueEntry> single = new LinkedList<QueueEntry>();
        single.add(new QueueEntryImpl(null, msg, Long.MIN_VALUE));

        List<List> routingData = super.createMessageData(null, single, headers, routing, messageHeaders);

        //Reformat data
        if (title != null) {
            column1.add(title);
            column2.add("");
            column1.add(Console.ROW_DIVIDER);
            column2.add(Console.ROW_DIVIDER);
        }

        // look at all columns in the routing Data
        for (List item : routingData) {
            // the item should be:
            //   Title
            //   *divider
            //   value
            // otherwise we can't reason about the correct value
            if (item.size() == 3) {
                //Filter out the columns we are not interested in.

                String columnName = item.get(0).toString();

                if (!(columnName.equals(Show.Columns.ID.name()) || columnName.equals(Show.Columns.Size.name()))) {
                    column1.add(columnName);
                    column2.add(item.get(2).toString());
                }
            }
        }
        column1.add(Console.ROW_DIVIDER);
        column2.add(Console.ROW_DIVIDER);
    }

    private boolean isPrintable(byte c) {
        return c > 31 && c < 127;
    }
}