All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.goodow.realtime.operation.list.AbstractReplaceOperation Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2013 Goodow.com
 * 
 * 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 com.goodow.realtime.operation.list;

import com.goodow.realtime.operation.AbstractOperation;

public abstract class AbstractReplaceOperation extends AbstractListOperation {
  public static final int TYPE = 11;

  protected final T oldValues;

  protected AbstractReplaceOperation(String id, int startIndex, T oldValues, T newValues) {
    super(TYPE, id, startIndex, newValues, -1);
    this.oldValues = oldValues;
    assert oldValues == null || getHelper().length(oldValues) == length;
  }

  @Override
  public void apply(ListTarget target) {
    target.replace(startIndex, values);
  }

  @Override
  public int transformIndexReference(int index, boolean rigthSide, boolean canBeDeleted) {
    return index;
  }

  @Override
  public AbstractReplaceOperation[] transformWith(AbstractOperation> operation,
      boolean arrivedAfter) {
    assert operation instanceof AbstractListOperation && isSameId(operation);
    AbstractListOperation op = (AbstractListOperation) operation;
    int endIndex0 = startIndex + length;
    int endIndex1 = op.startIndex + op.length;
    switch (op.type) {
      case AbstractInsertOperation.TYPE:
        if (op.startIndex <= startIndex) {
          // ....[...]....
          // ...[.......
          return asArray(create(startIndex + op.length, oldValues, values));
        } else if (op.startIndex < endIndex0) {
          // ....[...]....
          // ......[.....
          int len0 = op.startIndex - startIndex;
          return asArray(create(startIndex, oldValues == null ? null : getHelper().subset(
              oldValues, 0, len0), getHelper().subset(values, 0, len0)), create(endIndex1,
              oldValues == null ? null : getHelper().subset(oldValues, len0, length - len0),
              getHelper().subset(values, len0, length - len0)));
        } else {
          // ....[...]....
          // .........[.].
          return asArray(this);
        }
      case AbstractDeleteOperation.TYPE:
        if (op.startIndex >= endIndex0) {
          // ....[...]....
          // .........[.].
          return asArray(this);
        } else if (endIndex1 <= startIndex) {
          // ....[...]....
          // .[.]...
          return asArray(create(startIndex - op.length, oldValues, values));
        } else if (op.startIndex <= startIndex) {
          // ....[...]....
          // ...[..]...]
          return endIndex1 < endIndex0 ? asArray(create(op.startIndex, oldValues == null ? null
              : getHelper().subset(oldValues, endIndex1 - startIndex, endIndex0 - endIndex1),
              getHelper().subset(values, endIndex1 - startIndex, endIndex0 - endIndex1))) : null;
        } else {
          // ....[...]....
          // .....[.]..]
          return endIndex1 < endIndex0 ? asArray(create(startIndex, oldValues == null ? null
              : getHelper().replaceWith(oldValues, op.startIndex - startIndex, op.length, null),
              getHelper().replaceWith(values, op.startIndex - startIndex, op.length, null)))
              : asArray(create(startIndex, oldValues == null ? null : getHelper().subset(oldValues,
                  0, op.startIndex - startIndex), getHelper().subset(values, 0,
                  op.startIndex - startIndex)));
        }
      case AbstractReplaceOperation.TYPE:
        if (endIndex1 <= startIndex || op.startIndex >= endIndex0
            || (arrivedAfter && oldValues == null)) {
          // ....[...]....
          // .[.]. OR .[.].
          return asArray(this);
        } else if (op.startIndex <= startIndex) {
          // ....[...]....
          // ...[..]...]
          if (arrivedAfter) {
            T transformedOldValues =
                endIndex1 < endIndex0 ? getHelper().subset(op.values, startIndex - op.startIndex,
                    endIndex1 - startIndex, oldValues, endIndex1 - startIndex,
                    endIndex0 - endIndex1) : getHelper().subset(op.values,
                    startIndex - op.startIndex, length);
            return asArray(create(startIndex, transformedOldValues, values));
          } else {
            return endIndex1 < endIndex0 ? asArray(create(endIndex1, oldValues == null ? null
                : getHelper().subset(oldValues, endIndex1 - startIndex, endIndex0 - endIndex1),
                getHelper().subset(values, endIndex1 - startIndex, endIndex0 - endIndex1))) : null;
          }
        } else {
          // ....[...]....
          // .....[.]..]
          if (arrivedAfter) {
            T transformedOldValues =
                endIndex1 < endIndex0 ? getHelper().replaceWith(oldValues,
                    op.startIndex - startIndex, op.length, op.values) : getHelper().subset(
                    oldValues, 0, op.startIndex - startIndex, op.values, 0,
                    endIndex0 - op.startIndex);
            return asArray(create(startIndex, transformedOldValues, values));
          } else {
            AbstractReplaceOperation op1 =
                create(startIndex, oldValues == null ? null : getHelper().subset(oldValues, 0,
                    op.startIndex - startIndex), getHelper().subset(values, 0,
                    op.startIndex - startIndex));
            return endIndex1 < endIndex0 ? asArray(op1, create(endIndex1, oldValues == null ? null
                : getHelper().subset(oldValues, endIndex1 - startIndex, endIndex0 - endIndex1),
                getHelper().subset(values, endIndex1 - startIndex, endIndex0 - endIndex1)))
                : asArray(op1);
          }
        }
      default:
        throw new RuntimeException("Unsupported List Operation type: " + op.type);
    }
  }

  protected abstract AbstractReplaceOperation create(int startIndex, T oldValues, T newValues);
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy