Package printer

Source Code of printer.AuxPrintUtil

package printer;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import speclistener.SpecBaseListener;
import symboltable.ASTNode;
import symboltable.Constructor;
import symboltable.ContainsProperties;
import symboltable.Entity;
import symboltable.EntityProperty;
import symboltable.EnumProperty;
import symboltable.ExistentialProperty;
import symboltable.IntProperty;
import symboltable.NodeProperty;
import symboltable.Property;
import symboltable.StringProperty;
import static util.PrintUtil.*;

/**
*
* @author kostasferles
*/


/*
* REVIEW: The way that the properties for every are being collected is a bit messy. See if there is an efficient way
* to collect all the properties for constructors and not have to traverse multiple times a node (just for coordinating the
* variables for the file predicates and IDB rules).
*/
public class PrintLogicQLImportCode extends SpecBaseListener {

    Path csvOutputDir;
   
    private static class Var{
       
        final String varNameStart;

        int index = 0;

        String varName;

        private void setVarName(){
            varName = varNameStart + index;
        }

        public Var(String varNameStart){
            this.varNameStart = varNameStart;
            setVarName();
        }

        public Var(String varNameStart, int index){
            this.varNameStart = varNameStart;
            this.index = index;
            setVarName();
        }

        public void newVar(){
            index++;
            setVarName();
        }
       
        public int getCurrIndex(){
            return this.index;
        }

        @Override
        public String toString(){
            return varName;
        }
    }
   
    private BufferedWriter output;
   
    private Var enumVar;

    private Var nodeVar;

    private Var filePredVar;

    private CodeForCons currConsCode;
   
    private Constructor currCons;
   
    private String currNodeVar;
   
    private Stack<CodeForCons> consSt = new Stack<>();
   
    private boolean visitingCons = false;
   
    private LogicQLPrinter currPrinter;
   
    private LogicQLPrinter tmpPrinterForNonFuncProp;
   
    private final String delim;
   
    private void handleProperty(Property prop, LogicQLCode codeForProp){
        Property.Type pType = prop.getType();
       
        if(visitingCons){
            currConsCode.addCodeForProperty(codeForProp);
           
            if(consSt.isEmpty())
                currPrinter.addProperty(codeForProp);
        }
        else{
            switch(pType){
                case ManyToOne:
                case OneToOne:
                    if(!prop.isOptional()){
                        currPrinter.addProperty(codeForProp);
                        break;
                    }
                case OneToMany:
                case ManyToMany:
                    LogicQLPrinter pr = new LogicQLPrinter(tmpPrinterForNonFuncProp, getFullPropertyName(prop));
                    pr.addProperty(codeForProp);
                    writeToFile(output, pr.print(false));
                    break;
                case Existential:
                    LogicQLPrinter ePr = new LogicQLPrinter(tmpPrinterForNonFuncProp, getFullPropertyName(prop));
                    ePr.addProperty(codeForProp);
                    writeToFile(output, ePr.print(false));
                    break;
                default :
                    assert false;
            }
        }
    }
   
    private void enterContainsProps(ContainsProperties conProp){
        nodeVar = new Var("n");
        enumVar = new Var("e");
        filePredVar = new Var("v");
           
        Constructor cons = conProp.getConstructor();
        currCons = cons;
        currNodeVar = nodeVar.toString();
        currConsCode = new CodeForCons(cons, conProp.getName(), currNodeVar);
        nodeVar.newVar();
        currPrinter = new LogicQLPrinter(this.csvOutputDir, conProp.getName(), currConsCode, delim);
       
        Iterator<Property> it = cons.getProperties();
       
        visitingCons = true;
        while(it.hasNext()){
            this.enterProperty(it.next());
        }
        visitingCons = false;
       
        tmpPrinterForNonFuncProp = new LogicQLPrinter(currPrinter, "");
    }
   
    private CodeForCons getConsCodeForContainsPropObjs(ContainsProperties rangeConProps){
        Constructor rangeCons = rangeConProps.getConstructor();
        String rangeNodeVar = nodeVar.toString();
        CodeForCons rangeConsCode = new CodeForCons(rangeCons, rangeConProps.getName(), rangeNodeVar);
        boolean prevVisitingCons = visitingCons;
        currConsCode = rangeConsCode;
        nodeVar.newVar();

        Iterator<Property> it = rangeCons.getProperties();
        visitingCons = true;
        while(it.hasNext()){
            this.enterProperty(it.next());
        }
        visitingCons = prevVisitingCons;
        currConsCode = consSt.pop();
       
        return rangeConsCode;
    }
   
    public PrintLogicQLImportCode(BufferedWriter output, Path csvOutDir, String delim){
        this.delim = delim;
        this.output = output;
        this.csvOutputDir = csvOutDir;
    }
   
    @Override
    public void enterAstNode(ASTNode node){
        enterContainsProps(node);
    }
   
    @Override
    public void enterEntity(Entity en){
        enterContainsProps(en);
    }
   
    @Override
    public void enterProperty(Property p){
        if(!this.visitingCons && this.currCons.containsProperty(p)) return;
        super.enterProperty(p);
    }
   
    @Override
    public void enterStringProperty(StringProperty prop){
        CodeForStringProperty codeForProp = new CodeForStringProperty(currNodeVar, prop, filePredVar.toString());
        filePredVar.newVar();
        handleProperty(prop, codeForProp);
    }
   
    @Override
    public void enterIntProperty(IntProperty prop){
        CodeForIntProperty codeForProp = new CodeForIntProperty(currNodeVar, prop, filePredVar.toString());
        filePredVar.newVar();
        handleProperty(prop, codeForProp);
    }
   
    @Override
    public void enterEnumProperty(EnumProperty enumProp){
        CodeForEnumProperty codeForEnum = new CodeForEnumProperty(currNodeVar, enumProp, filePredVar.toString(), enumVar.toString());
        filePredVar.newVar();
        enumVar.newVar();
        handleProperty(enumProp, codeForEnum);
    }
   
    @Override
    public void enterNodeProperty(NodeProperty nodeProp){
        consSt.push(currConsCode);
        ASTNode rangeNode = nodeProp.getRangeNode();
        CodeForCons rangeConsCode = getConsCodeForContainsPropObjs(rangeNode);
       
        CodeForContainsPropsObj codeForProp = new CodeForContainsPropsObj(currNodeVar, currConsCode, nodeProp, rangeConsCode);
        handleProperty(nodeProp, codeForProp);
    }
   
    @Override
    public void enterEntityProperty(EntityProperty enProp){
        consSt.push(currConsCode);
        Entity rangeEntity = enProp.getRangeEntity();
        CodeForCons rangeConsCode = getConsCodeForContainsPropObjs(rangeEntity);
       
        CodeForContainsPropsObj codeFroProp = new CodeForContainsPropsObj(currNodeVar, currConsCode, enProp, rangeConsCode);
        handleProperty(enProp, codeFroProp);
    }
   
    @Override
    public void enterExistentialProperty(ExistentialProperty ep){
        CodeForExistentialProperty code = new CodeForExistentialProperty(currNodeVar, ep);
        handleProperty(ep, code);
    }
   
    @Override
    public void exitAstNode(ASTNode node){
        assert consSt.isEmpty();
        writeToFile(output, currPrinter.print(true));
    }
   
    @Override
    public void exitEntity(Entity en){
        assert consSt.isEmpty();
        writeToFile(output, currPrinter.print(true));
    }
   
}

interface Constants{
    final String identForFilePred = "                       <- ";
   
    final String identation = "                          ";
   
    final String filePredTail = ":fPred";
   
    final String ordIndexVar = "i";
}

class AuxPrintUtil implements Constants{
   
    public static String getPropertyToString(Property p, String var1, String var2){
        StringBuilder rv = new StringBuilder("+");
        String propName = getFullPropertyName(p);
        rv.append(propName);
        switch(p.getType()){
            case OneToOne:
            case ManyToOne:
                rv.append("(").
                   append(var1).
                   append(",").
                   append(var2).append(")");
                break;
            case OneToMany:
                if(!p.isOrdered()){
                    rv.append("(").
                       append(var2).
                       append(",").
                       append(var1).
                       append(")");
                }
                else{
                    rv.append("(").
                       append(var2).
                       append(",").
                       append(ordIndexVar).
                       append(",").
                       append(var1).append(")");
                }
                break;
            case ManyToMany:
                if(!p.isOrdered()){
                    rv.append("(").
                       append(var1).
                       append(",").
                       append(var2).
                       append(")");
                }
                else{
                    rv.append("(").
                       append(var1).
                       append(",").
                       append(ordIndexVar).
                       append(",").
                       append(var2).append(")");
                }
                break;
        }
       
        return rv.toString();
    }
   
    private static FileSystem fSystem = FileSystems.getDefault();
   
    public static String getLangDirectives(Path csvOutDir, String propName, String delim){
        StringBuilder rv = new StringBuilder();
        String filePredName = getFilePredName(propName);
        String fileName = csvOutDir.toString() + "/" + propName + ".csv";
        Path p = fSystem.getPath(fileName);
        if(!Files.exists(p)){
            try{
                Files.createFile(p);
            }catch(IOException er){
                System.err.println("failed to create csv file " + fileName);
                System.err.println("reason: " + er.getMessage());
            }
        }
        rv.append("lang:physical:filePath[`").
           append(filePredName).
           append("] = ").
           append(quote(fileName)).
           append(".\n").
           append("lang:physical:delimiter[`").
           append(filePredName).
           append("] = ").
           append(quote(delim)).
           append(".\nlang:physical:hasColumnNames[`").
           append(filePredName).
           append("] = false.\n");
       
        return rv.toString();
    }
   
    public static String getOrderedTail(Property prop){
        return (prop.isOrdered() ? ",int(" + ordIndexVar + ")" : "");
    }
   
    public static String getOrderedHead(Property prop){
        return (prop.isOrdered() ? "," + ordIndexVar : "");
    }
   
    public static String getFilePredName(String propName){
        return "_" + propName + filePredTail;
    }
}

class LogicQLPrinter implements Constants{
   
    private String cachedFilePredHead;
   
    private String cachedFilePredBody;
   
    private final String delim;
   
    private String relName;
   
    private CodeForCons cons;
   
    private List<LogicQLCode> functionalProps = new ArrayList<>();
   
    private Path csvOutDir;
   
    public LogicQLPrinter(Path csvDir, String relName, CodeForCons cons, String delim){
        this.cons = cons;
        this.relName = relName;
        this.delim = delim;
        this.csvOutDir = csvDir;
    }
   
    public LogicQLPrinter(LogicQLPrinter n, String withName){
        this.cons = n.cons;
        this.relName = withName;
        this.delim = n.delim;
        this.csvOutDir = n.csvOutDir;
        this.functionalProps = new ArrayList<>(n.functionalProps);
    }
   
    public void addProperty(LogicQLCode codeForFuncProp){
        functionalProps.add(codeForFuncProp);
    }
   
    private String printFilePredHead(){
        if(cachedFilePredHead == null){
            int funcPredSiz = functionalProps.size();
            assert funcPredSiz > 0;
           
            StringBuilder rv = new StringBuilder();
           
            rv.append(AuxPrintUtil.getFilePredName(relName)).
               append("(");
           
            rv.append(functionalProps.get(0).getFilePredVars());
           
            for(int i = 1 ; i < funcPredSiz ; i++){
                String code = functionalProps.get(i).getFilePredVars();
                rv.append(code.equals("") ? "" : ",").append(code);
            }
           
            rv.append(")");
           
            cachedFilePredHead = rv.toString();
        }
       
        return cachedFilePredHead;
    }
   
    private String printFilePredBody(){
        if(cachedFilePredBody == null){
            int funcPredSiz = functionalProps.size();
            assert  funcPredSiz > 0;
           
            StringBuilder rv = new StringBuilder(" -> ");
           
            rv.append(functionalProps.get(0).getFilePredBody());
            for(int i = 1 ; i < funcPredSiz ; i++){
                String code = functionalProps.get(i).getFilePredBody();
                rv.append(code.equals("") ? "" : ",").append(code);
            }
           
            cachedFilePredBody = rv.toString();
        }
       
        return cachedFilePredBody;
    }
   
    public String print(boolean printConsPorps){
        StringBuilder rv = new StringBuilder();
        StringBuilder tail = new StringBuilder();
       
        String filePredHead = printFilePredHead();
        String filePredBody = printFilePredBody();
       
        rv.append(filePredHead).
           append(filePredBody).
           append(".\n\n");
       
        rv.append(AuxPrintUtil.getLangDirectives(this.csvOutDir, relName, delim)).
           append("\n");
       
        rv.append(cons.getCodeForHead(true));
        if(printConsPorps){
            for(LogicQLCode code : functionalProps){
                boolean printCons = true;
                if(this.cons.containsProperty(code))
                    printCons = false;
                rv.append(",\n").append(code.getCodeForHead(printCons));
                String codeForBody = code.getCodeForBody();
                if(!codeForBody.equals(""))
                    tail.append(",\n").append(code.getCodeForBody());
            }
        }
        else{
            for(LogicQLCode code : functionalProps){
                if(!this.cons.containsProperty(code)){
                    rv.append(",\n").append(code.getCodeForHead(true));
                    String codeForBody = code.getCodeForBody();
                    if(!codeForBody.equals(""))
                        tail.append(",\n").append(code.getCodeForBody());
                }
            }
        }
       
        rv.append("\n").
           append(identForFilePred).
           append(filePredHead).
           append(tail).
           append(".\n\n");
       
        return rv.toString();
    }
   
}

abstract class LogicQLCode implements Constants{
   
    protected String nodeVar;
   
    public abstract String getFilePredVars();
   
    public abstract String getVarsForHead();
   
    public abstract String getFilePredBody();
   
    public abstract String getName();
   
    public abstract String getCodeForHead(boolean printCons);
   
    public abstract String getCodeForBody();
   
    public String getCodeForHeadCompl(){
        return "";
    }
   
    public LogicQLCode(String nodeVar){
        this.nodeVar = nodeVar;
    }

}

abstract class CodeForProperty extends LogicQLCode{
   
    protected Property prop;
   
    public CodeForProperty(String nodeVar, Property prop){
        super(nodeVar);
        this.prop = prop;
    }
   
    @Override
    public String getName(){
        return getFullPropertyName(prop);
    }
   
    @Override
    public String getCodeForBody(){
        return "";
    }
   
}

/*
* REVIEW: May it is possible to group up the primitive types class (string, int and maybe enum)
*/

class CodeForStringProperty extends CodeForProperty{

    private String filePredVarForString;
   
    public CodeForStringProperty(String nodeVar, StringProperty prop, String filePredVarForString) {
        super(nodeVar, prop);
        this.filePredVarForString = filePredVarForString;
    }

    @Override
    public String getFilePredVars() {
        return filePredVarForString;
    }

    @Override
    public String getVarsForHead() {
        return filePredVarForString + AuxPrintUtil.getOrderedHead(prop);
    }

    @Override
    public String getFilePredBody() {
        return "string(" + filePredVarForString + ")" + AuxPrintUtil.getOrderedTail(prop);
    }

    @Override
    public String getCodeForHead(boolean _) {
        return AuxPrintUtil.getPropertyToString(prop, nodeVar, filePredVarForString);
    }

}


class CodeForExistentialProperty extends CodeForProperty{
   
    public CodeForExistentialProperty(String nodeVar, ExistentialProperty ep){
        super(nodeVar, ep);
    }

    @Override
    public String getFilePredVars() {
        return "";
    }

    @Override
    public String getVarsForHead() {
        return "";
    }

    @Override
    public String getFilePredBody() {
        return "";
    }

    @Override
    public String getCodeForHead(boolean _) {
        StringBuilder rv = new StringBuilder("+");
        rv.append(getFullPropertyName(prop)).
           append("(").append(nodeVar).append(")");
        return rv.toString();
    }
}

class CodeForIntProperty extends CodeForProperty{
   
    private String filePredVarForInt;
   
    public CodeForIntProperty(String nodeVar, IntProperty prop, String filePredVarForString) {
        super(nodeVar, prop);
        this.filePredVarForInt = filePredVarForString;
    }

    @Override
    public String getFilePredVars() {
        return filePredVarForInt + AuxPrintUtil.getOrderedHead(prop);
    }

    @Override
    public String getVarsForHead() {
        return filePredVarForInt + AuxPrintUtil.getOrderedHead(prop);
    }

    @Override
    public String getFilePredBody() {
        return "int(" + filePredVarForInt + ")" + AuxPrintUtil.getOrderedTail(prop);
    }

    @Override
    public String getCodeForHead(boolean _) {
        return AuxPrintUtil.getPropertyToString(prop, nodeVar, filePredVarForInt);
    }
}

class CodeForEnumProperty extends CodeForProperty{
   
    private String filePredVarForEnumInt;
   
    private String enumVar;
   
    public CodeForEnumProperty(String nodeVar, EnumProperty prop, String filePredVarForEnumInt, String enumVar){
        super(nodeVar, prop);
        this.filePredVarForEnumInt = filePredVarForEnumInt;
        this.enumVar = enumVar;
    }

    @Override
    public String getFilePredVars() {
        return filePredVarForEnumInt + AuxPrintUtil.getOrderedHead(prop);
    }

    @Override
    public String getVarsForHead() {
        return enumVar + AuxPrintUtil.getOrderedHead(prop);
    }

    @Override
    public String getFilePredBody() {
        return "int(" + filePredVarForEnumInt + ")" + AuxPrintUtil.getOrderedTail(prop);
    }

    @Override
    public String getCodeForHead(boolean _) {
        return AuxPrintUtil.getPropertyToString(prop, nodeVar, enumVar);
    }
   
    @Override
    public String getCodeForBody() {
        StringBuilder rv = new StringBuilder();
        rv.append(CodeForEnumProperty.identation).
           append(((EnumProperty)prop).getEnumeration().getName()).
           append(":fromIndex[").
           append(filePredVarForEnumInt).
           append("] = ").
           append(enumVar);
        return rv.toString();
    }
   
   
   
}


class CodeForContainsPropsObj extends CodeForProperty{
   
    private CodeForCons thisCons;
   
    private CodeForCons rangeNodeCons;
   
    public CodeForContainsPropsObj(String varNode, CodeForCons thisCons, NodeProperty prop, CodeForCons rangeNodeCons){
        super(varNode, prop);
        this.rangeNodeCons = rangeNodeCons;
        this.thisCons = thisCons;
    }
   
    public CodeForContainsPropsObj(String varNode, CodeForCons thisCons, EntityProperty ep, CodeForCons rangeNodeCons){
        super(varNode, ep);
        this.rangeNodeCons = rangeNodeCons;
        this.thisCons = thisCons;
    }

    @Override
    public String getFilePredVars() {
        return rangeNodeCons.getFilePredVars() + AuxPrintUtil.getOrderedHead(prop);
    }

    @Override
    public String getVarsForHead() {
        return rangeNodeCons.nodeVar + AuxPrintUtil.getOrderedHead(prop);
    }

    @Override
    public String getFilePredBody() {
        return rangeNodeCons.getFilePredBody() + AuxPrintUtil.getOrderedTail(prop);
    }

    @Override
    public String getCodeForHead(boolean printCons) {
        String rangeConsStr = printCons ? rangeNodeCons.getCodeForHead(true) + ",\n" : "";
        return rangeConsStr + AuxPrintUtil.getPropertyToString(prop, nodeVar, rangeNodeCons.nodeVar);
    }
   
    @Override
    public String getCodeForHeadCompl(){
        return rangeNodeCons.getCodeForHeadCompl();
    }
}

class CodeForCons extends LogicQLCode{
   
    private String filePredVarsCached;
   
    private Constructor cons;
   
    private List<LogicQLCode> listOfPropCode = new ArrayList<>();
   
    private String typeToConstruct;
   
    public CodeForCons(Constructor cons, String typeToConstruct, String nodeVar){
        super(nodeVar);
        this.cons = cons;
        this.typeToConstruct = typeToConstruct;
    }
   
    public void addCodeForProperty(LogicQLCode code){
        listOfPropCode.add(code);
    }
   
    @Override
    public String getFilePredVars() {
        if(filePredVarsCached == null){
            int propSize = listOfPropCode.size();
            assert propSize > 0;

            StringBuilder rv = new StringBuilder();
            rv.append(listOfPropCode.get(0).getFilePredVars());
            for(int i = 1 ; i < propSize ; i++){
                String code = listOfPropCode.get(i).getFilePredVars();
                rv.append(code.equals("") ? "" : ",").append(code);
            }

            filePredVarsCached = rv.toString();
        }
        return filePredVarsCached;
    }
   
    @Override
    public String getVarsForHead(){
        return nodeVar;
    }

    @Override
    public String getFilePredBody() {
        int propSize = listOfPropCode.size();
        assert propSize > 0;
       
        StringBuilder rv = new StringBuilder();
        rv.append(listOfPropCode.get(0).getFilePredBody());
        for(int i = 1 ; i < propSize ; i++)
            rv.append(",").append(listOfPropCode.get(i).getFilePredBody());
       
        return rv.toString();
    }
   
    @Override
    public String getCodeForHead(boolean _){
        int propSz = this.listOfPropCode.size();
        assert propSz > 0;
        StringBuilder rv = new StringBuilder("+");
       
        rv.append(getName()).
           append("[").
           append(listOfPropCode.get(0).getVarsForHead());
       
        for(int i = 1 ; i < propSz ; ++i)
           rv.append(",").append(listOfPropCode.get(i).getVarsForHead());
       
        rv.append("] = ").
           append(nodeVar).
           append(",\n").
           append("+").
           append(typeToConstruct).
           append("(").
           append(nodeVar).
           append(")");
       
        for(LogicQLCode code : listOfPropCode){
            String complHead = code.getCodeForHeadCompl();
            if(!complHead.equals(""))
                rv.append(",\n").append(complHead);
        }
        return rv.toString();
    }
   
    @Override
    public String getCodeForHeadCompl(){
        return getCodeForHead(true);
    }
   
    @Override
    public String getCodeForBody(){
        StringBuilder rv = new StringBuilder();
       
        for(LogicQLCode code : listOfPropCode){
            String codeForBody = code.getCodeForBody();
            if(!codeForBody.equals(""))
                rv.append(",\n").append(identation).append(code.getCodeForBody());
        }
       
        return rv.toString();
    }

    @Override
    public String getName() {
        return cons.getParent().getName() + ":cons";
    }
   
    public boolean containsProperty(LogicQLCode code){
        return this.listOfPropCode.contains(code);
    }
   
}
TOP

Related Classes of printer.AuxPrintUtil

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.
Examples of symboltable.ASTNode">symboltable.ASTNode
  • symboltable.Constructor
  • symboltable.Entity
  • java.io.IOException
  • java.util.Random
  • 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.