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

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

/**
* 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.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.