Package org.waveprotocol.wave.model.conversation

Source Code of org.waveprotocol.wave.model.conversation.ConversationStructure

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.waveprotocol.wave.model.conversation;

import org.waveprotocol.wave.model.conversation.Conversation.Anchor;
import org.waveprotocol.wave.model.util.CollectionUtils;
import org.waveprotocol.wave.model.util.IdentityMap;

import java.util.Collection;
import java.util.Collections;

/**
* Exposes the structure in a conversation view. This structure is not live; it
* does not remain synchronized with the conversation structure as it changes.
*/
public final class ConversationStructure {

  /** Maps blips to conversations anchored at that blip. Never null. */
  private final IdentityMap<ConversationBlip, Collection<Conversation>> anchoring;

  /** Collection of non-root conversations not attached to any blip. Never null. */
  private final Collection<Conversation> unanchored;

  /** The main conversation, if there is one. */
  private final Conversation mainConversation;

  /**
   * Creates a conversation structure.
   */
  private ConversationStructure(IdentityMap<ConversationBlip, Collection<Conversation>> anchoring,
      Collection<Conversation> unanchored, Conversation mainConversation) {
    this.anchoring = anchoring;
    this.unanchored = unanchored;
    this.mainConversation = mainConversation;
  }

  /** @return the structure of a conversations in {@code wave}. */
  public static ConversationStructure of(ConversationView wave) {
    IdentityMap<ConversationBlip, Collection<Conversation>> anchoring = null;
    Collection<Conversation> unanchored = null;
    Conversation mainConversation = getMainConversation(wave);

    for (Conversation conversation : wave.getConversations()) {
      if (conversation == mainConversation) {
        continue;
      }

      Anchor anchor = conversation.getAnchor();
      ConversationBlip blip = anchor != null ? anchor.getBlip() : null;
      if (blip != null) {
        addLazily((anchoring = createIfNull(anchoring)), blip, conversation);
      } else {
        (unanchored = createIfNull(unanchored)).add(conversation);
      }
    }

    if (anchoring == null) {
      anchoring = CollectionUtils.emptyIdentityMap();
    }
    if (unanchored == null) {
      unanchored = Collections.emptySet();
    }
    return new ConversationStructure(anchoring, unanchored, mainConversation);
  }

  /**
   * Adds an item to the value collection in a map, creating the collection if
   * it does not yet exist.
   */
  private static <K, V> void addLazily(IdentityMap<K, Collection<V>> map, K key, V value) {
    Collection<V> list = map.get(key);
    if (list == null) {
      list = CollectionUtils.createQueue();
      map.put(key, list);
    }
    list.add(value);
  }

  /** @return a non-null version of {@code list}. */
  private static <T> Collection<T> createIfNull(Collection<T> list) {
    return list != null ? list : CollectionUtils.<T> createQueue();
  }

  /** @return a non-null version of {@code map}. */
  private static <K, V> IdentityMap<K, V> createIfNull(IdentityMap<K, V> map) {
    return map != null ? map : CollectionUtils.<K, V> createIdentityMap();
  }

  /** @return the conversations anchored at {@code blip}. Never null. */
  public Collection<Conversation> getAnchoredConversations(ConversationBlip blip) {
    Collection<Conversation> anchored = anchoring.get(blip);
    return anchored != null ? anchored : Collections.<Conversation> emptySet();
  }

  /** @return the non-root conversations not anchored to any blip. */
  public Collection<Conversation> getUnanchored() {
    return unanchored;
  }

  /** @return the main conversation in this wave. */
  public Conversation getMainConversation() {
    return mainConversation;
  }

  /**
   * Finds the main conversation in a wave. The main conversation is defined as
   * the root if there is one, or the first unanchored conversation otherwise.
   */
  public static Conversation getMainConversation(ConversationView view) {
    Conversation root = view.getRoot();
    if (root == null) {
      for (Conversation curr : view.getConversations()) {
        if (!curr.hasAnchor()) {
          root = curr;
          break;
        }
      }
    }
    return root;
  }
}
TOP

Related Classes of org.waveprotocol.wave.model.conversation.ConversationStructure

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.