/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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.apache.qpid.management.ui.views;
import org.apache.commons.codec.binary.Hex;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.apache.qpid.management.ui.ApplicationRegistry;
import static org.apache.qpid.management.ui.Constants.FAILURE_IMAGE;
import static org.apache.qpid.management.ui.Constants.SUCCESS_IMAGE;
import javax.management.openmbean.ArrayType;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Utility Class for displaying OpenMbean data types by creating required SWT widgets
*/
public class ViewUtility
{
public static final String OP_NAME = "operation_name";
public static final String OP_PARAMS = "parameters";
public static final String PARAMS_TEXT = "text";
public static final String FIRST = "First";
public static final String LAST = "Last";
public static final String NEXT = "Next";
public static final String PREV = "Previous";
public static final String INDEX = "Index";
private static final Comparator tabularDataComparator = new TabularDataComparator();
private static MBeanView _mbeanView = null;
private static List<String> SUPPORTED_ARRAY_DATATYPES = new ArrayList<String>();
static
{
SUPPORTED_ARRAY_DATATYPES.add("java.lang.String");
SUPPORTED_ARRAY_DATATYPES.add("java.lang.Boolean");
SUPPORTED_ARRAY_DATATYPES.add("java.lang.Character");
SUPPORTED_ARRAY_DATATYPES.add("java.lang.Integer");
SUPPORTED_ARRAY_DATATYPES.add("java.lang.Long");
SUPPORTED_ARRAY_DATATYPES.add("java.lang.Double");
SUPPORTED_ARRAY_DATATYPES.add("java.util.Date");
}
private static final int DEFAULT_CONTENT_SIZE = 198;
private static Button _firstButton, _nextButton, _previousButton, _lastButton;
private static Text _hexNumTextToEnd, _hexNumTextToStart;
/**
* Populates the composite with given openmbean data type (TabularType or CompositeType)
* @param toolkit
* @param parent composite
* @param data open mbean data type(either composite type or tabular data type)
*/
public static void populateCompositeWithData(FormToolkit toolkit, Composite parent, Object data)
{
if (data instanceof TabularDataSupport)
{
ViewUtility.createTabularDataHolder(toolkit, parent, (TabularDataSupport)data);
}
else if (data instanceof CompositeDataSupport)
{
ViewUtility.populateCompositeWithCompositeData(toolkit, parent, (CompositeDataSupport)data);
}
}
@SuppressWarnings("unchecked")
private static void createTabularDataHolder(FormToolkit toolkit, Composite parent, TabularDataSupport tabularData)
{
Composite composite = toolkit.createComposite(parent, SWT.BORDER);
GridLayout layout = new GridLayout(4, true);
layout.horizontalSpacing = 0;
layout.marginWidth = 0;
layout.marginHeight = 10;
layout.verticalSpacing = 10;
composite.setLayout(layout);
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Set entrySet = tabularData.entrySet();
ArrayList<Map.Entry> list = new ArrayList<Map.Entry>(entrySet);
if (list.size() == 0)
{
Text text = toolkit.createText(composite, " No records ", SWT.CENTER | SWT.SINGLE | SWT.READ_ONLY);
GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1);
text.setLayoutData(layoutData);
return;
}
Collections.sort(list, tabularDataComparator);
// Attach the tabular record to be retrieved and shown later when record is traversed
// using first/next/previous/last buttons
composite.setData(list);
// Create button and the composite for CompositeData
Composite compositeDataHolder = createCompositeDataHolder(toolkit, composite,
tabularData.getTabularType().getRowType());
// display the first record
CompositeData data = (CompositeData)(list.get(0)).getValue();
composite.setData(INDEX, 0);
populateCompositeWithCompositeData(toolkit, compositeDataHolder, data);
enableOrDisableTraversalButtons(composite);
}
private static void enableOrDisableTraversalButtons(Composite composite)
{
int index = (Integer)composite.getData(INDEX);
int size = ((List)composite.getData()).size();
((Button)composite.getData(FIRST)).setEnabled(true);
((Button)composite.getData(PREV)).setEnabled(true);
((Button)composite.getData(NEXT)).setEnabled(true);
((Button)composite.getData(LAST)).setEnabled(true);
if (index == 0)
{
((Button)composite.getData(FIRST)).setEnabled(false);
((Button)composite.getData(PREV)).setEnabled(false);
}
if (index == size -1)
{
((Button)composite.getData(NEXT)).setEnabled(false);
((Button)composite.getData(LAST)).setEnabled(false);
}
}
/**
* Sets up the given composite for holding a CompositeData. Create traversal buttons, label etc and
* creates a child Composite, which should be populated with the CompositeData
* @param toolkit
* @param dataHolder
* @param compositeType
* @return
*/
private static Composite createCompositeDataHolder(final FormToolkit toolkit, final Composite dataHolder, CompositeType compositeType)
{
String desc = compositeType.getDescription();
Label description = toolkit.createLabel(dataHolder, desc, SWT.CENTER);
description.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false, 4, 1));
// TODO nameLabel.setFont(font);
description.setText(desc);
// Add traversal buttons
final Button firstRecordButton = toolkit.createButton(dataHolder, FIRST, SWT.PUSH);
GridData layoutData = new GridData (GridData.HORIZONTAL_ALIGN_END);
layoutData.widthHint = 80;
firstRecordButton.setLayoutData(layoutData);
final Button previousRecordButton = toolkit.createButton(dataHolder, PREV, SWT.PUSH);
layoutData = new GridData (GridData.HORIZONTAL_ALIGN_END);
layoutData.widthHint = 80;
previousRecordButton.setLayoutData(layoutData);
final Button nextRecordButton = toolkit.createButton(dataHolder, NEXT, SWT.PUSH);
layoutData = new GridData (GridData.HORIZONTAL_ALIGN_BEGINNING);
layoutData.widthHint = 80;
nextRecordButton.setLayoutData(layoutData);
final Button lastRecordButton = toolkit.createButton(dataHolder, LAST, SWT.PUSH);
layoutData = new GridData (GridData.HORIZONTAL_ALIGN_BEGINNING);
layoutData.widthHint = 80;
lastRecordButton.setLayoutData(layoutData);
// Now create the composite, which will hold the CompositeData
final Composite composite = toolkit.createComposite(dataHolder, SWT.NONE);
GridLayout layout = new GridLayout();
layout.horizontalSpacing = layout.verticalSpacing = 0;
layout.marginHeight = layout.marginWidth = 0;
composite.setLayout(layout);
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1));
// Add button references. These references will be used when buttons
// are to enabled or disabled based of record index. e.g. for first record
// First and Previous buttons will be disabled.
dataHolder.setData(FIRST, firstRecordButton);
dataHolder.setData(NEXT, nextRecordButton);
dataHolder.setData(PREV, previousRecordButton);
dataHolder.setData(LAST, lastRecordButton);
// Listener for the traversal buttons. When a button is clicked the respective
// CompositeData will be populated in the composite
SelectionListener listener = new SelectionAdapter()
{
public void widgetSelected(SelectionEvent e)
{
if (!(e.widget instanceof Button))
{
return;
}
Button traverseButton =(Button)e.widget;
// Get the CompositeData respective to the button selected
CompositeData data = getCompositeData(dataHolder, traverseButton.getText());
populateCompositeWithCompositeData(toolkit, composite, data);
enableOrDisableTraversalButtons(dataHolder);
}
};
firstRecordButton.addSelectionListener(listener);
nextRecordButton.addSelectionListener(listener);
previousRecordButton.addSelectionListener(listener);
lastRecordButton.addSelectionListener(listener);
return composite;
}
/**
* The CompositeData is set as data with the Composite and using the index, this method will
* return the corresponding CompositeData
* @param compositeHolder
* @param dataIndex
* @return the CompositeData respective to the index
*/
private static CompositeData getCompositeData(Composite compositeHolder, String dataIndex)
{
List objectData = (List)compositeHolder.getData();
if (objectData == null || objectData.isEmpty())
{
// TODO
}
// Get the index of record to be shown.
int index = 0;
if (compositeHolder.getData(INDEX) != null)
{
index = (Integer)compositeHolder.getData(INDEX);
}
if (FIRST.equals(dataIndex))
{
index = 0;
}
else if (NEXT.equals(dataIndex))
{
index = index + 1;
}
else if (PREV.equals(dataIndex))
{
index = (index != 0) ? (index = index - 1) : index;
}
else if (LAST.equals(dataIndex))
{
index = objectData.size() -1;
}
// Set the index being shown.
compositeHolder.setData(INDEX, index);
return (CompositeData)((Map.Entry)objectData.get(index)).getValue();
}
/**
* Populates the given composite with the CompositeData. Creates required widgets to hold the data types
* @param toolkit
* @param parent
* @param data CompositeData
*/
@SuppressWarnings("unchecked")
private static void populateCompositeWithCompositeData(FormToolkit toolkit, Composite parent, CompositeData data)
{
Control[] oldControls = parent.getChildren();
for (int i = 0; i < oldControls.length; i++)
{
oldControls[i].dispose();
}
Composite compositeHolder = toolkit.createComposite(parent, SWT.NONE);
GridLayout layout = new GridLayout(4, false);
layout.horizontalSpacing = 10;
compositeHolder.setLayout(layout);
compositeHolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
// ItemNames in composite data
List<String> itemNames = new ArrayList<String>(data.getCompositeType().keySet());
for (String itemName : itemNames)
{
OpenType itemType = data.getCompositeType().getType(itemName);
Label keyLabel = toolkit.createLabel(compositeHolder, itemName, SWT.TRAIL);
GridData layoutData = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
layoutData.minimumWidth = 70;
keyLabel.setLayoutData(layoutData);
if (itemType.isArray())
{
OpenType type = ((ArrayType)itemType).getElementOpenType();
// If Byte array and mimetype is text, convert to text string
if (type.getClassName().equals(Byte.class.getName()))
{
String mimeType = null;
String encoding = null;
if (data.containsKey("MimeType"))
{
mimeType = (String)data.get("MimeType");
}
if (data.containsKey("Encoding"))
{
encoding = (String)data.get("Encoding");
}
if (encoding == null || encoding.length() == 0)
{
encoding = Charset.defaultCharset().name();
}
if ("text/plain".equals(mimeType))
{
convertByteArray(toolkit, compositeHolder, data, itemName, encoding);
}
else
{
handleBinaryMessageContent(toolkit, compositeHolder, data, itemName, encoding);
}
}
// If array of any other supported type, show as a list of String array
else if (SUPPORTED_ARRAY_DATATYPES.contains(type.getClassName()))
{
convertArrayItemForDisplay(compositeHolder, data, itemName);
}
else
{
setNotSupportedDataType(toolkit, compositeHolder);
}
}
else if (itemType instanceof TabularType)
{
Composite composite = toolkit.createComposite(compositeHolder, SWT.NONE);
composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1));
layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
composite.setLayout(layout);
createTabularDataHolder(toolkit, composite, (TabularDataSupport)data.get(itemName));
}
else
{
Text valueText = toolkit.createText(compositeHolder, String.valueOf(data.get(itemName)), SWT.READ_ONLY | SWT.BORDER);
valueText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1));
}
}
// layout the composite after creating new widgets.
parent.layout();
} //end of method
private static void convertByteArray(FormToolkit toolkit, Composite compositeHolder, CompositeData data, String itemName, String encoding)
{
byte[] byteArray = getByteArray(data, itemName);
try
{
String textMessage = new String(byteArray, encoding);
Text valueText = toolkit.createText(compositeHolder, textMessage, SWT.READ_ONLY | SWT.BORDER |
SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1);
gridData.heightHint = 300;
valueText.setLayoutData(gridData);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
private static byte[] getByteArray(CompositeData data, String itemName)
{
byte[] byteArray;
Object binaryData = data.get(itemName);
if(binaryData instanceof byte[])
{
byteArray = (byte[]) binaryData;
}
else
{
Byte[] objectArray = (Byte[]) binaryData;
byteArray = new byte[objectArray.length];
for(int i = 0; i < objectArray.length; i++)
{
byteArray[i] = objectArray[i];
}
}
return byteArray;
}
private static Shell getShell()
{
Shell shell = Display.getCurrent().getActiveShell();
// Under linux GTK getActiveShell returns null so we need to make a new shell for display.
// Under windows this is fine.
if (shell == null)
{
// This occurs under linux gtk
shell = new Shell(Display.getCurrent(), SWT.BORDER | SWT.CLOSE | SWT.MIN | SWT.MAX);
}
return shell;
}
private static int showBox(String title, String message, int icon)
{
MessageBox messageBox = new MessageBox(getShell(), icon);
messageBox.setMessage(message);
messageBox.setText(title);
return messageBox.open();
}
/**
* Creates widgets for object messages and populates the content in hexadecimal format.
* @param toolkit
* @param compositeHolder
* @param data
* @param itemName
* @param encoding
*/
private static void handleBinaryMessageContent(FormToolkit toolkit, Composite compositeHolder, CompositeData data, String itemName, String encoding)
{
final String thisEncoding = encoding;
final byte[] byteArray = getByteArray(data, itemName);
try
{
//create a new composite to contain the widgets required to display object messages.
final Composite localComposite = toolkit.createComposite(compositeHolder, SWT.NONE);
localComposite.setData("currentBytePos", 0);
localComposite.setData("startingBytePos", 0);
GridLayout layout = new GridLayout(2, true);
layout.marginWidth = 0;
layout.marginHeight = 0;
localComposite.setLayout(layout);
localComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
int startContentSize = DEFAULT_CONTENT_SIZE;
if (byteArray.length < DEFAULT_CONTENT_SIZE)
{
startContentSize = byteArray.length;
}
//create a text to display the hexadecimal views of object messages, it takes more space than ascii view as
//a hex uses 2 chars and 1 space, while ascii only uses 1 char and 1 space.
final Text hexText = toolkit.createText(localComposite,
displayByteFormat(localComposite, byteArray, startContentSize * 2, thisEncoding, "<<", true),
SWT.READ_ONLY | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.BORDER);
GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
gridData.widthHint = 144; //set to 222 if not using any fonts
gridData.heightHint = 200;
hexText.setLayoutData(gridData);
final Text asciiText = toolkit.createText(localComposite,
displayByteFormat(localComposite, byteArray, startContentSize * 2, thisEncoding, "<<", false),
SWT.READ_ONLY | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.BORDER);
gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
gridData.widthHint = 52;//set to 98 if not using any fonts
gridData.heightHint = 200;
asciiText.setLayoutData(gridData);
//use a monospaced font for a better layout
Font font = new Font(compositeHolder.getDisplay(), "Courier", 10, SWT.NORMAL);
hexText.setFont(font);
asciiText.setFont(font);
final ScrollBar hexScrollBar = hexText.getVerticalBar();
final ScrollBar asciiScrollBar = asciiText.getVerticalBar();
//create a sub composite to contain all the buttons
final Composite buttonComposite = toolkit.createComposite(localComposite, SWT.NONE);
layout = new GridLayout(7, false);
layout.marginWidth = 0;
buttonComposite.setLayout(layout);
buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
_firstButton = toolkit.createButton(buttonComposite, "<<", SWT.PUSH);
GridData layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
layoutData.widthHint = 40;
_firstButton.setLayoutData(layoutData);
_firstButton.setToolTipText("See the first n bytes");
_previousButton = toolkit.createButton(buttonComposite, "<", SWT.PUSH);
layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
layoutData.widthHint = 40;
_previousButton.setLayoutData(layoutData);
_previousButton.setToolTipText("See the previous n bytes");
_previousButton.setEnabled(false);
_hexNumTextToStart = toolkit.createText(buttonComposite, "0");
layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
layoutData.widthHint = 40;
_hexNumTextToStart.setLayoutData(layoutData);
_hexNumTextToStart.setEditable(false);
final Text hexNumText = toolkit.createText(buttonComposite, "" + startContentSize);
layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
layoutData.widthHint = 40;
hexNumText.setLayoutData(layoutData);
_hexNumTextToEnd = toolkit.createText(buttonComposite, "" + (byteArray.length - startContentSize));
layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
layoutData.widthHint = 40;
_hexNumTextToEnd.setLayoutData(layoutData);
_hexNumTextToEnd.setEditable(false);
_nextButton = toolkit.createButton(buttonComposite, ">", SWT.PUSH);
layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
layoutData.widthHint = 40;
_nextButton.setLayoutData(layoutData);
_nextButton.setToolTipText("See the next n bytes");
_nextButton.setEnabled(true);
_lastButton = toolkit.createButton(buttonComposite, ">>", SWT.PUSH);
layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
layoutData.widthHint = 40;
_lastButton.setToolTipText("See the last n bytes");
_lastButton.setLayoutData(layoutData);
SelectionListener listener = new SelectionAdapter()
{
public void widgetSelected(SelectionEvent e)
{
if (e.widget instanceof Button)
{
String numOfBytes = hexNumText.getText();
try
{
int n = Integer.parseInt(numOfBytes);
//Reset range display if user requests a large value
if (n > byteArray.length)
{
n = (byteArray.length > DEFAULT_CONTENT_SIZE) ? DEFAULT_CONTENT_SIZE : byteArray.length;
hexNumText.setText("" + n);
}
//rest if the user requests 0
if (n < 1)
{
n = DEFAULT_CONTENT_SIZE;
hexNumText.setText("" + n);
}
Button button = (Button) e.widget;
hexText.setText(displayByteFormat(localComposite, byteArray, n * 2, thisEncoding,
button.getText(), true));
asciiText.setText(displayByteFormat(localComposite, byteArray, n * 2, thisEncoding,
button.getText(), false));
}
catch (NumberFormatException exp)
{
popupErrorMessage("Error", "Please input the number of bytes you wish to look at");
}
}
if (e.widget instanceof ScrollBar)
{
//synchronize the movements of the two scrollbars
ScrollBar sb = (ScrollBar) e.widget;
if (sb.getParent().equals(hexText))
{
asciiScrollBar.setIncrement(sb.getIncrement());
asciiScrollBar.setSelection(sb.getSelection());
}
else if (sb.getParent().equals(asciiText))
{
hexScrollBar.setSelection(sb.getSelection());
hexScrollBar.setIncrement(sb.getIncrement());
}
}
}
};
localComposite.addControlListener(new ControlAdapter()
{
public void controlResized(ControlEvent e)
{
//if the control is resized, set different parameters to make a single line displays the same contents.
if (((GridLayout) localComposite.getLayout()).makeColumnsEqualWidth)
{
((GridLayout) localComposite.getLayout()).makeColumnsEqualWidth = false;
((GridLayout) localComposite.getLayout()).numColumns = 2;
((GridData) hexText.getLayoutData()).horizontalSpan = 1;
((GridData) hexText.getLayoutData()).widthHint = 144;
((GridData) asciiText.getLayoutData()).horizontalSpan = 1;
((GridData) asciiText.getLayoutData()).widthHint = 52;
((GridData) buttonComposite.getLayoutData()).horizontalSpan = 2;
}
else
{
((GridLayout) localComposite.getLayout()).makeColumnsEqualWidth = true;
((GridLayout) localComposite.getLayout()).numColumns = 42; //set to 47 if not using any fonts
((GridData) hexText.getLayoutData()).horizontalSpan = 25; // set to 30 if not using any fonts
((GridData) asciiText.getLayoutData()).horizontalSpan = 17; // set to 17 if not using any fonts
((GridData) buttonComposite.getLayoutData()).horizontalSpan = 42;
}
}
});
_firstButton.addSelectionListener(listener);
_previousButton.addSelectionListener(listener);
_nextButton.addSelectionListener(listener);
_lastButton.addSelectionListener(listener);
hexScrollBar.addSelectionListener(listener);
asciiScrollBar.addSelectionListener(listener);
//f.dispose();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
/**
* Format object messages to have a hexadecimal view and a ascii view.
* @param numOfBytes
* @param encoding
* @return
*/
private static String displayByteFormat(Composite localComposite, byte[] byteArray, int numOfBytes,
String encoding, String direction, boolean isHex)
{
final Hex hexeconder = new Hex();
final byte[] encoded = hexeconder.encode(byteArray);
int hexLength = byteArray.length * 2;
StringBuilder sb = new StringBuilder();
int currentBytePos = (Integer) localComposite.getData("currentBytePos");
int startingBytePos = (Integer) localComposite.getData("startingBytePos");
int strLength = 0;
int offset = 0;
String encStr;
if (isHex)
{
if (direction.equals("<<"))
{
strLength = (numOfBytes > hexLength) ? hexLength : numOfBytes;
offset = 0;
}
else if (direction.equals("<"))
{
strLength = (startingBytePos - numOfBytes < 0) ? startingBytePos : numOfBytes;
offset = (startingBytePos - numOfBytes < 0) ? 0 : startingBytePos - numOfBytes;
}
else if (direction.equals(">"))
{
strLength = (numOfBytes > (hexLength - currentBytePos)) ? hexLength - currentBytePos : numOfBytes;
offset = currentBytePos;
}
else if (direction.equals(">>"))
{
strLength = (numOfBytes > hexLength) ? hexLength : numOfBytes;
offset = (hexLength - numOfBytes > 0) ? hexLength - numOfBytes : 0;
}
else
{
strLength = hexLength;
offset = 0;
}
localComposite.setData("strLength", strLength);
localComposite.setData("currentBytePos", offset + strLength);
localComposite.setData("startingBytePos", offset);
if (_lastButton != null && !_lastButton.isDisposed())
{
//Set button state
_previousButton.setEnabled(offset != 0);
_nextButton.setEnabled(offset + strLength != hexLength);
//set the text fields
_hexNumTextToStart.setText("" + offset / 2);
_hexNumTextToEnd.setText("" + (hexLength - (offset + strLength)) / 2);
}
}
try
{
if (isHex)
{
encStr = new String(encoded, offset, strLength, encoding);
for (int c = 0; c < strLength; c++)
{
sb.append(encStr.charAt(c));
if (c % 2 == 1)
{
sb.append(" ");
}
}
return sb.toString().toUpperCase();
}
else
{
strLength = (Integer) localComposite.getData("strLength");
sb = new StringBuilder();
encStr = new String(byteArray, startingBytePos / 2, strLength / 2, encoding);
for (int c = 0; c < encStr.length(); c++)
{
char ch = encStr.charAt(c);
if (ch > 31 && ch < 127)
{
sb.append(ch);
}
else
{
sb.append("?");
}
sb.append(" ");
}
}
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
return sb.toString();
}
public static int popupInfoMessage(String title, String message)
{
return showBox(title, message, SWT.ICON_INFORMATION | SWT.OK);
}
public static int popupErrorMessage(String title, String message)
{
return showBox(title, message, SWT.ICON_ERROR | SWT.OK);
}
public static int popupConfirmationMessage(String title, String message)
{
return showBox(title, message,SWT.ICON_QUESTION | SWT.YES | SWT.NO);
}
public static int popupOkCancelConfirmationMessage(String title, String message)
{
return showBox(title, message,SWT.ICON_QUESTION | SWT.OK | SWT.CANCEL);
}
public static Shell createPopupShell(String title, int width, int height)
{
Display display = Display.getCurrent();
final Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE | SWT.MIN |SWT.MAX);
shell.setText(title);
shell.setLayout(new GridLayout());
int x = display.getBounds().width;
int y = display.getBounds().height;
shell.setBounds(x/4, y/4, width, height);
shell.addListener(SWT.Traverse, new Listener () {
public void handleEvent (Event event) {
switch (event.detail) {
case SWT.TRAVERSE_ESCAPE:
shell.close ();
event.detail = SWT.TRAVERSE_NONE;
event.doit = false;
break;
}
}
});
return shell;
}
public static Shell createModalDialogShell(Shell parent, String title)
{
final Shell shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
shell.setText(title);
shell.setLayout(new GridLayout());
shell.addListener(SWT.Traverse, new Listener () {
public void handleEvent (Event event) {
switch (event.detail) {
case SWT.TRAVERSE_ESCAPE:
shell.close ();
event.detail = SWT.TRAVERSE_NONE;
event.doit = false;
break;
}
}
});
return shell;
}
/**
* Creates a List widget for displaying array of strings
* @param compositeHolder
* @param data - containing the array item value
* @param itemName - item name
*/
private static void convertArrayItemForDisplay(Composite compositeHolder, CompositeData data, String itemName)
{
Object[] arrayItems = (Object[])data.get(itemName);
String[] items = new String[arrayItems.length];
for (int i = 0; i < arrayItems.length; i++)
{
items[i] = String.valueOf(arrayItems[i]);
}
org.eclipse.swt.widgets.List list = new org.eclipse.swt.widgets.List(compositeHolder,
SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.READ_ONLY);
list.setItems(items);
//list.setBackground(compositeHolder.getBackground());
list.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
}
private static void setNotSupportedDataType(FormToolkit toolkit, Composite compositeHolder)
{
Text valueText = toolkit.createText(compositeHolder, "--- Content can not be displayed ---", SWT.READ_ONLY);
valueText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1));
}
/**
* Converts the input string to displayable format by converting some character case or inserting space
* @param input
* @return formatted string
*/
public static String getDisplayText(String input)
{
StringBuffer result = new StringBuffer(input);
if (Character.isLowerCase(result.charAt(0)))
{
result.setCharAt(0, Character.toUpperCase(result.charAt(0)));
}
for (int i = 1; i < input.length(); i++)
{
if (Character.isUpperCase(result.charAt(i)) && !Character.isWhitespace(result.charAt(i - 1))
&& Character.isLowerCase(result.charAt(i - 1)))
{
result.insert(i, " ");
i++;
}
else if (Character.isLowerCase(result.charAt(i)) && Character.isWhitespace(result.charAt(i - 1)))
{
result.setCharAt(i, Character.toUpperCase(result.charAt(i)));
}
}
return result.toString();
}
/**
* Disposes the children of given Composite if not null and not already disposed
* @param parent composite
*/
public static void disposeChildren(Composite parent)
{
if (parent == null || parent.isDisposed())
{
return;
}
Control[] oldControls = parent.getChildren();
for (int i = 0; i < oldControls.length; i++)
{
oldControls[i].dispose();
}
}
public static char[] getHash(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException
{
byte[] data = text.getBytes("utf-8");
MessageDigest md = MessageDigest.getInstance("MD5");
for (byte b : data)
{
md.update(b);
}
byte[] digest = md.digest();
char[] hash = new char[digest.length ];
int index = 0;
for (byte b : digest)
{
hash[index++] = (char) b;
}
return hash;
}
private static class TabularDataComparator implements java.util.Comparator<Map.Entry>
{
public int compare(Map.Entry data1, Map.Entry data2)
{
if (data1.getKey() instanceof List)
{
Object obj1 = ((List)data1.getKey()).get(0);
Object obj2 = ((List)data2.getKey()).get(0);
String str1 = obj1.toString();
String str2 = obj2.toString();
if (obj1 instanceof String)
{
return str1.compareTo(str2);
}
try
{
return Long.valueOf(str1).compareTo(Long.valueOf(str2));
}
catch (Exception ex)
{
return -1;
}
}
return -1;
}
}
public static void setMBeanView(MBeanView mbeanView)
{
_mbeanView = mbeanView;
}
/**
* Report feedback for the operation
* @param result true if success, false if unsuccessful, null if invoked but void result type.
* @param successMessage
* @param failureMessage
*/
public static void operationResultFeedback(Boolean result, String successMessage, String failureMessage)
{
Image icon;
if(_mbeanView != null)
{
if(result == null)
{
icon = ApplicationRegistry.getImage(SUCCESS_IMAGE);
_mbeanView.populateStatusBar(icon, successMessage);
}
else if(result)
{
icon = ApplicationRegistry.getImage(SUCCESS_IMAGE);
_mbeanView.populateStatusBar(icon, successMessage);
}
else
{
icon = ApplicationRegistry.getImage(FAILURE_IMAGE);
_mbeanView.populateStatusBar(icon, failureMessage);
popupErrorMessage("Operation Failed", failureMessage);
}
}
}
public static void operationFailedStatusBarMessage(String failureMessage)
{
Image icon = ApplicationRegistry.getImage(FAILURE_IMAGE);
if(_mbeanView != null)
{
_mbeanView.populateStatusBar(icon, failureMessage);
}
}
public static void clearStatusBar()
{
if(_mbeanView != null)
{
_mbeanView.clearStatusBar();
}
}
public static void centerChildInParentShell(Shell parent, Shell child)
{
//get current parent shell size and location
int parentLocX = parent.getBounds().x;
int parentLocY = parent.getBounds().y;
int parentWidth = parent.getBounds().width;
int parentHeight = parent.getBounds().height;
//get current child size
int childWidth = child.getSize().x;
int childHeight = child.getSize().y;
//centre the child within/over the parent
child.setBounds((parentWidth - childWidth)/2 + parentLocX,
(parentHeight - childHeight)/2 + parentLocY,
childWidth, childHeight);
}
}