//created on: Thu Oct 13 19:35:26 CDT 2005
import org.jdom.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Iterator;
import java.util.Vector;
import java.io.File;
import java.io.IOException;
import java.io.FileWriter;
/** This is the class responsible for taking a JDOM tree's root Element (representing
the Model node) and convert it back to plain text model in a format that GUI dsl
can understand
*/
public class CubeXMLHandler{
public static String generateModelFileContent(Element model){
StringBuffer out=new StringBuffer();
out.append(generateGrammar(model.getChild("grammar")));
String constraints = generateConstraints(model.getChild("constraints"));
if (constraints.trim().length()>0)
out.append("\n\n%%\n"+constraints);
return out.toString();
}
public static String generateModelFile(Element model) throws IOException{
StringBuffer out=new StringBuffer();
out.append(generateGrammar(model.getChild("grammar")));
String constraints = generateConstraints(model.getChild("constraints"));
if (constraints.trim().length()>0)
out.append("\n\n%%\n"+constraints);
try {
File f = File.createTempFile("tempModel",".m");
if(!f.canWrite())throw new IOException("cant write in file");
FileWriter fw = new FileWriter(f);
fw.write(out.toString());
fw.close();
return f.getAbsolutePath();
}
catch(IOException ioe){
System.err.println(ioe);
throw ioe;
}
}
static String generateGrammar(Element grammar){
StringBuffer out=new StringBuffer();
List prods = grammar.getChildren("production");
Iterator it = prods.iterator();
while(it.hasNext()){
Element production = (Element)it.next();
out.append(generateProduction(production));
}
return out.toString();
}
static String generateProduction(Element prod){
StringBuffer out = new StringBuffer();
out.append(prod.getAttributeValue("name")+" : ");
List patterns = prod.getChildren("pattern");
Iterator it = patterns.iterator();
int count=0;
while(it.hasNext()){
Element pattern = (Element)it.next();
if(count>0)
out.append("\n\t | ");
out.append(generatePattern(pattern));
++count;
}
out.append(" ; \n\n");
return out.toString();
}
static String generatePattern(Element pattern){
StringBuffer out = new StringBuffer();
// primitive or prod refs
List primitive = pattern.getChildren();
Iterator it = primitive.iterator();
while(it.hasNext()){
Element node = (Element)it.next();
if(node.getAttributeValue("type").equals("optional") || node.getAttributeValue("type").equals("optional "))
out.append("["+node.getValue()+"] ");
else
out.append(node.getValue()+" ");
//if (node.getName().equals("primitive"))
// primitives.addElement(node.getTextTrim());
}
out.append(" :: "+pattern.getAttributeValue("name"));
return out.toString();
}
static String generateConstraints(Element constraints){
StringBuffer out=new StringBuffer();
if(constraints==null)
return "";
List constrs=constraints.getChildren("constraint");
Iterator it = constrs.iterator();
while(it.hasNext()){
Element child = (Element)((Element)it.next()).getChildren().get(0);
if (child==null)
continue;
out.append(generateOP(child)+";\n");
/*
if (child.getName().equals("iff"))
out.append(generateIFF(child)+";\n");
else if (child.getName().equals("implies"))
out.append(generateImplies(child)+";\n");
*/
}
return out.toString();
}
static String generateIFF(Element iff){
StringBuffer out=new StringBuffer();
List list = iff.getChildren();
if (list.size()<2)return "error <iff> token must have two arguments";
Element right = (Element)iff.getChildren().get(0);
Element left = (Element)iff.getChildren().get(1);
out.append(generateOP(left));
out.append(" iff ");
out.append(generateOP(right));
return out.toString();
}
static String generateImplies(Element implies){
StringBuffer out=new StringBuffer();
List list = implies.getChildren();
if (list.size()<2)return "error <implies> token must have two arguments";
Element right = (Element)implies.getChildren().get(0);
Element left = (Element)implies.getChildren().get(1);
out.append(generateOP(left));
out.append(" implies ");
out.append(generateOP(right));
return out.toString();
}
static String generateOP(Element node){
StringBuffer out = new StringBuffer();
if (node.getName().equals("and"))
out.append(" "+generateAND(node)+" ");
else if (node.getName().equals("or"))
out.append(" "+generateOR(node)+" ");
else if (node.getName().equals("not"))
out.append(" "+generateNOT(node)+" ");
else if (node.getName().equals("term"))
out.append(" "+node.getText()+" ");
else if (node.getName().equals("onlyone"))
out.append(" "+generateOnlyone(node)+" ");
else if (node.getName().equals("choose1"))
out.append(" "+generateChoose1(node)+" ");
else if (node.getName().equals("iff"))
out.append("("+generateIFF(node)+")");
else if (node.getName().equals("implies"))
out.append("("+generateImplies(node)+")");
return out.toString();
}
static String generateChoose1(Element node){
StringBuffer out = new StringBuffer();
List list = node.getChildren();
if (list.size()!=2)return "error <choose1> token must have two arguments";
if (node.getName().equals("term"))
return node.getText();
Element left = (Element)node.getChildren().get(0);
Element right = (Element)node.getChildren().get(1);
String temp = generateSubOnlyone(left)+","+generateSubOnlyone(right);
out.append("(choose1("+temp+"))");
return out.toString();
}
//When parsed, guidsl breaks choose1(..) into number of onlyone tokens.
//so here I generate a choose1(..) predicate
static String generateOnlyone(Element node){
StringBuffer out = new StringBuffer();
List list = node.getChildren();
if (list.size()!=2)return "error <onlyone> token must have two arguments";
if (node.getName().equals("term"))
return node.getText();
Element left = (Element)node.getChildren().get(0);
Element right = (Element)node.getChildren().get(1);
String temp=null;
if(left!=null && right!=null)
temp = generateSubOnlyone(left)+","+generateSubOnlyone(right);
else if (right==null)
temp = generateSubOnlyone(left);
else {
return "error <onlyone> has right side null";
}
out.append("(choose1("+temp+"))");
return out.toString();
}
static String generateSubOnlyone(Element node){
StringBuffer out = new StringBuffer();
if (node.getName().equals("term"))
return node.getText();
Element left = (Element)node.getChildren().get(0);
Element right = (Element)node.getChildren().get(1);
if(left!=null && right!=null)
out.append(generateSubOnlyone(left)+","+generateSubOnlyone(right));
else if(right==null)
out.append(generateSubOnlyone(left));
else
return "error <onlyone> has right side null";
return out.toString();
}
static String generateAND(Element and){
StringBuffer out = new StringBuffer();
List list = and.getChildren();
//if (list.size()!=2)return "error <and> token must have two arguments";
if (list.size()<1)return "error <and> token must have atleast one argument";
out.append("(");
for (int i=0;i<list.size();i++){
Element elm = (Element)list.get(i);
if (i>0)
out.append(" and ");
out.append(generateOP(elm));
}
out.append(")");
//Element left = (Element)and.getChildren().get(0);
//Element right = (Element)and.getChildren().get(1);
//out.append("("+generateOP(left));
//out.append(" and ");
//out.append(generateOP(right)+")");
return out.toString();
}
static String generateOR(Element or){
StringBuffer out = new StringBuffer();
List list = or.getChildren();
//if (list.size()!=2)return "error <and> token must have two arguments";
if (list.size()<1)return "error <or> token must have atleast one argument";
out.append("(");
for (int i=0;i<list.size();i++){
Element elm = (Element)list.get(i);
if (i>0)
out.append(" or ");
out.append(generateOP(elm));
}
out.append(")");
return out.toString();
}
static String generateNOT(Element not){
StringBuffer out = new StringBuffer();
List list = not.getChildren();
if (list.size()!=1)return "error <not> token must have one arguments";
Element left = (Element)not.getChildren().get(0);
out.append("not"+generateOP(left));
return out.toString();
}
}