/*
* org.openmicroscopy.shoola.env.data.views.DataServicesView
*
*------------------------------------------------------------------------------
* Copyright (C) 2006 University of Dundee. All rights reserved.
*
*
* This program 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 2 of the License, or
* (at your option) any later version.
* This program 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*------------------------------------------------------------------------------
*/
package org.openmicroscopy.shoola.env.data.views;
//Java imports
//Third-party libraries
//Application-internal dependencies
/**
* Just a marker for data view interfaces.
* <p>A data services view is a logical grouping of data and operations that
* serve a specific purpose for example to support dataset browsing
* by providing easy access to datasets, thumbnails, classifications, etc.
* A data services view is defined by an interface that extends <code>
* DataServiceView</code> and consists of a collection of asynchronous calls
* that operate on (possibly) large portions of a data model in the background.
* </p>
* <p>Agents obtain a reference to a given view through their registry by
* specifying the view's defining interface as follows (note the <i>
* required</i> cast on the returned reference):
* <pre><code>
* XxxView view = (XxxView)
* registry.getDataServicesView(XxxView.class);
* </code></pre></p>
* <p><code>XxxView</code> is obviously a made up name for one of the
* sub-interfaces of <code>DataServiceView</code> contained in this package.
* All calls are carried out asynchronously with respect to the caller's thread
* and return a {@link CallHandle} object which can be used to cancel execution.
* This object is then typically linked to a button so that the user can cancel
* the task, like in the following example:
* <pre><code>
* final CallHandle handle = view.loadSomeDataInTheBg(observer);
*
* //The above call returns immediately, so we don't have to wait.
* //While the task is carried out, we allow the user to change
* //her mind and cancel the task:
*
* cancelButton.addActionListener(new ActionListener() {
* public void actionPerformed(ActionEvent e) {
* handle.cancel();
* }
* });
* </code></pre></p>
* <p>The <code>observer</code> argument to the above call is an instance of
* {@link org.openmicroscopy.shoola.env.event.AgentEventListener}. Normally
* all calls within a view allow to specify this argument, which is used to
* provide the caller with feedback on the progress of the task and with its
* eventual outcome.</p>
* <p>Specifically, as the computation proceeds in the background,
* {@link org.openmicroscopy.shoola.env.data.events.DSCallFeedbackEvent}s are
* delivered to the <code>observer</code>. These event objects have a status
* field which contains a textual description of the activity currently being
* carried out within the computation and a progress indicator which is set to
* the percentage of the work done so far. So the indicator will be <code>0
* </code> for the first feedback event and, if the computation runs to
* completion, <code>100</code> for the last feedback event, which will always
* have its status field set to <code>null</code> note that a <code>null
* </code> status is also possible for the previous events if no description
* was available at the time the event was fired.<br>
* Moreover, any partial resutl that the computation makes available will be
* packed into the feedback event.</p>
* <p>It's important to keep in mind that the computation may not run to
* completion either because of an exception within the computation or
* because the agent {@link CallHandle#cancel() cancels} execution. In both
* cases, the feedback notification won't run to completion either. However,
* in any case a final
* {@link org.openmicroscopy.shoola.env.data.events.DSCallOutcomeEvent} is
* delivered to the <code>observer</code> to notify of the computation outcome
* the event's methods can be used to find out the actual outcome and
* retrieve any result or exception. Every call documents what is the returned
* object and what are the possible exceptions so that the caller can later
* cast the returned value or exception as appropriate.</p>
* <p>Here's the code for a prototypical observer:
* <pre><code>
* public void eventFired(AgentEvent ae)
* {
* if (ae instanceof DSCallFeedbackEvent) { //Progress notification.
* update((DSCallFeedbackEvent) ae); //Inform the user.
* } else { //Outcome notification.
* DSCallOutcomeEvent oe = (DSCallOutcomeEvent) ae;
* switch (oe.getState()) {
* case DSCallOutcomeEvent.CANCELLED: //The user cancelled.
* handleCancellation();
* break;
* case DSCallOutcomeEvent.ERROR: //The call threw an exception.
* handleException(oe.getException());
* break;
* case DSCallOutcomeEvent.NO_RESULT: //The call returned no value.
* handleNullResult();
* break;
* case DSCallOutcomeEvent.HAS_RESULT: //The call returned a value.
* handleResult(oe.getResult());
* }
* }
* }
* </code></pre></p>
* <p>Because this logic is likely to be common to most of the observers, the
* {@link org.openmicroscopy.shoola.env.data.events.DSCallAdapter} class factors
* it out to provide a more convenient way to write obsevers. Back to our
* previous example, the <code>observer</code> could look something like the
* following:
* <pre><code>
* observer = new DSCallAdapter() {
* public void update(DSCallFeedbackEvent fe) { //Received some feedback.
* String status = fe.getStatus();
* int percDone = fe.getPercentDone();
* if (status == null)
* status = (percDone == 100) ? "Done" : //Else
* ""; //Description wasn't available.
* statusBar.setText(status); //A JLabel object part of the UI.
* progressBar.setValue(percDone); //A JProgressBar object part of the UI.
* }
* public void onEnd() { //Called right before any of the handleXXX methods.
* progressBar.setVisible(false); //Because the computation has finished.
* }
* public void handleResult(Object result) { //Computation returned a result.
* //We have a non-null return value. Cast it to what
* //loadSomeDataInTheBg() declared to return.
* SomeData data = (SomeData) result;
*
* //Update model, UI, etc.
* }
* public void handleCancellation() { //Computation was cancelled.
* UserNotifier un = registry.getUserNotifier();
* un.notifyInfo("Data Loading", "SomeData task cancelled.");
* }
* public void handleException(Throwable exc) { //An error occurred.
* UserNotifier un = registry.getUserNotifier();
* un.notifyError("Data Loading Failure",
* "Couldn't retrieve SomeData.", exc);
* }
* };
* </code></pre></p>
*
* <p>Note that the <code>observer</code>'s code in the example above works
* just like any other <i>Swing</i> listener. In fact, all events are delivered
* <i>sequentially</i> and wihin the <i>Swing</i> event dispatching thread.
* This means the <code>observer</code> can run synchronously with respect to
* the UI and won't need to worry about concurrency issues as long as it
* runs within <i>Swing</i>. Finally, also note that subsquent feedback events
* imply computation progress and the
* {@link org.openmicroscopy.shoola.env.data.events.DSCallOutcomeEvent} is
* always the last event to be delivered in order of time.</p>
*
* @author Jean-Marie Burel
* <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
* @author <br>Andrea Falconi
* <a href="mailto:a.falconi@dundee.ac.uk">
* a.falconi@dundee.ac.uk</a>
* @version 2.2
* <small>
* (<b>Internal version:</b> $Revision$ $Date$)
* </small>
* @since OME2.2
*/
public interface DataServicesView
{
}