// Path: try_java_ee7-web/src/main/java/enterprisegeeks/rest/dto/Message.java
// @XmlRootElement
// public class Message {
// 
//     private String key;
//     private String message;
// 
//     public Message(){}
//     
//     public static Message of(String key, String message) {
//         Message m = new Message();
//         m.key = key;
//         m.message = message;
//         return m;
//     }
//     
//     public String getKey() {
//         return key;
//     }
// 
//     public void setKey(String key) {
//         this.key = key;
//     }
// 
//     public String getMessage() {
//         return message;
//     }
// 
//     public void setMessage(String message) {
//         this.message = message;
//     }
// 
// }


import enterprisegeeks.rest.dto.Message;
import java.util.List;
import java.util.stream.Collectors;
import javax.json.JsonStructure;
import javax.validation.ConstraintViolationException;
import javax.ws.rs.Produces;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package enterprisegeeks.rest;


/**
 * Bean Validationの例外に対するマッピング。
 * 
 * エラーメッセージをレスポンスに設定する。
 */
@Provider // 特定の例外に対して、処理を行う。Providerアノテーションで自動判別される。
public class BeanValidationExceptionMapper implements ExceptionMapper<ConstraintViolationException> {

    @Override
    @Produces(MediaType.APPLICATION_JSON)
    public Response toResponse(ConstraintViolationException exception) {
        
        // メソッドの戻り値が List<SomeObject> の場合は、List形式のデータを返しても動作する。
        // が、Responseを返す場合は、entity()にlistを渡すと、ジェネリクスが解消できないので、
        // 正常に動かない。
        
        // 方法1. List<SomeObject>型のフィールドを持つクラスを別途作り、そのクラスで返す。
        
        // 方法2. 配列で返す。
        //Message[] list = 
        //    exception.getConstraintViolations().stream()
        //        .map(v -> Message.of(last(v.getPropertyPath().toString()), v.getMessage()))
        //        .toArray(Message[]::new);
        
        // 方法3 genericEntity
// Path: try_java_ee7-web/src/main/java/enterprisegeeks/rest/dto/Message.java
// @XmlRootElement
// public class Message {
// 
//     private String key;
//     private String message;
// 
//     public Message(){}
//     
//     public static Message of(String key, String message) {
//         Message m = new Message();
//         m.key = key;
//         m.message = message;
//         return m;
//     }
//     
//     public String getKey() {
//         return key;
//     }
// 
//     public void setKey(String key) {
//         this.key = key;
//     }
// 
//     public String getMessage() {
//         return message;
//     }
// 
//     public void setMessage(String message) {
//         this.message = message;
//     }
// 
// }


// Path: try_java_ee7-web/src/main/java/enterprisegeeks/rest/BeanValidationExceptionMapper.java
import enterprisegeeks.rest.dto.Message;
import java.util.List;
import java.util.stream.Collectors;
import javax.json.JsonStructure;
import javax.validation.ConstraintViolationException;
import javax.ws.rs.Produces;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package enterprisegeeks.rest;


/**
 * Bean Validationの例外に対するマッピング。
 * 
 * エラーメッセージをレスポンスに設定する。
 */
@Provider // 特定の例外に対して、処理を行う。Providerアノテーションで自動判別される。
public class BeanValidationExceptionMapper implements ExceptionMapper<ConstraintViolationException> {

    @Override
    @Produces(MediaType.APPLICATION_JSON)
    public Response toResponse(ConstraintViolationException exception) {
        
        // メソッドの戻り値が List<SomeObject> の場合は、List形式のデータを返しても動作する。
        // が、Responseを返す場合は、entity()にlistを渡すと、ジェネリクスが解消できないので、
        // 正常に動かない。
        
        // 方法1. List<SomeObject>型のフィールドを持つクラスを別途作り、そのクラスで返す。
        
        // 方法2. 配列で返す。
        //Message[] list = 
        //    exception.getConstraintViolations().stream()
        //        .map(v -> Message.of(last(v.getPropertyPath().toString()), v.getMessage()))
        //        .toArray(Message[]::new);
        
        // 方法3 genericEntity
        List<Message> list = 