All Downloads are FREE. Search and download functionalities are using the official Maven repository.

paa.coder.noodleCriteriaBuilder.springAdapters.converters.RestFieldConverter Maven / Gradle / Ivy

package paa.coder.noodleCriteriaBuilder.springAdapters.converters;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import lombok.AllArgsConstructor;
import paa.coder.noodleCriteriaBuilder.restFilter.payloads.RestCriteria;
import paa.coder.noodleCriteriaBuilder.restFilter.payloads.RestOrder;
import paa.coder.noodleCriteriaBuilder.restFilter.payloads.RestQuery;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Stream;

public interface RestFieldConverter {
    interface FieldNamePolicy extends Function{

        String DEFAULT_VALUE = "DEFAULT";
        FieldNamePolicy DEFAULT = s->s;

        String CAMEL_CASE_VALUE = "CAMEL_CASE";
        FieldNamePolicy CAMEL_CASE = s-> Pattern.compile("(?:_)([a-z])").matcher(s).replaceAll(m -> m.group(1).toUpperCase());

        String SNAKE_CASE_VALUE = "SNAKE_CASE";
        FieldNamePolicy SNAKE_CASE = s->s.replaceAll("([A-Z]+)([A-Z][a-z])", "$1_$2").replaceAll("([a-z])([A-Z])", "$1_$2");
        String LOWER_SNAKE_CASE_VALUE = "LOWER_SNAKE_CASE";
        FieldNamePolicy LOWER_SNAKE_CASE = s-> SNAKE_CASE.apply(s).toLowerCase();

        String UPPER_SNAKE_CASE_VALUE = "UPPER_SNAKE_CASE";
        FieldNamePolicy UPPER_SNAKE_CASE = s-> SNAKE_CASE.apply(s).toUpperCase();

        class Error extends RuntimeException{
            public Error(String message){
                super(message);
            }
        }
    }

    class Store{

        private final Map mapFieldNamePolicy = new HashMap<>();

        public Store(){
            mapFieldNamePolicy.put(RestFieldConverter.FieldNamePolicy.DEFAULT_VALUE, RestFieldConverter.FieldNamePolicy.DEFAULT);
            mapFieldNamePolicy.put(RestFieldConverter.FieldNamePolicy.CAMEL_CASE_VALUE, RestFieldConverter.FieldNamePolicy.CAMEL_CASE);
            mapFieldNamePolicy.put(RestFieldConverter.FieldNamePolicy.SNAKE_CASE_VALUE, RestFieldConverter.FieldNamePolicy.SNAKE_CASE);
            mapFieldNamePolicy.put(RestFieldConverter.FieldNamePolicy.UPPER_SNAKE_CASE_VALUE, RestFieldConverter.FieldNamePolicy.UPPER_SNAKE_CASE);
            mapFieldNamePolicy.put(RestFieldConverter.FieldNamePolicy.LOWER_SNAKE_CASE_VALUE, RestFieldConverter.FieldNamePolicy.LOWER_SNAKE_CASE);
        }

        void addFieldNamePolicy(String name, RestFieldConverter.FieldNamePolicy policy){
            mapFieldNamePolicy.put(name, policy);
        }

        public Entry build(String fieldNamePolicyValue){
            final FieldNamePolicy fieldNamePolicy = mapFieldNamePolicy.get(fieldNamePolicyValue);
            if(fieldNamePolicy==null){
                throw new FieldNamePolicy.Error(String.format("policy with name %s not found",fieldNamePolicyValue));
            }
            return new Entry(fieldNamePolicy);

        }

        @AllArgsConstructor
        public static class Entry{
            private final FieldNamePolicy fieldNamePolicy;

            public void customizeMapper(ObjectMapper mapper){
                SimpleModule criteriaModule = new SimpleModule("RestCriteriaModule");
                criteriaModule.addSerializer(RestCriteria.class, new CriteriaSerializer());
                criteriaModule.addDeserializer(RestCriteria.class, new CriteriaDeserializer(this));
                mapper.registerModule(criteriaModule);

                SimpleModule orderModule = new SimpleModule("RestOrderModule");
                orderModule.addSerializer(RestOrder.class, new RestFieldConverter.OrderSerializer());
                orderModule.addDeserializer(RestOrder.class, new RestFieldConverter.OrderDeserializer(this));
                mapper.registerModule(orderModule);

            }
        }

    }
    class CriteriaSerializer extends StdSerializer {

        public CriteriaSerializer() {
            this(RestCriteria.class);
        }

        public CriteriaSerializer(Class t) {
            super(t);
        }
        @Override
        public void serialize(RestCriteria restCriteria, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException{
            jsonGenerator.writeStartObject();
            jsonGenerator.writeStringField("field", restCriteria.getField());
            jsonGenerator.writeStringField("operator", restCriteria.getOperator());
            jsonGenerator.writeObjectField("query", restCriteria.getQuery());
            jsonGenerator.writeObjectField("value", restCriteria.getValue());
            jsonGenerator.writeEndObject();
        }

    }
    class CriteriaDeserializer extends StdDeserializer{

        private final Store.Entry storeEntry;

        public CriteriaDeserializer(Store.Entry storeEntry) {
            this(null,storeEntry);
        }

        public CriteriaDeserializer(Class vc, Store.Entry storeEntry) {
            super(vc);
            this.storeEntry = storeEntry;
        }
        @Override
        public RestCriteria deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException{

            final RestCriteria restCriteria = new RestCriteria();

            final JsonNode treeNode = jsonParser.readValueAsTree();

            Function findNode = s->Optional.ofNullable(treeNode.get(s)).orElse(NullNode.instance);

            final JsonNode field = findNode.apply("field");
            if(!field.isNull()){
                restCriteria.setField(storeEntry.fieldNamePolicy.apply(field.asText()));
            }

            final JsonNode operator = findNode.apply("operator");
            if(!operator.isNull()){
                restCriteria.setOperator(operator.asText());
            }


            final JsonNode queryNode = findNode.apply("query");
            if(!queryNode.isNull()){
                 restCriteria.setQuery(queryNode.traverse(jsonParser.getCodec()).readValueAs(RestQuery.class));

            }

            final JsonNode valueNode = findNode.apply("value");
            if(!valueNode.isNull()){
                restCriteria.setValue(valueNode.traverse(jsonParser.getCodec()).readValueAs(Object.class));
            }

            return restCriteria;
        }

    }

    class OrderSerializer extends StdSerializer {
        public OrderSerializer() {
            this(RestOrder.class);
        }

        public OrderSerializer(Class t) {
            super(t);
        }

        @Override
        public void serialize(RestOrder restOrder, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException{
            jsonGenerator.writeStartObject();

            jsonGenerator.writeArrayFieldStart("fields");
            for (String f : restOrder.getFields()) {
                jsonGenerator.writeString(f);
            }
            jsonGenerator.writeEndArray();

            jsonGenerator.writeBooleanField("isAsc",restOrder.isAsc());
            jsonGenerator.writeEndObject();
        }
    }

    class OrderDeserializer extends StdDeserializer{

        private final Store.Entry storeEntry;
        public OrderDeserializer(Store.Entry storeEntry) {
            this(null,storeEntry);
        }

        public OrderDeserializer(Class vc,Store.Entry storeEntry) {
            super(vc);
            this.storeEntry = storeEntry;
        }

        @Override
        public RestOrder deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException{

            final RestOrder restCriteria = new RestOrder();

            final JsonNode treeNode = jsonParser.readValueAsTree();

            Function findNode = s->Optional.ofNullable(treeNode.findValue(s)).orElse(NullNode.instance);

            final JsonNode fields = findNode.apply("fields");
            if(!fields.isNull() && fields instanceof ArrayNode ){
                for(JsonNode next : fields){
                    if(! next.isNull()){
                        restCriteria.getFields().add(storeEntry.fieldNamePolicy.apply(next.asText()));
                    }
                }
            }

            final JsonNode asc = findNode.apply("asc");
            if(!asc.isNull()){
                restCriteria.setAsc(asc.asBoolean());
            }else{
                final JsonNode isAsc = findNode.apply("isAsc");
                if(!isAsc.isNull()){
                    restCriteria.setAsc(isAsc.asBoolean());
                }
            }

            return restCriteria;
        }
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy