Package com.google.collide.client.document

Source Code of com.google.collide.client.document.DocumentManagerNetworkController

// 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.document;

import com.google.collide.client.AppContext;
import com.google.collide.client.communication.FrontendApi.ApiCallback;
import com.google.collide.client.document.DocumentManager.GetDocumentCallback;
import com.google.collide.client.status.StatusMessage;
import com.google.collide.client.status.StatusMessage.MessageType;
import com.google.collide.client.util.PathUtil;
import com.google.collide.client.util.logging.Log;
import com.google.collide.dto.FileContents.ContentType;
import com.google.collide.dto.GetFileContentsResponse;
import com.google.collide.dto.RoutingTypes;
import com.google.collide.dto.ServerError.FailureReason;
import com.google.collide.dto.client.DtoClientImpls.GetFileContentsImpl;
import com.google.collide.json.shared.JsonArray;
import com.google.collide.json.shared.JsonStringMap;
import com.google.collide.shared.util.JsonCollections;
import com.google.common.base.Preconditions;

/**
* Controller responsible for loading documents (and uneditable files) from the
* server.
*
* This class accepts multiple calls to
* {@link #load(PathUtil, GetDocumentCallback)} for the same path and intelligently
* batches together the callbacks so only one network request will occur.
*/
class DocumentManagerNetworkController {

  private final DocumentManager documentManager;
  private final AppContext appContext;

  /** Path to a list of {@link GetDocumentCallback} */
  JsonStringMap<JsonArray<GetDocumentCallback>> outstandingCallbacks = JsonCollections.createMap();

  private StatusMessage loadingMessage;

  DocumentManagerNetworkController(DocumentManager documentManager, AppContext appContext) {
    this.documentManager = documentManager;
    this.appContext = appContext;
  }

  public void teardown() {
    if (loadingMessage != null) {
      cancelLoadingMessage();
    }
   
    appContext.getMessageFilter().removeMessageRecipient(RoutingTypes.GETFILECONTENTSRESPONSE);
  }

  void load(PathUtil path, GetDocumentCallback callback) {
    boolean shouldRequestFile = addCallback(path, callback);

    if (shouldRequestFile) {
      requestFile(path);
    }
  }

  private boolean addCallback(PathUtil path, GetDocumentCallback callback) {
    JsonArray<GetDocumentCallback> callbacks = outstandingCallbacks.get(path.getPathString());

    if (callbacks == null) {
      callbacks = JsonCollections.createArray(callback);
      outstandingCallbacks.put(path.getPathString(), callbacks);
      return true;

    } else {
      callbacks.add(callback);
      return false;
    }
  }

  private void requestFile(final PathUtil path) {
    delayLoadingMessage(path);
   
    // Fetch the file's contents
    GetFileContentsImpl getFileContents = GetFileContentsImpl.make().setPath(path.getPathString());
    appContext.getFrontendApi().GET_FILE_CONTENTS.send(getFileContents,
        new ApiCallback<GetFileContentsResponse>() {

          @Override
          public void onMessageReceived(GetFileContentsResponse response) {
              handleFileReceived(response);
          }

          @Override
          public void onFail(FailureReason reason) {
            Log.error(getClass(), "Failed to retrieve file contents for path " + path);
          }
        });
  }

  /**
   * Called when the file contents are received from the network. Routes to the appropriate content
   * handling mechanism depending on whether or not the file content type is text, an image, or some
   * other binary file.
   */
  private void handleFileReceived(GetFileContentsResponse response) {
    boolean isUneditable =
        (response.getFileContents().getContentType() == ContentType.UNKNOWN_BINARY)
        || (response.getFileContents().getContentType() == ContentType.IMAGE);
    PathUtil path = new PathUtil(response.getFileContents().getPath());

    cancelLoadingMessage();

    JsonArray<GetDocumentCallback> callbacks = outstandingCallbacks.remove(path.getPathString());
    Preconditions.checkNotNull(callbacks);

    if (!response.getFileExists()) {
      // Dispatch to callbacks directly
      for (int i = 0, n = callbacks.size(); i < n; i++) {
        callbacks.get(i).onFileNotFoundReceived();
      }
    } else if (isUneditable) {
      // Dispatch to callbacks directly
      for (int i = 0, n = callbacks.size(); i < n; i++) {
        callbacks.get(i).onUneditableFileContentsReceived(response.getFileContents());
      }
    } else {
      documentManager.handleEditableFileReceived(response.getFileContents(), callbacks);
    }
  }

  private void delayLoadingMessage(PathUtil path) {
    cancelLoadingMessage();
    loadingMessage =
        new StatusMessage(appContext.getStatusManager(), MessageType.LOADING, "Loading "
            + path.getBaseName() + "...");
    loadingMessage.fireDelayed(StatusMessage.DEFAULT_DELAY);
  }

  private void cancelLoadingMessage() {
    if (loadingMessage != null) {
      loadingMessage.cancel();
      loadingMessage = null;
    }
  }
}
TOP

Related Classes of com.google.collide.client.document.DocumentManagerNetworkController

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.