com.vmware.appfactory.taskqueue.tasks.TaskRecorder.java Source code

Java tutorial

Introduction

Here is the source code for com.vmware.appfactory.taskqueue.tasks.TaskRecorder.java

Source

/* ***********************************************************************
 * VMware ThinApp Factory
 * Copyright (c) 2009-2013 VMware, Inc. All Rights Reserved.
 *
 * 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 com.vmware.appfactory.taskqueue.tasks;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.vmware.appfactory.taskqueue.tasks.state.AbstractCaptureState;
import com.vmware.appfactory.taskqueue.tasks.state.AppConvertState;
import com.vmware.appfactory.taskqueue.tasks.state.FeedConvertState;
import com.vmware.appfactory.taskqueue.tasks.state.FeedScanState;
import com.vmware.appfactory.taskqueue.tasks.state.ManualModeState;
import com.vmware.appfactory.taskqueue.tasks.state.TaskState;
import com.vmware.appfactory.taskqueue.tasks.state.tasks.AppFactoryTask;
import com.vmware.appfactory.taskqueue.tasks.state.tasks.TaskFactory;

/**
 * Strictly responsible for storing information about running tasks
 * and responding to various queries.
 *
 * Main tasks are:
 *  - record a new task, including:
 *      - the task itself
 *        (which has an ID and an "item handle", which is a reference
 *        to the TAF object being worked on by the task, such as App-123
 *        or Feed-99)
 *
 *  - remove a task by id
 *
 *  - list all tasks
 *
 *  - find tasks by:
 *     - id
 *     - MetaStatus of the task
 *     - type of the task
 *
 * This class is not concerned with the operations involving running the task
 * or changing the task state.
 */
@SuppressWarnings("AccessToStaticFieldLockedOnInstance")
class TaskRecorder {

    @Nonnull
    private final Map<Long, AppFactoryTask> mapTaskIdToTask;

    @Nonnull
    private final Multimap<String, AppFactoryTask> mapTaskHandleToTasks;

    @Nonnull
    public static final Function<AppFactoryTask, TaskState> fnGetCurrentState = new Function<AppFactoryTask, TaskState>() {
        @Override
        public TaskState apply(AppFactoryTask input) {
            return input.getCurrentTaskState();
        }
    };

    TaskRecorder(int expectedSize, int maxFinishedSize, int expectedTasksPerId) {

        mapTaskIdToTask = Maps.newHashMapWithExpectedSize(expectedSize);
        mapTaskHandleToTasks = LinkedHashMultimap.create(expectedSize + maxFinishedSize, expectedTasksPerId);

    }

    /**
     * Records a new task.
     *
     * @param task    The task itself.  It must have an ID field set.
     */
    public synchronized void recordTask(AppFactoryTask task) {
        long taskId = task.getCurrentTaskState().getId();
        mapTaskIdToTask.put(taskId, task);

        String taskHandle = task.getTaskHandle();
        mapTaskHandleToTasks.put(taskHandle, task);
    }

    /**
     * Deletes a task from the recorder.
     *
     * @param taskId
     * id of the task to delete
     *
     * @return the AppFactoryTask which was removed from the recorder,
     * or null if no task by the given id was found.
     */
    @Nullable
    public synchronized AppFactoryTask eraseTask(long taskId) {
        AppFactoryTask removedTask = mapTaskIdToTask.remove(taskId);
        if (null == removedTask) {
            // nothing more to do
            return null;
        }

        String taskHandle = removedTask.getTaskHandle();
        mapTaskHandleToTasks.remove(taskHandle, removedTask);

        return removedTask;
    }

    /**
     * @return a list of all tasks currently recorded, completed or not,
     *         in no particular order.
     */
    @Nonnull
    public synchronized List<AppFactoryTask> getAllTasks() {
        return ImmutableList.copyOf(mapTaskIdToTask.values());
    }

    @Nullable
    public synchronized TaskState findTaskById(long id) {
        AppFactoryTask task = mapTaskIdToTask.get(id);
        if (null == task) {
            return null;
        }
        return task.getCurrentTaskState();
    }

    @Nonnull
    public synchronized Iterable<? extends AbstractCaptureState> findActiveTasksForApp(final long appId) {
        return Iterables.filter(
                Iterables.concat(findTasksForRecord(AppConvertState.TYPE, appId, AppConvertState.class),
                        findTasksForRecord(ManualModeState.TYPE, appId, ManualModeState.class)),
                MetaStatusPredicate.NOT_FINISHED);
    }

    synchronized AppFactoryTask getTaskFromId(long taskId) {
        return mapTaskIdToTask.get(taskId);
    }

    @Nonnull
    synchronized Iterable<? extends TaskState> findActiveTasksForFeed(final long feedId) {
        return Iterables.filter(
                Iterables.concat(findTasksForRecord(FeedScanState.TYPE, feedId, FeedScanState.class),
                        findTasksForRecord(FeedConvertState.TYPE, feedId, FeedConvertState.class)),
                MetaStatusPredicate.NOT_FINISHED);
    }

    @SuppressWarnings("unchecked")
    private <T extends TaskState> Iterable<T> findTasksForRecord(String taskType, long recordId,
            @Nonnull Class<T> klass) {
        String recordHandle = TaskFactory.makeRecordId(taskType, recordId);
        return ImmutableList.copyOf((Iterable<T>) Iterables.filter(
                Collections.unmodifiableCollection(
                        Collections2.transform(mapTaskHandleToTasks.get(recordHandle), fnGetCurrentState)),
                Predicates.instanceOf(klass)));
    }
}