Skip to content

Implement http patch method #134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@
<dependency>
<groupId>net.code-story</groupId>
<artifactId>fluent-rest-test</artifactId>
<version>1.5</version>
<version>1.7</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
*/
package net.codestory.http.annotations;

import static java.util.Optional.*;
import static java.util.stream.Stream.of;
import static net.codestory.http.constants.Methods.*;
import net.codestory.http.misc.UrlConcat;

import java.lang.reflect.*;
import java.lang.reflect.Method;

import net.codestory.http.misc.*;
import static java.util.Optional.ofNullable;
import static java.util.stream.Stream.of;
import static net.codestory.http.constants.Methods.*;

public class AnnotationHelper {
private AnnotationHelper() {
Expand All @@ -36,6 +36,7 @@ public static void parseAnnotations(String urlPrefix, Class<?> resourceType, Met
for (Method method : targetType.getMethods()) {
of(method.getAnnotationsByType(Get.class)).forEach(get -> callback.onMethod(GET, url(urlPrefix, classPrefix, get.value()), method));
of(method.getAnnotationsByType(Post.class)).forEach(post -> callback.onMethod(POST, url(urlPrefix, classPrefix, post.value()), method));
of(method.getAnnotationsByType(Patch.class)).forEach(patch -> callback.onMethod(PATCH, url(urlPrefix, classPrefix, patch.value()), method));
of(method.getAnnotationsByType(Put.class)).forEach(put -> callback.onMethod(PUT, url(urlPrefix, classPrefix, put.value()), method));
of(method.getAnnotationsByType(Delete.class)).forEach(delete -> callback.onMethod(DELETE, url(urlPrefix, classPrefix, delete.value()), method));
of(method.getAnnotationsByType(Head.class)).forEach(head -> callback.onMethod(HEAD, url(urlPrefix, classPrefix, head.value()), method));
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/net/codestory/http/annotations/Patch.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright (C) 2013-2015 all@code-story.net
*
* 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 net.codestory.http.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Documented
@Target(METHOD)
@Retention(RUNTIME)
@Repeatable(Patches.class)
public @interface Patch {
String value() default "";
}
30 changes: 30 additions & 0 deletions src/main/java/net/codestory/http/annotations/Patches.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright (C) 2013-2015 all@code-story.net
*
* 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 net.codestory.http.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface Patches {
Patch[] value();
}
1 change: 1 addition & 0 deletions src/main/java/net/codestory/http/constants/Methods.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public abstract class Methods {
public static final String GET = "GET";
public static final String POST = "POST";
public static final String PUT = "PUT";
public static final String PATCH = "PATCH";
public static final String DELETE = "DELETE";
public static final String HEAD = "HEAD";
public static final String OPTIONS = "OPTIONS";
Expand Down
42 changes: 42 additions & 0 deletions src/main/java/net/codestory/http/routes/RouteCollection.java
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,42 @@ public RouteCollection put(String uriPattern, FourParamsRoute route) {
return this;
}

@Override
public Routes patch(String uriPattern, NoParamRoute route) {
add(PATCH, checkParametersCount(uriPattern, 0), route);
return this;
}

@Override
public Routes patch(String uriPattern, NoParamRouteWithContext route) {
add(PATCH, checkParametersCount(uriPattern, 0), route);
return this;
}

@Override
public Routes patch(String uriPattern, OneParamRoute route) {
add(PATCH, checkParametersCount(uriPattern, 1), route);
return this;
}

@Override
public Routes patch(String uriPattern, TwoParamsRoute route) {
add(PATCH, checkParametersCount(uriPattern, 2), route);
return this;
}

@Override
public Routes patch(String uriPattern, ThreeParamsRoute route) {
add(PATCH, checkParametersCount(uriPattern, 3), route);
return this;
}

@Override
public Routes patch(String uriPattern, FourParamsRoute route) {
add(PATCH, checkParametersCount(uriPattern, 4), route);
return this;
}

@Override
public RouteCollection delete(String uriPattern, NoParamRoute route) {
add(DELETE, checkParametersCount(uriPattern, 0), route);
Expand Down Expand Up @@ -445,6 +481,12 @@ public Routes anyPut(NoParamRouteWithContext route) {
return this;
}

@Override
public Routes anyPatch(NoParamRouteWithContext route) {
routes.addCatchAllRoute(new CatchAllRoute(PATCH, route));
return this;
}

@Override
public Routes anyOptions(NoParamRouteWithContext route) {
routes.addCatchAllRoute(new CatchAllRoute(OPTIONS, route));
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/net/codestory/http/routes/Routes.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,20 @@ public interface Routes extends Serializable {

Routes put(String uriPattern, FourParamsRoute route);

Routes anyPatch(NoParamRouteWithContext route);

Routes patch(String uriPattern, NoParamRoute route);

Routes patch(String uriPattern, NoParamRouteWithContext route);

Routes patch(String uriPattern, OneParamRoute route);

Routes patch(String uriPattern, TwoParamsRoute route);

Routes patch(String uriPattern, ThreeParamsRoute route);

Routes patch(String uriPattern, FourParamsRoute route);

Routes anyOptions(NoParamRouteWithContext route);

Routes options(String uriPattern, Object payload);
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/net/codestory/http/routes/RoutesWithPattern.java
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,36 @@ public RoutesWithPattern put(FourParamsRoute route) {
return this;
}

public RoutesWithPattern patch(NoParamRoute route) {
routes.put(currentUriPattern, route);
return this;
}

public RoutesWithPattern patch(NoParamRouteWithContext route) {
routes.put(currentUriPattern, route);
return this;
}

public RoutesWithPattern patch(OneParamRoute route) {
routes.put(currentUriPattern, route);
return this;
}

public RoutesWithPattern patch(TwoParamsRoute route) {
routes.put(currentUriPattern, route);
return this;
}

public RoutesWithPattern patch(ThreeParamsRoute route) {
routes.put(currentUriPattern, route);
return this;
}

public RoutesWithPattern patch(FourParamsRoute route) {
routes.put(currentUriPattern, route);
return this;
}

public RoutesWithPattern delete(NoParamRoute route) {
routes.delete(currentUriPattern, route);
return this;
Expand Down
11 changes: 11 additions & 0 deletions src/test/java/net/codestory/http/CatchAllTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ public void catch_all_put() {
post("/route").should().respond(405);
}

@Test
public void catch_all_patch() {
configure(routes -> routes
.anyPatch((context) -> "Hello")
);

patch("/").should().contain("Hello");
patch("/any").should().contain("Hello");
post("/route").should().respond(405);
}

@Test
public void catch_all_options() {
configure(routes -> routes
Expand Down
79 changes: 79 additions & 0 deletions src/test/java/net/codestory/http/PatchTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* Copyright (C) 2013-2015 all@code-story.net
*
* 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 net.codestory.http;

import net.codestory.http.annotations.Patch;
import net.codestory.http.testhelpers.AbstractProdWebServerTest;
import org.junit.Test;

public class PatchTest extends AbstractProdWebServerTest {
@Test
public void patch() {
configure(routes -> routes
.patch("/patch", () -> "Done")
);

patch("/patch").should().contain("Done");
}

@Test
public void content_as_bytes() {
configure(routes -> routes
.patch("/patch", context -> context.request().contentAsBytes())
);

patch("/patch", "Bob").should().contain("Bob");
}

@Test
public void content_as_string() {
configure(routes -> routes
.patch("/patch", context -> context.request().content())
);

patch("/patch", "Joe").should().contain("Joe");
}

@Test
public void resource() {
configure(routes -> routes
.add(new patchResource())
);

patch("/order/12", "{\"name\":\"foo\",\"quantity\":42}").should().contain("order 12 : 42xfoo");
}

@Test
public void resource_class() {
configure(routes -> routes
.add(patchResource.class)
);

patch("/order/12", "{\"name\":\"foo\",\"quantity\":42}").should().contain("order 12 : 42xfoo");
}

public static class patchResource {
@Patch("/order/:id")
public String update(String id, Order order) {
return "order " + id + " : " + order.quantity + "x" + order.name;
}
}

static class Order {
String name;
int quantity;
}
}