package com.yoghurt.crypto.transactions.client.widget; import java.util.ArrayList; import java.util.Collection; import java.util.Map.Entry; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.CssResource; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Widget; import com.googlecode.gwt.crypto.bouncycastle.util.encoders.Hex; import com.yoghurt.crypto.transactions.client.resources.R; import com.yoghurt.crypto.transactions.client.util.misc.Color; public abstract class HexViewer<T> extends ContextFieldSet<Entry<T, byte[]>> { interface HexViewerUiBinder extends UiBinder<Widget, HexViewer<?>> {} private static final HexViewerUiBinder UI_BINDER = GWT.create(HexViewerUiBinder.class); public interface CustomStyle extends CssResource { String byteSet(); } @UiField CustomStyle style; private FlowPanel byteSetContainer; protected ArrayList<ContextField<Entry<T, byte[]>>> activeFields; public HexViewer() { this(null); } public HexViewer(final FieldContextFactory<Entry<T, byte[]>> contextFactory) { super(contextFactory); UI_BINDER.createAndBindUi(this); } /** * Set the container for this hex viewer. */ public void setValue(final Collection<Entry<T, byte[]>> container) { boolean quickAdd = false; int counter = 0; for (final Entry<T, byte[]> entry : container) { final byte[] bytesForValue = getBytesForValue(entry); final Color typeColor = getFieldColor(entry); // Change the value for each field for (final byte bite : bytesForValue) { final String hex = getHexFromByte(bite); if(quickAdd || counter >= fields.size()) { addField(entry, typeColor, hex); quickAdd = true; } else { final ContextField<Entry<T, byte[]>> contextField = fields.get(counter); contextField.setValue(entry); contextField.setColor(typeColor); contextField.setContent(hex); } counter++; } } // Reverse remove the remainder for(int i = fields.size() - 1;i >= counter; i--) { removeField(i); } } public void addFields(final Entry<T, byte[]> value) { final Color typeColor = getFieldColor(value); for (final byte bite : getBytesForValue(value)) { final String hex = getHexFromByte(bite); addField(value, typeColor, hex); } } protected String getHexFromByte(final byte bite) { return new String(Hex.encode(new byte[] { bite })).toUpperCase(); } @Override protected void displayContextForValue(final Entry<T, byte[]> value) { clearActiveFields(); // activeFields = findValueFields(value); if (activeFields == null) { return; } for (final ContextField<Entry<T, byte[]>> w : activeFields) { w.setActive(true); } } @Override protected void clearActivity() { super.clearActivity(); clearActiveFields(); } private void clearActiveFields() { if (activeFields != null) { for (final ContextField<Entry<T, byte[]>> field : activeFields) { field.setActive(false); } } } protected byte[] getBytesForValue(final Entry<T, byte[]> entry) { return entry.getValue(); } @Override protected ContextField<Entry<T, byte[]>> addField(final ContextField<Entry<T, byte[]>> field) { if (byteSetContainer == null) { byteSetContainer = new FlowPanel(); byteSetContainer.setStyleName(style.byteSet()); byteSetContainer.addStyleName(R.css().flex()); add(byteSetContainer); } byteSetContainer.add(field); if (byteSetContainer.getWidgetCount() == 8) { byteSetContainer = null; } return field; } @Override public void removeField(final int index) { final ContextField<Entry<T, byte[]>> contextField = fields.get(index); final FlowPanel byteSetContainer = (FlowPanel) contextField.getParent(); contextField.removeFromParent(); if(byteSetContainer.getWidgetCount() == 0) { byteSetContainer.removeFromParent(); } else { this.byteSetContainer = byteSetContainer; } fields.remove(index); } @Override public void clear() { super.clear(); byteSetContainer = null; clearActiveFields(); } }