Package com.envoisolutions.sxc.builder.impl

Source Code of com.envoisolutions.sxc.builder.impl.BuilderImpl

package com.envoisolutions.sxc.builder.impl;

import com.envoisolutions.sxc.Context;
import com.envoisolutions.sxc.Reader;
import com.envoisolutions.sxc.Writer;
import com.envoisolutions.sxc.builder.BuildException;
import com.envoisolutions.sxc.builder.Builder;
import com.envoisolutions.sxc.builder.ElementParserBuilder;
import com.envoisolutions.sxc.builder.ElementWriterBuilder;
import com.envoisolutions.sxc.compiler.Compiler;
import com.envoisolutions.sxc.compiler.JavacCompiler;
import com.envoisolutions.sxc.util.Util;
import com.sun.codemodel.CodeWriter;
import com.sun.codemodel.JClassAlreadyExistsException;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JMod;
import com.sun.codemodel.JClass;
import com.sun.codemodel.writer.FileCodeWriter;

import java.io.File;
import java.io.IOException;

public class BuilderImpl implements Builder {

    private ElementParserBuilderImpl parserBuilder;
    private File file;
    private BuildContext buildContext;
    private ElementWriterBuilderImpl writerBuilder;
    private Compiler compiler = new JavacCompiler();
    private String contextClassName;

    /**
     *
     * @param readerClassName
     *      Fully qualified class name of the reader to be generated.
     *      null to not generate the reader.
     * @param writerClassName
     *      Fully qualified class name of the writer to be generated.
     *      null to not generate the writer.
     * @param contextClassName
     *      Fully qualified class name of the {@link Context}-derived class to be generated.
     *      null to not generate one.
     */
    public BuilderImpl(String readerClassName, String writerClassName, String contextClassName) {
        this.buildContext = new BuildContext();
        if(readerClassName!=null)
            parserBuilder = new ElementParserBuilderImpl(buildContext,readerClassName);
        if(writerClassName!=null)
            writerBuilder = new ElementWriterBuilderImpl(buildContext,writerClassName);

        if(contextClassName!=null) {
            try {
                JDefinedClass cc = buildContext.getCodeModel()._class(contextClassName);
                cc.method(JMod.PUBLIC, Reader.class,"createReader")
                    .body()._return( parserBuilder!=null
                        ? JExpr._new(parserBuilder.getReaderClass())
                        : JExpr._null());
                cc.method(JMod.PUBLIC, Writer.class,"createWriter")
                    .body()._return( writerBuilder!=null
                        ? JExpr._new(writerBuilder.getWriterClass())
                        : JExpr._null());
            } catch (JClassAlreadyExistsException e) {
                throw new BuildException(e);
            }
        }
        this.contextClassName = contextClassName;
    }

    /**
     * Generates both reader and writer by using default names.
     */
    public BuilderImpl() {
        this("generated.sxc.Reader","generated.sxc.Writer","generated.sxc.Context");
    }

    public ElementParserBuilder getParserBuilder() {
        return parserBuilder;
    }

    public ElementWriterBuilder getWriterBuilder() {
        return writerBuilder;
    }

    public void setReaderBaseClass(Class<? extends Reader> c) {
        setReaderBaseClass(getCodeModel().ref(c));
    }

    public void setReaderBaseClass(JClass c) {
        parserBuilder.baseClass = c;
    }

    public JCodeModel getCodeModel() {
        return buildContext.getCodeModel();
    }

    public JMethod getParserConstructor() {
        return parserBuilder.constructor;
    }

    public void write(File dir) throws IOException, BuildException {
        this.file = dir;

        // file = new File(file, new Long(System.currentTimeMillis()).toString());
        file.mkdirs();

        write(new FileCodeWriter(file));
    }

    public void write(CodeWriter writer) throws IOException, BuildException {
        if(parserBuilder!=null)
            parserBuilder.write();
        if(writerBuilder!=null)
            writerBuilder.write();
       
        buildContext.getCodeModel().build(writer);
    }
   
    public Context compile() {
        boolean delete = true;
        File dir = null;
        if (file == null) {
            try {
                String cdir = System.getProperty("com.envoisolutions.sxc.output.directory");
               
                if (cdir == null) {
                    dir = File.createTempFile("compile", "");
                } else {
                    dir = new File(cdir);
                    delete = false;
                }

                dir.delete();
               
                dir.mkdirs();
                write(dir);
               
               
            } catch (IOException e) {
                throw new BuildException(e);
            }
        }
       
        ClassLoader cl = compiler.compile(file);

        // Only delete if the output directory hasn't been set
        if (delete && file == null) {
            Util.delete(dir);
        }

        // TODO: simply load the generated context class and get rid of CompiledContext
        return new CompiledContext(cl,
            parserBuilder!=null ? parserBuilder.readerClass.fullName() : null,
            writerBuilder!=null ? writerBuilder.getWriterClass().fullName() : null);
    }
   
    public Compiler getCompiler() {
        return compiler;
    }

    public void setCompiler(Compiler compiler) {
        this.compiler = compiler;
    }

   
}
TOP

Related Classes of com.envoisolutions.sxc.builder.impl.BuilderImpl

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.