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

com.speedment.plugins.json.internal.JsonEncoderImpl Maven / Gradle / Ivy

There is a newer version: 3.2.10
Show newest version
/**
 *
 * Copyright (c) 2006-2016, Speedment, Inc. All Rights Reserved.
 *
 * 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 com.speedment.plugins.json.internal;

import com.speedment.plugins.json.JsonCollector;
import com.speedment.plugins.json.JsonEncoder;
import com.speedment.runtime.config.Project;
import com.speedment.runtime.config.identifier.TableIdentifier;
import com.speedment.runtime.core.manager.Manager;
import com.speedment.runtime.field.*;
import com.speedment.runtime.field.method.*;
import com.speedment.runtime.field.trait.HasFinder;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Stream;

import static com.speedment.common.invariant.NullUtil.requireNonNulls;
import static com.speedment.plugins.json.internal.JsonUtil.jsonField;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;

/**
 * The default implementation of the {@link JsonEncoder} interface.
 * 
 * @param   the entity type
 * 
 * @author  Emil Forslund
 * @since   1.0.0
 */
final class JsonEncoderImpl implements JsonEncoder {
    
    private final Map> getters;
    private final Project project;
    private final Manager manager;

    /**
     * Constructs an empty JsonEncoder with no fields added to the output
     * renderer.
     */
    JsonEncoderImpl(Project project, Manager manager) {
        this.getters = new LinkedHashMap<>();
        this.project = requireNonNull(project);
        this.manager = requireNonNull(manager);
    }

    /**************************************************************************/
    /*                             Getters                                    */
    /**************************************************************************/
    
    /**
     * {@inheritDoc}
     */
    @Override
    public Manager getManager() {
        return manager;
    }

    /**************************************************************************/
    /*                          Field Putters                                 */
    /**************************************************************************/
    
    /**
     * {@inheritDoc}
     */
    @Override
    public  JsonEncoder put(ReferenceField field) {
        return putHelper(field, ReferenceField::getter, this::put);
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public  JsonEncoder putByte(ByteField field) {
        return putHelper(field, ByteField::getter, this::putByte);
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public  JsonEncoder putShort(ShortField field) {
        return putHelper(field, ShortField::getter, this::putShort);
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public  JsonEncoder putInt(IntField field) {
        return putHelper(field, IntField::getter, this::putInt);
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public  JsonEncoder putLong(LongField field) {
        return putHelper(field, LongField::getter, this::putLong);
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public  JsonEncoder putFloat(FloatField field) {
        return putHelper(field, FloatField::getter, this::putFloat);
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public  JsonEncoder putDouble(DoubleField field) {
        return putHelper(field, DoubleField::getter, this::putDouble);
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public  JsonEncoder putChar(CharField field) {
        return putHelper(field, CharField::getter, this::putChar);
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public  JsonEncoder putBoolean(BooleanField field) {
        return putHelper(field, BooleanField::getter, this::putBoolean);
    }
    
    private , G extends Getter> JsonEncoder putHelper(
        F field, Function getter, BiFunction> putter) {
        
        requireNonNulls(field, getter, putter);
        final String columnName = jsonField(project, field.identifier());
        return putter.apply(columnName, getter.apply(field));
    }

    /**************************************************************************/
    /*                        Put Labels with Getters                         */
    /**************************************************************************/
    
    /**
     * {@inheritDoc}
     */
    @Override
    public  JsonEncoder put(String label, ReferenceGetter getter) {
        return putHelper(label, e -> jsonValue(getter.apply(e)));
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public JsonEncoder putByte(String label, ByteGetter getter) {
        return putHelper(label, e -> jsonValue(getter.applyAsByte(e)));
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public JsonEncoder putShort(String label, ShortGetter getter) {
        return putHelper(label, e -> jsonValue(getter.applyAsShort(e)));
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public JsonEncoder putInt(String label, IntGetter getter) {
        return putHelper(label, e -> jsonValue(getter.applyAsInt(e)));
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public JsonEncoder putLong(String label, LongGetter getter) {
        return putHelper(label, e -> jsonValue(getter.applyAsLong(e)));
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public JsonEncoder putFloat(String label, FloatGetter getter) {
        return putHelper(label, e -> jsonValue(getter.applyAsFloat(e)));
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public JsonEncoder putDouble(String label, DoubleGetter getter) {
        return putHelper(label, e -> jsonValue(getter.applyAsDouble(e)));
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public JsonEncoder putChar(String label, CharGetter getter) {
        return putHelper(label, e -> jsonValue(getter.applyAsChar(e)));
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public JsonEncoder putBoolean(String label, BooleanGetter getter) {
        return putHelper(label, e -> jsonValue(getter.applyAsBoolean(e)));
    }
    
    private JsonEncoder putHelper(String label, Function jsonValue) {
        requireNonNull(label);
        getters.put(label, e -> "\"" + label + "\":" + jsonValue.apply(e));
        return this;
    }
    
    /**************************************************************************/
    /*                        Put Fields with Finders                         */
    /**************************************************************************/
    
    /**
     * {@inheritDoc}
     */
    @Override
    public  & HasFinder> 
    JsonEncoder put(FIELD field, JsonEncoder encoder) {
        requireNonNulls(field, encoder);
        final String columnName = jsonField(project, field.identifier());
        final Manager fkManager = encoder.getManager();
        final TableIdentifier identifier = fkManager.getTableIdentifier();
        final FindFrom entityFinder = field.finder(identifier, () -> fkManager.stream());
        return put(columnName, entityFinder, encoder);
    }

    /**************************************************************************/
    /*                        Put Labels with Finders                         */
    /**************************************************************************/
    
    /**
     * {@inheritDoc}
     */
    @Override
    public  JsonEncoder put(
            String label, 
            FindFrom finder, 
            JsonEncoder fkEncoder) {
        
        requireNonNulls(label, finder, fkEncoder);
        getters.put(label, e -> "\"" + label + "\":" + 
            fkEncoder.apply(finder.apply(e))
        );
        
        return this;
    }

    /**************************************************************************/
    /*                        Put Labels with Find Many                       */
    /**************************************************************************/
    
    /**
     * {@inheritDoc}
     */
    @Override
    public  JsonEncoder putStreamer(
            String label, 
            Function> streamer, 
            JsonEncoder fkEncoder) {
        
        requireNonNulls(label, streamer, fkEncoder);
        getters.put(label, e -> "\"" + label + "\":[" + 
            streamer.apply(e).map(fkEncoder::apply).collect(joining(",")) + 
            "]"
        );
        
        return this;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public  JsonEncoder putStreamer(
            String label, 
            Function> streamer, 
            Function fkEncoder) {
        
        requireNonNulls(label, streamer, fkEncoder);
        getters.put(label, e -> "\"" + label + "\":[" + 
            streamer.apply(e).map(fkEncoder).collect(joining(",")) +
            "]"
        );
        
        return this;
    }

    /**************************************************************************/
    /*                             Remove by Label                            */
    /**************************************************************************/
    
    /**
     * {@inheritDoc}
     */
    @Override
    public JsonEncoder remove(String label) {
        requireNonNull(label);
        getters.remove(label);
        return this;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public JsonEncoder remove(Field field) {
        requireNonNull(field);
        getters.remove(jsonField(project, field.identifier()));
        return this;
    }

    /**************************************************************************/
    /*                                  Encode                                */
    /**************************************************************************/
    
    /**
     * {@inheritDoc}
     */
    @Override
    public String apply(ENTITY entity) {
        return entity == null ? "null" : "{"
            + getters.values().stream()
            .map(g -> g.apply(entity))
            .collect(joining(","))
            + "}";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public JsonCollector collector() {
        return JsonCollector.toJson(this);
    }

    /**************************************************************************/
    /*                  Protected and Private Helper Methods                  */
    /**************************************************************************/

    /**
     * Parse the specified value into JSON.
     * 
     * @param value  the value
     * @return       the JSON encoded value
     */
    private static String jsonValue(byte value) {
        return String.valueOf(value);
    }
    
    /**
     * Parse the specified value into JSON.
     * 
     * @param value  the value
     * @return       the JSON encoded value
     */
    private static String jsonValue(short value) {
        return String.valueOf(value);
    }
    
    /**
     * Parse the specified value into JSON.
     * 
     * @param value  the value
     * @return       the JSON encoded value
     */
    private static String jsonValue(int value) {
        return String.valueOf(value);
    }
    
    /**
     * Parse the specified value into JSON.
     * 
     * @param value  the value
     * @return       the JSON encoded value
     */
    private static String jsonValue(long value) {
        return String.valueOf(value);
    }
    
    /**
     * Parse the specified value into JSON.
     * 
     * @param value  the value
     * @return       the JSON encoded value
     */
    private static String jsonValue(float value) {
        return String.valueOf(value);
    }
    
    /**
     * Parse the specified value into JSON.
     * 
     * @param value  the value
     * @return       the JSON encoded value
     */
    private static String jsonValue(double value) {
        return String.valueOf(value);
    }
    
    /**
     * Parse the specified value into JSON.
     * 
     * @param value  the value
     * @return       the JSON encoded value
     */
    private static String jsonValue(char value) {
        return String.valueOf(value);
    }
    
    /**
     * Parse the specified value into JSON.
     * 
     * @param value  the value
     * @return       the JSON encoded value
     */
    private static String jsonValue(boolean value) {
        return String.valueOf(value);
    }

    /**
     * Parse the specified value into JSON.
     * 
     * @param in  the value
     * @return    the JSON encoded value
     */
    private static String jsonValue(Object in) {
        // in is nullable, a field can certainly be null
        final String value;

        if (in instanceof Optional) {
            final Optional o = (Optional) in;
            return o.map(JsonEncoderImpl::jsonValue).orElse("null");
        } else if (in == null) {
            value = "null";
        } else if (in instanceof Byte
            || in instanceof Short
            || in instanceof Integer
            || in instanceof Long
            || in instanceof Boolean
            || in instanceof Float
            || in instanceof Double) {
            value = String.valueOf(in);
        } else {
            value = "\"" + String.valueOf(in).replace("\"", "\\\"") + "\"";
        }

        return value;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy