Package org.milyn.ejc

Source Code of org.milyn.ejc.WriteMethod

/*
* Milyn - Copyright (C) 2006 - 2010
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License (version 2.1) as published by the Free Software
* Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU Lesser General Public License for more details:
* http://www.gnu.org/licenses/lgpl.txt
*/
package org.milyn.ejc;

import org.milyn.config.Configurable;
import org.milyn.edisax.model.internal.Component;
import org.milyn.edisax.model.internal.ContainerNode;
import org.milyn.edisax.model.internal.DelimiterType;
import org.milyn.edisax.model.internal.Delimiters;
import org.milyn.edisax.model.internal.Field;
import org.milyn.edisax.model.internal.MappingNode;
import org.milyn.edisax.model.internal.Segment;
import org.milyn.edisax.model.internal.SegmentGroup;
import org.milyn.edisax.model.internal.ValueNode;
import org.milyn.edisax.util.EDIUtils;
import org.milyn.javabean.DataDecoder;
import org.milyn.javabean.DataEncoder;
import org.milyn.javabean.decoders.DABigDecimalDecoder;
import org.milyn.javabean.pojogen.JClass;
import org.milyn.javabean.pojogen.JMethod;
import org.milyn.javabean.pojogen.JNamedType;
import org.milyn.javabean.pojogen.JType;
import org.milyn.smooks.edi.EDIWritable;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.*;

/**
* EDIWritable bean serialization class.
*
* @author <a href="mailto:tom.fennelly@gmail.com">tom.fennelly@gmail.com</a>
*/
class WriteMethod extends JMethod {

    private JClass jClass;
    private MappingNode mappingNode;
    private boolean appendFlush = false;
    private boolean trunacate;
    private DelimiterType terminatingDelimiter;

    WriteMethod(JClass jClass, MappingNode mappingNode) {
        super("write");
        addParameter(new JType(Writer.class), "writer");
        addParameter(new JType(Delimiters.class), "delimiters");
        getExceptions().add(new JType(IOException.class));
        jClass.getImplementTypes().add(new JType(EDIWritable.class));
        jClass.getMethods().add(this);
        this.jClass = jClass;
        this.mappingNode = mappingNode;
        this.trunacate = (mappingNode instanceof ContainerNode && ((ContainerNode)mappingNode).isTruncatable());

        if(trunacate) {
            jClass.getRawImports().add(new JType(StringWriter.class));
            jClass.getRawImports().add(new JType(List.class));
            jClass.getRawImports().add(new JType(ArrayList.class));
            jClass.getRawImports().add(new JType(EDIUtils.class));
            jClass.getRawImports().add(new JType(DelimiterType.class));
        }
    }

    public void writeObject(JNamedType property, DelimiterType delimiterType, BindingConfig bindingConfig, MappingNode mappingNode) {
        writeDelimiter(delimiterType);
        writeObject(property, bindingConfig, mappingNode);
    }

    public void writeObject(JNamedType property, BindingConfig bindingConfig, MappingNode mappingNode) {
        appendToBody("\n        if(" + property.getName() + " != null) {");
        if(mappingNode instanceof Segment) {
            if(!((Segment) mappingNode).getFields().isEmpty() && (bindingConfig.getParent() == null || bodyLength() > 0)) {
                appendToBody("\n            nodeWriter.write(\"" + ((Segment)mappingNode).getSegcode() + "\");");
                appendToBody("\n            nodeWriter.write(delimiters.getField());");
            }
        }
        appendToBody("\n            " + property.getName() + ".write(nodeWriter, delimiters);");
        if(trunacate) {
            appendToBody("\n            nodeTokens.add(nodeWriter.toString());");
            appendToBody("\n            ((StringWriter)nodeWriter).getBuffer().setLength(0);");
        }
        appendToBody("\n        }");
    }

    public void writeValue(JNamedType property, ValueNode modelNode, DelimiterType delimiterType) {
        writeDelimiter(delimiterType);
        writeValue(property, modelNode);
    }

    public void writeValue(JNamedType property, ValueNode modelNode) {
        appendToBody("\n        if(" + property.getName() + " != null) {");

        DataDecoder dataDecoder = modelNode.getDecoder();
        if(dataDecoder instanceof DataEncoder) {
            String encoderName = property.getName() + "Encoder";
            Class<? extends DataDecoder> decoderClass = dataDecoder.getClass();

            // Add the property for the encoder instance...
            jClass.getProperties().add(new JNamedType(new JType(decoderClass), encoderName));

            // Create the encoder in the constructor...
            JMethod defaultConstructor = jClass.getDefaultConstructor();
            defaultConstructor.appendToBody("\n        " + encoderName + " = new " + decoderClass.getSimpleName() + "();");

            // Configure the encoder in the constructor (if needed)....
            if(dataDecoder instanceof Configurable) {
                Properties configuration = ((Configurable) dataDecoder).getConfiguration();

                if(configuration != null) {
                    Set<Map.Entry<Object, Object>> encoderConfig = configuration.entrySet();
                    String encoderPropertiesName = encoderName + "Properties";

                    jClass.getRawImports().add(new JType(Properties.class));
                    defaultConstructor.appendToBody("\n        Properties " + encoderPropertiesName + " = new Properties();");
                    for(Map.Entry<Object, Object> entry : encoderConfig) {
                        defaultConstructor.appendToBody("\n        " + encoderPropertiesName + ".setProperty(\"" + entry.getKey() + "\", \"" + entry.getValue() + "\");");
                    }
                    defaultConstructor.appendToBody("\n        " + encoderName + ".setConfiguration(" + encoderPropertiesName + ");");
                }
            }

            // Add the encoder encode instruction to te write method...
            if (decoderClass == DABigDecimalDecoder.class){
                appendToBody("\n            nodeWriter.write(delimiters.escape(" + encoderName + ".encode(" + property.getName() + ", delimiters)));");
            } else {
                appendToBody("\n            nodeWriter.write(delimiters.escape(" + encoderName + ".encode(" + property.getName() + ")));");
            }
        } else {
            appendToBody("\n            nodeWriter.write(delimiters.escape(" + property.getName() + ".toString()));");
        }

        if(trunacate) {
            appendToBody("\n            nodeTokens.add(nodeWriter.toString());");
            appendToBody("\n            ((StringWriter)nodeWriter).getBuffer().setLength(0);");
        }

        appendToBody("\n        }");
    }

    public void writeSegmentCollection(JNamedType property, SegmentGroup segmentGroup) {
        appendToBody("\n        if(" + property.getName() + " != null && !" + property.getName() + ".isEmpty()) {");
        appendToBody("\n            for(" + property.getType().getGenericType().getSimpleName() + " " + property.getName() + "Inst : " + property.getName() + ") {");

        if(segmentGroup instanceof Segment && !((Segment) segmentGroup).getFields().isEmpty()) {
            appendToBody("\n                nodeWriter.write(\"" + segmentGroup.getSegcode() + "\");");
            appendToBody("\n                nodeWriter.write(delimiters.getField());");
            if(trunacate) {
                appendToBody("\n                nodeTokens.add(nodeWriter.toString());");
                appendToBody("\n                ((StringWriter)nodeWriter).getBuffer().setLength(0);");
            }
        }

        appendToBody("\n                " + property.getName() + "Inst.write(nodeWriter, delimiters);");
        appendToBody("\n            }");
        appendToBody("\n        }");
    }

    @Override
    public String getBody() {
        StringBuilder builder = new StringBuilder();

        if(trunacate) {
            builder.append("\n        Writer nodeWriter = new StringWriter();\n");
            builder.append("\n        List<String> nodeTokens = new ArrayList<String>();\n");
        } else {
            builder.append("\n        Writer nodeWriter = writer;\n");
        }

        builder.append(super.getBody());

        if(trunacate) {
            builder.append("\n        nodeTokens.add(nodeWriter.toString());");
            if(mappingNode instanceof Segment) {
                builder.append("\n        writer.write(EDIUtils.concatAndTruncate(nodeTokens, DelimiterType.FIELD, delimiters));");
            } else if(mappingNode instanceof Field) {
                builder.append("\n        writer.write(EDIUtils.concatAndTruncate(nodeTokens, DelimiterType.COMPONENT, delimiters));");
            } else if(mappingNode instanceof Component) {
                builder.append("\n        writer.write(EDIUtils.concatAndTruncate(nodeTokens, DelimiterType.SUBCOMPONENT, delimiters));");
            }
        }

        if(terminatingDelimiter != null) {
            writeDelimiter(terminatingDelimiter, "writer", builder);
        }
        if(appendFlush) {
            builder.append("\n        writer.flush();");
        }

        return builder.toString();
    }

    public void writeDelimiter(DelimiterType delimiterType) {
        writeDelimiter(delimiterType, "nodeWriter", getBodyBuilder());
    }

    private void writeDelimiter(DelimiterType delimiterType, String writerVariableName, StringBuilder builder) {
        if(bodyLength() == 0) {
            return;
        }

        switch (delimiterType) {
            case SEGMENT:
                builder.append("\n        " + writerVariableName + ".write(delimiters.getSegmentDelimiter());");
                break;
            case FIELD:
                builder.append("\n        " + writerVariableName + ".write(delimiters.getField());");
                break;
            case FIELD_REPEAT:
                builder.append("\n        " + writerVariableName + ".write(delimiters.getFieldRepeat());");
                break;
            case COMPONENT:
                builder.append("\n        " + writerVariableName + ".write(delimiters.getComponent());");
                break;
            case SUB_COMPONENT:
                builder.append("\n        " + writerVariableName + ".write(delimiters.getSubComponent());");
                break;
            case DECIMAL_SEPARATOR:
                builder.append("\n        " + writerVariableName + ".write(delimiters.getDecimalSeparator());");
                break;
            default:
                throw new UnsupportedOperationException("Unsupported '" + DelimiterType.class.getName() + "' enum conversion.  Enum '" + delimiterType + "' not specified in switch statement.");
        }
    }

    public void addFlush() {
        appendFlush = true;
    }

    public void addTerminatingDelimiter(DelimiterType delimiterType) {
        terminatingDelimiter = delimiterType;
    }
}
TOP

Related Classes of org.milyn.ejc.WriteMethod

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.