Package com.google.collide.client.workspace

Source Code of com.google.collide.client.workspace.WorkspacePlaceNavigationHandler

// Copyright 2012 Google 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.google.collide.client.workspace;

import com.google.collide.client.AppContext;
import com.google.collide.client.code.CodePanelBundle;
import com.google.collide.client.code.NavigationAreaExpansionEvent;
import com.google.collide.client.code.ParticipantModel;
import com.google.collide.client.collaboration.CollaborationManager;
import com.google.collide.client.collaboration.DocOpsSavedNotifier;
import com.google.collide.client.collaboration.IncomingDocOpDemultiplexer;
import com.google.collide.client.communication.FrontendApi.ApiCallback;
import com.google.collide.client.document.DocumentManager;
import com.google.collide.client.history.PlaceNavigationHandler;
import com.google.collide.client.search.FileNameSearch;
import com.google.collide.client.search.TreeWalkFileNameSearchImpl;
import com.google.collide.client.util.Elements;
import com.google.collide.dto.GetWorkspaceMetaDataResponse;
import com.google.collide.dto.ServerError.FailureReason;
import com.google.collide.dto.client.DtoClientImpls.GetWorkspaceMetaDataImpl;
import com.google.collide.shared.util.ListenerRegistrar.Remover;
import com.google.collide.shared.util.ListenerRegistrar.RemoverManager;
import com.google.gwt.core.client.Scheduler;

import elemental.events.Event;
import elemental.events.EventListener;
import elemental.events.EventRemover;
import elemental.events.KeyboardEvent;
import elemental.events.KeyboardEvent.KeyCode;

/**
* Handler for the selection of a Workspace.
*/
// TODO: At some point we should try to make reEnter work on this thing.
public class WorkspacePlaceNavigationHandler
    extends PlaceNavigationHandler<WorkspacePlace.NavigationEvent> {

  private final AppContext appContext;
  private final FileNameSearch searchIndex;
  private final RemoverManager keyListenerRemoverManager;

  // Presenters and Controllers that require cleanup.
  private Header header;
  private DocumentManager documentManager;
  private CollaborationManager collaborationManager;

  private WorkspacePlace workspacePlace;
  private WorkspaceShell shell;
  private FileTreeModelNetworkController fileNetworkController;
  private KeepAliveTimer keepAliveTimer;
  private ParticipantModel participantModel;
  private CodePanelBundle codePanelBundle;

  public WorkspacePlaceNavigationHandler(AppContext appContext) {
    this.appContext = appContext;
    this.keyListenerRemoverManager = new RemoverManager();
    this.searchIndex = TreeWalkFileNameSearchImpl.create();  
  }

  @Override
  protected void cleanup() {
    if (codePanelBundle != null) {
      codePanelBundle.cleanup();
    }

    if (collaborationManager != null) {
      collaborationManager.cleanup();
    }

    if (documentManager != null) {
      documentManager.cleanup();
    }

    if (keyListenerRemoverManager != null) {
      keyListenerRemoverManager.remove();
    }

    if (keepAliveTimer != null) {
      keepAliveTimer.cancel();
    }
  }

  @Override
  protected void enterPlace(final WorkspacePlace.NavigationEvent navigationEvent) {

    // Instantiate the Root View for the Workspace.
    final WorkspaceShell.Resources res = appContext.getResources();
    WorkspaceShell.View workspaceShellView = new WorkspaceShell.View(res);
    workspacePlace = navigationEvent.getPlace();

    FileTreeModelNetworkController.OutgoingController fileTreeModelOutgoingNetworkController =
        new FileTreeModelNetworkController.OutgoingController(appContext);
    FileTreeModel fileTreeModel =
        new FileTreeModel(fileTreeModelOutgoingNetworkController);

    documentManager = DocumentManager.create(fileTreeModel, appContext);

    searchIndex.setFileTreeModel(fileTreeModel);

    participantModel = ParticipantModel.create(
        appContext.getFrontendApi(), appContext.getMessageFilter());

    IncomingDocOpDemultiplexer docOpRecipient = IncomingDocOpDemultiplexer.create(
        appContext.getMessageFilter());
    collaborationManager = CollaborationManager.create(
        appContext, documentManager, participantModel, docOpRecipient);

    DocOpsSavedNotifier docOpSavedNotifier =
        new DocOpsSavedNotifier(documentManager, collaborationManager);

    fileNetworkController = FileTreeModelNetworkController.create(
        fileTreeModel, appContext, navigationEvent.getPlace());

    header = Header.create(workspaceShellView.getHeaderView(),
        workspaceShellView,
        workspacePlace,
        appContext,
        searchIndex,
        fileTreeModel);

    shell = WorkspaceShell.create(workspaceShellView, header);

    // Attach to the DOM.
    Elements.replaceContents(AppContext.GWT_ROOT, shell.getView().getElement());

    // Reset the tab title
    Elements.setCollideTitle("");

    // Add a HotKey listener for to auto-focus the AwesomeBox.
    /*
     * The GlobalHotKey stuff utilizes the wave signal event stuff which filters alt+enter as an
     * unimportant event. This prevents us from using the GlobalHotKey manager here.
     *
     * Note: This is capturing since the editor likes to nom-nom keys, in the dart re-write lets
     * think about this sort of stuff ahead of time.
     */
    final EventRemover eventRemover =
        Elements.getBody().addEventListener(Event.KEYDOWN, new EventListener() {
          @Override
          public void handleEvent(Event evt) {
            KeyboardEvent event = (KeyboardEvent) evt;
            if (event.isAltKey() && event.getKeyCode() == KeyCode.ENTER) {
              appContext.getAwesomeBoxComponentHostModel().revertToDefaultComponent();
              header.getAwesomeBoxComponentHost().show();
            }
          }
        }, true);
    // Track this for removal in cleanup
    keyListenerRemoverManager.track(new Remover() {
      @Override
      public void remove() {
        eventRemover.remove();
      }
    });

    codePanelBundle = new CodePanelBundle(appContext,
        shell,
        fileTreeModel,
        searchIndex,
        documentManager,
        participantModel,
        docOpRecipient,
        navigationEvent.getPlace());
    codePanelBundle.attach();

    if (!navigationEvent.shouldNavExpand()) {
      workspacePlace.fireEvent(new NavigationAreaExpansionEvent(false));
    }

    // Send a message to enter the workspace and initialize the workspace.
    appContext.getFrontendApi().GET_WORKSPACE_META_DATA.send(
        GetWorkspaceMetaDataImpl.make(), new ApiCallback<GetWorkspaceMetaDataResponse>() {

          @Override
          public void onMessageReceived(GetWorkspaceMetaDataResponse message) {
            if (!navigationEvent.getPlace().isActive()) {
              return;
            }

            // Start the keep-alive timer at 10 second intervals.
            keepAliveTimer = new KeepAliveTimer(appContext, 5000);
            keepAliveTimer.start();

            codePanelBundle.enterWorkspace(navigationEvent, message);
          }

          @Override
          public void onFail(FailureReason reason) {
            if (FailureReason.UNAUTHORIZED == reason) {
              /*
               * User is not authorized to access this workspace.
               *
               * At this point, the components of the WorkspacePlace already sent multiple requests
               * to the frontend that are bound to fail with the same reason. However, we don't want
               * to gate loading the workspace to handle the rare case that a user accesses a branch
               * that they do not have permission to access. Better to make the workspace load fast
               * and log errors if the user is not authorized.
               */
              UnauthorizedUser unauthorizedUser = UnauthorizedUser.create(res);
              shell.setPerspective(unauthorizedUser.getView().getElement());
            }
          }
        });
  }

  @Override
  protected void reEnterPlace(
      final WorkspacePlace.NavigationEvent navigationEvent, boolean hasNewState) {
    if (hasNewState || navigationEvent.shouldForceReload()) {
      // Simply do the default action which is to run cleanup/enter.
      super.reEnterPlace(navigationEvent, hasNewState);
    } else {
      // we check to see if we end up being the active leaf and if so show the
      // no file selected panel.
      Scheduler.get().scheduleFinally(new Scheduler.ScheduledCommand() {
        @Override
        public void execute() {
          if (navigationEvent.isActiveLeaf()) {
            codePanelBundle.showNoFileSelectedPanel();
          }
        }
      });
    }
  }
}
TOP

Related Classes of com.google.collide.client.workspace.WorkspacePlaceNavigationHandler

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.