/*
* Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License, Version 1.0,
* which accompanies this distribution and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*
*/
package net.rim.ejde.internal.ui.views;
import java.util.HashSet;
import java.util.Set;
import net.rim.ejde.internal.util.DebugUtils;
import org.apache.log4j.Logger;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.swt.widgets.Display;
public class DebuggerLiveUpdateJob extends Job implements IDebugEventSetListener {
private static final Logger _log = Logger.getLogger( DebuggerLiveUpdateJob.class );
private VarContentDebugView _view;
private boolean _isLiveUpdateCanceled = false;
private boolean _skipUpdate = false;
private Set< IJavaThread > debugThreadList = new HashSet< IJavaThread >();
public DebuggerLiveUpdateJob( String name, VarContentDebugView view ) {
super( name );
DebugPlugin.getDefault().addDebugEventListener( this );
_view = view;
_log.trace( "Debugger live update job was created" );
}
public void cancelUpdate() {
_isLiveUpdateCanceled = true;
}
public boolean isUpdateCanceled() {
return _isLiveUpdateCanceled;
}
@Override
protected IStatus run( IProgressMonitor monitor ) {
_log.trace( "Debugger live update job started" );
_isLiveUpdateCanceled = false;
while( !_isLiveUpdateCanceled && !monitor.isCanceled() ) {
try {
Thread.sleep( 2000 );
} catch( InterruptedException e ) {
_log.error( e );
}
try {
updateUI();
} catch( CoreException e ) {
_log.error( e );
}
}
if( monitor.isCanceled() ) {
_isLiveUpdateCanceled = true;
}
return Status.OK_STATUS;
}
private void updateUI() throws CoreException {
if( _isLiveUpdateCanceled ) {
return;
}
if( _skipUpdate ) {
return;
}
ILaunch launch = DebugUtils.getRIMLaunch();
if( launch == null ) {
return;
}
IDebugTarget debugTarget = launch.getDebugTarget();
if( debugTarget == null ) {
return;
}
if( hasThreadSuspended( debugTarget ) ) {
return;
}
if( !debugTarget.isSuspended() && debugTarget.canSuspend() ) {
debugTarget.suspend();
try {
Thread.sleep( 1000 );
} catch( InterruptedException e ) {
_log.error( e );
}
Display.getDefault().syncExec( new Runnable() {
@Override
public void run() {
try {
_log.trace( "Updating debugger view" );
if( !_view.getTableView().getTable().isDisposed() ) {
_view.refresh();
}
} catch( CoreException e ) {
_log.error( e );
}
}
} );
if( debugTarget.canResume() ) {
resumeDebugger( debugTarget );
}
}
}
private void resumeDebugger( IDebugTarget debugTarget ) {
IThread[] threads;
try {
threads = debugTarget.getThreads();
} catch( DebugException e ) {
_log.error( e );
return;
}
for( int i = 0; i < threads.length; i++ ) {
if( !debugThreadList.contains( threads[ i ] ) ) {
try {
if( threads[ i ].canResume() ) {
threads[ i ].resume();
}
} catch( DebugException e ) {
_log.error( e );
}
}
}
}
private boolean hasThreadSuspended( IDebugTarget debugTarget ) {
IThread[] threads;
try {
threads = debugTarget.getThreads();
} catch( DebugException e ) {
_log.error( e );
return false;
}
for( int i = 0; i < threads.length; i++ ) {
if( threads[ i ].isSuspended() ) {
return true;
}
}
return false;
}
@Override
public void handleDebugEvents( DebugEvent[] events ) {
for( int i = 0; i < events.length; i++ ) {
if( events[ i ].getKind() == DebugEvent.SUSPEND && events[ i ].getDetail() == DebugEvent.BREAKPOINT ) {
_skipUpdate = true;
if( events[ i ].getSource() != null && ( events[ i ].getSource() instanceof IJavaThread ) ) {
debugThreadList.add( (IJavaThread) events[ i ].getSource() );
}
}
if( events[ i ].getKind() == DebugEvent.RESUME && events[ i ].getDetail() == DebugEvent.CLIENT_REQUEST ) {
_skipUpdate = false;
if( events[ i ].getSource() != null && ( events[ i ].getSource() instanceof IJavaThread ) ) {
debugThreadList.remove( events[ i ].getSource() );
}
}
}
}
}