Package org.waveprotocol.wave.client.wavepanel.render

Source Code of org.waveprotocol.wave.client.wavepanel.render.DocumentRegistries

/**
* 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.client.wavepanel.render;

import org.waveprotocol.wave.client.editor.Editor;
import org.waveprotocol.wave.client.editor.content.Registries;
import org.waveprotocol.wave.client.doodad.DoodadInstallers.BlipInstaller;
import org.waveprotocol.wave.client.doodad.DoodadInstallers.ConversationInstaller;
import org.waveprotocol.wave.client.doodad.DoodadInstallers.GlobalInstaller;
import org.waveprotocol.wave.model.conversation.Conversation;
import org.waveprotocol.wave.model.conversation.ConversationBlip;
import org.waveprotocol.wave.model.conversation.WaveletBasedConversation;
import org.waveprotocol.wave.model.util.CollectionUtils;
import org.waveprotocol.wave.model.util.IdentityMap;
import org.waveprotocol.wave.model.wave.Wavelet;

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

/**
* A collection of doodad handlers, used to create {@link Registries} for
* documents on demand.
*
* Doodad handlers are categorised into global, per-conversation, and per-blip,
* according to the needs of each particular doodad handler.
*
*/
public final class DocumentRegistries {

  /**
   * Builder that collects doodads to be installed. After collection, the set of
   * handlers is concretized into a {@link DocumentRegistries}, and handlers can
   * not be installed after that.
   */
  public static final class Builder {
    private Collection<GlobalInstaller> gis;
    private Collection<ConversationInstaller> cis;
    private Collection<BlipInstaller> bis;

    public Builder use(ConversationInstaller c) {
      (cis = lazyCreate(cis)).add(c);
      return this;
    }

    public Builder use(BlipInstaller b) {
      (bis = lazyCreate(bis)).add(b);
      return this;
    }

    public Builder use(GlobalInstaller g) {
      (gis = lazyCreate(gis)).add(g);
      return this;
    }

    public DocumentRegistries build() {
      Registries root = Editor.ROOT_REGISTRIES;
      for (GlobalInstaller gi : nonNull(gis)) {
        gi.install(root);
      }
      return new DocumentRegistries(root, nonNull(cis), nonNull(bis));
    }

    private static <T> Collection<T> lazyCreate(Collection<T> xs) {
      return xs == null ? CollectionUtils.<T> createQueue() : xs;
    }

    private static <T> Collection<T> nonNull(Collection<T> xs) {
      return xs == null ? Collections.<T> emptyList() : xs;
    }
  }

  /**
   * Per-conversation registry bundle.
   */
  private class ConversationRegistries {
    /** Registries from which blip registries are forked. */
    // Intentionally make 'registries' refer to the per-conv one.
    @SuppressWarnings("hiding")
    private final Registries registries;

    private final IdentityMap<ConversationBlip, Registries> blipRegistries =
      CollectionUtils.createIdentityMap();

    // Context used to install per-blip handlers.

    private final Wavelet w;
    private final Conversation c;

    ConversationRegistries(Registries registries, Wavelet w, Conversation c) {
      this.registries = registries;
      this.w = w;
      this.c = c;
    }

    /**
     * Extends this conversation's registres for a blip. Per-blip doodads are
     * installed in the new registries.
     */
    private Registries extendFor(ConversationBlip b) {
      Registries r = registries.createExtension();
      for (BlipInstaller bi : bis) {
        bi.install(w, c, b, r);
      }
      return r;
    }

    /**
     * @return the registries for a blip, lazily creating one if none exists.
     */
    Registries getBlipRegistries(ConversationBlip b) {
      Registries rs = blipRegistries.get(b);
      if (rs == null) {
        rs = extendFor(b);
        blipRegistries.put(b, rs);
      }
      return rs;
    }
  }

  /** Root registries, from which conversation registries are forked. */
  private final Registries registries;

  /** Per-conversation doodads to install in each per-conversation registry. */
  private final Collection<ConversationInstaller> cis;

  /** Per-blip doodads to install in each per-blip registry. */
  private final Collection<BlipInstaller> bis;

  /**
   * Per-conversation registries (which each contain their own per-blip
   * registries.
   */
  private final IdentityMap<Conversation, ConversationRegistries> conversationRegistries =
      CollectionUtils.createIdentityMap();

  private DocumentRegistries(Registries r, Collection<ConversationInstaller> cis,
      Collection<BlipInstaller> bis) {
    this.registries = r;
    this.cis = cis;
    this.bis = bis;
  }

  /** @return a builder for the registries collection. */
  public static Builder builder() {
    return new Builder();
  }

  /** Creates a per-conversation registries bundle. */
  private ConversationRegistries extendFor(Conversation c) {
    Registries r = registries.createExtension();
    for (ConversationInstaller ci : cis) {
      ci.install(((WaveletBasedConversation) c).getWavelet(), c, r);
    }
    return new ConversationRegistries(r, ((WaveletBasedConversation) c).getWavelet(), c);
  }

  /**
   * Loads the registries bundle for a conversation. If no bundle currently
   * exists, a new one is created, and the per-conversation doodads are
   * installed in it. Never returns null.
   */
  private ConversationRegistries getConversationRegistries(Conversation c) {
    ConversationRegistries rs = conversationRegistries.get(c);
    if (rs == null) {
      rs = extendFor(c);
      conversationRegistries.put(c, rs);
    }
    return rs;
  }

  /**
   * Loads the registries bundle for a blip. If no bundle currently exists, a
   * new one is created, and the per-blip doodads are installed in it. Never
   * returns null.
   */
  public Registries get(ConversationBlip blip) {
    return getConversationRegistries(blip.getConversation()).getBlipRegistries(blip);
  }
}
TOP

Related Classes of org.waveprotocol.wave.client.wavepanel.render.DocumentRegistries

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.