Skip to content

Commit

Permalink
json patch now generates ExpressionSpec for DynamoDB UpdateItem
Browse files Browse the repository at this point in the history
  • Loading branch information
cm-alexp committed Aug 18, 2016
1 parent 71b57cc commit a901a12
Show file tree
Hide file tree
Showing 22 changed files with 989 additions and 11 deletions.
11 changes: 8 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
target
.idea
META-INF
out
build
/out
/classes
/build
.gradle

.classpath
.project
.settings
/bin/
/test-output
23 changes: 23 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,16 @@ dependencies {
version: "2.0.1");
compile(group: "com.github.fge", name: "jackson-coreutils",
version: "1.6");
compile(group: "com.amazonaws", name:"aws-java-sdk-dynamodb", version:"1.11.27");
testCompile(group: "org.testng", name: "testng", version: "6.8.7") {
exclude(group: "junit", module: "junit");
exclude(group: "org.beanshell", module: "bsh");
exclude(group: "org.yaml", module: "snakeyaml");
};
testCompile(group: "org.mockito", name: "mockito-core", version: "1.9.5");
testCompile(group: "org.assertj", name: "assertj-core", version: "1.7.0");
testCompile(group:"com.jayway.jsonpath", name:"json-path-assert", version:"2.2.0");
testCompile(group: "com.amazonaws", name:"DynamoDBLocal", version:"1.11.0.1");
}

javadoc.options.links("http://docs.oracle.com/javase/6/docs/api/");
Expand All @@ -80,6 +83,26 @@ javadoc.options.links("http://fge.github.io/jackson-coreutils/");
*/
repositories {
mavenCentral();
maven {
url 'http://dynamodb-local.s3-website-us-west-2.amazonaws.com/release'
}

}

task copyNativeDeps(type: Copy) {
from (configurations.testCompile) {
include "*.dylib"
include "*.so"
include "*.dll"
}
into 'build/libs'
}

test.dependsOn copyNativeDeps
test.doFirst {
systemProperty "java.library.path", 'build/libs'
environment "DYLD_LIBRARY_PATH", './build/libs'
environment "LD_LIBRARY_PATH", './build/libs'
}

/*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2015-2016 the original author or authors.
*
* 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.amazonaws.services.dynamodbv2.xspec;

import com.amazonaws.services.dynamodbv2.xspec.NULL;

/**
* TODO for daisuke
*
* @since 0.13
* @version $Id$
* @author Alexander Patrikalakis
*/
public class NULLComparable extends NULL {
public NULLComparable(String path) {
super(path);
}
public ComparatorCondition eq(Operand that) {
return new ComparatorCondition("=", this, that);
}
public static final LiteralOperand generateNull() {
return new LiteralOperand((Object) null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2015-2016 the original author or authors.
*
* 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.amazonaws.services.dynamodbv2.xspec;

/**
* TODO for daisuke
*
* @since 0.13
* @version $Id$
* @author Alexander Patrikalakis
*/
public class PathSetAction extends UpdateAction {
public PathSetAction(PathOperand attr, PathOperand value) {
super("SET", attr, value);
}
}
17 changes: 16 additions & 1 deletion src/main/java/com/github/fge/jsonpatch/AddOperation.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2014, Francis Galiegue ([email protected])
* Copyright (c) 2016, Alexander Patrikalakis ([email protected])
* Copyright (c) 2015, Daisuke Miyamoto ([email protected])
*
* This software is dual-licensed under:
*
Expand All @@ -19,6 +21,7 @@

package com.github.fge.jsonpatch;

import com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
Expand All @@ -28,6 +31,7 @@
import com.github.fge.jackson.jsonpointer.ReferenceToken;
import com.github.fge.jackson.jsonpointer.TokenResolver;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;


/**
Expand Down Expand Up @@ -99,6 +103,17 @@ public JsonNode apply(final JsonNode node)
? addToArray(path, node)
: addToObject(path, node);
}

@Override
public void applyToBuilder(ExpressionSpecBuilder builder) {
final TokenResolver<JsonNode> node = Iterators.getLast(path.iterator(), null /*default*/);
if(null == node || "-".equals(node.getToken().getRaw())) {
//list_append
throw new UnsupportedOperationException("list_append not supported yet");
} else {
super.applyToBuilder(builder);
}
}

private JsonNode addToArray(final JsonPointer path, final JsonNode node)
throws JsonPatchException
Expand Down Expand Up @@ -133,7 +148,7 @@ private JsonNode addToObject(final JsonPointer path, final JsonNode node)
{
final JsonNode ret = node.deepCopy();
final ObjectNode target = (ObjectNode) path.parent().get(ret);
target.put(Iterables.getLast(path).getToken().getRaw(), value);
target.set(Iterables.getLast(path).getToken().getRaw(), value);
return ret;
}
}
13 changes: 13 additions & 0 deletions src/main/java/com/github/fge/jsonpatch/CopyOperation.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2014, Francis Galiegue ([email protected])
* Copyright (c) 2016, Alexander Patrikalakis ([email protected])
* Copyright (c) 2015, Daisuke Miyamoto ([email protected])
*
* This software is dual-licensed under:
*
Expand All @@ -19,6 +21,8 @@

package com.github.fge.jsonpatch;

import com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder;
import com.amazonaws.services.dynamodbv2.xspec.PathSetAction;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
Expand Down Expand Up @@ -60,4 +64,13 @@ public JsonNode apply(final JsonNode node)
"jsonPatch.noSuchPath"));
return new AddOperation(path, dupData).apply(node);
}

@Override
public void applyToBuilder(ExpressionSpecBuilder builder) {
String copyPath = pathGenerator.apply(from);
String setPath = pathGenerator.apply(path);
//set the attribute in the path location
builder.addUpdate(new PathSetAction(ExpressionSpecBuilder.attribute(setPath),
ExpressionSpecBuilder.attribute(copyPath)));
}
}
25 changes: 21 additions & 4 deletions src/main/java/com/github/fge/jsonpatch/JsonPatch.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2014, Francis Galiegue ([email protected])
* Copyright (c) 2016, Alexander Patrikalakis ([email protected])
* Copyright (c) 2015, Daisuke Miyamoto ([email protected])
*
* This software is dual-licensed under:
*
Expand All @@ -19,6 +21,7 @@

package com.github.fge.jsonpatch;

import com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
Expand All @@ -32,6 +35,7 @@

import java.io.IOException;
import java.util.List;
import java.util.function.Supplier;

/**
* Implementation of JSON Patch
Expand Down Expand Up @@ -89,16 +93,16 @@
* <p><b>IMPORTANT NOTE:</b> the JSON Patch is supposed to be VALID when the
* constructor for this class ({@link JsonPatch#fromJson(JsonNode)} is used.</p>
*/
public final class JsonPatch
implements JsonSerializable
public class JsonPatch
implements JsonSerializable, Supplier<ExpressionSpecBuilder>
{
private static final MessageBundle BUNDLE
= MessageBundles.getBundle(JsonPatchMessages.class);

/**
* List of operations
*/
private final List<JsonPatchOperation> operations;
protected final List<JsonPatchOperation> operations;

/**
* Constructor
Expand Down Expand Up @@ -126,7 +130,7 @@ public static JsonPatch fromJson(final JsonNode node)
throws IOException
{
BUNDLE.checkNotNull(node, "jsonPatch.nullInput");
return JacksonUtils.getReader().withType(JsonPatch.class)
return JacksonUtils.getReader().forType(JsonPatch.class)
.readValue(node);
}

Expand All @@ -148,6 +152,19 @@ public JsonNode apply(final JsonNode node)

return ret;
}

/**
* Converts this JsonPatch into an ExpressionSpecBuilder
* @return an expression spec builder that contains the updates contained in this
* patch
*/
public ExpressionSpecBuilder get() {
ExpressionSpecBuilder builder = new ExpressionSpecBuilder();
for(JsonPatchOperation operation : operations) {
operation.applyToBuilder(builder);
}
return builder;
}

@Override
public String toString()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2014, Francis Galiegue ([email protected])
* Copyright (c) 2016, Alexander Patrikalakis ([email protected])
*
* This software is dual-licensed under:
*
Expand All @@ -19,6 +20,7 @@

package com.github.fge.jsonpatch;

@SuppressWarnings("serial")
public final class JsonPatchException
extends Exception
{
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/com/github/fge/jsonpatch/JsonPatchOperation.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/*
* Copyright (c) 2014, Francis Galiegue ([email protected])
* Copyright (c) 2016, Alexander Patrikalakis ([email protected])
* Copyright (c) 2015, Daisuke Miyamoto ([email protected])
*
* This software is dual-licensed under:
*
Expand Down Expand Up @@ -27,10 +29,13 @@
import com.github.fge.jackson.jsonpointer.JsonPointer;
import com.github.fge.msgsimple.bundle.MessageBundle;
import com.github.fge.msgsimple.load.MessageBundles;
import com.google.common.base.Function;

import static com.fasterxml.jackson.annotation.JsonSubTypes.*;
import static com.fasterxml.jackson.annotation.JsonTypeInfo.*;

import com.amazonaws.services.dynamodbv2.xspec.ExpressionSpecBuilder;

@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "op")

@JsonSubTypes({
Expand Down Expand Up @@ -61,6 +66,8 @@ public abstract class JsonPatchOperation
{
protected static final MessageBundle BUNDLE
= MessageBundles.getBundle(JsonPatchMessages.class);

Function<JsonPointer, String> pathGenerator = new JsonPathToAttributePath();

protected final String op;

Expand Down Expand Up @@ -94,6 +101,12 @@ protected JsonPatchOperation(final String op, final JsonPointer path)
public abstract JsonNode apply(final JsonNode node)
throws JsonPatchException;

/**
* Apply the current patch operation to an update expression builder
* @param builder the builder to apply this expression to
*/
public abstract void applyToBuilder(ExpressionSpecBuilder builder);

@Override
public abstract String toString();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2016, Alexander Patrikalakis ([email protected])
* Copyright (c) 2015, Daisuke Miyamoto ([email protected])
*
* This software is dual-licensed under:
*
* - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
* later version;
* - the Apache Software License (ASL) version 2.0.
*
* The text of this file and of both licenses is available at the root of this
* project or, if you have the jar distribution, in directory META-INF/, under
* the names LGPL-3.0.txt and ASL-2.0.txt respectively.
*
* Direct link to the sources:
*
* - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
* - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
*/
package com.github.fge.jsonpatch;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jackson.jsonpointer.JsonPointer;
import com.github.fge.jackson.jsonpointer.TokenResolver;
import com.google.common.base.Function;
import com.google.common.base.Joiner;

public class JsonPathToAttributePath implements Function<JsonPointer, String> {

private static Pattern ARRAY_PATTERN = Pattern.compile("(0|[1-9][0-9]+)");


@Override
public String apply(JsonPointer pointer) {
List<String> elements = new ArrayList<String>();
for (TokenResolver<JsonNode> tokenResolver : pointer) {
String token = tokenResolver.getToken().getRaw();
if (ARRAY_PATTERN.matcher(token).matches()) {
String last = elements.get(elements.size() - 1);
elements.set(elements.size() - 1, String.format("%s[%s]", last, token));
} else {
elements.add(token);
}
}

return Joiner.on(".").join(elements);
}
}
Loading

0 comments on commit a901a12

Please sign in to comment.