com.goodow.realtime.operation.TransformerImpl 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;
import com.goodow.realtime.operation.create.CreateOperation;
import com.goodow.realtime.operation.cursor.ReferenceShiftedOperation;
import com.goodow.realtime.operation.list.AbstractDeleteOperation;
import com.goodow.realtime.operation.list.AbstractInsertOperation;
import com.goodow.realtime.operation.list.AbstractReplaceOperation;
import com.goodow.realtime.operation.list.SimpleDeleteOperation;
import com.goodow.realtime.operation.list.json.JsonHelper;
import com.goodow.realtime.operation.list.json.JsonInsertOperation;
import com.goodow.realtime.operation.list.json.JsonReplaceOperation;
import com.goodow.realtime.operation.list.string.StringHelper;
import com.goodow.realtime.operation.list.string.StringInsertOperation;
import com.goodow.realtime.operation.map.AbstractMapOperation;
import com.goodow.realtime.operation.map.json.JsonMapOperation;
import com.goodow.realtime.operation.util.Pair;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import elemental.json.JsonArray;
import elemental.json.JsonValue;
public class TransformerImpl> implements Transformer {
@Override
public List compact(List operations) {
return operations;
}
public AbstractOperation> createOperation(JsonArray serialized) {
AbstractOperation> op = null;
switch ((int) serialized.getNumber(0)) {
case CreateOperation.TYPE:
op = CreateOperation.parse(serialized);
break;
case AbstractMapOperation.TYPE:
op = JsonMapOperation.parse(serialized);
break;
case AbstractInsertOperation.TYPE:
switch ((int) serialized.getArray(3).getNumber(0)) {
case JsonHelper.TYPE:
op = JsonInsertOperation.parse(serialized);
break;
case StringHelper.TYPE:
op = StringInsertOperation.parse(serialized);
break;
default:
throw new UnsupportedOperationException("Unknow insert operation sub-type: "
+ serialized.toJson());
}
break;
case AbstractDeleteOperation.TYPE:
op = SimpleDeleteOperation.parse(serialized);
break;
case AbstractReplaceOperation.TYPE:
op = JsonReplaceOperation.parse(serialized);
break;
case ReferenceShiftedOperation.TYPE:
op = ReferenceShiftedOperation.parse(serialized);
break;
default:
throw new UnsupportedOperationException("Unknow operation type: " + serialized.toJson());
}
return op;
}
@SuppressWarnings("unchecked")
@Override
public T createOperation(String userId, String sessionId, JsonValue serialized) {
JsonArray ops = (JsonArray) serialized;
int length = ops.length();
assert length > 0;
List> operations = new ArrayList>(length);
for (int i = 0; i < length; i++) {
operations.add(createOperation(ops.getArray(i)));
}
return (T) new RealtimeOperation(userId, sessionId, operations);
}
@Override
public Pair, List> transform(List clientOps, List serverOps) {
assert !clientOps.contains(null) && !serverOps.contains(null);
List transformedClientOps = new ArrayList();
List transformedServerOps = new LinkedList(serverOps);
for (T clientOp : clientOps) {
transform(transformedClientOps, clientOp, transformedServerOps, 0, true);
}
return Pair.of(transformedClientOps, transformedServerOps);
}
@Override
public void transform(List transformedResults, T operation, List operations,
int startIndex, boolean arrivedAfter) {
assert operation != null;
if (startIndex == operations.size()) {
transformedResults.add(operation);
return;
}
@SuppressWarnings("rawtypes")
Operation op1 = operations.get(startIndex);
assert op1 != null;
if (operation instanceof AbstractOperation
&& !((AbstractOperation>) operation).isSameId((AbstractOperation>) op1)) {
transform(transformedResults, operation, operations, ++startIndex, arrivedAfter);
return;
}
@SuppressWarnings("unchecked")
Pair pair =
arrivedAfter ? operation.transformWith(op1) : op1.transformWith(operation);
T[] transformedOps1 = arrivedAfter ? pair.second : pair.first;
operations.remove(startIndex);
if (transformedOps1 != null) {
for (T op : transformedOps1) {
operations.add(startIndex++, op);
}
}
T[] transformedOps0 = arrivedAfter ? pair.first : pair.second;
if (transformedOps0 == null) {
return;
} else {
for (T op : transformedOps0) {
transform(transformedResults, op, operations, startIndex, arrivedAfter);
}
}
}
}