/******************************************************************************* * 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 java.util.Collections; import java.util.List; import java.util.Timer; import java.util.TimerTask; import org.eclipse.jface.viewers.ILazyContentProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.widgets.Display; 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.IWorkspace; import com.subgraph.vega.api.model.WorkspaceCloseEvent; import com.subgraph.vega.api.model.WorkspaceOpenEvent; import com.subgraph.vega.api.model.WorkspaceResetEvent; import com.subgraph.vega.api.model.conditions.ConditionSetChanged; import com.subgraph.vega.api.model.conditions.IHttpConditionManager; import com.subgraph.vega.api.model.conditions.IHttpConditionSet; import com.subgraph.vega.api.model.requests.IRequestLog; import com.subgraph.vega.api.model.requests.IRequestLogRecord; import com.subgraph.vega.api.model.requests.IRequestLogUpdateListener; import com.subgraph.vega.api.model.requests.RequestLogUpdateEvent; public class HttpViewContentProviderLazy implements ILazyContentProvider { private static final int UPDATE_INTERVAL = 500; private IWorkspace currentWorkspace; private TableViewer tableViewer; private List<IRequestLogRecord> records; private final IRequestLogUpdateListener callback; private final IEventHandler conditionSetListener; private TimerTask updateTask; private final Timer updateTimer = new Timer(); private int lastUpdateCount; private int currentCount; private IHttpConditionSet filterCondition; public HttpViewContentProviderLazy() { callback = createUpdateListener(); conditionSetListener = createConditionSetListener(); } @Override public void dispose() { } @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { if(updateTask != null) updateTask.cancel(); if(!(viewer instanceof TableViewer)) { tableViewer = null; return; } tableViewer = (TableViewer) viewer; if(newInput instanceof IModel) setNewInput((IModel) newInput); else setNullInput(); } private void setNullInput() { currentCount = lastUpdateCount = 0; tableViewer.setItemCount(0); currentWorkspace = null; updateTask = null; filterCondition = null; } private void setNewInput(IModel model) { if(model == null) { setNullInput(); return; } filterCondition = model.addConditionSetTracker(IHttpConditionManager.CONDITION_SET_FILTER, conditionSetListener); filterCondition.setMatchOnEmptySet(true); currentWorkspace = model.addWorkspaceListener(createWorkspaceListener()); if(currentWorkspace != null) currentWorkspace.getRequestLog().addUpdateListener(callback, filterCondition); reloadRecords(); updateTask = createTimerTask(tableViewer.getControl().getDisplay()); updateTimer.scheduleAtFixedRate(updateTask, 0, UPDATE_INTERVAL); } private IRequestLogUpdateListener createUpdateListener() { return new IRequestLogUpdateListener() { @Override public void update(RequestLogUpdateEvent event) { currentCount = event.getRecordCount(); } }; } private IEventHandler createConditionSetListener() { return new IEventHandler() { @Override public void handleEvent(IEvent event) { if(event instanceof ConditionSetChanged) { final IHttpConditionSet conditionSet = ((ConditionSetChanged) event).getConditionSet(); setConditionFilter(conditionSet); } } }; } private IEventHandler createWorkspaceListener() { return new IEventHandler() { @Override public void handleEvent(IEvent event) { if(event instanceof WorkspaceOpenEvent) onWorkspaceOpen((WorkspaceOpenEvent) event); else if(event instanceof WorkspaceResetEvent) onWorkspaceReset((WorkspaceResetEvent) event); else if(event instanceof WorkspaceCloseEvent) onWorkspaceClose((WorkspaceCloseEvent) event); reloadRecords(); } }; } private void onWorkspaceOpen(WorkspaceOpenEvent event) { currentWorkspace.getRequestLog().removeUpdateListener(callback); currentWorkspace = event.getWorkspace(); currentWorkspace.getRequestLog().addUpdateListener(callback, filterCondition); } private void onWorkspaceReset(WorkspaceResetEvent event) { currentWorkspace.getRequestLog().removeUpdateListener(callback); currentWorkspace = event.getWorkspace(); currentWorkspace.getRequestLog().addUpdateListener(callback, filterCondition); } private void onWorkspaceClose(WorkspaceCloseEvent event) { currentWorkspace.getRequestLog().removeUpdateListener(callback); } @Override public void updateElement(int index) { if(index >= records.size()) { records = queryRecords(); } final IRequestLogRecord record = (index < records.size()) ? (records.get(index)) : (null); if(record != null) { tableViewer.replace(record, index); } } private void reloadRecords() { records = queryRecords(); currentCount = records.size(); lastUpdateCount = -1; resetTable(); } private List<IRequestLogRecord> queryRecords() { if(currentWorkspace == null) return Collections.emptyList(); final IRequestLog requestLog = currentWorkspace.getRequestLog(); if(filterCondition == null) return requestLog.getAllRecords(); else return requestLog.getRecordsByConditionSet(filterCondition); } public void setConditionFilter(IHttpConditionSet conditionSet) { if(conditionSet != null) conditionSet.setMatchOnEmptySet(true); final IRequestLog requestLog = currentWorkspace.getRequestLog(); filterCondition = conditionSet; requestLog.removeUpdateListener(callback); requestLog.addUpdateListener(callback, conditionSet); reloadRecords(); } private void resetTable() { final Display display = tableViewer.getControl().getDisplay(); if(display == null) return; display.syncExec(new Runnable() { @Override public void run() { if(tableViewer.getTable().isDisposed()) return; tableViewer.getTable().setSelection(0); tableViewer.getTable().showSelection(); tableViewer.setItemCount(currentCount); tableViewer.refresh(true); } }); } private TimerTask createTimerTask(final Display display) { return new TimerTask() { @Override public void run() { if(lastUpdateCount != currentCount) { display.syncExec(new Runnable() { @Override public void run() { lastUpdateCount = currentCount; if(!tableViewer.getControl().isDisposed()) tableViewer.setItemCount(currentCount); } }); } } }; } }