/******************************************************************************* * Copyright (c) 2011 Subgraph. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Subgraph - initial API and implementation ******************************************************************************/ package com.subgraph.vega.ui.http.requestviewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TabFolder; import org.eclipse.swt.widgets.TabItem; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import com.subgraph.vega.api.events.IEvent; import com.subgraph.vega.api.events.IEventHandler; import com.subgraph.vega.api.model.IModel; import com.subgraph.vega.api.model.WorkspaceCloseEvent; import com.subgraph.vega.api.model.WorkspaceResetEvent; import com.subgraph.vega.api.model.requests.IRequestLogRecord; import com.subgraph.vega.ui.http.Activator; import com.subgraph.vega.ui.httpviewer.HttpMessageViewer; public class RequestResponseViewer { private final static String VERTICAL_ICON = "icons/vertical.png"; private final static String HORIZONTAL_ICON = "icons/horizontal.png"; private final static String TABBED_ICON = "icons/tabbed.png"; private final static String UP_ICON = "icons/up.png"; private final static String DOWN_ICON = "icons/down.png"; private final static String CONFIG_ICON = "icons/configure.png"; private final ImageCache imageCache; private final SashForm parentForm; private final Composite parentComposite; private final Menu optionsMenu; private final Composite toolbarComposite; private ToolItem hideItem; private SashForm sashForm; private TabFolder tabFolder; private Composite rootComposite; private HttpMessageViewer requestViewer; private HttpMessageViewer responseViewer; private IRequestLogRecord currentRecord; private boolean displayImages = true; private boolean displayImagesAsHex = false; private boolean urlDecodeState = false; private boolean hideState = false; public RequestResponseViewer(SashForm parentForm) { imageCache = new ImageCache(Activator.PLUGIN_ID); this.parentForm = parentForm; parentComposite = new Composite(parentForm, SWT.NONE); parentComposite.setLayout(new FormLayout()); optionsMenu = createOptionsMenu(parentForm.getShell()); toolbarComposite = createToolbarComposite(parentComposite); FormData fd = new FormData(); fd.left = new FormAttachment(0); fd.right = new FormAttachment(100); fd.top = new FormAttachment(0); toolbarComposite.setLayoutData(fd); setTabbedMode(); IModel model = Activator.getDefault().getModel(); model.addWorkspaceListener(new IEventHandler() { @Override public void handleEvent(IEvent event) { if (event instanceof WorkspaceCloseEvent || event instanceof WorkspaceResetEvent) { handleWorkspaceCloseOrReset(); } } }); } private void handleWorkspaceCloseOrReset() { clearViewers(); } private Composite createToolbarComposite(Composite parent) { final Composite c = new Composite(parentComposite, SWT.NONE); final GridLayout layout = new GridLayout(2, false); layout.marginWidth = 0; layout.marginHeight = 0; layout.horizontalSpacing = 0; c.setLayout(layout); Composite tb = createLayoutToolBar(c); tb.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); tb = createConfigureToolBar(c); tb.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); return c; } private ToolBar createLayoutToolBar(Composite parent) { ToolBar tb = new ToolBar(parent, SWT.NONE); ToolItem tabbed = new ToolItem(tb, SWT.RADIO); tabbed.setImage(imageCache.get(TABBED_ICON)); tabbed.setToolTipText("Tabbed Request/Response layout"); tabbed.setSelection(true); tabbed.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { setTabbedMode(); } }); ToolItem horiz = new ToolItem(tb, SWT.RADIO); horiz.setImage(imageCache.get(HORIZONTAL_ICON)); horiz.setToolTipText("Horizontal Request/Response layout"); horiz.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { setHorizontalSashMode(); } }); ToolItem vert = new ToolItem(tb, SWT.RADIO); vert.setImage(imageCache.get(VERTICAL_ICON)); vert.setToolTipText("Vertical Request/Response layout"); vert.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { setVerticalSashMode(); } }); tb.pack(); return tb; } private ToolBar createConfigureToolBar(Composite parent) { final ToolBar tb = new ToolBar(parent, SWT.NONE); final ToolItem config = new ToolItem(tb, SWT.DROP_DOWN); config.setImage(imageCache.get(CONFIG_ICON)); config.setToolTipText("Options"); config.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { final Rectangle r = config.getBounds(); final Point p = new Point(r.x, r.y + r.height); optionsMenu.setLocation(tb.getDisplay().map(tb, null, p)); optionsMenu.setVisible(true); } }); hideItem = new ToolItem(tb, SWT.PUSH); hideItem.setImage(imageCache.get(UP_ICON)); hideItem.setToolTipText("Hide Request Table"); hideItem.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { toggleHideState(); } }); tb.pack(); return tb; } private Menu createOptionsMenu(Shell shell) { final Menu menu = new Menu(shell, SWT.POP_UP); final MenuItem displayImagesItem = new MenuItem(menu, SWT.CHECK); displayImagesItem.setText("Display Images"); displayImagesItem.setSelection(displayImages); final MenuItem imagesAsHexItem = new MenuItem(menu, SWT.CHECK); imagesAsHexItem.setText("Display Images with Hex Viewer"); final MenuItem decodeItem = new MenuItem(menu, SWT.CHECK); decodeItem.setText("Remove URL encoding"); displayImagesItem.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { boolean value = displayImagesItem.getSelection(); imagesAsHexItem.setEnabled(value); setDisplayImageState(value); displayImages = value; } }); imagesAsHexItem.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { boolean value = imagesAsHexItem.getSelection(); setDisplayImagesAsHexState(value); displayImagesAsHex = value; } }); decodeItem.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { boolean value = decodeItem.getSelection(); setUrlDecodeState(value); urlDecodeState = value; } }); return menu; } private void setDisplayImageState(boolean value) { requestViewer.setDisplayImages(value); responseViewer.setDisplayImages(value); } private void setDisplayImagesAsHexState(boolean value) { requestViewer.setDisplayImagesAsHex(value); responseViewer.setDisplayImagesAsHex(value); } private void setUrlDecodeState(boolean value) { requestViewer.setDecodeUrlEncoding(value); responseViewer.setDecodeUrlEncoding(value); } private void toggleHideState() { if(hideState) { hideState = false; hideItem.setImage(imageCache.get(UP_ICON)); hideItem.setToolTipText("Hide Request Table"); parentForm.setMaximizedControl(null); } else { hideState = true; hideItem.setToolTipText("Show Request Table"); hideItem.setImage(imageCache.get(DOWN_ICON)); parentForm.setMaximizedControl(parentComposite); } } public void setTabbedMode() { sashForm = null; recreateRootComposite(); tabFolder = new TabFolder(rootComposite, SWT.TOP); createMessageViewers(tabFolder); final TabItem requestItem = new TabItem(tabFolder, SWT.NONE); requestItem.setText("Request"); requestItem.setControl(requestViewer); final TabItem responseItem = new TabItem(tabFolder, SWT.NONE); responseItem.setText("Response"); responseItem.setControl(responseViewer); parentComposite.layout(); if(currentRecord != null) processCurrentTransaction(); setDisplayResponse(); } private void createMessageViewers(Composite parent) { requestViewer = new HttpMessageViewer(parent); requestViewer.setEditable(false); responseViewer = new HttpMessageViewer(parent); responseViewer.setEditable(false); setDisplayImageState(displayImages); setDisplayImagesAsHexState(displayImagesAsHex); setUrlDecodeState(urlDecodeState); } public void setDisplayResponse() { if(tabFolder != null) tabFolder.setSelection(1); } private void recreateRootComposite() { if(rootComposite != null) rootComposite.dispose(); rootComposite = new Composite(parentComposite, SWT.NONE); rootComposite.setLayout(new FillLayout()); final FormData fd = new FormData(); fd.left = new FormAttachment(0); fd.right = new FormAttachment(100); fd.top = new FormAttachment(toolbarComposite); fd.bottom = new FormAttachment(100); rootComposite.setLayoutData(fd); } public void setVerticalSashMode() { configureSashMode(SWT.VERTICAL); } public void setHorizontalSashMode() { configureSashMode(SWT.HORIZONTAL); } private void configureSashMode(int mode) { tabFolder = null; if(sashForm != null) { if(sashForm.getOrientation() != mode) sashForm.setOrientation(mode); return; } recreateRootComposite(); sashForm = new SashForm(rootComposite, mode); createMessageViewers(sashForm); sashForm.setWeights(new int[] {50, 50}); parentComposite.layout(); processCurrentTransaction(); } public void setCurrentRecord(IRequestLogRecord record) { currentRecord = record; processCurrentTransaction(); } private void processCurrentTransaction() { if(currentRecord == null) { clearViewers(); return; } requestViewer.displayHttpRequest(currentRecord.getRequest()); responseViewer.displayHttpResponse(currentRecord.getResponse()); } private void clearViewers() { requestViewer.clearContent(); responseViewer.clearContent(); } }