/** * * Copyright (c) 2006-2017, 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; 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.function.Function; import java.util.stream.Stream; /** * An encoder that can transform Speedment entities to JSON. * <p> * <em>Example usage:</em> * {@code * Manager<Address> addresses = app.managerOf(Address.class); * Manager<Employee> employees = app.managerOf(Employee.class); * Manager<Employee> departments = app.managerOf(Department.class); * * // Include street, zip-code and city only. * JconEncoder<Address> addrEncoder = JsonEncoder.noneOf(addresses) * .add(Address.STREET) * .add(Address.ZIPCODE) * .add(Address.CITY); * * // Do not expose SSN but do inline the home address. * JconEncoder<Employee> empEncoder = JsonEncoder.allOf(employees) * .remove(Employee.SSN) * .remove(Employee.DEPARTMENT); // Go the other way around * .add(Employee.HOME_ADDRESS, addrEncoder); // Foreign key * * // Inline every employee in the department. * JconEncoder<Department> depEncoder = JsonEncoder.allOf(departments) * .putStreamer("employees", Department::employees, empEncoder); * * String json = depEncoder.apply(departments.findAny().get()); * } * * @param <ENTITY> entity type * * @author Emil Forslund * @since 2.1.0 */ public interface JsonEncoder<ENTITY> { /**************************************************************************/ /* Getters */ /**************************************************************************/ /** * Returns the manager for the entity type that this encoder works with. * * @return the manager */ Manager<ENTITY> getManager(); /**************************************************************************/ /* Field Putters */ /**************************************************************************/ /** * Include the specified field in the encoder. * * @param <D> the database type * @param <V> the java type * @param field the field type * @return a reference to this encoder */ <D, V> JsonEncoder<ENTITY> put(ReferenceField<ENTITY, D, V> field); /** * Include the specified field in the encoder. * * @param <D> the database type * @param field the field type * @return a reference to this encoder */ <D> JsonEncoder<ENTITY> putByte(ByteField<ENTITY, D> field); /** * Include the specified field in the encoder. * * @param <D> the database type * @param field the field type * @return a reference to this encoder */ <D> JsonEncoder<ENTITY> putShort(ShortField<ENTITY, D> field); /** * Include the specified field in the encoder. * * @param <D> the database type * @param field the field type * @return a reference to this encoder */ <D> JsonEncoder<ENTITY> putInt(IntField<ENTITY, D> field); /** * Include the specified field in the encoder. * * @param <D> the database type * @param field the field type * @return a reference to this encoder */ <D> JsonEncoder<ENTITY> putLong(LongField<ENTITY, D> field); /** * Include the specified field in the encoder. * * @param <D> the database type * @param field the field type * @return a reference to this encoder */ <D> JsonEncoder<ENTITY> putFloat(FloatField<ENTITY, D> field); /** * Include the specified field in the encoder. * * @param <D> the database type * @param field the field type * @return a reference to this encoder */ <D> JsonEncoder<ENTITY> putDouble(DoubleField<ENTITY, D> field); /** * Include the specified field in the encoder. * * @param <D> the database type * @param field the field type * @return a reference to this encoder */ <D> JsonEncoder<ENTITY> putChar(CharField<ENTITY, D> field); /** * Include the specified field in the encoder. * * @param <D> the database type * @param field the field type * @return a reference to this encoder */ <D> JsonEncoder<ENTITY> putBoolean(BooleanField<ENTITY, D> field); /**************************************************************************/ /* Put Labels with Getters */ /**************************************************************************/ /** * Include the specified label in the encoder, using the specified getter to * determine its value. If the label is the same as an existing field name, * it will be replaced. * * @param <T> the reference type of the field * @param label the label to store it under * @param getter how to retreive the value to store * @return a reference to this encoder */ <T> JsonEncoder<ENTITY> put(String label, ReferenceGetter<ENTITY, T> getter); /** * Include the specified label in the encoder, using the specified getter to * determine its value. If the label is the same as an existing field name, * it will be replaced. * * @param label the label to store it under * @param getter how to retreive the value to store * @return a reference to this encoder */ JsonEncoder<ENTITY> putByte(String label, ByteGetter<ENTITY> getter); /** * Include the specified label in the encoder, using the specified getter to * determine its value. If the label is the same as an existing field name, * it will be replaced. * * @param label the label to store it under * @param getter how to retreive the value to store * @return a reference to this encoder */ JsonEncoder<ENTITY> putShort(String label, ShortGetter<ENTITY> getter); /** * Include the specified label in the encoder, using the specified getter to * determine its value. If the label is the same as an existing field name, * it will be replaced. * * @param label the label to store it under * @param getter how to retreive the value to store * @return a reference to this encoder */ JsonEncoder<ENTITY> putInt(String label, IntGetter<ENTITY> getter); /** * Include the specified label in the encoder, using the specified getter to * determine its value. If the label is the same as an existing field name, * it will be replaced. * * @param label the label to store it under * @param getter how to retreive the value to store * @return a reference to this encoder */ JsonEncoder<ENTITY> putLong(String label, LongGetter<ENTITY> getter); /** * Include the specified label in the encoder, using the specified getter to * determine its value. If the label is the same as an existing field name, * it will be replaced. * * @param label the label to store it under * @param getter how to retreive the value to store * @return a reference to this encoder */ JsonEncoder<ENTITY> putFloat(String label, FloatGetter<ENTITY> getter); /** * Include the specified label in the encoder, using the specified getter to * determine its value. If the label is the same as an existing field name, * it will be replaced. * * @param label the label to store it under * @param getter how to retreive the value to store * @return a reference to this encoder */ JsonEncoder<ENTITY> putDouble(String label, DoubleGetter<ENTITY> getter); /** * Include the specified label in the encoder, using the specified getter to * determine its value. If the label is the same as an existing field name, * it will be replaced. * * @param label the label to store it under * @param getter how to retreive the value to store * @return a reference to this encoder */ JsonEncoder<ENTITY> putChar(String label, CharGetter<ENTITY> getter); /** * Include the specified label in the encoder, using the specified getter to * determine its value. If the label is the same as an existing field name, * it will be replaced. * * @param label the label to store it under * @param getter how to retreive the value to store * @return a reference to this encoder */ JsonEncoder<ENTITY> putBoolean(String label, BooleanGetter<ENTITY> getter); /**************************************************************************/ /* Put Fields with Finders */ /**************************************************************************/ /** * Include the specified foreign key field in the encoder, embedding foreign * entities as inner JSON objects. * * @param <FK_ENTITY> the type of the foreign entity * @param <FIELD> the type of the field itself * * @param field the foreign key field * @param encoder encoder for the foreign entity * @return a reference to this encoder */ <FK_ENTITY, FIELD extends Field<ENTITY> & HasFinder<ENTITY, FK_ENTITY>> JsonEncoder<ENTITY> put(FIELD field, JsonEncoder<FK_ENTITY> encoder); /**************************************************************************/ /* Put Labels with Finders */ /**************************************************************************/ /** * Include the specified label in this encoder, populating it with an inner * JSON object representing a foreign entity. This can be used to create * custom object hierarchies. If the specified label already exists in the * encoder, it will be replaced. * * @param <FK_ENTITY> the foreign entity type * @param label the label to store it under * @param finder a finder method used to retrieve the foreign entity * @param fkEncoder an encoder for the foreign entity type * @return a reference to this encoder */ <FK_ENTITY> JsonEncoder<ENTITY> put( String label, FindFrom<ENTITY, FK_ENTITY> finder, JsonEncoder<FK_ENTITY> fkEncoder); /**************************************************************************/ /* Put Labels with Find Many */ /**************************************************************************/ /** * Include the specified label in this encoder, using it to store an array * of inner JSON objects determined by applying the specified streaming * method. If the specified label already exists in the encoder, it will be * replaced. * * @param <FK_ENTITY> the foreign entity type * @param label the label to store it under * @param streamer the streaming method to use * @param fkEncoder encoder for the foreign entity type * @return a reference to this encoder */ <FK_ENTITY> JsonEncoder<ENTITY> putStreamer( String label, Function<ENTITY, Stream<FK_ENTITY>> streamer, JsonEncoder<FK_ENTITY> fkEncoder); /** * Include the specified label in this encoder, using it to store an array * of inner JSON objects determined by applying the specified streaming * method. If the specified label already exists in the encoder, it will be * replaced. * * @param <FK_ENTITY> the foreign entity type * @param label the label to store it under * @param streamer the streaming method to use * @param fkEncoder encoder for the foreign entity type * @return a reference to this encoder */ <FK_ENTITY> JsonEncoder<ENTITY> putStreamer( String label, Function<ENTITY, Stream<FK_ENTITY>> streamer, Function<FK_ENTITY, String> fkEncoder); /**************************************************************************/ /* Remove by Label */ /**************************************************************************/ /** * Exclude the specified label from this encoder. If the label was not * already included, this method will have no effect. * <p> * This method can be used to remove fields as well if the correct field * name is specified. * * @param label the label to remove * @return a reference to this encoder */ JsonEncoder<ENTITY> remove(String label); /** * Exclude the specified field from this encoder. If the field was not * already included in the encoder, this method has no effect. * * @param field the field to remove * @return a reference to this encoder */ JsonEncoder<ENTITY> remove(Field<ENTITY> field); /**************************************************************************/ /* Encode */ /**************************************************************************/ /** * Encodes the specified entity using this encoder. * * @param entity the entity to encode * @return the JSON encoded string */ String apply(ENTITY entity); /** * Returns a collector that will use this encoder to encode any incoming * entities. * * @return the collector */ JsonCollector<ENTITY> collector(); }