Package org.waveprotocol.wave.model.operation.testing

Source Code of org.waveprotocol.wave.model.operation.testing.StringDomain$StringOp$Delete

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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.waveprotocol.wave.model.operation.Domain;
import org.waveprotocol.wave.model.operation.OperationException;
import org.waveprotocol.wave.model.operation.OperationPair;
import org.waveprotocol.wave.model.operation.TransformException;
import org.waveprotocol.wave.model.operation.testing.StringDomain.StringOp.Component;
import org.waveprotocol.wave.model.operation.testing.StringDomain.StringOp.Delete;
import org.waveprotocol.wave.model.operation.testing.StringDomain.StringOp.Insert;
import org.waveprotocol.wave.model.operation.testing.StringDomain.StringOp.Skip;

public class StringDomain implements Domain<StringDomain.Data, StringDomain.StringOp> {

  public static final class Data {
    private final StringBuilder value = new StringBuilder();

    @Override
    public String toString() {
      return value.toString();
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + ((value == null) ? 0 : value.hashCode());
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj)
        return true;
      if (obj == null)
        return false;
      if (getClass() != obj.getClass())
        return false;
      Data other = (Data) obj;
      return value.toString().equals(other.value.toString());
    }
  }

  public static class StringOp {
    final List<Component> components;

    public StringOp(List<Component> components) {
      this.components = new ArrayList<Component>(components);
    }

    public StringOp(Component[] ... componentGroups) {
      this.components = new ArrayList<Component>();
      for (Component[] group : componentGroups) {
        components.addAll(Arrays.asList(group));
      }
    }

    void apply(Data d) throws OperationException {
      int location = 0;
      for (Component c : components) {
        location += c.apply(location, d);
      }
    }

    static abstract class Component {
      abstract int apply(int location, Data d) throws OperationException;
    }

    static class Insert extends Component {
      final char inserted;

      public Insert(char inserted) {
        this.inserted = inserted;
      }

      @Override
      int apply(int location, Data d) throws OperationException {
        d.value.insert(location, inserted);
        return 1;
      }

      @Override
      public String toString() {
        return inserted + "";
      }
    }

    static class Delete extends Component {
      final char deleted;

      public Delete(char deleted) {
        this.deleted = deleted;
      }

      @Override
      int apply(int location, Data d) throws OperationException {
        if (location >= d.value.length()) {
          throw new OperationException("Delete at end");
        }
        d.value.deleteCharAt(location);
        return 0;
      }

      @Override
      public String toString() {
        return ((char) (deleted - 'A' + 'a')) + "";
      }
    }

    static class Skip extends Component {
      static final Skip INSTANCE = new Skip();

      @Override
      int apply(int location, Data d) throws OperationException {
        if (location >= d.value.length()) {
          throw new OperationException("Skip past end");
        }
        return 1;
      }

      @Override
      public String toString() {
        return "-";
      }
    }

    @Override
    public String toString() {
      StringBuilder b = new StringBuilder();
      for (Component c : components) {
        b.append(c.toString());
      }
      return b.toString();
    }
  }

  private StringOp.Insert[] i(String text) {
    StringOp.Insert[] group = new StringOp.Insert[text.length()];
    for (int i = 0; i < text.length(); i++) {
      group[i] = new StringOp.Insert(text.charAt(i));
    }
    return group;
  }

  private StringOp.Delete[] d(String text) {
    StringOp.Delete[] group = new StringOp.Delete[text.length()];
    for (int i = 0; i < text.length(); i++) {
      group[i] = new StringOp.Delete(text.charAt(i));
    }
    return group;
  }

  private StringOp.Skip[] s(int distance) {
    StringOp.Skip[] group = new StringOp.Skip[distance];
    for (int i = 0; i < distance; i++) {
      group[i] = StringOp.Skip.INSTANCE;
    }
    return group;
  }

  @Override
  public void apply(StringOp op, Data state) throws OperationException {
    op.apply(state);
  }

  @Override
  public StringOp asOperation(Data state) {
    return new StringOp(i(state.value.toString()));
  }

  @Override
  public StringOp compose(StringOp f, StringOp g) throws OperationException {
    Iterator<Component> after = f.components.iterator();
    Iterator<Component> before = g.components.iterator();

    //System.err.println("XXXX");

    List<Component> list = new ArrayList<Component>();
    Component beforeComponent = null;
    Component afterComponent = null;
    boolean advanceBefore = true;
    boolean advanceAfter = true;
    while ((!advanceBefore || before.hasNext()) && (!advanceAfter || after.hasNext())) {
      if (advanceBefore) beforeComponent = before.next();
      if (advanceAfter) afterComponent = after.next();
      advanceBefore = false;
      advanceAfter = false;
      if (beforeComponent instanceof Skip) {
        if (afterComponent instanceof Skip) {
          //System.err.println("SS " + beforeComponent + " " + afterComponent);
          list.add(Skip.INSTANCE);
          advanceBefore = true;
          advanceAfter = true;
        } else if (afterComponent instanceof Insert) {
          //System.err.println("SI " + beforeComponent + " " + afterComponent);
          list.add(afterComponent);
          advanceAfter = true;
        } else {
          //System.err.println("SD " + beforeComponent + " " + afterComponent);
          assert afterComponent instanceof Delete;
          list.add(afterComponent);
          advanceBefore = true;
          advanceAfter = true;
        }
      } else if (beforeComponent instanceof Insert) {
        if (afterComponent instanceof Skip) {
          //System.err.println("IS " + beforeComponent + " " + afterComponent);
          list.add(beforeComponent);
          advanceBefore = true;
          advanceAfter = true;
        } else if (afterComponent instanceof Insert) {
          //System.err.println("II " + beforeComponent + " " + afterComponent);
          list.add(afterComponent);
          advanceAfter = true;
        } else {
          //System.err.println("ID " + beforeComponent + " " + afterComponent);
          assert afterComponent instanceof Delete;
          advanceBefore = true;
          advanceAfter = true;
        }
      } else {
        assert beforeComponent instanceof Delete;
        if (afterComponent instanceof Skip) {
          //System.err.println("DS " + beforeComponent + " " + afterComponent);
          list.add(beforeComponent);
          advanceBefore = true;
        } else if (afterComponent instanceof Insert) {
          //System.err.println("DI " + beforeComponent + " " + afterComponent);
          list.add(afterComponent);
          advanceAfter = true;
        } else {
          assert afterComponent instanceof Delete;
          //System.err.println("DD " + beforeComponent + " " + afterComponent);
          list.add(beforeComponent);
          advanceBefore = true;
        }
      }
    }

    if (!advanceBefore && beforeComponent != null) {
      list.add(beforeComponent);
    }
    while (before.hasNext()) {
      list.add(before.next());
      //System.err.println("Finally before: " + list.get(list.size() - 1));
    }

    if (!advanceAfter && afterComponent != null) {
      list.add(afterComponent);
    }
    while (after.hasNext()) {
      list.add(after.next());
      //System.err.println("Finally after: " + list.get(list.size() - 1));
    }

    StringOp op = new StringOp(list);

    //System.err.println("Composed " + f + " of " + g + " = " + op);
    return op;
  }

  @Override
  public OperationPair<StringOp> transform(StringOp clientOp, StringOp serverOp)
      throws TransformException {
    Iterator<Component> client = clientOp.components.iterator();
    Iterator<Component> server = serverOp.components.iterator();

    //System.err.println("=======================");

    List<Component> clientList = new ArrayList<Component>();
    List<Component> serverList = new ArrayList<Component>();
    Component clientComponent = null;
    Component serverComponent = null;
    boolean advanceClient = true;
    boolean advanceServer = true;
    while ((!advanceServer || server.hasNext()) && (!advanceClient || client.hasNext())) {
      if (advanceClient) clientComponent = client.next();
      if (advanceServer) serverComponent = server.next();
      advanceClient = false;
      advanceServer = false;
      if (serverComponent instanceof Insert) {
        //System.err.println("I? " + serverComponent + " " + clientComponent);
        serverList.add(serverComponent);
        clientList.add(Skip.INSTANCE);
        advanceServer = true;
      } else if (serverComponent instanceof Skip) {
        if (clientComponent instanceof Skip) {
          //System.err.println("SS " + serverComponent + " " + clientComponent);
          serverList.add(Skip.INSTANCE);
          clientList.add(Skip.INSTANCE);
          advanceServer = true;
          advanceClient = true;
        } else if (clientComponent instanceof Insert) {
          //System.err.println("SI " + serverComponent + " " + clientComponent);
          serverList.add(Skip.INSTANCE);
          clientList.add(clientComponent);
          advanceClient = true;
        } else {
          //System.err.println("SD " + serverComponent + " " + clientComponent);
          assert clientComponent instanceof Delete;
          clientList.add(clientComponent);
          advanceClient = true;
          advanceServer = true;
        }
      } else {
        assert serverComponent instanceof Delete;
        if (clientComponent instanceof Skip) {
          //System.err.println("DS " + serverComponent + " " + clientComponent);
          serverList.add(serverComponent);
          advanceServer = true;
          advanceClient = true;
        } else if (clientComponent instanceof Insert) {
          //System.err.println("DI " + serverComponent + " " + clientComponent);
          serverList.add(Skip.INSTANCE);
          clientList.add(clientComponent);
          advanceClient = true;
        } else {
          //System.err.println("DD " + serverComponent + " " + clientComponent);
          assert clientComponent instanceof Delete;
          advanceClient = true;
          advanceServer = true;
        }
      }
    }

    if (!advanceClient && clientComponent != null) {
      clientList.add(clientComponent);
      //System.err.println("Client:  " + clientList.get(clientList.size() - 1));
    }
    while (client.hasNext()) {
      clientList.add(client.next());
      //System.err.println("Client:  " + clientList.get(clientList.size() - 1));
    }

    if (!advanceServer && serverComponent != null) {
      serverList.add(serverComponent);
      //System.err.println("Server:  " + serverList.get(serverList.size() - 1));
    }
    while (server.hasNext()) {
      serverList.add(server.next());
      //System.err.println("Server:  " + serverList.get(serverList.size() - 1));
    }

    StringOp clientOp2 = new StringOp(clientList);
    StringOp serverOp2 = new StringOp(serverList);

    return new OperationPair<StringOp>(clientOp2, serverOp2);
  }

  @Override
  public boolean equivalent(Data state1, Data state2) {
    return state1.equals(state2);
  }

  @Override
  public Data initialState() {
    return new Data();
  }

  @Override
  public StringOp invert(StringOp operation) {
    // TODO Auto-generated method stub
    //return null;
    throw new UnsupportedOperationException("invert");
  }
}
TOP

Related Classes of org.waveprotocol.wave.model.operation.testing.StringDomain$StringOp$Delete

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.