Package org.waveprotocol.wave.model.document.operation

Source Code of org.waveprotocol.wave.model.document.operation.AnnotationBoundaryMapBuilder$AnnotationBoundaryMapImpl

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

import org.waveprotocol.wave.model.util.CollectionUtils;
import org.waveprotocol.wave.model.util.Pair;
import org.waveprotocol.wave.model.util.ReadableStringMap.ProcV;
import org.waveprotocol.wave.model.util.ReadableStringSet.Proc;
import org.waveprotocol.wave.model.util.StringMap;
import org.waveprotocol.wave.model.util.StringSet;

import java.util.Arrays;
import java.util.Comparator;

/**
* A more convenient builder than AnnotationBoundaryMapImpl.builder().
*
* @author ohler@google.com (Christian Ohler)
*/
// TODO(ohler): merge with AnnotationBoundaryMapImpl.Builder
public final class AnnotationBoundaryMapBuilder {

  private final StringSet endKeys = CollectionUtils.createStringSet();
  private final StringMap<Pair<String, String>> changes = CollectionUtils.createStringMap();

  public AnnotationBoundaryMapBuilder() {}

  /**
   * Adds an end of the given key to the boundary map under construction.  This
   * overrides any previous calls to change() with that key.
   */
  public AnnotationBoundaryMapBuilder end(String key) {
    changes.remove(key);
    endKeys.add(key);
    return this;
  }

  /**
   * Adds a change of the given key from oldValue to newValue to the boundary
   * map under construction.  This overrides any previous calls to change()
   * or end() with the same key.
   */
  public AnnotationBoundaryMapBuilder change(String key, String oldValue, String newValue) {
    endKeys.remove(key);
    changes.put(key, Pair.of(oldValue, newValue));
    return this;
  }

  private static class Triplet {
    final String key;
    final String oldValue;
    final String newValue;

    public Triplet(String key, String oldValue, String newValue) {
      assert key != null;
      this.key = key;
      this.oldValue = oldValue;
      this.newValue = newValue;
    }
  }

  private static Comparator<Triplet> TRIPLET_COMPARATOR = new Comparator<Triplet>() {
    @Override
    public int compare(Triplet a, Triplet b) {
      return a.key.compareTo(b.key);
    }
  };

  private static class AnnotationBoundaryMapImpl implements AnnotationBoundaryMap {
    final String[] ends;
    final Triplet[] changes;

    public AnnotationBoundaryMapImpl(String[] ends, Triplet[] changes) {
      this.ends = ends;
      this.changes = changes;
    }

    @Override
    public int changeSize() {
      return changes.length;
    }

    @Override
    public int endSize() {
      return ends.length;
    }

    @Override
    public String getChangeKey(int i) {
      return changes[i].key;
    }

    @Override
    public String getEndKey(int i) {
      return ends[i];
    }

    @Override
    public String getNewValue(int i) {
      return changes[i].newValue;
    }

    @Override
    public String getOldValue(int i) {
      return changes[i].oldValue;
    }
  }

  /**
   * Returns an AnnotationBoundaryMap that corresponds to this builder's state.
   *
   * Behaviour is undefined if this builder is used after calling this method.
   */
  public AnnotationBoundaryMap build() {
    final String[] ends = new String[endKeys.countEntries()];
    final Triplet[] changes = new Triplet[this.changes.countEntries()];
    endKeys.each(new Proc() {
      int i = 0;
      @Override
      public void apply(String key) {
        ends[i] = key;
        i++;
      }});
    this.changes.each(new ProcV<Pair<String, String>> () {
      int i = 0;
      @Override
      public void apply(String key, Pair<String, String> value) {
        changes[i] = new Triplet(key, value.first, value.second);
        i++;
      }});
    Arrays.sort(ends);
    Arrays.sort(changes, TRIPLET_COMPARATOR);
    return new AnnotationBoundaryMapImpl(ends, changes);
  }

}
TOP

Related Classes of org.waveprotocol.wave.model.document.operation.AnnotationBoundaryMapBuilder$AnnotationBoundaryMapImpl

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.