/******************************************************************************* * Copyright (c) 2011 Wind River Systems, Inc. and others. 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: * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tm.te.tcf.locator; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.tm.tcf.protocol.Protocol; import org.eclipse.tm.te.tcf.locator.interfaces.IScanner; import org.eclipse.tm.te.tcf.locator.interfaces.nodes.ILocatorModel; import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel; /** * Locator model scanner implementation. */ public class Scanner extends Job implements IScanner { // Reference to the parent model instance. private final ILocatorModel parentModel; // Reference to the scanner configuration private final Map<String, Object> configuration = new HashMap<String, Object>(); // Flag to mark if the scanner is terminated private AtomicBoolean terminated = new AtomicBoolean(false); /** * Constructor. * * @param parentModel The parent model instance. Must not be <code>null</code>. */ public Scanner(ILocatorModel parentModel) { super(Scanner.class.getName()); Assert.isNotNull(parentModel); this.parentModel = parentModel; } /** * Returns the parent model instance. * * @return The parent model instance. */ protected ILocatorModel getParentModel() { return parentModel; } /* (non-Javadoc) * @see org.eclipse.tm.te.tcf.locator.core.interfaces.IScanner#setConfiguration(java.util.Map) */ @Override public void setConfiguration(Map<String, Object> configuration) { Assert.isNotNull(configuration); this.configuration.clear(); this.configuration.putAll(configuration); } /* (non-Javadoc) * @see org.eclipse.tm.te.tcf.locator.core.interfaces.IScanner#getConfiguration() */ @Override public Map<String, Object> getConfiguration() { return configuration; } /* (non-Javadoc) * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) */ @Override protected IStatus run(IProgressMonitor monitor) { if (monitor == null) monitor = new NullProgressMonitor(); // Get the current list of peers known to the parent model IPeerModel[] peers = getParentModel().getPeers(); // Do we have something to scan at all if (peers.length > 0) { // The first runnable is setting the thread which will finish // the job at the end Protocol.invokeLater(new Runnable() { @Override public void run() { Scanner.this.setThread(Thread.currentThread()); } }); // Loop the nodes and try to get an channel for (IPeerModel peer : peers) { // Check for the progress monitor getting canceled if (monitor.isCanceled() || isTerminated()) break; // Create the scanner runnable Runnable runnable = new ScannerRunnable(this, peer); // Submit for execution Protocol.invokeLater(runnable); } // The last runnable will terminate the job as soon all // scanner runnable's are processed and will reschedule the job final IStatus result = monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS; Protocol.invokeLater(new Runnable() { @Override public void run() { Scanner.this.done(result); Long delay = (Long)getConfiguration().get(IScanner.PROP_SCHEDULE); if (delay != null) { Scanner.this.schedule(delay.longValue()); } } }); } return peers.length > 0 ? ASYNC_FINISH : Status.OK_STATUS; } /* (non-Javadoc) * @see org.eclipse.tm.te.tcf.locator.core.interfaces.IScanner#terminate() */ @Override public void terminate() { terminated.set(true); } /* (non-Javadoc) * @see org.eclipse.tm.te.tcf.locator.core.interfaces.IScanner#isTerminated() */ @Override public final boolean isTerminated() { return terminated.get(); } /* (non-Javadoc) * @see org.eclipse.core.runtime.jobs.Job#shouldRun() */ @Override public boolean shouldRun() { return Platform.isRunning() && !getParentModel().isDisposed() && !isTerminated(); } /* (non-Javadoc) * @see org.eclipse.core.runtime.jobs.Job#shouldSchedule() */ @Override public boolean shouldSchedule() { return Platform.isRunning() && !getParentModel().isDisposed() && !isTerminated(); } }