TurtleDB
A mini distributed database system
src/ca/uqac/dim/turtledb/XmlQueryVisitor.java
Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002     Simple distributed database engine
00003     Copyright (C) 2012  Sylvain Hallé
00004 
00005     This program is free software: you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation, either version 3 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017  -------------------------------------------------------------------------*/
00018 package ca.uqac.dim.turtledb;
00019 
00020 import java.util.*;
00021 import javax.xml.parsers.*;
00022 import org.w3c.dom.*;
00023 
00024 /*package*/ class XmlQueryVisitor extends QueryVisitor
00025 {
00026   protected Document m_doc;
00027   protected Stack<Node> m_parts;
00028 
00029   public Document getDocument()
00030   {
00031     Node n = m_parts.pop();
00032     m_doc.appendChild(n);
00033     return m_doc;
00034   }
00035 
00036   public XmlQueryVisitor()
00037   {
00038     super();
00039     m_parts = new Stack<Node>();
00040     m_doc = null;
00041     DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
00042     DocumentBuilder builder = null;
00043     try
00044     {
00045       builder = builderFactory.newDocumentBuilder();
00046       m_doc = builder.newDocument();
00047     }
00048     catch (ParserConfigurationException e)
00049     {
00050       e.printStackTrace();  
00051     }
00052   }
00053 
00054   @Override
00055   public void visit(Intersection r)
00056   {
00057     visitNAry("intersection", r);
00058   }
00059 
00060   @Override
00061   public void visit(Union r)
00062   {
00063     visitNAry("union", r);
00064   }
00065 
00066   @Override
00067   public void visit(Projection r)
00068   {
00069     Node n = m_doc.createElement("projection");
00070     Node schema = createSchemaNode(r.m_schema);
00071     Node relation = m_parts.pop();
00072     n.appendChild(schema);
00073     n.appendChild(relation);
00074     Node op = m_doc.createElement("operand");
00075     op.appendChild(n);
00076     m_parts.push(op);
00077   }
00078 
00079   @Override
00080   public void visit(Selection r)
00081   {
00082     Node n = m_doc.createElement("selection");
00083     Node condition = createConditionNode(r.m_condition);
00084     Node relation = m_parts.pop();
00085     n.appendChild(condition);
00086     n.appendChild(relation);
00087     Node op = m_doc.createElement("operand");
00088     op.appendChild(n);
00089     m_parts.push(op);
00090   }
00091 
00092   @Override
00093   public void visit(VariableTable r)
00094   {
00095     Node n = m_doc.createElement("vartable");
00096     Node name = m_doc.createElement("name");
00097     name.setTextContent(r.getName());
00098     Node site = m_doc.createElement("site");
00099     site.setTextContent(r.getSite());
00100     n.appendChild(name);
00101     n.appendChild(site);
00102     if (r.m_relation != null)
00103     {
00104       Node relation = m_parts.pop();
00105       n.appendChild(relation);
00106     }
00107     Node op = m_doc.createElement("operand");
00108     op.appendChild(n);
00109     m_parts.push(op);
00110   }
00111 
00112   @Override
00113   public void visit(Table r)
00114   {
00115     Node n = m_doc.createElement("table");
00116     Node schema = createSchemaNode(r.m_schema);
00117     n.appendChild(schema);
00118     RelationStreamIterator it = r.streamIterator();
00119     it.reset();
00120     while (it.hasNext())
00121     {
00122       Tuple t = it.next();
00123       Node t_node = createTupleNode(t);
00124       n.appendChild(t_node);
00125     }
00126     Node op = m_doc.createElement("operand");
00127     op.appendChild(n);
00128     m_parts.push(op);
00129   }
00130   
00131   @Override
00132   public void visit(Join r) throws VisitorException
00133   {
00134     Node n = m_doc.createElement("join");
00135     Node n_right = m_parts.pop(); // RHS
00136     Node n_left = m_parts.pop(); // LHS
00137     Node condition = createConditionNode(r.m_condition);
00138     n.appendChild(condition);
00139     n.appendChild(n_left);
00140     n.appendChild(n_right);
00141     Node op = m_doc.createElement("operand");
00142     op.appendChild(n);
00143     m_parts.push(op);
00144   }
00145 
00146   @Override
00147   public void visit(Product r) throws VisitorException
00148   {
00149     visitNAry("product", r);
00150   }
00151   
00152   protected void visitNAry(String operator, NAryRelation r)
00153   {
00154     Node n = m_doc.createElement(operator);
00155     for (int i = 0; i < r.m_relations.size(); i++)
00156     {
00157       Node n_op = m_parts.pop();
00158       n.appendChild(n_op);
00159     }
00160     Node op = m_doc.createElement("operand");
00161     op.appendChild(n);
00162     m_parts.push(op);
00163   }
00164 
00165   protected Node createSchemaNode(Schema sch)
00166   {
00167     Node n = m_doc.createElement("schema");
00168     for (Attribute a : sch)
00169     {
00170       Node attnode = m_doc.createElement("attribute");
00171       attnode.setTextContent(a.toString());
00172       n.appendChild(attnode);
00173     }
00174     return n;
00175   }
00176 
00177   protected Node createConditionNode(Condition c)
00178   {
00179     XmlConditionVisitor xcv = new XmlConditionVisitor(m_doc);
00180     c.accept(xcv);
00181     return xcv.getNode();
00182   }
00183 
00184   protected Node createTupleNode(Tuple t)
00185   {
00186     Node tuple = m_doc.createElement("tuple");
00187     for (Attribute a : t.keySet())
00188     {
00189       String a_name = a.toString();
00190       String a_val = t.get(a).toString();
00191       Node atval = m_doc.createElement(a_name);
00192       atval.setTextContent(a_val);
00193       tuple.appendChild(atval);
00194     }
00195     return tuple;
00196   }
00197 }