//package ameba.core.ws.rs; // //import ameba.message.internal.MediaType; //import com.fasterxml.jackson.databind.JsonNode; //import com.fasterxml.jackson.databind.ObjectMapper; //import com.github.fge.jsonpatch.JsonPatch; //import com.github.fge.jsonpatch.JsonPatchException; //import org.glassfish.jersey.message.MessageBodyWorkers; // //import javax.inject.Inject; //import javax.ws.rs.GET; //import javax.ws.rs.InternalServerErrorException; //import javax.ws.rs.WebApplicationException; //import javax.ws.rs.core.Context; //import javax.ws.rs.core.MultivaluedHashMap; //import javax.ws.rs.core.UriInfo; //import javax.ws.rs.ext.MessageBodyWriter; //import javax.ws.rs.ext.ReaderInterceptor; //import javax.ws.rs.ext.ReaderInterceptorContext; //import java.io.ByteArrayInputStream; //import java.io.ByteArrayOutputStream; //import java.io.IOException; //import java.lang.annotation.Annotation; //import java.lang.reflect.Method; // ///** // * <p>JsonPatchInterceptor class.</p> // * // * @author icode // * @since 0.1.6e // */ //@PATCH //public class JsonPatchInterceptor implements ReaderInterceptor { // // private final UriInfo uriInfo; // private final MessageBodyWorkers workers; // @Inject // private ObjectMapper mapper; // // /** // * {@code PatchingInterceptor} injection constructor. // * // * @param uriInfo {@code javax.ws.rs.core.UriInfo} proxy instance. // * @param workers {@link org.glassfish.jersey.message.MessageBodyWorkers} message body workers. // */ // public JsonPatchInterceptor(@Context UriInfo uriInfo, @Context MessageBodyWorkers workers) { // this.uriInfo = uriInfo; // this.workers = workers; // } // // /** // * {@inheritDoc} // */ // @SuppressWarnings("unchecked") // @Override // public Object aroundReadFrom(ReaderInterceptorContext readerInterceptorContext) throws IOException, WebApplicationException { // if (!MediaType.APPLICATION_JSON_PATCH_TYPE.equals(readerInterceptorContext.getMediaType())) { // return readerInterceptorContext.proceed(); // } // // // Get the resource we are being called on, and find the GET method // Object resource = uriInfo.getMatchedResources().get(0); // // Method found = null; // for (Method next : resource.getClass().getMethods()) { // if (next.getAnnotation(GET.class) != null) { // found = next; // break; // } // } // // if (found == null) { // throw new InternalServerErrorException("No matching GET method on resource"); // } // // // Invoke the get method to get the state we are trying to patch // Object bean; // try { // bean = found.invoke(resource); // } catch (Exception e) { // throw new WebApplicationException(e); // } // // // Convert this object to a an array of bytes // ByteArrayOutputStream baos = new ByteArrayOutputStream(); // MessageBodyWriter bodyWriter = // workers.getMessageBodyWriter(bean.getClass(), bean.getClass(), // new Annotation[0], MediaType.APPLICATION_JSON_TYPE); // // bodyWriter.writeTo(bean, bean.getClass(), bean.getClass(), // new Annotation[0], MediaType.APPLICATION_JSON_TYPE, // new MultivaluedHashMap<String, Object>(), baos); // // // // Use the Jackson 2.x classes to convert both the incoming patch // // and the current state of the object into a JsonNode / JsonPatch // JsonNode serverState = mapper.readValue(baos.toByteArray(), JsonNode.class); // JsonNode patchAsNode = mapper.readValue(readerInterceptorContext.getInputStream(), JsonNode.class); // JsonPatch patch = JsonPatch.fromJson(patchAsNode); // // try { // // Apply the patch // JsonNode result = patch.apply(serverState); // // // Stream the result & modify the stream on the readerInterceptor // ByteArrayOutputStream resultAsByteArray = new ByteArrayOutputStream(); // mapper.writeValue(resultAsByteArray, result); // readerInterceptorContext.setInputStream(new ByteArrayInputStream(resultAsByteArray.toByteArray())); // // // Pass control back to the Jersey code // return readerInterceptorContext.proceed(); // } catch (JsonPatchException ex) { // throw new InternalServerErrorException("Error applying patch.", ex); // } // } //}