Package org.waveprotocol.wave.model.document.util

Source Code of org.waveprotocol.wave.model.document.util.AnnotationRegistryImpl$HandlerData

/**
* Copyright 2009 Google Inc.
*
* 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 org.waveprotocol.wave.model.document.util;

import com.google.common.annotations.VisibleForTesting;

import org.waveprotocol.wave.model.document.AnnotationBehaviour;
import org.waveprotocol.wave.model.document.AnnotationMutationHandler;
import org.waveprotocol.wave.model.util.ChainedData;
import org.waveprotocol.wave.model.util.CollectionUtils;
import org.waveprotocol.wave.model.util.DataDomain;
import org.waveprotocol.wave.model.util.StringMap;

import java.util.Iterator;

/**
* StringMap based implementation
*
* @author danilatos@google.com (Daniel Danilatos)
*
*/
public class AnnotationRegistryImpl implements AnnotationRegistry {

  private static class HandlerData {
    final StringMap<AnnotationMutationHandler> handlers = CollectionUtils.createStringMap();
    final StringMap<AnnotationBehaviour> behaviours = CollectionUtils.createStringMap();
  }

  private static final DataDomain<HandlerData, HandlerData> handlerDataDomain =
      new DataDomain<HandlerData, HandlerData>() {
        @Override
        public void compose(HandlerData target, HandlerData changes, HandlerData base) {
          target.handlers.clear();
          copyInto(target, base);
          copyInto(target, changes);
        }

        private void copyInto(final HandlerData target, HandlerData source) {
          target.handlers.putAll(source.handlers);
          target.behaviours.putAll(source.behaviours);
        }

        @Override
        public HandlerData empty() {
          return new HandlerData();
        }

        @Override
        public HandlerData readOnlyView(HandlerData modifiable) {
          return modifiable;
        }
      };

  public static final AnnotationRegistryImpl ROOT = new AnnotationRegistryImpl();

  private final ChainedData<HandlerData, HandlerData> data;

  @VisibleForTesting
  public AnnotationRegistryImpl() {
    data = new ChainedData<HandlerData, HandlerData>(handlerDataDomain);
  }

  @VisibleForTesting
  private AnnotationRegistryImpl(AnnotationRegistryImpl parent) {
    data = new ChainedData<HandlerData, HandlerData>(parent.data);
  }

  /**
   * Create a copy of this registry for further extension.
   *
   * TODO(user): Consider more efficient propagation of changes to children.
   */
  @Override
  public AnnotationRegistryImpl createExtension() {
    AnnotationRegistryImpl child = new AnnotationRegistryImpl(this);
    return child;
  }

  @Override
  public void registerHandler(String prefix, AnnotationMutationHandler handler) {
    Util.validatePrefix(prefix);
    data.modify().handlers.put(prefix, handler);
  }

  @Override
  public void registerBehaviour(String prefix, AnnotationBehaviour behaviour) {
    Util.validatePrefix(prefix);
    data.modify().behaviours.put(prefix, behaviour);
  }

  @Override
  public Iterator<AnnotationMutationHandler> getHandlers(final String prefix) {
    final String parts = prefix + "/";

    final StringMap<AnnotationMutationHandler> handlers = data.inspect().handlers;
    return new Iterator<AnnotationMutationHandler>() {
      int fromIndex = -1;
      AnnotationMutationHandler next;

      {
        getNext();
      }

      @Override
      public boolean hasNext() {
        return next != null;
      }

      @Override
      public AnnotationMutationHandler next() {
        AnnotationMutationHandler ret = next;
        getNext();
        return ret;
      }

      private void getNext() {
        while ((fromIndex = parts.indexOf('/', fromIndex + 1)) != -1) {
          AnnotationMutationHandler handler = handlers.get(parts.substring(0, fromIndex));
          if (handler != null) {
            next = handler;
            return;
          }
        }
        next = null;
      }

      @Override
      public void remove() {
        throw new UnsupportedOperationException("getHandlers iterator: remove");
      }
    };
  }

  @Override
  public Iterator<AnnotationBehaviour> getBehaviours(final String prefix) {
    final String parts = prefix + "/";

    final StringMap<AnnotationBehaviour> behaviours = data.inspect().behaviours;
    return new Iterator<AnnotationBehaviour>() {
      int fromIndex = -1;
      AnnotationBehaviour next;

      {
        getNext();
      }

      @Override
      public boolean hasNext() {
        return next != null;
      }

      @Override
      public AnnotationBehaviour next() {
        AnnotationBehaviour ret = next;
        getNext();
        return ret;
      }

      private void getNext() {
        while ((fromIndex = parts.indexOf('/', fromIndex + 1)) != -1) {
          AnnotationBehaviour behaviour = behaviours.get(parts.substring(0, fromIndex));
          if (behaviour != null) {
            next = behaviour;
            return;
          }
        }
        next = null;
      }

      @Override
      public void remove() {
        throw new UnsupportedOperationException("getBehaviours iterator: remove");
      }
    };
  }

  @Override
  public AnnotationBehaviour getClosestBehaviour(String key) {
    // TODO(patcoleman): optimise?
    AnnotationBehaviour closest = null;
    Iterator<AnnotationBehaviour> behaviours = getBehaviours(key);
    while (behaviours.hasNext()) {
      closest = behaviours.next();
    }
    return closest;
  }
}
TOP

Related Classes of org.waveprotocol.wave.model.document.util.AnnotationRegistryImpl$HandlerData

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.