generators.PhpGenerator.java Source code

Java tutorial

Introduction

Here is the source code for generators.PhpGenerator.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package generators;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import generators.php.ExpressionGenerator;
import java.util.List;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import util.StringUtils;
import vality.Entity;
import vality.EquationSolver;
import vality.expression.Expressable;
import vality.Field;
import vality.expression.FieldExpression;
import vality.expression.OperatorExpression;
import vality.State;
import vality.UnsolvableException;

public class PhpGenerator implements Generator {

    private Entity entity;

    public PhpGenerator(Entity entity) {
        this.entity = entity;
    }

    @Override
    public String generateCode() {
        String text = "<?php\n" + "class " + entity.getName() + " {\n";

        text += generateConstructor();
        text += generateFieldList();
        text += generateCheckFunction();
        text += generateEvalFunction();

        text += "}\n";
        text += "?>\n";
        return text;
    }

    private String generateCheckFunction() {
        String text = "";
        text += "    public function check($fromState, $toState) {\n";
        text += "        $ok = true;\n";
        for (State s : entity.getStates().values()) {
            text += "        if ($toState === '" + s.getToName() + "'"
                    + (s.getFromName() != null ? " && $fromState === '" + s.getFromName() + "'" : "") + ") {\n";
            text += generateStateChecks(s);
            text += "        }\n";
        }
        text += "        return $ok;\n";
        text += "    }\n";
        return text;
    }

    private String generateStateChecks(State s) {
        String text = "";
        for (Expressable e : s.getConditions()) {
            text += "        $ok &= (" + (new generators.php.ExpressionGenerator(e)) + ");\n";
        }
        return text;
    }

    private String generateConstructor() {
        String text = "    public function __construct(";
        // parameter list
        text += Joiner.on(", ")
                .join(Lists.transform(new ArrayList<>(entity.getFields().values()), new Function<Field, String>() {
                    @Override
                    public String apply(Field f) {
                        return "$" + f.getName();
                    }
                }));
        text += ") {\n";

        // assignments
        text += Joiner.on("\n")
                .join(Lists.transform(new ArrayList<>(entity.getFields().values()), new Function<Field, String>() {
                    @Override
                    public String apply(Field f) {
                        return "        $this->" + f.getName() + " = $" + f.getName() + ";";
                    }
                }));
        text += "\n    }\n";
        return text;

    }

    private String generateFieldList() {
        String text = "";

        for (Field f : entity.getFields().values()) {
            text += "    private $" + f.getName() + ";\n";
            text += "    public function get" + StringUtils.toUpperFirstChar(f.getName()) + "() {\n";
            text += "        return $this->" + f.getName() + ";\n";
            text += "    }\n";
            text += "    public function set" + StringUtils.toUpperFirstChar(f.getName()) + "($" + f.getName()
                    + ") {\n";
            text += "        $this->" + f.getName() + " = $" + f.getName() + ";\n";
            text += "    }\n";
        }
        return text;
    }

    private String getter(String name) {
        return "$this->get" + StringUtils.toUpperFirstChar(name) + "()";
    }

    private String getter(Field field) {
        return getter(field.getName());
    }

    private String setter(String name, String code) {
        return "$this->set" + StringUtils.toUpperFirstChar(name) + "(" + code + ")";
    }

    private String getter(Field field, String code) {
        return setter(field.getName(), code);
    }

    /*
     * strategy in target
     * 
    - for all unset variables
        - find equation that assigns to it from already set variables
        - run it
    - are there still unset variables? yes, create diagnostic message
    - are there still equations? yes, create diagnostic message
    * 
     * strategy in creation
     *   - for all existing combinations, 
     * 
     *  
     */
    private String generateEvalFunction() {
        String text = "";

        List<State> states = new ArrayList<>(entity.getStates().values());

        text += "    public function evaluate($fromState, $toState) {\n";
        for (State state : states) {
            text += "        if ($toState === '" + state.getToName() + "'"
                    + (state.getFromName() != null ? " && $fromState === '" + state.getFromName() + "'" : "")
                    + ") {\n";
            text += "            for ($i = 0; $i < "
                    + (state.getConditions().size() * entity.getFields().values().size()) + "; ++$i) {\n";

            for (Field toField : entity.getFields().values()) {
                for (Expressable expr : state.getConditions()) {
                    if (expr.findFieldExpression(new FieldExpression(toField)).size() > 0) {
                        text += "                // " + expr + "\n";
                        text += "                if (" + getter(toField) + " === null";
                        for (Field exprField : expr.findAllFields()) {
                            if (!exprField.equals(toField))
                                text += " && " + getter(exprField) + " !== null";
                        }
                        text += ")\n";
                        text += "                    $this->_" + state.getToName() + "_" + state.getFromName()
                                + "_calculate_" + toField.getName() + "_";
                        for (Field exprField : expr.findAllFields()) {
                            if (!exprField.equals(toField))
                                text += "_" + exprField.getName();
                        }
                        text += "();\n";
                    }
                }
            }
            text += "            }\n";
            text += "        }\n";
            text += "    }\n";
        }

        for (State state : states) {
            for (Field toField : entity.getFields().values()) {
                for (Expressable expr : state.getConditions()) {
                    OperatorExpression oe = (OperatorExpression) expr;
                    if (expr.findFieldExpression(new FieldExpression(toField)).size() > 0) {
                        text += "        // " + expr + "\n";
                        try {
                            EquationSolver equationSolver = new EquationSolver(expr);
                            List<Expressable> otherConditions = state.getOtherConditions(expr);
                            try {
                                OperatorExpression equ = (OperatorExpression) equationSolver
                                        .solve(new FieldExpression(toField));
                                text += createCalculateFunction(state, equ, toField);
                            } catch (UnsolvableException ue) {
                                text += "       // ---> unsolvable for " + toField.getName() + "\n";
                            }
                            /*
                            for (Expressable otherEx : equationSolver.replaceAll(otherConditions)) {
                            EquationSolver otherEquSolver = new EquationSolver(otherEx);
                            for (Field otherToField : otherEx.findAllFields()) {
                                try {
                                    OperatorExpression otherEqu = (OperatorExpression) otherEquSolver.solve(new FieldExpression(otherToField));
                                    text += createCalculateFunction(otherEqu, otherToField);
                                } catch (UnsolvableException ue) {
                                    text += "       // ---> unsolvable for " + otherToField.getName() + "\n";
                                }
                            }
                            }
                            * */
                        } catch (Exception ex) {
                            Logger.getLogger(PhpGenerator.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }
        }
        return text;
    }

    private String createCalculateFunction(State state, OperatorExpression equ, Field toField) {
        String text = "";
        text += "    // -> " + equ + "\n";
        text += "    private function _" + state.getToName() + "_" + state.getFromName() + "_calculate_"
                + toField.getName() + "__";
        text += Joiner.on("_").join(Lists.transform(equ.getRhs().findAllFields(), new Function<Field, String>() {

            @Override
            public String apply(Field f) {
                return f.getName();
            }
        }));
        text += "() {\n";
        text += "       " + setter(toField.getName(), new ExpressionGenerator(equ.getRhs()).toString()) + ";\n";
        text += "    }\n";
        return text;
    }
}