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

dk.nversion.copybook.serializers.FullMapper Maven / Gradle / Ivy

Go to download

CopyBook serializer and deserializer for Java where CopyBook lines are used to annotate a normal Java class

The newest version!
/*
 * Copyright (c) 2015. Troels Liebe Bentsen 
 * Licensed under the MIT license (LICENSE.txt)
 */

package dk.nversion.copybook.serializers;

import dk.nversion.copybook.exceptions.CopyBookException;

import java.lang.reflect.Array;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FullMapper extends CopyBookMapperBase {

    public  byte[] serialize(T obj) {
        ByteBuffer buffer = ByteBuffer.wrap(new byte[this.maxRecordSize]);
        writeFieldsToBuffer(this.fields, buffer, obj);
        byte[] result = new byte[buffer.position()];
        System.arraycopy(buffer.array(), 0, result, 0, buffer.position()); // Copy bytes to result array
        return result;
    }

    private  void writeFieldsToBuffer(List fields, ByteBuffer buffer, T rootObj) {
        for(CopyBookField field : fields) {
            if(field.isArray()) {
                Object array = field.getObject(rootObj);
                int arraySize = Math.max(array != null ? Array.getLength(array) : 0, field.getMinOccurs());
                if(field.hasSubCopyBookFields()) {
                    // Complex array types fx. Request[]
                    for (int i = 0; i < arraySize; i++) {
                        writeFieldsToBuffer(field.getSubCopyBookFields(), buffer, field.getObject(rootObj, i));
                    }

                } else {
                    // Simple array types, fx. int[]
                    for (int i = 0; i < arraySize; i++) {
                        buffer.put(field.getBytes(rootObj, array, i, true));
                    }
                }

            } else if(field.hasSubCopyBookFields()) {
                // Complex type fx, Request
                writeFieldsToBuffer(field.getSubCopyBookFields(), buffer, field.getObject(rootObj));

            } else {
                // Simple type fx. int
                byte[] bytes = field.getBytes(rootObj, true);
                if(bytes != null) {
                    buffer.put(bytes);

                } else if(rootObj == null) {
                    throw new CopyBookException("Root object for field '" + field.getFieldName() + "' is null and the TypeConverter '" + field.getConverter().getClass().getSimpleName() + "' does not support null filler");

                } else {
                    throw new CopyBookException("TypeConverter " + field.getConverter().getClass().getSimpleName() + " returned null for field " + field.getFieldName());
                }
            }
        }
    }

    public  T deserialize(byte[] bytes, Class type) {
        try {
            T obj = type.newInstance();
            ByteBuffer buffer = ByteBuffer.wrap(bytes);
            readFieldsFromBuffer(this.fields, buffer, obj, "", new HashMap<>());
            return obj;

        } catch (IllegalAccessException | InstantiationException e) {
            throw new CopyBookException("Failed to create new object", e);
        }
    }

    private void readFieldsFromBuffer(List fields, ByteBuffer buffer, Object obj, String name, Map counters) {
        for(CopyBookField field : fields) {
            String fieldName = name + "." + field.getFieldName();
            if(field.isArray()) {
                int arraySize = field.getMaxOccurs();

                // Support field ending in _count as counter keys
                if(counters.containsKey(fieldName + "_count")) {
                    arraySize = counters.get(fieldName + "_count");

                // Support depending on cobol syntax for counters
                } else if(counters.containsKey(field.getCounterKey())) {
                    arraySize = counters.get(field.getCounterKey());
                }

                Object array = field.createArrayObject(obj, arraySize);
                if(field.hasSubCopyBookFields()) {
                    // Complex array types fx. Request[]
                    for (int i = 0; i < arraySize; i++) {
                        readFieldsFromBuffer(field.getSubCopyBookFields(), buffer, field.createObject(array, i), fieldName, counters);
                    }

                    // Move position in buffer to next location with data
                    if(field.getMinOccurs() > arraySize) {
                        int skipSize = (field.getMinOccurs() - arraySize) * field.getRecursiveMinSize() / field.getMinOccurs();
                        buffer.position(buffer.position() + skipSize);
                    }

                } else {
                    // Simple array types, fx. int[]
                    for (int i = 0; i < arraySize; i++) {
                        field.setBytes(array, i, buffer, true);
                    }

                    // Move position in buffer to next location with data
                    if(field.getMinOccurs() > arraySize) {
                        buffer.position(buffer.position() + (field.getMinOccurs() - arraySize) * field.getSize());
                    }
                }

            } else if(field.hasSubCopyBookFields()) {
                // Complex type fx, Request
                readFieldsFromBuffer(field.getSubCopyBookFields(), buffer, field.createObject(obj), fieldName, counters);

            } else {
                // Simple type fx. int, String or types we support with TypeConverters
                Object value = field.setBytes(obj, buffer, true);

                // Save field name and counter value for later use
                if(value != null) {
                    if (field.getField().getType().equals(Integer.TYPE) && fieldName.endsWith("_count")) {
                        counters.put(fieldName, (Integer) value);
                    }
                    if (field.isCounter()) {
                        counters.put(field.getName(), (Integer)value);
                    }
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy