JAL-3878 Add javadocs to created classes and reformat code.
authorMateusz Warowny <mmzwarowny@dundee.ac.uk>
Fri, 12 Nov 2021 15:00:02 +0000 (16:00 +0100)
committerMateusz Warowny <mmzwarowny@dundee.ac.uk>
Fri, 12 Nov 2021 15:00:02 +0000 (16:00 +0100)
16 files changed:
src/jalview/gui/WebServicesMenuBuilder.java
src/jalview/ws2/MenuEntryProviderI.java
src/jalview/ws2/PollableTaskI.java
src/jalview/ws2/PollableTaskListenerI.java
src/jalview/ws2/PollingTaskExecutor.java
src/jalview/ws2/ResultSupplier.java
src/jalview/ws2/WSJob.java
src/jalview/ws2/WebServiceDiscoverer.java
src/jalview/ws2/WebServiceI.java
src/jalview/ws2/WebServiceInfoUpdater.java
src/jalview/ws2/WebServiceWorkerI.java
src/jalview/ws2/WebServiceWorkerListener.java
src/jalview/ws2/WebServiceWorkerListenersList.java
src/jalview/ws2/gui/ProgressBarUpdater.java
src/jalview/ws2/operations/AlignmentOperation.java
src/jalview/ws2/operations/Operation.java

index 2a17bf4..2aae0ff 100644 (file)
@@ -19,6 +19,11 @@ import jalview.util.MessageManager;
 import jalview.ws2.WebServiceI;
 import jalview.ws2.operations.Operation;
 
+/**
+ * 
+ * @author mmwarowny
+ *
+ */
 public class WebServicesMenuBuilder
 {
   @FunctionalInterface
@@ -68,7 +73,7 @@ public class WebServicesMenuBuilder
     var keysSet = new HashSet<>(oneshotOperations.keySet());
     keysSet.addAll(interactiveOperations.keySet());
     var keys = new ArrayList<>(keysSet);
-    keys.sort(Comparator.<String>naturalOrder());
+    keys.sort(Comparator.<String> naturalOrder());
     for (String opType : keys)
     {
       var submenu = new JMenu(opType);
@@ -87,12 +92,12 @@ public class WebServicesMenuBuilder
   }
 
   private void addOneshotOperations(List<Operation> operations, JMenu submenu,
-          AlignFrame frame)
+      AlignFrame frame)
   {
     operations = new ArrayList<>(operations);
     operations.sort(Comparator
-            .<Operation, String>comparing(o -> o.getHostName())
-            .<String>thenComparing(o -> o.getName()));
+        .<Operation, String> comparing(o -> o.getHostName())
+        .<String> thenComparing(o -> o.getName()));
     String lastHost = null;
     for (final Operation op : operations)
     {
@@ -123,7 +128,7 @@ public class WebServicesMenuBuilder
       groupedOperations.get(op.getName()).add(op);
     }
     var keys = new ArrayList<>(groupedOperations.keySet());
-    keys.sort(Comparator.<String>naturalOrder());
+    keys.sort(Comparator.<String> naturalOrder());
     for (String opName : keys)
     {
       var ops = groupedOperations.get(opName);
@@ -155,7 +160,8 @@ public class WebServicesMenuBuilder
             MessageManager.getString("label.choose_jabaws_server")));
         for (final Operation op : ops)
         {
-          if (op == selectedOperation) continue;
+          if (op == selectedOperation)
+            continue;
           var hostItem = new JMenuItem(op.getHostName());
           hostItem.setForeground(Color.blue);
           hostItem.addActionListener(e -> {
index a5e2d0f..b6f0e9c 100755 (executable)
@@ -4,8 +4,25 @@ import javax.swing.JMenu;
 
 import jalview.gui.AlignFrame;
 
+/**
+ * Functional interface provided by {@link jalview.ws2.operations.Operation}
+ * instances to construct the menu entry for the operations. The instances are
+ * passed to the {@link jalview.gui.WebServicesMenuBuilder} and called during
+ * menu construction.
+ * 
+ * @author mmwarowny
+ */
 @FunctionalInterface
 public interface MenuEntryProviderI
 {
+  /**
+   * Build menu entries directly under the given menu. This method is called by
+   * {@link jalview.gui.WebServicesMenuBuilder} during menu construction.
+   * 
+   * @param parent
+   *          parent menu
+   * @param frame
+   *          current alignFrame
+   */
   public void buildMenu(JMenu parent, AlignFrame frame);
 }
index 88c7371..d097974 100644 (file)
@@ -1,12 +1,51 @@
 package jalview.ws2;
 
+/**
+ * The {@code PollableTaskI} interface should be implemented by classes
+ * representing a background task that must be polled repeatedly to check for
+ * completion. Those are typically jobs that run on a remote host and need to be
+ * periodically checked for status updates.
+ * 
+ * The life-cycle of a task consist of calling {@link #start} method once to
+ * start the process, followed by repeated calls to {@link #poll} that should
+ * check for execution status and finally {@link #done} method that finalizes
+ * the process.
+ * 
+ * The instances can be started with {@link PollingTaskExecutor} which manages
+ * start up, polling and finalization of the task using a thread executor.
+ * 
+ * @author mmwarowny
+ *
+ */
 public interface PollableTaskI
 {
+  /**
+   * Called by the executor once and the beginning to start the task. May throw
+   * any exception, in such case the task will be interrupted.
+   * 
+   * @throws Exception
+   */
   void start() throws Exception;
 
+  /**
+   * Called repeatedly by the executor to check for task completion. The
+   * implementation should check the remote host for job status updates and
+   * return true when the task is finished. If any exception is thrown, the task
+   * is interrupted.
+   * 
+   * @return whether the task is done
+   * @throws Exception
+   */
   boolean poll() throws Exception;
 
+  /**
+   * @return whether the task is done
+   */
   boolean isDone();
 
+  /**
+   * Called once the task is done running ({@link #poll} returned true) to
+   * finalize the task and collect the results.
+   */
   void done();
 }
index e5a3682..d69b2d9 100644 (file)
@@ -1,14 +1,57 @@
 package jalview.ws2;
 
+/**
+ * Classes listening to the pollable task events must implement
+ * {@link PollableTaskListenerI}. They can be added to the
+ * {@link PollingTaskExecutor} to respond to the task execution events.
+ * 
+ * @author mmwarowny
+ *
+ */
 public interface PollableTaskListenerI
 {
+  /**
+   * Called when a new task is submitted for execution after its
+   * {@link PollableTask#start} method was called successfully.
+   * 
+   * @param task
+   *          submitted task
+   */
   public void submitted(PollableTaskI task);
 
+  /**
+   * Called when a new task failed to start and raised an uncaught exception.
+   * 
+   * @param task
+   *          task that failed
+   * @param e
+   *          raised exception
+   */
   public void submissionFailed(PollableTaskI task, Exception e);
 
+  /**
+   * Called when polling resulted in an uncaught exception.
+   * 
+   * @param task
+   *          task that failed
+   * @param e
+   *          raised exception
+   */
   public void pollFailed(PollableTaskI task, Exception e);
 
+  /**
+   * Called when a task is cancelled.
+   * 
+   * @param task
+   *          cancelled task
+   */
   public void cancelled(PollableTaskI task);
 
+  /**
+   * Called when the task finished execution either successfully or not.
+   * 
+   * @param task
+   *          finished task
+   */
   public void done(PollableTaskI task);
 }
index 3e04c17..c003e49 100644 (file)
@@ -8,11 +8,31 @@ import java.util.concurrent.TimeUnit;
 
 import jalview.bin.Cache;
 
+/**
+ * An object that executes submitted {@link PollableTaskI} tasks using
+ * {@link SchedulekExecutorservice}. The task is first started using its
+ * {@link PollableTaskI#start} method and then repeatedly polled every second
+ * with {@link PollableTaskI#poll}.
+ * 
+ * The {@link PollingTaskExecutor} automates the process of running tasks and
+ * provides convenient interface to listen to events associated with task
+ * execution.
+ * 
+ * @author mmwarowny
+ *
+ */
 public class PollingTaskExecutor
 {
   private ScheduledExecutorService executor = Executors
-          .newSingleThreadScheduledExecutor();
-
+      .newSingleThreadScheduledExecutor();
+
+  /**
+   * Submit the task for execution. Calls task's {@code start} method and, if
+   * started successfully, schedules next poll after one second.
+   * 
+   * @param task
+   *          task to submit
+   */
   public void submit(final PollableTaskI task)
   {
     executor.submit(() -> {
@@ -30,6 +50,14 @@ public class PollingTaskExecutor
     });
   }
 
+  /**
+   * Poll the task by calling it's {@code poll} method. If not finished, the
+   * next poll is scheduled to happen after one second, otherwise task's
+   * {@code done} method is called immediately.
+   * 
+   * @param task
+   *          task to poll
+   */
   private void poll(PollableTaskI task)
   {
     boolean done;
@@ -55,11 +83,21 @@ public class PollingTaskExecutor
 
   private WebServiceThreadSupport wsThreadSupport = new WebServiceThreadSupport();
 
+  /**
+   * Add listener of the task related events.
+   * 
+   * @param listener
+   *          listener to add
+   */
   public void addThreadListener(PollableTaskListenerI listener)
   {
     wsThreadSupport.addListener(listener);
   }
 
+  /**
+   * @param listener
+   *          listener to be removed
+   */
   public void removeThreadListener(PollableTaskListenerI listener)
   {
     wsThreadSupport.removeListener(listener);
index 3642d8e..68979c2 100644 (file)
@@ -7,6 +7,17 @@ import jalview.api.AlignViewportI;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceI;
 
+/**
+ * A generic function which supplies job result from the remote job to the
+ * worker object when the job is finished. Typically, the interface is
+ * implemented by one of the {@link WebServiceI} object methods and passed to
+ * the {@link WebServiceWorkerI} object on its creation.
+ * 
+ * @author mmwarowny
+ *
+ * @param <T>
+ *          result type
+ */
 @FunctionalInterface
 public interface ResultSupplier<T>
 {
index 0de6b22..979eaf9 100755 (executable)
@@ -70,6 +70,11 @@ public final class WSJob implements Serializable
             jobId, creationTime);
   }
 
+  /**
+   * Get the ordinal numer of the job.
+   * 
+   * @return job number
+   */
   public int getJobNum()
   {
     return jobNum;
index 513610c..2dfa1ef 100644 (file)
@@ -9,6 +9,20 @@ import java.util.concurrent.CopyOnWriteArrayList;
 
 import jalview.ws2.operations.Operation;
 
+/**
+ * The discoverer and the supplier of the operations/web services available
+ * on the remote hosts. Each web service client used should have it's
+ * implementation of the discoverer acting as an intermediary between the servers
+ * and jalview application. There is no need for more than one discoverer
+ * per web client per application, therefore singletons can be used.
+ * 
+ * The discoverer stores a list of url endpoints where the services can be
+ * found and builds instances of {@link jalview.ws2.operations.Operation}
+ * with associated implementations of {@link jalview.ws2.WebServiceI}.
+ * 
+ * @author mmwarowny
+ *
+ */
 public interface WebServiceDiscoverer
 {
   public static final int STATUS_OK = 1;
@@ -19,47 +33,131 @@ public interface WebServiceDiscoverer
 
   public static final int STATUS_UNKNOWN = -2;
 
+  /**
+   * Get the list of urls that this discoverer will use.
+   */
   public List<String> getUrls();
 
+  /**
+   * Set the list of urls where this discoverer will search for services.
+   */
   public void setUrls(List<String> wsUrls);
 
+  /**
+   * Test if the url is a valid url for that service discoverer.
+   */
   public boolean testUrl(URL url);
 
+  /**
+   * Get the availability status of the services at the url. Return one of the
+   * status codes {@code STATUS_OK}, {@code STATUS_NO_SERVICES},
+   * {@code STATUS_INVALID} or {@code STATUS_UNKNOWN}.
+   * 
+   * @return status code for the services availability
+   */
   public int getStatusForUrl(String url);
 
+  /**
+   * Get the list of operations found on the servers.
+   * 
+   * @return list of operations found
+   */
   public List<Operation> getOperations();
 
+  /**
+   * @return whether there are services found
+   */
   public boolean hasServices();
 
+  /**
+   * Check if service discovery is still in progress. List of operations may be
+   * incomplete when the discoverer is running.
+   * 
+   * @return whether the discoverer is running
+   */
   public boolean isRunning();
 
+  /**
+   * Check if the discoverer is done searching for services. List of operations
+   * should be complete if this methods returns true.
+   * 
+   * @return whether the discoverer finished
+   */
   public boolean isDone();
 
+  /**
+   * Start the service discovery and return a future which will be set with this
+   * discoverer when the process is completed. This method should be called once
+   * on startup and then every time the urls list is updated.
+   * 
+   * @return future that will be set on discovery completion
+   */
   public CompletableFuture<WebServiceDiscoverer> startDiscoverer();
 
+  /**
+   * Get the error messages that occurred during service discovery.
+   * 
+   * @return error message
+   */
   public String getErrorMessages();
 
+  /**
+   * An interface for the listeners observing the changes to the operations
+   * list.
+   * 
+   * @author mmwarowny
+   */
   @FunctionalInterface
   static interface ServiceChangeListener
   {
+    /**
+     * Called whenever the operations list of the observed discoverer changes
+     * with that discoverer as the first argument and current operations list as
+     * the second. Operations list can be empty if there are no services or the
+     * list was cleared at the beginning of the discovery.
+     * 
+     * @param discoverer
+     * @param list
+     */
     public void operationsChanged(WebServiceDiscoverer discoverer,
-            List<Operation> list);
+        List<Operation> list);
   }
 
   List<ServiceChangeListener> serviceListeners = new CopyOnWriteArrayList<>();
 
+  /**
+   * Add an operations list observer that will be notified of any changes.
+   * 
+   * @param listener
+   *          operations list listener
+   */
   public default void addServiceChangeListener(
-          ServiceChangeListener listener)
+      ServiceChangeListener listener)
   {
     serviceListeners.add(listener);
   }
 
+  /**
+   * Remove the listener from the observers list.
+   * 
+   * @param listener
+   *          listener to be removed
+   */
   public default void removeServiceChangeListener(
-          ServiceChangeListener listener)
+      ServiceChangeListener listener)
   {
     serviceListeners.remove(listener);
   }
 
+  /**
+   * Called whenever the list of operations changes. Notifies all listeners of
+   * the change to the operations list. Typically, should be called with an
+   * empty list at the beginning of the service discovery process and for the
+   * second time with the list of discovered operations after that.
+   * 
+   * @param list
+   *          new list of discovered operations
+   */
   default void fireOperationsChanged(List<Operation> list)
   {
     for (var listener : serviceListeners)
index a09233f..cdb201e 100755 (executable)
@@ -20,21 +20,75 @@ import jalview.ws2.operations.Operation;
  */
 public interface WebServiceI
 {
+  /**
+   * Get the hostname/url of the remote server which is supplying the service.
+   * 
+   * @return host name
+   */
   public String getHostName();
 
+  /**
+   * Get the short name of the service supplier.
+   * 
+   * @return short service supplier name
+   */
   public String getProviderName();
 
+  /**
+   * Get the name of the service
+   * 
+   * @return service name
+   */
   String getName();
 
+  /**
+   * Get the description of the service.
+   * 
+   * @return service description
+   */
   String getDescription();
 
+  /**
+   * Return whether the service provider user-adjustable parameters.
+   * 
+   * @return whether service has parameters
+   */
   boolean hasParameters();
 
+  /**
+   * Get a {@link ParamDatastoreI} object containing service parameters and
+   * presets.
+   * 
+   * @return service parameters and presets
+   */
   public ParamDatastoreI getParamStore();
 
+  /**
+   * Submit new job to the service with the supplied input sequences and
+   * arguments. Implementations should perform all data parsing necessary for
+   * the job submission and start a new job on the remote server.
+   * 
+   * @param sequences
+   *          input sequences
+   * @param args
+   *          user provided arguments
+   * @return job id
+   * @throws IOException
+   *           submission failed due to a connection error
+   */
   public String submit(List<SequenceI> sequences, List<ArgumentI> args)
-          throws IOException;
+      throws IOException;
 
+  /**
+   * Update the progress of the running job according to the state reported by
+   * the server. Implementations should fetch the current job status from the
+   * server and update status and log messages on the provided job object.
+   * 
+   * @param job
+   *          job to update
+   * @throws IOException
+   *           server error occurred
+   */
   public void updateProgress(WSJob job) throws IOException;
 
   public void cancel(WSJob job) throws IOException;
index c9557c6..a4d0f70 100644 (file)
@@ -6,6 +6,17 @@ import java.util.Objects;
 
 import jalview.gui.WebserviceInfo;
 
+/**
+ * A helper class that can be attached as a listener to the {@link WSJob}
+ * object. It updates the job status in the {@link jalview.gui.WebServiceInfo}
+ * window according to the state changes of the job object.
+ * 
+ * The {@link WebServiceInfoUpdater} object allows to decouple GUI updates
+ * from the web service worker logic.
+ * 
+ * @author mmwarowny
+ *
+ */
 public class WebServiceInfoUpdater implements PropertyChangeListener
 {
   private final WebServiceWorkerI worker;
index 38c82a2..6f3ef9f 100644 (file)
@@ -5,18 +5,51 @@ import java.util.List;
 
 import jalview.ws2.utils.WSJobList;
 
+/**
+ * {@link WebServiceWorkerI} interface is an extension of {@link PollableTaskI}
+ * that adds getter methods for fields that are specific for the web service
+ * tasks such as uid, sub-jobs and underlying web service client as well as a
+ * method to add listeners to the worker events. {@link WebServiceWorkerI}
+ * objects perform operations needed to start, poll and finalize jobs running on
+ * the server as well as store sub-jobs created in the process. They use their
+ * associated {@link WebServiceI} object to submit and poll the jobs and fetch
+ * and parse the result when it's ready.
+ * 
+ * @author mmwarowny
+ *
+ */
 public interface WebServiceWorkerI extends PollableTaskI
-{  
+{
+  /**
+   * Get unique identifier of this worker. Identifier should be randomly
+   * generated on object creation and must remain unchanged. Unique id can be
+   * generated using {@link jalview.util.MathUtils#getUID}.
+   * 
+   * @return worker unique id
+   */
   long getUID();
 
+  /**
+   * Get the sub-jobs created by the worker during job submission.
+   * 
+   * @return sub-jobs
+   */
   WSJobList getJobs();
 
+  /**
+   * Gather and parse input data and submit one or more jobs to the web service
+   * using associated {@link WebServiceI} object.
+   */
   void start() throws IOException;
 
   boolean poll() throws IOException;
 
   WebServiceI getWebService();
 
+  /**
+   * Check if all sub-jobs finished execution and return whether this task has
+   * completed.
+   */
   default boolean isDone()
   {
     if (getJobs().size() == 0)
@@ -29,11 +62,14 @@ public interface WebServiceWorkerI extends PollableTaskI
     return true;
   }
 
-  /*
-   * Called by the executor when the worker transitions to the done state
-   * either normally or exceptionally.
-   */
   void done();
-  
+
+  /**
+   * Add worker listeners to this worker that will be notified about any state
+   * changes to this worker.
+   * 
+   * @param listener
+   *          listener to add
+   */
   public void addListener(WebServiceWorkerListener listener);
 }
index 16ee7bd..74eb144 100644 (file)
@@ -1,16 +1,72 @@
 package jalview.ws2;
 
+/**
+ * The listener interface for receiving signals from the
+ * {@link WebServiceWorkerI} about the state changes or new sub-jobs spawned.
+ * 
+ * The {@link WebServiceWorkerListener} objects created from that interface are
+ * then registered with a worker objects using
+ * {@link WebServiceWorkerI#addListener} method. When an event occurs, a
+ * relevant method in the listener is invoked with the worker that emitted the
+ * signal as a first parameter and, optionally, followed by additional event
+ * details.
+ * 
+ * @author mmwarowny
+ *
+ */
 public interface WebServiceWorkerListener
 {
+  /**
+   * Called when the worker started successfully.
+   * 
+   * @param source
+   *          worker that emitted the signal
+   */
   void workerStarted(WebServiceWorkerI source);
-  
+
+  /**
+   * Called when the worker failed to start the jobs.
+   * 
+   * @param source
+   *          worker that emitted the signal
+   */
   void workerNotStarted(WebServiceWorkerI source);
-  
+
+  /**
+   * Called when the worker creates a new job
+   * 
+   * @param source
+   *          worker that emitted the signal
+   * @param job
+   *          newly created job
+   */
   void jobCreated(WebServiceWorkerI source, WSJob job);
-  
+
+  /**
+   * Called when polling the job results in an exception.
+   * 
+   * @param source
+   *          worker that emitted the signal
+   * @param job
+   *          polled job
+   * @param e
+   *          exception that occurred
+   */
   void pollException(WebServiceWorkerI source, WSJob job, Exception e);
-  
+
+  /**
+   * Called when the polling has finished and the finalization process begun.
+   * 
+   * @param source
+   *          worker that emitted the signal
+   */
   void workerCompleting(WebServiceWorkerI source);
-  
+
+  /**
+   * Called when the worker completes its work.
+   * 
+   * @param source
+   *          worker that emitted the signal
+   */
   void workerCompleted(WebServiceWorkerI source);
 }
index a09c958..bce6d57 100644 (file)
@@ -4,67 +4,136 @@ import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.function.Consumer;
 
+/**
+ * Utility class that manages a list of {@link WebServiceWorkerListener} and
+ * dispatches signals to them. An instance of this class can be used as a member
+ * field of the {@link WebServiceWorkerI} object to easily store listeners and
+ * delegate signals to them. Firing any signal with this object will invoke a
+ * corresponding method on all registered listeners in order they were
+ * registered.
+ * 
+ * @author mmwarowny
+ *
+ */
 public class WebServiceWorkerListenersList
 {
   private WebServiceWorkerI owner;
+
   private List<WebServiceWorkerListener> listeners = new CopyOnWriteArrayList<>();
-  
+
+  /**
+   * Constructs a listeners list object with the worker which will be given
+   * to the listeners as the source of the signals.
+   * 
+   * @param worker the worker to be given as the source for signals
+   */
   public WebServiceWorkerListenersList(WebServiceWorkerI worker)
   {
     this.owner = worker;
   }
-  
+
+  /**
+   * Add listener to the listeners list. The listener will be notified of
+   * any signals triggered with this object.
+   * 
+   * @param listener listener to add
+   */
   public void addListener(WebServiceWorkerListener listener)
   {
     listeners.add(listener);
   }
-  
+
+  /**
+   * Remove listener from the lsiteners list. The listener will no longer be
+   * notified of the emitted signals.
+   * 
+   * @param listener listener to remove
+   */
   public void removeListener(WebServiceWorkerListener listener)
   {
     listeners.remove(listener);
   }
-  
+
+  /**
+   * Emit "worker started" signal to all listeners.
+   */
   public void fireWorkerStarted()
   {
     for (var listener : listeners)
       listener.workerStarted(owner);
   }
-  
+
+  /**
+   * Emit "worker not started" signal to all listeners.
+   */
   public void fireWorkerNotStarted()
   {
     for (var listener : listeners)
       listener.workerNotStarted(owner);
   }
-  
+
+  /**
+   * Emit "job created" signal to all listeners passing the job that has been
+   * created to them.
+   * 
+   * @param job newly created job
+   */
   public void fireJobCreated(WSJob job)
   {
     for (var listener : listeners)
       listener.jobCreated(owner, job);
   }
-  
+
+  /**
+   * Emit "poll exception" signal to all listener when an exception occurred
+   * during job polling. The job which caused an exception as well as the exception
+   * are passed to all listeners.
+   * 
+   * @param job polled job
+   * @param e exception that occurred
+   */
   public void firePollException(WSJob job, Exception e)
   {
     for (var listener : listeners)
       listener.pollException(owner, job, e);
   }
-  
+
+  /**
+   * Emit "worker completing" signal to all listeners when the worker starts
+   * collecting and parsing the results.
+   */
   public void fireWorkerCompleting()
   {
     for (var listener : listeners)
       listener.workerCompleting(owner);
   }
-  
+
+  /**
+   * Emit "worker completed" signal to all listeners indicating that the worker
+   * finished processing data and finalized the jobs. 
+   */
   public void fireWorkerCompleted()
   {
     for (var listener : listeners)
       listener.workerCompleted(owner);
   }
   
+  /**
+   * Get the list of registered listeners. The returned list should not be
+   * modified externally and its content may change when workers are added
+   * or removed from the list.
+   * @return
+   */
   public List<WebServiceWorkerListener> getListeners()
   {
     return listeners;
   }
-  
+
+  /**
+   * Execute an operation for each listener in the listeners list.
+   * 
+   * @param consumer listener object consumer 
+   */
   public void forEach(Consumer<WebServiceWorkerListener> consumer)
   {
     for (var listener : listeners)
index 24c71d7..89deb06 100644 (file)
@@ -7,15 +7,21 @@ import jalview.gui.IProgressIndicator;
 import jalview.ws2.WSJob;
 import jalview.ws2.WSJobStatus;
 
+/**
+ * Monitors annotation jobs' status and updates progress indicators accordingly.
+ * 
+ * @author mmwarowny
+ *
+ */
 public class ProgressBarUpdater implements PropertyChangeListener
 {
   private IProgressIndicator progressIndicator;
-  
+
   public ProgressBarUpdater(IProgressIndicator progressIndicator)
   {
     this.progressIndicator = progressIndicator;
   }
-  
+
   @Override
   public void propertyChange(PropertyChangeEvent evt)
   {
index 1f0a602..ea8e529 100644 (file)
@@ -59,6 +59,7 @@ import jalview.ws2.gui.AlignmentMenuBuilder;
 import jalview.ws2.utils.WSJobList;
 
 /**
+ * Implementation of the {@link Operation} for multiple sequence alignment jobs.
  *
  * @author mmwarowny
  *
@@ -68,7 +69,6 @@ public class AlignmentOperation implements Operation
   private final WebServiceI service;
 
   private final ResultSupplier<AlignmentI> supplier;
-  
 
   public AlignmentOperation(
       WebServiceI service,
@@ -83,7 +83,7 @@ public class AlignmentOperation implements Operation
   {
     return service.getName();
   }
-  
+
   @Override
   public String getDescription()
   {
@@ -101,13 +101,13 @@ public class AlignmentOperation implements Operation
   {
     return service.getHostName();
   }
-  
+
   @Override
   public boolean hasParameters()
   {
     return service.hasParameters();
   }
-  
+
   @Override
   public ParamDatastoreI getParamStore()
   {
@@ -137,7 +137,7 @@ public class AlignmentOperation implements Operation
   {
     return true;
   }
-  
+
   @Override
   public boolean isAlignmentAnalysis()
   {
@@ -156,13 +156,13 @@ public class AlignmentOperation implements Operation
   {
     return false;
   }
-  
+
   @Override
   public boolean getFilterNonStandardSymbols()
   {
     return true;
   }
-  
+
   @Override
   public boolean getNeedsAlignedSequences()
   {
@@ -175,7 +175,6 @@ public class AlignmentOperation implements Operation
     return new AlignmentMenuBuilder(this);
   }
 
-
   /**
    * Implementation of the web service worker performing multiple sequence
    * alignment.
@@ -211,12 +210,12 @@ public class AlignmentOperation implements Operation
     private Map<Long, JobInput> inputs = new LinkedHashMap<>();
 
     private Map<Long, Integer> exceptionCount = new HashMap<>();
-    
+
     private final int MAX_RETRY = 5;
 
     public AlignmentWorker(AlignmentView msa, List<ArgumentI> args,
-            String alnTitle, boolean submitGaps, boolean preserveOrder,
-            AlignViewport viewport)
+        String alnTitle, boolean submitGaps, boolean preserveOrder,
+        AlignViewport viewport)
     {
       this.msa = msa;
       this.dataset = viewport.getAlignment().getDataset();
@@ -263,7 +262,7 @@ public class AlignmentOperation implements Operation
       {
         JobInput input = JobInput.create(conmsa[i], 2, submitGaps);
         WSJob job = new WSJob(service.getProviderName(), service.getName(),
-                service.getHostName());
+            service.getHostName());
         job.setJobNum(i);
         inputs.put(job.getUid(), input);
         jobs.add(job);
@@ -300,7 +299,7 @@ public class AlignmentOperation implements Operation
         {
           job.setStatus(WSJobStatus.INVALID);
           job.setErrorLog(
-                  MessageManager.getString("label.empty_alignment_job"));
+              MessageManager.getString("label.empty_alignment_job"));
         }
       }
       if (numValid > 0)
@@ -331,29 +330,28 @@ public class AlignmentOperation implements Operation
             Cache.log.error(format("Polling job %s failed.", job), e);
             listeners.firePollException(job, e);
             int count = exceptionCount.getOrDefault(job.getUid(),
-                    MAX_RETRY);
+                MAX_RETRY);
             if (--count <= 0)
             {
               job.setStatus(WSJobStatus.SERVER_ERROR);
               Cache.log.warn(format(
-                      "Attempts limit exceeded. Droping job %s.", job));
+                  "Attempts limit exceeded. Droping job %s.", job));
             }
             exceptionCount.put(job.getUid(), count);
           } catch (OutOfMemoryError e)
           {
             job.setStatus(WSJobStatus.BROKEN);
             Cache.log.error(
-                    format("Out of memory when retrieving job %s", job), e);
+                format("Out of memory when retrieving job %s", job), e);
           }
           Cache.log.debug(
-                  format("Job %s status is %s", job, job.getStatus()));
+              format("Job %s status is %s", job, job.getStatus()));
         }
         done &= job.getStatus().isDone() || job.getStatus().isFailed();
       }
       return done;
     }
 
-
     @Override
     public void done()
     {
@@ -365,7 +363,7 @@ public class AlignmentOperation implements Operation
           continue;
         try
         {
-          AlignmentI alignment = supplier.getResult(job, 
+          AlignmentI alignment = supplier.getResult(job,
               dataset.getSequences(), viewport);
           if (alignment != null)
           {
@@ -418,16 +416,16 @@ public class AlignmentOperation implements Operation
             width = Integer.max(width, emptySeq.getLength());
           // pad shorter sequences with gaps
           String gapSeq = String.join("",
-                  Collections.nCopies(width, Character.toString(gapChar)));
+              Collections.nCopies(width, Character.toString(gapChar)));
           List<SequenceI> seqs = new ArrayList<>(
-                  alnSeqs.size() + emptySeqs.size());
+              alnSeqs.size() + emptySeqs.size());
           seqs.addAll(alnSeqs);
           seqs.addAll(emptySeqs);
           for (var seq : seqs)
           {
             if (seq.getLength() < width)
               seq.setSequence(seq.getSequenceAsString()
-                      + gapSeq.substring(seq.getLength()));
+                  + gapSeq.substring(seq.getLength()));
           }
           SequenceI[] result = seqs.toArray(new SequenceI[0]);
           AlignmentOrder msaOrder = new AlignmentOrder(result);
@@ -488,24 +486,23 @@ public class AlignmentOperation implements Operation
         }
       }
     }
-    
+
     private Consumer<AlignmentResult> resultConsumer;
-    
+
     public void setResultConsumer(Consumer<AlignmentResult> consumer)
     {
       this.resultConsumer = consumer;
     }
 
-    private WebServiceWorkerListenersList listeners = 
-        new WebServiceWorkerListenersList(this);
-    
+    private WebServiceWorkerListenersList listeners = new WebServiceWorkerListenersList(this);
+
     @Override
     public void addListener(WebServiceWorkerListener listener)
     {
       listeners.addListener(listener);
     }
   }
-  
+
   public class AlignmentResult
   {
     AlignmentI aln;
@@ -515,7 +512,7 @@ public class AlignmentOperation implements Operation
     HiddenColumns hidden;
 
     AlignmentResult(AlignmentI aln, List<AlignmentOrder> alorders,
-            HiddenColumns hidden)
+        HiddenColumns hidden)
     {
       this.aln = aln;
       this.alorders = alorders;
@@ -548,8 +545,8 @@ public class AlignmentOperation implements Operation
     final Map<String, ? extends Map> sequenceNames;
 
     private JobInput(int numSequences, List<SequenceI> inputSequences,
-            List<SequenceI> emptySequences,
-            @SuppressWarnings("rawtypes") Map<String, ? extends Map> names)
+        List<SequenceI> emptySequences,
+        @SuppressWarnings("rawtypes") Map<String, ? extends Map> names)
     {
       this.inputSequences = Collections.unmodifiableList(inputSequences);
       this.emptySequences = Collections.unmodifiableList(emptySequences);
@@ -562,10 +559,10 @@ public class AlignmentOperation implements Operation
     }
 
     static JobInput create(SequenceI[] sequences, int minLength,
-            boolean submitGaps)
+        boolean submitGaps)
     {
       assert minLength >= 0 : MessageManager.getString(
-              "error.implementation_error_minlen_must_be_greater_zero");
+          "error.implementation_error_minlen_must_be_greater_zero");
       int numSeq = 0;
       for (SequenceI seq : sequences)
       {
@@ -592,20 +589,20 @@ public class AlignmentOperation implements Operation
           if (!submitGaps)
           {
             seqString = AlignSeq.extractGaps(
-                    jalview.util.Comparison.GapChars, seqString);
+                jalview.util.Comparison.GapChars, seqString);
           }
           inputSequences.add(new Sequence(newName, seqString));
         }
         else
         {
           String seqString = "";
-          if (seq.getEnd() >= seq.getStart())  // true if gaps only
+          if (seq.getEnd() >= seq.getStart()) // true if gaps only
           {
             seqString = seq.getSequenceAsString();
             if (!submitGaps)
             {
               seqString = AlignSeq.extractGaps(
-                      jalview.util.Comparison.GapChars, seqString);
+                  jalview.util.Comparison.GapChars, seqString);
             }
           }
           emptySequences.add(new Sequence(newName, seqString));
index f02bb59..bd12041 100644 (file)
@@ -3,38 +3,117 @@ package jalview.ws2.operations;
 import jalview.ws.params.ParamDatastoreI;
 import jalview.ws2.MenuEntryProviderI;
 
+/**
+ * Operation represents an action which can be performed with a (web)service or
+ * calculator. Examples of operations are multiple sequence alignment or
+ * sequence annotation. There should be one Operation implementation for each
+ * operation that Jalview can perform on sequences or alignments. The concrete
+ * implementations may be further parameterized to alter the functionality (e.g.
+ * making the operation interactive) or restrict input data (e.g. limit to
+ * proteins only).
+ * 
+ * @author mmwarowny
+ *
+ */
 public interface Operation
 {
+  /**
+   * Get the name of the operation. Typically fetched from the server.
+   * 
+   * @return operation name
+   */
   public String getName();
-  
+
+  /**
+   * Get the description of the operation. Typically fetched from the server.
+   * 
+   * @return operation description
+   */
   public String getDescription();
 
+  /**
+   * Get the name of the category that the operation falls into. Used to group
+   * the operations under the web services menu.
+   * 
+   * @return category name
+   */
   public String getTypeName();
 
+  /**
+   * Get the hostname/url of the server which this operation is delegated to.
+   * Typically fetched from the accompanying web service instance.
+   * 
+   * @return server url
+   */
   public String getHostName();
-  
+
+  /**
+   * Check if the operation has user-customizable input parameters.
+   * 
+   * @return if has parameters
+   */
   public boolean hasParameters();
-  
+
+  /**
+   * Returns parameter datastore for this operations containing input parameters
+   * and available presets.
+   * 
+   * @return parameter datastore of the operation
+   */
   public ParamDatastoreI getParamStore();
 
+  /**
+   * @return minimum accepted number of sequences
+   */
   public int getMinSequences();
 
+  /**
+   * @return maximum accepted number of sequences
+   */
   public int getMaxSequences();
 
+  /**
+   * @return whether gaps should be included
+   */
   public boolean canSubmitGaps();
 
+  /**
+   * @return whether works with protein sequences
+   */
   public boolean isProteinOperation();
 
+  /**
+   * @return whether works with nucleotide sequences
+   */
   public boolean isNucleotideOperation();
 
+  /**
+   * @return whether should be run interactively
+   */
   public boolean isInteractive();
 
+  /**
+   * Get the menu builder for this operation which will be used to construct the
+   * web services menu. The builder will be given the parent menu entry which it
+   * should attach menu items to and the current align frame.
+   * 
+   * @return menu entry builder instance
+   */
   public MenuEntryProviderI getMenuBuilder();
 
+  /**
+   * @return whether this operation is alignment analysis
+   */
   public boolean isAlignmentAnalysis();
-  
+
+  /**
+   * @return whether non-standatds symbols should be filtered out
+   */
   public boolean getFilterNonStandardSymbols();
-  
+
+  /**
+   * @return whether it needs aligned sequences
+   */
   public boolean getNeedsAlignedSequences();
 
 }