xquery-engine / src / Main.java
Main.java
Raw
import main.expressions.ExpressionBuilder;
import main.expressions.JoinContainer;
import main.expressions.NodeContainer;
import main.expressions.Writer;
import main.parsers.XGrammarLexer;
import main.parsers.XGrammarParser;

import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.tree.ParseTree;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {

    private static boolean isValidPath(String path){
        Path pathCheck = Paths.get(path);
        return Files.exists(pathCheck);
    }
    public static void main(String[] args) throws ParserConfigurationException, TransformerException, IOException {

        /*
            / - Selects descendant from current node
            // - Selects any descendant node that matches from current node
         */

        // ./src/main/queries/outputs/output1.xml
        System.out.println(args[0]);
        if (args.length != 2 || !isValidPath(args[0])) {
            throw new IllegalArgumentException("Specify valid input and output files");
        }


        String inFileName = args[0];
        String outFileName = args[1];


        //System.out.println(Files.readAllBytes(Paths.get(inFileName)));
        String query = new String(Files.readAllBytes(Paths.get(inFileName)));


        // Rewriter
        final long startTime = System.currentTimeMillis();
        System.out.println("REWRITE RESULT: ");
        query = Writer.RewriteFullQuery(query);
        final long endTime = System.currentTimeMillis();
        System.out.println(query);
        System.out.println("**********************************************************");
        System.out.println("Total query rewrite execution time: " + (endTime - startTime) + " milliseconds");
        System.out.println("**********************************************************");



        // Query Execution
        final XGrammarLexer lexer = new XGrammarLexer(CharStreams.fromString(query));
        final CommonTokenStream tokens = new CommonTokenStream(lexer);
        final XGrammarParser parser = new XGrammarParser(tokens);

        final long runStartTime = System.currentTimeMillis();
        ParseTree tree = parser.prog();
        ExpressionBuilder visitor = new ExpressionBuilder();
        NodeContainer result = visitor.visit(tree);
        final long runEndTime = System.currentTimeMillis();
        System.out.println("**********************************************************");
        System.out.println("Total query runtime: " + (runEndTime - runStartTime) + " milliseconds");
        System.out.println("**********************************************************");
        //result.printElements();
        List<Node> resultNodes = result.validNodes;


        // Write output tree
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
        Document doc = docBuilder.newDocument();
        doc.setXmlStandalone(true);

        // System.out.println(resultNodes.size());

        if (resultNodes.size() == 1){
            doc.appendChild(doc.importNode(result.validNodes.get(0), true));
        } else{
            Node resultNode = doc.createElement("RESULT");
            // Add query result nodes to xml object
            for (Node node : resultNodes) {
                if (node != null) {
                    resultNode.appendChild(doc.importNode(node, true));
                }
            }
            doc.appendChild(resultNode);
        }

//        System.out.println(resultNodes.size());
//        System.out.println(resultNodes);



        // Generate output xml file
        Source xslt = new StreamSource(new File("src/main/resources/strip_whitespace.xslt"));
        TransformerFactory tfFactory = TransformerFactory.newInstance();
        Transformer transformer = tfFactory.newTransformer(xslt);
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
        DOMSource source = new DOMSource(doc);
        StringWriter writer = new StringWriter();
//        StreamResult streamResult = new StreamResult(writer);
        StreamResult streamResult = new StreamResult(new FileOutputStream(outFileName));
        transformer.transform(source, streamResult);
//        System.out.println(writer);
    }
}


/*
        query = "for $b in doc(\"input\")/book,\n" +
                "$a in doc(\"input\")/entry,\n" +
                "$tb in $b/title,\n" +
                "$ta in $a/title\n" +
                "where $tb eq $ta\n" +
                "return\n" +
                "<opening_tag>\n" +
                "{$a}\n" +
                "</opening_tag>";

        query = "for $b in doc(\"input\")/book,\n" +
                "$a in doc(\"input\")/entry,\n" +
                "$tb in $b/title,\n" +
                "$ta in $a/title\n" +
                "where $tb eq $ta\n" +
                "return\n" +
                "<book-with-prices>\n" +
                "{ $tb,\n" +
                "<price-review>{ $a/price//price }</price-review>,\n" +
                "<price>{ $b/price//price }</price> }\n" +
                "</book-with-prices>";

        query = "for $s in doc(\"j_caesar.xml\")//SPEAKER, $a in doc(\"j_caesar.xml\")//ACT,\n" +
                "\n" +
                "$sp in $a//SPEAKER, $stxt in $s/text()\n" +
                "\n" +
                "where $sp eq $s and $stxt = \"CAESAR\"\n" +
                "\n" +
                "return <act> { $a/TITLE/text()} </act>";


        query = "for $b1 in doc(\"input\")/book,\n" +
                "$aj in $b1/author/first/text(),\n" +
                "$a1 in $b1/author,\n" +
                "$af1 in $a1/first,\n" +
                "$al1 in $a1/last,\n" +
                "$b2 in doc(\"input\")/book,\n" +
                "$a21 in $b2/author,\n" +
                "$af21 in $a21/first,\n" +
                "$al21 in $a21/last,\n" +
                "$a22 in $b2/author,\n" +
                "$af22 in $a22/first,\n" +
                "$al22 in $a22/last,\n" +
                "$b3 in doc(\"input\")/book,\n" +
                "$a3 in $b3/author,\n" +
                "$af3 in $a3/first,\n" +
                "$al3 in $a3/last\n" +
                "where $aj eq \"John\" and\n" +
                "$a1 eq \"John\" and\n" +
                "$af21 eq $af1  and $al1 eq $al21 and\n" +
                "$af22 eq $af3 and $al22 eq $al3\n" +
                "return <triplet> {$b1, $b2, $b3} </triplet>";


        query = "for $b1 in doc(\"j_caesar.xml\")//PGROUP,\n" +
                "     $tb1 in $b1/PERSONA,\n" +
                "     $b2 in doc(\"j_caesar.xml\")//SPEECH,\n" +
                "     $tb2 in $b2/SPEAKER,\n" +
                "     $b3 in doc(\"j_caesar.xml\")//ACT,\n" +
                "     $tb3 in $b3//SPEAKER,\n" +
                "where $tb1 eq $tb3 and $tb2 eq $tb3\n" +
                "return <triplet>{$b1, $b2, $b3}</triplet>";
*/







//testing joinOrderings method
        /*
            //test case 1
            System.out.println("Join ordering: test case 1");
            ArrayList<ArrayList<Integer>> test = new ArrayList<>();
            test.add(new ArrayList<>(Arrays.asList(2,3)));
            test.add(new ArrayList<>(Arrays.asList(4,5)));
            test.add(new ArrayList<>(Arrays.asList(5,6)));
            test.add(new ArrayList<>(Arrays.asList(0,1)));
            test.add(new ArrayList<>(Arrays.asList(1,2)));
            test.add(new ArrayList<>(Arrays.asList(1,4)));
            Writer.determineJoinOrdering(test);
            System.out.println(Writer.joinOrderings);
        */

        /*
            //test case 2
            System.out.println("Join ordering: test case 2");
            ArrayList<ArrayList<Integer>> test2 = new ArrayList<>();
            test2.add(new ArrayList<>(Arrays.asList(2,3)));
            test2.add(new ArrayList<>(Arrays.asList(4,5)));
            test2.add(new ArrayList<>(Arrays.asList(7,8)));
            Writer.determineJoinOrdering(test2);
            System.out.println(Writer.joinOrderings);
         */

        /*
            //test case 3
            ArrayList<ArrayList<Integer>> test3 = new ArrayList<>();
            test3.add(new ArrayList<>(Arrays.asList(7,8)));
            test3.add(new ArrayList<>(Arrays.asList(9,10)));
            test3.add(new ArrayList<>(Arrays.asList(12,15)));
            test3.add(new ArrayList<>(Arrays.asList(7,15)));
            test3.add(new ArrayList<>(Arrays.asList(1, 9)));
            test3.add(new ArrayList<>(Arrays.asList(9, 12)));
            //System.out.println(test3);
            Writer.determineJoinOrdering(test3);
            System.out.println(Writer.joinOrderings);

        */






    //Writer.initiateWriter(query); //1.
    //JoinContainer newJoinObj = Writer.joinInfo;
    //System.out.println("Final Tag Name: " + newJoinObj.finalTagName);
    //System.out.println("Final Var Name: " + newJoinObj.tupleName);
    //System.out.println(newJoinObj.varGroupIds);
    //System.out.println(newJoinObj.varForGroupings);
    //System.out.println(newJoinObj.varVarGroupings);
    //System.out.println(newJoinObj.singleConditions);
    //System.out.println(newJoinObj.doubleVarConditions);
    //System.out.println(newJoinObj.nodesToReturn);

    //Writer.buildJoinTerms(); //2.


    //for(Integer id: Writer.joinTerms.keySet()){
    //    System.out.println("joinTerm for groupId: " + id);
    //    System.out.println(Writer.joinTerms.get(id));
    //}



    //Writer.determineJoinOrdering(new ArrayList<>(Writer.joinInfo.doubleVarConditions.keySet())); //3.
    //System.out.println(Writer.joinOrderings);

    //Writer.performEntireJoin(); 4.
    //System.out.println(Writer.joinRewriteResult);