com.jitlogic.zico.client.views.traces.TraceRecordSearchDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.jitlogic.zico.client.views.traces.TraceRecordSearchDialog.java

Source

/**
 * Copyright 2012-2015 Rafal Lewczuk <rafal.lewczuk@jitlogic.com>
 * <p/>
 * This is free software. You can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * <p/>
 * This software is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * <p/>
 * You should have received a copy of the GNU General Public License
 * along with this software. If not, see <http://www.gnu.org/licenses/>.
 */

package com.jitlogic.zico.client.views.traces;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.ActionCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.BrowserEvents;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Style;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.IdentityColumn;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.view.client.CellPreviewEvent;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.ProvidesKey;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.inject.assistedinject.Assisted;
import com.jitlogic.zico.client.*;
import com.jitlogic.zico.client.api.TraceDataService;
import com.jitlogic.zico.client.resources.Resources;
import com.jitlogic.zico.shared.data.TraceRecordSearchQuery;
import com.jitlogic.zico.shared.data.TraceInfo;
import com.jitlogic.zico.shared.data.TraceRecordInfo;
import com.jitlogic.zico.shared.data.TraceRecordSearchResult;
import com.jitlogic.zico.widgets.client.*;
import org.fusesource.restygwt.client.Method;
import org.fusesource.restygwt.client.MethodCallback;

import javax.inject.Inject;
import java.util.HashSet;
import java.util.Set;

public class TraceRecordSearchDialog implements IsPopupWindow {
    interface TraceRecordSearchViewUiBinder extends UiBinder<Widget, TraceRecordSearchDialog> {
    }

    private static TraceRecordSearchViewUiBinder ourUiBinder = GWT.create(TraceRecordSearchViewUiBinder.class);

    @UiField
    CheckBox chkEql;

    @UiField
    TextBox txtSearchFilter;

    @UiField
    CheckBox chkClass;

    @UiField
    CheckBox chkMethod;

    @UiField
    CheckBox chkAttribs;

    @UiField
    CheckBox chkExceptionText;

    @UiField
    CheckBox chkErrorsOnly;

    @UiField
    CheckBox chkMethodsWithAttrs;

    @UiField
    CheckBox chkIgnoreCase;

    @UiField
    Label lblSumStats;

    @UiField(provided = true)
    DataGrid<TraceRecordInfo> resultsGrid;

    private ListDataProvider<TraceRecordInfo> resultsStore;
    private TraceCallTableBuilder rowBuilder;
    private SingleSelectionModel<TraceRecordInfo> selectionModel;
    private Set<String> expandedDetails = new HashSet<String>();

    private TraceInfo trace;
    private String rootPath = "";

    private TraceCallTreePanel panel;

    private TraceDataService traceDataService;

    private PopupWindow window;

    private MessageDisplay md;
    private final String MDS;

    @Inject
    public TraceRecordSearchDialog(TraceDataService traceDataService, MessageDisplay md,
            @Assisted TraceCallTreePanel panel, @Assisted TraceInfo trace) {

        this.traceDataService = traceDataService;
        this.trace = trace;
        this.panel = panel;
        this.md = md;

        this.MDS = "TraceRecordSearch:" + trace.getHostName() + ":" + trace.getDataOffs();

        createResultsGrid();

        window = new PopupWindow(ourUiBinder.createAndBindUi(this));
        window.setCaption("Search for methods");
        window.resizeAndCenter(900, 600);

        txtSearchFilter.addKeyDownHandler(new KeyDownHandler() {
            @Override
            public void onKeyDown(KeyDownEvent event) {
                if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
                    doSearch();
                }
            }
        });

        chkClass.setValue(true);
        chkMethod.setValue(true);
        chkAttribs.setValue(true);
        chkIgnoreCase.setValue(true);
    }

    @UiHandler("btnSearch")
    void clickSearch(ClickEvent e) {
        doSearch();
    }

    private static final ProvidesKey<TraceRecordInfo> KEY_PROVIDER = new ProvidesKey<TraceRecordInfo>() {
        @Override
        public Object getKey(TraceRecordInfo rec) {
            return rec.getPath();
        }
    };

    private static final String EXPANDER_EXPAND = AbstractImagePrototype.create(Resources.INSTANCE.expanderExpand())
            .getHTML();
    private static final String EXPANDER_COLLAPSE = AbstractImagePrototype
            .create(Resources.INSTANCE.expanderCollapse()).getHTML();

    private final Cell<TraceRecordInfo> DETAIL_EXPANDER_CELL = new ActionCell<TraceRecordInfo>("",
            new ActionCell.Delegate<TraceRecordInfo>() {
                @Override
                public void execute(TraceRecordInfo rec) {
                    toggleDetails(rec);
                }
            }) {
        @Override
        public void render(Cell.Context context, TraceRecordInfo tr, SafeHtmlBuilder sb) {
            if ((tr.getAttributes() != null && tr.getAttributes().size() > 0) || tr.getExceptionInfo() != null) {
                sb.appendHtmlConstant("<span style=\"cursor: pointer;\">");
                sb.appendHtmlConstant(expandedDetails.contains(tr.getPath()) ? EXPANDER_COLLAPSE : EXPANDER_EXPAND);
                sb.appendHtmlConstant("</span>");
            }
        }
    };

    private AbstractCell<TraceRecordInfo> METHOD_CELL = new AbstractCell<TraceRecordInfo>() {
        @Override
        public void render(Context context, TraceRecordInfo tr, SafeHtmlBuilder sb) {
            String color = tr.getExceptionInfo() != null ? "red" : tr.getAttributes() != null ? "blue" : "black";
            sb.appendHtmlConstant("<span style=\"color: " + color + ";\">");
            sb.append(SafeHtmlUtils.fromString(tr.getMethod()));
            sb.appendHtmlConstant("</span>");
        }
    };

    private final static String SMALL_CELL_CSS = Resources.INSTANCE.zicoCssResources().traceSmallCell();

    private AbstractCell<TraceRecordInfo> METHOD_PCT_CELL = new AbstractCell<TraceRecordInfo>() {
        @Override
        public void render(Context context, TraceRecordInfo rec, SafeHtmlBuilder sb) {
            double pct = 100.0 * rec.getTime() / trace.getExecutionTime();
            String color = "rgb(" + ((int) (pct * 2.49)) + ",0,0)";
            sb.appendHtmlConstant("<div class=\"" + SMALL_CELL_CSS + "\" style=\"color: " + color + ";\">");
            sb.append(SafeHtmlUtils.fromString(NumberFormat.getFormat("###.0").format(pct) + "%"));
            sb.appendHtmlConstant("</div>");
        }
    };

    private void createResultsGrid() {

        resultsGrid = new DataGrid<TraceRecordInfo>(1024 * 1024, ZicoDataGridResources.INSTANCE, KEY_PROVIDER);
        selectionModel = new SingleSelectionModel<TraceRecordInfo>(KEY_PROVIDER);
        resultsGrid.setSelectionModel(selectionModel);

        Column<TraceRecordInfo, TraceRecordInfo> colExpander = new IdentityColumn<TraceRecordInfo>(
                DETAIL_EXPANDER_CELL);
        resultsGrid.addColumn(colExpander, "#");
        resultsGrid.setColumnWidth(colExpander, 32, Style.Unit.PX);

        Column<TraceRecordInfo, TraceRecordInfo> colMethod = new IdentityColumn<TraceRecordInfo>(METHOD_CELL);
        resultsGrid.addColumn(colMethod, new ResizableHeader<TraceRecordInfo>("Method", resultsGrid, colMethod));
        resultsGrid.setColumnWidth(colMethod, 100, Style.Unit.PCT);

        Column<TraceRecordInfo, String> colTime = new Column<TraceRecordInfo, String>(new TextCell()) {
            @Override
            public String getValue(TraceRecordInfo rec) {
                return ClientUtil.formatDuration(rec.getTime());
            }
        };
        resultsGrid.addColumn(colTime, new ResizableHeader<TraceRecordInfo>("Time", resultsGrid, colTime));
        resultsGrid.setColumnWidth(colTime, 50, Style.Unit.PX);

        Column<TraceRecordInfo, String> colCalls = new Column<TraceRecordInfo, String>(new TextCell()) {
            @Override
            public String getValue(TraceRecordInfo rec) {
                return "" + rec.getCalls();
            }
        };
        resultsGrid.addColumn(colCalls, new ResizableHeader<TraceRecordInfo>("Calls", resultsGrid, colCalls));
        resultsGrid.setColumnWidth(colCalls, 50, Style.Unit.PX);

        Column<TraceRecordInfo, String> colErrors = new Column<TraceRecordInfo, String>(new TextCell()) {
            @Override
            public String getValue(TraceRecordInfo rec) {
                return "" + rec.getErrors();
            }
        };
        resultsGrid.addColumn(colErrors, new ResizableHeader<TraceRecordInfo>("Errors", resultsGrid, colErrors));
        resultsGrid.setColumnWidth(colErrors, 50, Style.Unit.PX);

        Column<TraceRecordInfo, TraceRecordInfo> colPct = new IdentityColumn<TraceRecordInfo>(METHOD_PCT_CELL);
        resultsGrid.addColumn(colPct, new ResizableHeader<TraceRecordInfo>("Pct", resultsGrid, colPct));
        resultsGrid.setColumnWidth(colPct, 50, Style.Unit.PX);

        rowBuilder = new TraceCallTableBuilder(resultsGrid, expandedDetails);
        resultsGrid.setTableBuilder(rowBuilder);

        resultsGrid.setSkipRowHoverStyleUpdate(true);
        resultsGrid.setSkipRowHoverFloatElementCheck(true);
        resultsGrid.setSkipRowHoverCheck(true);
        resultsGrid.setKeyboardSelectionPolicy(HasKeyboardSelectionPolicy.KeyboardSelectionPolicy.DISABLED);

        resultsGrid.addCellPreviewHandler(new CellPreviewEvent.Handler<TraceRecordInfo>() {
            @Override
            public void onCellPreview(CellPreviewEvent<TraceRecordInfo> event) {
                NativeEvent nev = event.getNativeEvent();
                String eventType = nev.getType();
                if ((BrowserEvents.KEYDOWN.equals(eventType) && nev.getKeyCode() == KeyCodes.KEY_ENTER)
                        || BrowserEvents.DBLCLICK.equals(nev.getType())) {
                    doGoTo();
                }
                //if (BrowserEvents.CONTEXTMENU.equals(eventType)) {
                //    selection.setSelected(event.getValue(), true);
                //    contextMenu.showAt(event.getNativeEvent().getClientX(), event.getNativeEvent().getClientY());
                //}
            }
        });

        resultsGrid.addDomHandler(new DoubleClickHandler() {
            @Override
            public void onDoubleClick(DoubleClickEvent event) {
                event.preventDefault();
            }
        }, DoubleClickEvent.getType());
        resultsGrid.addDomHandler(new ContextMenuHandler() {
            @Override
            public void onContextMenu(ContextMenuEvent event) {
                event.preventDefault();
            }
        }, ContextMenuEvent.getType());

        resultsStore = new ListDataProvider<TraceRecordInfo>();
        resultsStore.addDataDisplay(resultsGrid);
    }

    private void toggleDetails(TraceRecordInfo rec) {
        String path = rec.getPath();
        if (expandedDetails.contains(path)) {
            expandedDetails.remove(path);
        } else {
            expandedDetails.add(path);
        }
        resultsGrid.redrawRow(resultsStore.getList().indexOf(rec));
    }

    private void doGoTo() {
        TraceRecordInfo tri = selectionModel.getSelectedObject();
        int idx = tri != null ? resultsStore.getList().indexOf(tri) : 0;
        panel.setResults(resultsStore.getList(), idx);
        window.hide();
    }

    public void setRootPath(String rootPath) {
        if (this.rootPath != rootPath) {
            this.rootPath = rootPath;
            this.resultsStore.getList().clear();
            this.lblSumStats.setText("n/a");
        }
    }

    private void doSearch() {

        TraceRecordSearchQuery expr = new TraceRecordSearchQuery();

        expr.setType(chkEql.getValue() ? TraceRecordSearchQuery.EQL_QUERY : TraceRecordSearchQuery.TXT_QUERY);

        GWT.log("Search Type=" + expr.getType());

        expr.setFlags((chkErrorsOnly.getValue() ? TraceRecordSearchQuery.ERRORS_ONLY : 0)
                | (chkMethodsWithAttrs.getValue() ? TraceRecordSearchQuery.METHODS_WITH_ATTRS : 0)
                | (chkClass.getValue() ? TraceRecordSearchQuery.SEARCH_CLASSES : 0)
                | (chkMethod.getValue() ? TraceRecordSearchQuery.SEARCH_METHODS : 0)
                | (chkAttribs.getValue() ? TraceRecordSearchQuery.SEARCH_ATTRS : 0)
                | (chkExceptionText.getValue() ? TraceRecordSearchQuery.SEARCH_EX_MSG : 0)
                | (chkIgnoreCase.getValue() ? TraceRecordSearchQuery.IGNORE_CASE : 0));

        expr.setSearchExpr(txtSearchFilter.getText().length() > 0 ? txtSearchFilter.getText() : null);

        GWT.log("Search flags=" + expr.getFlags());

        md.info(MDS, "Searching records ...");

        expr.setHostName(trace.getHostName());
        expr.setTraceOffs(trace.getDataOffs());
        expr.setMinTime(0);
        expr.setPath(rootPath);

        traceDataService.searchRecords(expr, new MethodCallback<TraceRecordSearchResult>() {
            @Override
            public void onFailure(Method method, Throwable e) {
                md.error(MDS, "Error performing search request", e);
            }

            @Override
            public void onSuccess(Method method, TraceRecordSearchResult response) {
                resultsStore.getList().clear();
                resultsStore.getList().addAll(response.getResult());
                lblSumStats.setText(response.getResult().size() + " methods, "
                        + NumberFormat.getFormat("###.0").format(response.getRecurPct())
                        + "% of trace execution time. " + "Time: "
                        + ClientUtil.formatDuration(response.getRecurTime()) + " non-recursive" + ", "
                        + ClientUtil.formatDuration(response.getMinTime()) + " min, " + ", "
                        + ClientUtil.formatDuration(response.getMaxTime()) + " max."

                );
                txtSearchFilter.setFocus(true);
                md.clear(MDS);
            }
        });
    }

    @Override
    public PopupWindow asPopupWindow() {
        return window;
    }

}