Package name.pehl.karaka.client.activity.presenter

Source Code of name.pehl.karaka.client.activity.presenter.ActivityController

package name.pehl.karaka.client.activity.presenter;

import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HasHandlers;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.gwtplatform.dispatch.shared.DispatchAsync;
import name.pehl.karaka.client.activity.dispatch.CopyActivityAction;
import name.pehl.karaka.client.activity.dispatch.CopyActivityResult;
import name.pehl.karaka.client.activity.dispatch.DeleteActivityAction;
import name.pehl.karaka.client.activity.dispatch.DeleteActivityResult;
import name.pehl.karaka.client.activity.dispatch.SaveActivityAction;
import name.pehl.karaka.client.activity.dispatch.SaveActivityResult;
import name.pehl.karaka.client.activity.dispatch.StartActivityAction;
import name.pehl.karaka.client.activity.dispatch.StartActivityResult;
import name.pehl.karaka.client.activity.dispatch.StopActivityAction;
import name.pehl.karaka.client.activity.dispatch.StopActivityResult;
import name.pehl.karaka.client.activity.dispatch.TickActivityAction;
import name.pehl.karaka.client.activity.dispatch.TickActivityResult;
import name.pehl.karaka.client.activity.event.ActivitiesLoadedEvent;
import name.pehl.karaka.client.activity.event.ActivitiesLoadedEvent.ActivitiesLoadedHandler;
import name.pehl.karaka.client.activity.event.ActivityAction.Action;
import name.pehl.karaka.client.activity.event.ActivityActionEvent;
import name.pehl.karaka.client.activity.event.ActivityActionEvent.ActivityActionHandler;
import name.pehl.karaka.client.activity.event.ActivityChangedEvent;
import name.pehl.karaka.client.activity.event.RunningActivityLoadedEvent;
import name.pehl.karaka.client.activity.event.RunningActivityLoadedEvent.RunningActivityLoadedHandler;
import name.pehl.karaka.client.activity.event.TickEvent;
import name.pehl.karaka.client.application.Message;
import name.pehl.karaka.client.application.ShowMessageEvent;
import name.pehl.karaka.client.dispatch.KarakaCallback;
import name.pehl.karaka.client.project.RefreshProjectsEvent;
import name.pehl.karaka.client.tag.RefreshTagsEvent;
import name.pehl.karaka.shared.model.Activities;
import name.pehl.karaka.shared.model.Activity;
import name.pehl.karaka.shared.model.Project;
import name.pehl.karaka.shared.model.Tag;

import java.util.List;
import java.util.Set;

import static java.util.logging.Level.INFO;
import static name.pehl.karaka.client.activity.event.ActivityChanged.ChangeAction.*;
import static name.pehl.karaka.client.logging.Logger.Category.activity;
import static name.pehl.karaka.client.logging.Logger.info;

/**
* <p>
* Singelton class which controls the current activity and the list of displayed
* placeRequestFor. This is the <strong>only</strong> place where the current
* activity can be resumed, started, stopped, changed, deleted or copied. All
* relevant presenters must notify this controller with appropriate events. In
* return this controller responds with events to notify other presenters.
* </p>
* <h3>Events</h3>
* <ol>
* <li>IN</li>
* <ul>
* <li>{@linkplain ActivityActionEvent}</li>
* <li>{@linkplain ActivitiesLoadedEvent}</li>
* <li>{@linkplain RunningActivityLoadedEvent}</li>
* </ul>
* <li>OUT</li>
* <ul>
* <li>{@linkplain ActivityChangedEvent}</li>
* <li>{@linkplain RefreshProjectsEvent}</li>
* <li>{@linkplain RefreshTagsEvent}</li>
* <li>{@linkplain ShowMessageEvent}</li>
* <li>{@linkplain TickEvent}</li>
* </ul>
* </ol>
* <h3>Dispatcher actions</h3>
* <ul>
* <li>{@linkplain CopyActivityAction}</li>
* <li>{@linkplain DeleteActivityAction}</li>
* <li>{@linkplain SaveActivityAction}</li>
* <li>{@linkplain StartActivityAction}</li>
* <li>{@linkplain StopActivityAction}</li>
* <li>{@linkplain TickActivityAction}</li>
* </ul>
*
* @author $Author: harald.pehl $
* @version $Date: 2010-12-23 13:52:44 +0100 (Do, 23. Dez 2010) $ $Revision: 192
*          $
*/
public class ActivityController implements RepeatingCommand, HasHandlers, RunningActivityLoadedHandler,
        ActivitiesLoadedHandler, ActivityActionHandler
{
    // ------------------------------------------------------- (static) members

    static final int TICK_INTERVAL = 60 * 1000;
    static final String ONE_DAY = "P1D";
    final EventBus eventBus;
    final Scheduler scheduler;
    final DispatchAsync dispatcher;
    /**
     * Should I tick?
     */
    boolean ticking;
    /**
     * The currently running actvity. Null if no activity is running.
     */
    Activity runningActivity;
    /**
     * The currently displayed placeRequestFor
     */
    Activities activities;


    // ------------------------------------------------------------------ setup


    @Inject
    public ActivityController(final EventBus eventBus, final Scheduler scheduler, final DispatchAsync dispatcher)
    {
        super();
        this.eventBus = eventBus;
        this.scheduler = scheduler;
        this.dispatcher = dispatcher;
    }

    public void init()
    {
        eventBus.addHandler(RunningActivityLoadedEvent.getType(), this);
        eventBus.addHandler(ActivitiesLoadedEvent.getType(), this);
        eventBus.addHandler(ActivityActionEvent.getType(), this);
    }


    // --------------------------------------------------------- event handling

    @Override
    public void fireEvent(GwtEvent<?> event)
    {
        eventBus.fireEventFromSource(event, this);
    }

    @Override
    public void onRunningActivityLoaded(RunningActivityLoadedEvent event)
    {
        runningActivity = event.getActivity();
        startTicking();
        // the first 'tick' will happen in TICK_INTERVAL millis, so tick now to update the UI
        tick();
    }

    @Override
    public void onActivitiesLoaded(ActivitiesLoadedEvent event)
    {
        activities = event.getActivities();
    }

    @Override
    public void onActivityAction(ActivityActionEvent event)
    {
        Action action = event.getAction();
        Activity activity = event.getActivity();
        switch (action)
        {
            case SAVE:
                save(activity);
                break;
            case COPY:
                copy(activity);
                break;
            case START_STOP:
                if (activity.isRunning())
                {
                    stop(activity);
                }
                else
                {
                    start(activity);
                }
                break;
            case DELETE:
                delete(activity);
                break;
            default:
                break;
        }
    }


    // -------------------------------------------------- activity crud methods

    void save(final Activity activityToSave)
    {
        info(activity, "About to save " + activityToSave);
        dispatcher.execute(new SaveActivityAction(activityToSave), new KarakaCallback<SaveActivityResult>(eventBus)
        {
            @Override
            public void onSuccess(SaveActivityResult result)
            {
                Activity savedActivity = result.getSaved();
                info(activity, activityToSave + " successfully saved as " + savedActivity);
                activities.update(savedActivity);
                ActivityChangedEvent.fire(ActivityController.this, CHANGED, savedActivity, activities);
                ShowMessageEvent.fire(ActivityController.this,
                        new Message(INFO, "Activity \"" + savedActivity.getName() + "\" saved", true));
                checkAndrefreshProjectsAndTags(activityToSave);
            }
        });
    }

    void copy(final Activity activityToCopy)
    {
        info(activity, "About to copy " + activityToCopy);
        dispatcher.execute(new CopyActivityAction(activityToCopy, ONE_DAY),
                new KarakaCallback<CopyActivityResult>(eventBus)
                {
                    @Override
                    public void onSuccess(CopyActivityResult result)
                    {
                        Activity copiedActivity = result.getCopy();
                        info(activity, activityToCopy + " successfully copied as " + copiedActivity);
                        activities.update(copiedActivity);
                        ActivityChangedEvent.fire(ActivityController.this, NEW, copiedActivity, activities);
                        ShowMessageEvent.fire(ActivityController.this,
                                new Message(INFO, "Activity \"" + copiedActivity.getName() + "\" added", true));
                    }
                });
    }

    void start(final Activity activityToResumeOrStart)
    {
        info(activity, "About to resume / start " + activityToResumeOrStart);
        if (activityToResumeOrStart.isRunning())
        {
            info(activity, activityToResumeOrStart + " already running");
        }
        else
        {
            dispatcher.execute(new StartActivityAction(activityToResumeOrStart),
                    new KarakaCallback<StartActivityResult>(eventBus)
                    {
                        @Override
                        public void onSuccess(final StartActivityResult result)
                        {
                            Set<Activity> modifiedActivities = result.getModified();
                            runningActivity = extractRunningActivity(modifiedActivities);
                            boolean resumed = modifiedActivities.contains(activityToResumeOrStart);
                            info(activity,
                                    activityToResumeOrStart + " successfully " + (resumed ? "resumed" : "started") + ". Modified activities: " + modifiedActivities);
                            activities.update(modifiedActivities.toArray(new Activity[]{}));
                            ActivityChangedEvent
                                    .fire(ActivityController.this, resumed ? RESUMED : STARTED, runningActivity,
                                            activities);
                            ShowMessageEvent.fire(ActivityController.this, new Message(INFO, "Activity \""
                                    + runningActivity.getName() + "\" " + (resumed ? "resumed" : "started"), true));
                            checkAndrefreshProjectsAndTags(activityToResumeOrStart);
                            startTicking();
                        }
                    });
        }
    }

    void stop(final Activity activityToStop)
    {
        info(activity, "About to stop " + activityToStop);
        if (activityToStop.isStopped())
        {
            info(activity, activityToStop + " already stopped");
        }
        else
        {
            if (!activityToStop.equals(runningActivity))
            {
                throw new IllegalStateException("Trying to stop " + activityToStop
                        + " which is not the same as the internal running " + runningActivity + "!");
            }
            stopTicking();
            dispatcher.execute(new StopActivityAction(activityToStop), new KarakaCallback<StopActivityResult>(eventBus)
            {
                @Override
                public void onSuccess(StopActivityResult result)
                {
                    Activity stoppedActivity = result.getStopped();
                    info(activity,
                            activityToStop + " successfully stopped as " + stoppedActivity);
                    activities.update(stoppedActivity);
                    ActivityChangedEvent.fire(ActivityController.this, STOPPED, stoppedActivity, activities);
                    ShowMessageEvent.fire(ActivityController.this,
                            new Message(INFO, "Activity \"" + stoppedActivity.getName() + "\" stopped", true));
                }
            });
        }
    }

    void delete(final Activity activityToDelete)
    {
        info(activity, "About to delete " + activityToDelete);
        if (activityToDelete.isRunning())
        {
            if (!activityToDelete.equals(runningActivity))
            {
                throw new IllegalStateException("Trying to delete running " + activityToDelete
                        + " which is not the same as the internal running " + runningActivity + "!");
            }
            stopTicking();
        }
        dispatcher
                .execute(new DeleteActivityAction(activityToDelete), new KarakaCallback<DeleteActivityResult>(eventBus)
                {
                    @Override
                    public void onSuccess(DeleteActivityResult result)
                    {
                        info(activity, activityToDelete + " successfully deleted");
                        activities.remove(activityToDelete);
                        ActivityChangedEvent.fire(ActivityController.this, DELETE, activityToDelete, activities);
                        ShowMessageEvent.fire(ActivityController.this,
                                new Message(INFO, "Activity \"" + activityToDelete.getName() + "\" deleted", true));
                    }
                });
    }

    /**
     * Called after an activity was saved successfully. If the unsaved activity
     * contained a transient project or tags, we have to refresh our local caches!
     *
     * @param activity The activity before it was saved
     */
    private void checkAndrefreshProjectsAndTags(Activity activity)
    {
        Project project = activity.getProject();
        if (project != null && project.isTransient())
        {
            RefreshProjectsEvent.fire(this);
        }
        List<Tag> tags = activity.getTags();
        for (Tag tag : tags)
        {
            if (tag.isTransient())
            {
                RefreshTagsEvent.fire(this);
                break;
            }
        }
    }

    private Activity extractRunningActivity(final Set<Activity> activities)
    {
        for (Activity activity : activities)
        {
            if (activity.isRunning())
            {
                return activity;
            }
        }
        return null;
    }


    // ------------------------------------------------------------------- tick

    private void startTicking()
    {
        ticking = true;
        scheduler.scheduleFixedPeriod(ActivityController.this, TICK_INTERVAL);
    }

    /**
     * Stops the {@code runningActivity} and sets it to <code>null</code>.
     */
    private void stopTicking()
    {
        ticking = false;
        runningActivity = null;
    }

    @Override
    public boolean execute()
    {
        return tick();
    }

    private boolean tick()
    {
        if (ticking)
        {
            info(activity, "About to tick " + runningActivity);
            dispatcher.execute(new TickActivityAction(runningActivity), new KarakaCallback<TickActivityResult>(eventBus)
            {
                @Override
                public void onSuccess(TickActivityResult result)
                {
                    Set<Activity> modifiedActivities = result.getModified();
                    runningActivity = extractRunningActivity(modifiedActivities);
                    info(activity,
                            runningActivity + " successfully ticked. Modified activities: " + modifiedActivities);
                    activities.update(modifiedActivities.toArray(new Activity[]{}));
//                    updateActivities(runningActivity, runningActivity);
                    TickEvent.fire(ActivityController.this, runningActivity, activities);
                }
            });
        }
        return ticking;
    }
}
TOP

Related Classes of name.pehl.karaka.client.activity.presenter.ActivityController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.