TurtleDB
A mini distributed database system
|
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 }