//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);
// }
// }
//}