org.shaf.shell.action.ActionBase.java Source code

Java tutorial

Introduction

Here is the source code for org.shaf.shell.action.ActionBase.java

Source

/**
 * Copyright 2014-2015 SHAF-WORK
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.shaf.shell.action;

import java.util.Arrays;

import org.shaf.core.content.OutcomeContent;
import org.shaf.core.content.ProgressContent;
import org.shaf.core.content.ReceiptContent;
import org.shaf.core.util.TimeUtils;
import org.shaf.shell.util.ViewUtils;

import com.google.common.base.Strings;

/**
 * An abstract process execution action. This class should be extended by any
 * class interested in providing specific logic for different execution actions.
 * 
 * @author Mykola Galushka
 */
public abstract class ActionBase extends AbstractAction {

    /**
     * The property name for sleep interval between checking on execution
     * progress.
     */
    private final static String PROGRESS_CHECK_INTERVAL = "progress.check.interval";

    /**
     * This method initiates the process execution.
     * 
     * <p>
     * Each "submit" command-line must contain at least one argument. The first
     * argument represents the process alias. The rest of arguments represent
     * process options and used for it initialization.
     * 
     * <p>
     * This method performs the following steps:
     * <ol>
     * <li>requests a process description from the server for the specified
     * alias;</li>
     * <li>parses the command line according obtained description;</li>
     * <li>initiates the process execution on the server side;</li>
     * <li>returns the job ID from received response.</li>
     * </ol>
     * 
     * @param context
     *            the action context.
     * @param args
     *            the command arguments.
     * @return the job initialization receipt.
     * @throws Exception
     *             if an error occurs.
     */
    protected ReceiptContent submit(final ActionContext context, final String[] args) throws Exception {
        String alias = args[0];
        String[] arguments = (args.length > 1) ? Arrays.copyOfRange(args, 1, args.length) : new String[0];

        return context.getController().submitProcess(alias, arguments);
    }

    /**
     * This method waits until the process execution is completed.
     * 
     * <p>
     * This method performs the following steps:
     * 
     * <ol>
     * <li>requests the outcome for initialized job (the job is identified by
     * its ID);</li>
     * <li>if the returned outcome represents the execution progress, the
     * monitor puts itself to sleep and performs the same request again;</li>
     * <li>if the returned outcome represents the execution result, the monitor
     * is terminated and result displayed in the terminal;</li>
     * <li>if the monitor is terminated via shutdown hook, information about
     * executing job is displayed in the terminal for future references.</li>
     * </ol>
     * 
     * @param context
     *            the action context.
     * @param id
     *            the job ID.
     * @param wait
     *            if {@code true} then this method will be waiting until the
     *            monitoring job is completed, {@code false} indicates just one
     *            off check.
     * @return the process execution outcome.
     * @throws Exception
     *             if an error occurs.
     */
    public OutcomeContent watch(final ActionContext context, final String id, final boolean wait) throws Exception {
        OutcomeContent outcome = null;

        StringBuilder info = new StringBuilder();
        int lastLength = info.length();
        do {
            outcome = context.getController().getOutcome(id);

            if (outcome == null) {
                throw new IllegalArgumentException("no outcome for specified job ID.");
            } else {
                if (outcome instanceof ProgressContent) {
                    if (wait) {
                        info = new StringBuilder();
                        info.append("Job #");
                        info.append(id);
                        info.append(" - ");
                        info.append(TimeUtils.formatTimeInterval(outcome.getTime()));
                        info.append(' ');
                        info.append(ViewUtils.bar(((ProgressContent) outcome).getProgress()));
                        info.append((info.length() < lastLength) ? Strings.repeat(" ", lastLength - info.length())
                                : "");
                        info.append('\r');

                        lastLength = info.toString().trim().length();
                        context.show(info);

                        Thread.sleep(context.getConfig().getLong(PROGRESS_CHECK_INTERVAL, 1000L));
                    }
                }
            }
        } while ((outcome instanceof ProgressContent) && wait);

        context.show(Strings.repeat(" ", lastLength) + "\r");

        return outcome;
    }

    /**
     * Forget the result of completed process.
     * 
     * @param context
     *            the action context.
     * @param id
     *            the job ID.
     * @throws Exception
     *             if an error occurs.
     */
    protected ReceiptContent forget(final ActionContext context, final String id) throws Exception {
        return context.getController().forgetOutcome(id);
    }
}