diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/AddOperation.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/AddOperation.java index ca8fbf981..4d0ca6827 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/AddOperation.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/AddOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -16,26 +16,30 @@ package org.springframework.data.rest.webmvc.json.patch; /** - * Operation to add a new value to the given "path". - * Will throw a {@link PatchException} if the path is invalid or if the given value - * is not assignable to the given path. + * Operation to add a new value to the given "path". Will throw a {@link PatchException} if the path is invalid or if + * the given value is not assignable to the given path. * * @author Craig Walls + * @author Oliver Gierke */ -public class AddOperation extends PatchOperation { +class AddOperation extends PatchOperation { /** * Constructs the add operation + * * @param path The path where the value will be added. (e.g., '/foo/bar/4') * @param value The value to add. */ public AddOperation(String path, Object value) { super("add", path, value); } - + + /* + * (non-Javadoc) + * @see org.springframework.data.rest.webmvc.json.patch.PatchOperation#perform(java.lang.Object, java.lang.Class) + */ @Override void perform(Object targetObject, Class type) { addValue(targetObject, evaluateValueFromTarget(targetObject, type)); } - } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/CopyOperation.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/CopyOperation.java index e2ba689ef..ee8f84817 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/CopyOperation.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/CopyOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -37,8 +37,9 @@ import static org.springframework.data.rest.webmvc.json.patch.PathToSpEL.*; *

* * @author Craig Walls + * @author Oliver Gierke */ -public class CopyOperation extends FromOperation { +class CopyOperation extends FromOperation { /** * Constructs the copy operation @@ -50,9 +51,12 @@ public class CopyOperation extends FromOperation { super("copy", path, from); } + /* + * (non-Javadoc) + * @see org.springframework.data.rest.webmvc.json.patch.PatchOperation#perform(java.lang.Object, java.lang.Class) + */ @Override void perform(Object target, Class type) { - addValue(target, pathToExpression(from).getValue(target)); + addValue(target, pathToExpression(getFrom()).getValue(target)); } - } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/FromOperation.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/FromOperation.java index 05a3e9e58..5fffe7dcd 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/FromOperation.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/FromOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -16,16 +16,19 @@ package org.springframework.data.rest.webmvc.json.patch; /** - * Abstract base class for operations requiring a source property, such as "copy" and "move". - * (e.g., copy from here to there. + * Abstract base class for operations requiring a source property, such as "copy" and "move". (e.g., copy from + * here to there. + * * @author Craig Walls + * @author Oliver Gierke */ -public abstract class FromOperation extends PatchOperation { +abstract class FromOperation extends PatchOperation { + + private final String from; - protected String from; - /** * Constructs the operation + * * @param op The name of the operation to perform. (e.g., 'copy') * @param path The operation's target path. (e.g., '/foo/bar/4') * @param from The operation's source path. (e.g., '/foo/bar/5') @@ -34,9 +37,8 @@ public abstract class FromOperation extends PatchOperation { super(op, path); this.from = from; } - + public String getFrom() { return from; } - } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/JsonLateObjectEvaluator.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/JsonLateObjectEvaluator.java index 55de8965e..59ccd15c4 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/JsonLateObjectEvaluator.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/JsonLateObjectEvaluator.java @@ -15,6 +15,9 @@ */ package org.springframework.data.rest.webmvc.json.patch; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -23,23 +26,23 @@ import com.fasterxml.jackson.databind.ObjectMapper; * * @author Craig Walls */ +@RequiredArgsConstructor class JsonLateObjectEvaluator implements LateObjectEvaluator { - private static final ObjectMapper MAPPER = new ObjectMapper(); - - private JsonNode valueNode; - - public JsonLateObjectEvaluator(JsonNode valueNode) { - this.valueNode = valueNode; - } + private final @NonNull ObjectMapper mapper; + private final @NonNull JsonNode valueNode; + /* + * (non-Javadoc) + * @see org.springframework.data.rest.webmvc.json.patch.LateObjectEvaluator#evaluate(java.lang.Class) + */ @Override public Object evaluate(Class type) { + try { - return MAPPER.readValue(valueNode.traverse(), type); + return mapper.readValue(valueNode.traverse(), type); } catch (Exception e) { return null; } } - } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/JsonPatchPatchConverter.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/JsonPatchPatchConverter.java index bf2834cb3..27bff320f 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/JsonPatchPatchConverter.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/JsonPatchPatchConverter.java @@ -15,13 +15,13 @@ */ package org.springframework.data.rest.webmvc.json.patch; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import org.springframework.util.Assert; - -import com.fasterxml.jackson.core.JsonPointer; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -35,21 +35,10 @@ import com.fasterxml.jackson.databind.node.ObjectNode; * @author Oliver Gierke * @author Mathias Düsterhöft */ +@RequiredArgsConstructor public class JsonPatchPatchConverter implements PatchConverter { - private final ObjectMapper mapper; - - /** - * Creates a new {@link JsonPatchPatchConverter} for the given {@link ObjectMapper}. - * - * @param mapper must not be {@literal null}. - */ - public JsonPatchPatchConverter(ObjectMapper mapper) { - - Assert.notNull(mapper, "ObjectMapper must not be null!"); - - this.mapper = mapper; - } + private final @NonNull ObjectMapper mapper; /** * Constructs a {@link Patch} object given a JsonNode. @@ -58,13 +47,16 @@ public class JsonPatchPatchConverter implements PatchConverter { * @return a {@link Patch} */ public Patch convert(JsonNode jsonNode) { + if (!(jsonNode instanceof ArrayNode)) { throw new IllegalArgumentException("JsonNode must be an instance of ArrayNode"); } ArrayNode opNodes = (ArrayNode) jsonNode; List ops = new ArrayList(opNodes.size()); + for (Iterator elements = opNodes.elements(); elements.hasNext();) { + JsonNode opNode = elements.next(); String opType = opNode.get("op").textValue(); @@ -105,18 +97,25 @@ public class JsonPatchPatchConverter implements PatchConverter { List operations = patch.getOperations(); JsonNodeFactory nodeFactory = JsonNodeFactory.instance; ArrayNode patchNode = nodeFactory.arrayNode(); + for (PatchOperation operation : operations) { + ObjectNode opNode = nodeFactory.objectNode(); opNode.set("op", nodeFactory.textNode(operation.getOp())); opNode.set("path", nodeFactory.textNode(operation.getPath())); + if (operation instanceof FromOperation) { + FromOperation fromOp = (FromOperation) operation; opNode.set("from", nodeFactory.textNode(fromOp.getFrom())); } + Object value = operation.getValue(); + if (value != null) { opNode.set("value", mapper.valueToTree(value)); } + patchNode.add(opNode); } @@ -124,6 +123,7 @@ public class JsonPatchPatchConverter implements PatchConverter { } private Object valueFromJsonNode(String path, JsonNode valueNode) { + if (valueNode == null || valueNode.isNull()) { return null; } else if (valueNode.isTextual()) { @@ -137,36 +137,11 @@ public class JsonPatchPatchConverter implements PatchConverter { } else if (valueNode.isLong()) { return valueNode.asLong(); } else if (valueNode.isObject()) { - return new JsonLateObjectEvaluator(valueNode); + return new JsonLateObjectEvaluator(mapper, valueNode); } else if (valueNode.isArray()) { // TODO: Convert valueNode to array } return null; } - - /** - * Returns whether the trailing element of the given {@link JsonPointer} is a pointer into an array or collection. - * - * @param pointer must not be {@literal null}. - * @return - */ - private static boolean isCollectionElementReference(String pointer) { - - String[] segments = pointer.split("/"); - - if (segments.length == 0) { - return false; - } - - String trailing = segments[segments.length - 1]; - - try { - Integer.parseInt(trailing); - return true; - } catch (NumberFormatException o_O) { - return false; - } - } - } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/LateObjectEvaluator.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/LateObjectEvaluator.java index aa4303cbd..652310f7c 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/LateObjectEvaluator.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/LateObjectEvaluator.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -19,18 +19,15 @@ package org.springframework.data.rest.webmvc.json.patch; *

* Strategy interface for resolving values from an operation definition. *

- * *

- * {@link Patch} implementation generically defines a patch without being tied to any particular - * patch specification. But it's important to know the patch format when resolving the value of - * an operation, as the value format will likely be tied to the patch specification. For example, - * the value attribute of a JSON Patch operation will contain a JSON object. A different - * patch specification may define values in some non-JSON format. + * {@link Patch} implementation generically defines a patch without being tied to any particular patch specification. + * But it's important to know the patch format when resolving the value of an operation, as the value format will likely + * be tied to the patch specification. For example, the value attribute of a JSON Patch operation will + * contain a JSON object. A different patch specification may define values in some non-JSON format. *

- * *

- * This interface allows for pluggable evaluation of values, allowing {@link Patch} to remain - * independent of any specific patch representation. + * This interface allows for pluggable evaluation of values, allowing {@link Patch} to remain independent of any + * specific patch representation. *

* * @author Craig Walls @@ -38,5 +35,4 @@ package org.springframework.data.rest.webmvc.json.patch; public interface LateObjectEvaluator { Object evaluate(Class type); - } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/MoveOperation.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/MoveOperation.java index 863c852e8..ef1869c4a 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/MoveOperation.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/MoveOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -17,34 +17,37 @@ package org.springframework.data.rest.webmvc.json.patch; /** *

- * Operation that moves a value from the given "from" path to the given "path". - * Will throw a {@link PatchException} if either path is invalid or if the from path is non-nullable. + * Operation that moves a value from the given "from" path to the given "path". Will throw a {@link PatchException} if + * either path is invalid or if the from path is non-nullable. *

- * *

- * NOTE: When dealing with lists, the move operation may effectively be a no-op. - * That's because the order of a list is probably dictated by a database query that produced the list. - * Moving things around in the list will have no bearing on the values of each item in the list. - * When the same list resource is retrieved again later, the order will again be decided by the query, - * effectively undoing any previous move operation. + * NOTE: When dealing with lists, the move operation may effectively be a no-op. That's because the order of a list is + * probably dictated by a database query that produced the list. Moving things around in the list will have no bearing + * on the values of each item in the list. When the same list resource is retrieved again later, the order will again be + * decided by the query, effectively undoing any previous move operation. *

* * @author Craig Walls + * @author Oliver Gierke */ -public class MoveOperation extends FromOperation { +class MoveOperation extends FromOperation { /** * Constructs the move operation. + * * @param path The path to move the source value to. (e.g., '/foo/bar/4') * @param from The source path from which a value will be moved. (e.g., '/foo/bar/5') */ public MoveOperation(String path, String from) { super("move", path, from); } - + + /* + * (non-Javadoc) + * @see org.springframework.data.rest.webmvc.json.patch.PatchOperation#perform(java.lang.Object, java.lang.Class) + */ @Override void perform(Object target, Class type) { - addValue(target, popValueAtPath(target, from)); + addValue(target, popValueAtPath(target, getFrom())); } - } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/Patch.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/Patch.java index 05f25ecea..d0ad2c587 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/Patch.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/Patch.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -27,6 +27,7 @@ import java.util.List; *

* * @author Craig Walls + * @author Oliver Gierke */ public class Patch { diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PatchConverter.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PatchConverter.java index 0f00404c4..4b1ebdc56 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PatchConverter.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PatchConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -29,6 +29,7 @@ import com.fasterxml.jackson.databind.JsonNode; *

* * @author Craig Walls + * @author Oliver Gierke * @param A type holding a representation of the patch. For example, a JsonNode if working with JSON Patch. */ public interface PatchConverter { @@ -48,5 +49,4 @@ public interface PatchConverter { * @return the patch representation object. */ T convert(Patch patch); - } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PatchException.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PatchException.java index 5eb393caf..9f902afab 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PatchException.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PatchException.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -19,6 +19,7 @@ package org.springframework.data.rest.webmvc.json.patch; * Exception thrown if an error occurs in the course of applying a Patch. * * @author Craig Walls + * @author Oliver Gierke */ public class PatchException extends RuntimeException { @@ -27,9 +28,8 @@ public class PatchException extends RuntimeException { public PatchException(String message) { super(message); } - + public PatchException(String message, Exception e) { super(message, e); } - } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PatchOperation.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PatchOperation.java index 2bb53eb5c..f28fb8191 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PatchOperation.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PatchOperation.java @@ -27,15 +27,13 @@ import org.springframework.expression.ExpressionException; * * @author Craig Walls * @author Mathias Düsterhöft + * @author Oliver Gierke */ public abstract class PatchOperation { protected final String op; - protected final String path; - protected final Object value; - protected final Expression spelExpression; /** @@ -57,6 +55,7 @@ public abstract class PatchOperation { * {@link LateObjectEvaluator}. */ public PatchOperation(String op, String path, Object value) { + this.op = op; this.path = path; this.value = value; @@ -92,17 +91,22 @@ public abstract class PatchOperation { * @return the value popped from the list */ protected Object popValueAtPath(Object target, String removePath) { + Integer listIndex = targetListIndex(removePath); Expression expression = pathToExpression(removePath); Object value = expression.getValue(target); + if (listIndex == null) { + try { expression.setValue(target, null); return value; } catch (NullPointerException e) { throw new PatchException("Path '" + removePath + "' is not nullable."); } + } else { + Expression parentExpression = pathToParentExpression(removePath); List list = (List) parentExpression.getValue(target); list.remove(listIndex >= 0 ? listIndex.intValue() : list.size() - 1); @@ -117,17 +121,19 @@ public abstract class PatchOperation { * @param target The target object. * @param value The value to add. */ + @SuppressWarnings({ "unchecked", "null" }) protected void addValue(Object target, Object value) { + Expression parentExpression = pathToParentExpression(path); Object parent = parentExpression != null ? parentExpression.getValue(target) : null; Integer listIndex = targetListIndex(path); + if (parent == null || !(parent instanceof List) || listIndex == null) { spelExpression.setValue(target, value); } else { - @SuppressWarnings("unchecked") + List list = (List) parentExpression.getValue(target); - int addAtIndex = listIndex >= 0 ? listIndex.intValue() : list.size(); - list.add(addAtIndex, value); + list.add(listIndex >= 0 ? listIndex.intValue() : list.size(), value); } } @@ -148,6 +154,7 @@ public abstract class PatchOperation { * @return the value at the path on the given target object. */ protected Object getValueFromTarget(Object target) { + try { return spelExpression.getValue(target); } catch (ExpressionException e) { @@ -177,11 +184,9 @@ public abstract class PatchOperation { */ abstract void perform(Object target, Class type); - // private helpers - private Integer targetListIndex(String path) { - String[] pathNodes = path.split("\\/"); + String[] pathNodes = path.split("\\/"); String lastNode = pathNodes[pathNodes.length - 1]; if ("~".equals(lastNode)) { @@ -194,5 +199,4 @@ public abstract class PatchOperation { return null; } } - } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PathToSpEL.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PathToSpEL.java index f5412045f..abafd299b 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PathToSpEL.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/PathToSpEL.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-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. @@ -61,8 +61,6 @@ public class PathToSpEL { return spelToExpression(pathNodesToSpEL(copyOf(path.split("\\/"), path.split("\\/").length - 1))); } - // private helpers - private static String pathToSpEL(String path) { return pathNodesToSpEL(path.split("\\/")); } @@ -71,7 +69,9 @@ public class PathToSpEL { StringBuilder spelBuilder = new StringBuilder(); for (int i = 0; i < pathNodes.length; i++) { + String pathNode = pathNodes[i]; + if (pathNode.length() == 0) { continue; } @@ -82,20 +82,26 @@ public class PathToSpEL { } try { + int index = Integer.parseInt(pathNode); spelBuilder.append('[').append(index).append(']'); + } catch (NumberFormatException e) { + if (spelBuilder.length() > 0) { spelBuilder.append('.'); } + spelBuilder.append(pathNode); } } String spel = spelBuilder.toString(); + if (spel.length() == 0) { spel = "#this"; } + return spel; } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/RemoveOperation.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/RemoveOperation.java index f9a71642e..51f638ad3 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/RemoveOperation.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/RemoveOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -16,24 +16,29 @@ package org.springframework.data.rest.webmvc.json.patch; /** - * Operation that removes the value at the given path. - * Will throw a {@link PatchException} if the given path isn't valid or if the path is non-nullable. + * Operation that removes the value at the given path. Will throw a {@link PatchException} if the given path isn't valid + * or if the path is non-nullable. * * @author Craig Walls + * @author Oliver Gierke */ public class RemoveOperation extends PatchOperation { /** * Constructs the remove operation + * * @param path The path of the value to be removed. (e.g., '/foo/bar/4') */ public RemoveOperation(String path) { super("remove", path); } - + + /* + * (non-Javadoc) + * @see org.springframework.data.rest.webmvc.json.patch.PatchOperation#perform(java.lang.Object, java.lang.Class) + */ @Override void perform(Object target, Class type) { popValueAtPath(target, path); } - } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/ReplaceOperation.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/ReplaceOperation.java index e287168b2..6629f4c1b 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/ReplaceOperation.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/ReplaceOperation.java @@ -24,16 +24,20 @@ public class ReplaceOperation extends PatchOperation { /** * Constructs the replace operation + * * @param path The path whose value is to be replaced. (e.g., '/foo/bar/4') * @param value The value that will replace the current path value. */ public ReplaceOperation(String path, Object value) { super("replace", path, value); } - + + /* + * (non-Javadoc) + * @see org.springframework.data.rest.webmvc.json.patch.PatchOperation#perform(java.lang.Object, java.lang.Class) + */ @Override void perform(Object target, Class type) { setValueOnTarget(target, evaluateValueFromTarget(target, type)); } - } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/TestOperation.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/TestOperation.java index 27df04aa0..9c2681225 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/TestOperation.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/patch/TestOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -43,22 +43,29 @@ class TestOperation extends PatchOperation { super("test", path, value); } + /* + * (non-Javadoc) + * @see org.springframework.data.rest.webmvc.json.patch.PatchOperation#perform(java.lang.Object, java.lang.Class) + */ @Override void perform(Object target, Class type) { + Object expected = normalizeIfNumber(evaluateValueFromTarget(target, type)); Object actual = normalizeIfNumber(getValueFromTarget(target)); + if (!ObjectUtils.nullSafeEquals(expected, actual)) { throw new PatchException("Test against path '" + path + "' failed."); } } private Object normalizeIfNumber(Object expected) { + if (expected instanceof Double || expected instanceof Float) { expected = BigDecimal.valueOf(((Number) expected).doubleValue()); } else if (expected instanceof Number) { expected = BigInteger.valueOf(((Number) expected).longValue()); } + return expected; } - } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/AddOperationTest.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/AddOperationTests.java similarity index 92% rename from spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/AddOperationTest.java rename to spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/AddOperationTests.java index 677318860..95fcf981f 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/AddOperationTest.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/AddOperationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -22,49 +22,47 @@ import java.util.List; import org.junit.Test; -public class AddOperationTest { +public class AddOperationTests { - @Test public void addBooleanPropertyValue() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", false)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - + AddOperation add = new AddOperation("/1/complete", true); add.perform(todos, Todo.class); - + assertTrue(todos.get(1).isComplete()); } @Test public void addStringPropertyValue() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", false)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - + AddOperation add = new AddOperation("/1/description", "BBB"); add.perform(todos, Todo.class); - + assertEquals("BBB", todos.get(1).getDescription()); } - @Test public void addItemToList() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", false)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - + AddOperation add = new AddOperation("/1", new Todo(null, "D", true)); add.perform(todos, Todo.class); - + assertEquals(4, todos.size()); assertEquals("A", todos.get(0).getDescription()); assertFalse(todos.get(0).isComplete()); @@ -75,5 +73,4 @@ public class AddOperationTest { assertEquals("C", todos.get(3).getDescription()); assertFalse(todos.get(3).isComplete()); } - } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/CopyOperationTest.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/CopyOperationTests.java similarity index 85% rename from spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/CopyOperationTest.java rename to spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/CopyOperationTests.java index f309f5524..c0785876c 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/CopyOperationTest.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/CopyOperationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -22,16 +22,16 @@ import java.util.List; import org.junit.Test; -public class CopyOperationTest { +public class CopyOperationTests { @Test public void copyBooleanPropertyValue() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - + CopyOperation copy = new CopyOperation("/1/complete", "/0/complete"); copy.perform(todos, Todo.class); @@ -40,12 +40,12 @@ public class CopyOperationTest { @Test public void copyStringPropertyValue() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - + CopyOperation copy = new CopyOperation("/1/description", "/0/description"); copy.perform(todos, Todo.class); @@ -54,12 +54,12 @@ public class CopyOperationTest { @Test public void copyBooleanPropertyValueIntoStringProperty() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - + CopyOperation copy = new CopyOperation("/1/description", "/0/complete"); copy.perform(todos, Todo.class); @@ -68,83 +68,87 @@ public class CopyOperationTest { @Test public void copyListElementToBeginningOfList() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", false)); todos.add(new Todo(2L, "B", true)); todos.add(new Todo(3L, "C", false)); - + CopyOperation copy = new CopyOperation("/0", "/1"); copy.perform(todos, Todo.class); - + assertEquals(4, todos.size()); - assertEquals(2L, todos.get(0).getId().longValue()); // NOTE: This could be problematic if you try to save it to a DB because there'll be duplicate IDs + assertEquals(2L, todos.get(0).getId().longValue()); // NOTE: This could be problematic if you try to save it to a DB + // because there'll be duplicate IDs assertEquals("B", todos.get(0).getDescription()); assertTrue(todos.get(0).isComplete()); } @Test public void copyListElementToMiddleOfList() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - + CopyOperation copy = new CopyOperation("/2", "/0"); copy.perform(todos, Todo.class); - + assertEquals(4, todos.size()); - assertEquals(1L, todos.get(2).getId().longValue()); // NOTE: This could be problematic if you try to save it to a DB because there'll be duplicate IDs + assertEquals(1L, todos.get(2).getId().longValue()); // NOTE: This could be problematic if you try to save it to a DB + // because there'll be duplicate IDs assertEquals("A", todos.get(2).getDescription()); assertTrue(todos.get(2).isComplete()); } - + @Test public void copyListElementToEndOfList_usingIndex() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - + CopyOperation copy = new CopyOperation("/3", "/0"); copy.perform(todos, Todo.class); - + assertEquals(4, todos.size()); - assertEquals(1L, todos.get(3).getId().longValue()); // NOTE: This could be problematic if you try to save it to a DB because there'll be duplicate IDs + assertEquals(1L, todos.get(3).getId().longValue()); // NOTE: This could be problematic if you try to save it to a DB + // because there'll be duplicate IDs assertEquals("A", todos.get(3).getDescription()); assertTrue(todos.get(3).isComplete()); } - + @Test public void copyListElementToEndOfList_usingTilde() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - + CopyOperation copy = new CopyOperation("/~", "/0"); copy.perform(todos, Todo.class); - + assertEquals(4, todos.size()); - assertEquals(new Todo(1L, "A", true), todos.get(3)); // NOTE: This could be problematic if you try to save it to a DB because there'll be duplicate IDs + assertEquals(new Todo(1L, "A", true), todos.get(3)); // NOTE: This could be problematic if you try to save it to a + // DB because there'll be duplicate IDs } @Test public void copyListElementFromEndOfList_usingTilde() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - + CopyOperation copy = new CopyOperation("/0", "/~"); copy.perform(todos, Todo.class); - - assertEquals(4, todos.size()); - assertEquals(new Todo(3L, "C", false), todos.get(0)); // NOTE: This could be problematic if you try to save it to a DB because there'll be duplicate IDs - } + assertEquals(4, todos.size()); + assertEquals(new Todo(3L, "C", false), todos.get(0)); // NOTE: This could be problematic if you try to save it to a + // DB because there'll be duplicate IDs + } } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/JsonPatchTest.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/JsonPatchTests.java similarity index 91% rename from spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/JsonPatchTest.java rename to spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/JsonPatchTests.java index 1c7590a71..4e8c62bbe 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/JsonPatchTest.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/JsonPatchTests.java @@ -36,11 +36,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; * @author Oliver Gierke * @author Mathias Düsterhöft */ -public class JsonPatchTest { +public class JsonPatchTests { @Test public void manySuccessfulOperations() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "B", false)); @@ -62,7 +62,7 @@ public class JsonPatchTest { @Test public void failureAtBeginning() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "B", false)); @@ -80,7 +80,6 @@ public class JsonPatchTest { assertEquals("Test against path '/5/description' failed.", e.getMessage()); } - // nothing should have changed assertEquals(6, todos.size()); assertFalse(todos.get(1).isComplete()); assertEquals("D", todos.get(3).getDescription()); @@ -90,7 +89,7 @@ public class JsonPatchTest { @Test public void failureInMiddle() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "B", false)); @@ -108,7 +107,6 @@ public class JsonPatchTest { assertEquals("Test against path '/5/description' failed.", e.getMessage()); } - // nothing should have changed assertEquals(6, todos.size()); assertFalse(todos.get(1).isComplete()); assertEquals("D", todos.get(3).getDescription()); @@ -117,11 +115,11 @@ public class JsonPatchTest { } private Patch readJsonPatch(String jsonPatchFile) throws IOException, JsonParseException, JsonMappingException { + ClassPathResource resource = new ClassPathResource(jsonPatchFile, getClass()); - ObjectMapper mapper = new ObjectMapper(); - JsonNode node = mapper.readValue(resource.getInputStream(), JsonNode.class); - Patch patch = new JsonPatchPatchConverter(mapper).convert(node); + JsonNode node = new ObjectMapper().readValue(resource.getInputStream(), JsonNode.class); + Patch patch = new JsonPatchPatchConverter(new ObjectMapper()).convert(node); + return patch; } - } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/MoveOperationTest.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/MoveOperationTests.java similarity index 88% rename from spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/MoveOperationTest.java rename to spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/MoveOperationTests.java index 5c3178efa..d1e5b2ebf 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/MoveOperationTest.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/MoveOperationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -22,16 +22,16 @@ import java.util.List; import org.junit.Test; -public class MoveOperationTest { +public class MoveOperationTests { @Test public void moveBooleanPropertyValue() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - + try { MoveOperation move = new MoveOperation("/1/complete", "/0/complete"); move.perform(todos, Todo.class); @@ -45,12 +45,12 @@ public class MoveOperationTest { @Test public void moveStringPropertyValue() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - + MoveOperation move = new MoveOperation("/1/description", "/0/description"); move.perform(todos, Todo.class); @@ -59,12 +59,12 @@ public class MoveOperationTest { @Test public void moveBooleanPropertyValueIntoStringProperty() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - + try { MoveOperation move = new MoveOperation("/1/description", "/0/complete"); move.perform(todos, Todo.class); @@ -77,23 +77,23 @@ public class MoveOperationTest { // // NOTE: Moving an item about in a list probably has zero effect, as the order of the list is - // usually determined by the DB query that produced the list. Moving things around in a - // java.util.List and then saving those items really means nothing to the DB, as the - // properties that determined the original order are still the same and will result in - // the same order when the objects are queries again. + // usually determined by the DB query that produced the list. Moving things around in a + // java.util.List and then saving those items really means nothing to the DB, as the + // properties that determined the original order are still the same and will result in + // the same order when the objects are queries again. // - + @Test public void moveListElementToBeginningOfList() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", false)); todos.add(new Todo(2L, "B", true)); todos.add(new Todo(3L, "C", false)); - + MoveOperation move = new MoveOperation("/0", "/1"); move.perform(todos, Todo.class); - + assertEquals(3, todos.size()); assertEquals(2L, todos.get(0).getId().longValue()); assertEquals("B", todos.get(0).getDescription()); @@ -102,53 +102,53 @@ public class MoveOperationTest { @Test public void moveListElementToMiddleOfList() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - + MoveOperation move = new MoveOperation("/2", "/0"); move.perform(todos, Todo.class); - + assertEquals(3, todos.size()); assertEquals(1L, todos.get(2).getId().longValue()); assertEquals("A", todos.get(2).getDescription()); assertTrue(todos.get(2).isComplete()); } - + @Test public void moveListElementToEndOfList_usingIndex() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - + MoveOperation move = new MoveOperation("/2", "/0"); move.perform(todos, Todo.class); - + assertEquals(3, todos.size()); assertEquals(1L, todos.get(2).getId().longValue()); assertEquals("A", todos.get(2).getDescription()); assertTrue(todos.get(2).isComplete()); } - + @Test public void moveListElementToBeginningOfList_usingTilde() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(3L, "C", false)); todos.add(new Todo(4L, "E", false)); todos.add(new Todo(2L, "G", false)); - + List expected = new ArrayList(); expected.add(new Todo(1L, "A", true)); expected.add(new Todo(2L, "G", false)); expected.add(new Todo(3L, "C", false)); expected.add(new Todo(4L, "E", false)); - + MoveOperation move = new MoveOperation("/1", "/~"); move.perform(todos, Todo.class); assertEquals(expected, todos); @@ -156,19 +156,19 @@ public class MoveOperationTest { @Test public void moveListElementToEndOfList_usingTilde() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", true)); todos.add(new Todo(2L, "G", false)); todos.add(new Todo(3L, "C", false)); todos.add(new Todo(4L, "E", false)); - + List expected = new ArrayList(); expected.add(new Todo(1L, "A", true)); expected.add(new Todo(3L, "C", false)); expected.add(new Todo(4L, "E", false)); expected.add(new Todo(2L, "G", false)); - + MoveOperation move = new MoveOperation("/~", "/1"); move.perform(todos, Todo.class); assertEquals(expected, todos); diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/PathToSpelTest.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/PathToSpelTests.java similarity index 90% rename from spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/PathToSpelTest.java rename to spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/PathToSpelTests.java index db6e7f6c2..c6e8debf4 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/PathToSpelTest.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/PathToSpelTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -23,26 +23,31 @@ import java.util.List; import org.junit.Test; import org.springframework.expression.Expression; -public class PathToSpelTest { +public class PathToSpelTests { @Test public void listIndex() { + Expression expr = PathToSpEL.pathToExpression("/1/description"); + List todos = new ArrayList(); todos.add(new Todo(1L, "A", false)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); - assertEquals("B", (String) expr.getValue(todos)); + + assertEquals("B", (String) expr.getValue(todos)); } - + @Test public void listTilde() { + Expression expr = PathToSpEL.pathToExpression("/~/description"); + List todos = new ArrayList(); todos.add(new Todo(1L, "A", false)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); + assertEquals("C", (String) expr.getValue(todos)); } - } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/RemoveOperationTest.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/RemoveOperationTests.java similarity index 91% rename from spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/RemoveOperationTest.java rename to spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/RemoveOperationTests.java index 7338a645f..b87a994e8 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/RemoveOperationTest.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/RemoveOperationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -22,31 +22,31 @@ import java.util.List; import org.junit.Test; -public class RemoveOperationTest { +public class RemoveOperationTests { @Test public void removePropertyFromObject() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", false)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); new RemoveOperation("/1/description").perform(todos, Todo.class); - + assertNull(todos.get(1).getDescription()); } @Test public void removeItemFromList() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", false)); todos.add(new Todo(2L, "B", false)); todos.add(new Todo(3L, "C", false)); new RemoveOperation("/1").perform(todos, Todo.class); - + assertEquals(2, todos.size()); assertEquals("A", todos.get(0).getDescription()); assertEquals("C", todos.get(1).getDescription()); diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/ReplaceOperationTest.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/ReplaceOperationTests.java similarity index 90% rename from spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/ReplaceOperationTest.java rename to spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/ReplaceOperationTests.java index f68cd7c63..f8d9e6964 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/ReplaceOperationTest.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/ReplaceOperationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -24,11 +24,11 @@ import org.junit.Test; import com.fasterxml.jackson.databind.ObjectMapper; -public class ReplaceOperationTest { +public class ReplaceOperationTests { @Test public void replaceBooleanPropertyValue() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", false)); todos.add(new Todo(2L, "B", false)); @@ -42,7 +42,7 @@ public class ReplaceOperationTest { @Test public void replaceTextPropertyValue() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", false)); todos.add(new Todo(2L, "B", false)); @@ -56,7 +56,7 @@ public class ReplaceOperationTest { @Test public void replaceTextPropertyValueWithANumber() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", false)); todos.add(new Todo(2L, "B", false)); @@ -76,8 +76,9 @@ public class ReplaceOperationTest { Todo todo = new Todo(1L, "A", false); + ObjectMapper mapper = new ObjectMapper(); ReplaceOperation replace = new ReplaceOperation("/type", - new JsonLateObjectEvaluator(new ObjectMapper().readTree("{ \"value\" : \"new\" }"))); + new JsonLateObjectEvaluator(mapper, mapper.readTree("{ \"value\" : \"new\" }"))); replace.perform(todo, Todo.class); assertNotNull(todo.getType()); diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/TestOperationTest.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/TestOperationTests.java similarity index 90% rename from spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/TestOperationTest.java rename to spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/TestOperationTests.java index 2a00c29ee..348e9603a 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/TestOperationTest.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/TestOperationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-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. @@ -20,16 +20,16 @@ import java.util.List; import org.junit.Test; -public class TestOperationTest { +public class TestOperationTests { @Test public void testPropertyValueEquals() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", false)); todos.add(new Todo(2L, "B", true)); todos.add(new Todo(3L, "C", false)); - + TestOperation test = new TestOperation("/0/complete", false); test.perform(todos, Todo.class); @@ -38,28 +38,27 @@ public class TestOperationTest { } - @Test(expected=PatchException.class) + @Test(expected = PatchException.class) public void testPropertyValueNotEquals() throws Exception { - // initial Todo list + List todos = new ArrayList(); todos.add(new Todo(1L, "A", false)); todos.add(new Todo(2L, "B", true)); todos.add(new Todo(3L, "C", false)); - + TestOperation test = new TestOperation("/0/complete", true); test.perform(todos, Todo.class); } - + @Test public void testListElementEquals() throws Exception { + List todos = new ArrayList(); todos.add(new Todo(1L, "A", false)); todos.add(new Todo(2L, "B", true)); todos.add(new Todo(3L, "C", false)); - + TestOperation test = new TestOperation("/1", new Todo(2L, "B", true)); test.perform(todos, Todo.class); - } - } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/TodoList.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/TodoList.java index 78d9b03f8..9c7e84d59 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/TodoList.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/patch/TodoList.java @@ -15,9 +15,12 @@ */ package org.springframework.data.rest.webmvc.json.patch; +import lombok.Data; + import java.io.Serializable; import java.util.List; +@Data public class TodoList implements Serializable { private static final long serialVersionUID = 1L; @@ -25,29 +28,4 @@ public class TodoList implements Serializable { private List todos; private Todo[] todoArray; private String name; - - public List getTodos() { - return todos; - } - - public void setTodos(List todos) { - this.todos = todos; - } - - public Todo[] getTodoArray() { - return todoArray; - } - - public void setTodoArray(Todo[] todoArray) { - this.todoArray = todoArray; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - }