package dom;
import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.util.ArrayList;
class Dom {
protected Document doc;
protected int tab;
private String[] xml = new String[1];
private File dir;
private String dirPathR;
private Element root;
private PrintWriter pw;
//コンストラクタ
public Dom(String dirPath) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
/* XML文書を読み込む. */
dirPathR = dirPath;
dir = new File(dirPath);
xml = dir.list(new XMLFilter());
doc = db.parse(new FileInputStream(dirPath+xml[0]));
//出発点
root = doc.getDocumentElement();
//出力用
} catch (Exception e) {
e.printStackTrace();
}
tab = 0;
}
public void getNodeName(Node node) {
tabbing();
/* ノード名を出力 */
System.out.println("Node name= " + node.getNodeName());
}
protected void tabbing() {
for (int i = 0; i < tab; i++) {
System.out.print("\t");
}
}
private void Walk(Node node) {
/*
* これは,XML文書のインデントなどの空白のノードを読み飛ばすための処理. Node.TEXT_NODE
* ノードがテキストで,ノードの値の空白を除いた文字列の長さが0の場合は読み飛ばす.
*/
if (node.getNodeType() == Node.TEXT_NODE && node.getNodeValue().trim().length() == 0) {
return;
}
getNodeName(node);
tab++;
//親視点/親処理
/* node.getFirstChild : nodeの最初の子を得る */
/* child.getNextSibling : childの兄弟ノードを得る */
for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
//親視点/子処理
if(child.getNodeType() == Node.ELEMENT_NODE){
if(child.getNodeName().equals("binaryRelation")){
String parentFname = child.getParentNode().getAttributes().getNamedItem("name").getNodeValue();
NodeList cnl = child.getChildNodes();
String max_value="";
String min_value="";
String currentFname="";
for(int i=0; i<cnl.getLength(); i++){
Node n = cnl.item(i);
//System.out.println(n.getNodeName());
if(n.getNodeName().equals("cardinality")){
max_value = n.getAttributes().getNamedItem("max").getNodeValue();
min_value = n.getAttributes().getNamedItem("min").getNodeValue();
}else if(n.getNodeName().equals("solitaryFeature")){
currentFname = n.getAttributes().getNamedItem("name").getNodeValue();
}
}
if(max_value.equals(min_value)){
//mandatory
System.out.println("======mandatory=====");
System.out.println(currentFname);
pw.println("(int "+currentFname+" 0 1)");
pw.println("(imp (= "+parentFname+" 0) (= "+currentFname+" 0))");
pw.println("(imp (= "+parentFname+" 1) (= "+currentFname+" 1))");
}else{
//optional
System.out.println("=====optional=====");
System.out.println(currentFname);
pw.println("(int "+currentFname+" 0 1)");
pw.println("(imp (= "+parentFname+" 0) (= "+currentFname+" 0))");
pw.println("(imp (= "+parentFname+" 1) (|| (= "+currentFname+" 1) 1))");
}
}else if(child.getNodeName().equals("setRelation")){
String parentFname = child.getParentNode().getAttributes().getNamedItem("name").getNodeValue();
NodeList cnl = child.getChildNodes();
String max_value="";
String min_value="";
ArrayList<String> GFname = new ArrayList<String>();
String currentFname = "";
String currentFlist="";
for(int i=0; i<cnl.getLength(); i++){
Node n = cnl.item(i);
if(n.getNodeName().equals("cardinality")){
max_value = n.getAttributes().getNamedItem("max").getNodeValue();
min_value = n.getAttributes().getNamedItem("min").getNodeValue();
}else if(n.getNodeName().equals("groupedFeature")){
currentFname = n.getAttributes().getNamedItem("name").getNodeValue();
GFname.add(currentFname);
currentFlist += " "+currentFname;
}
}
if(max_value.equals(min_value)){
//alternative
System.out.println("=====alternative=====");
System.out.println(currentFlist);
for(int i=0; i<GFname.size(); i++){
pw.println("(int "+GFname.get(i)+" 0 1)");
}
pw.println("(imp (= "+parentFname+" 0) (= (+"+currentFlist+") 0))");
pw.println("(imp (= "+parentFname+" 1) (= (+"+currentFlist+") 1))");
}else{
//or_relation
System.out.println("=====or_relation=====");
System.out.println(currentFlist);
for(int i=0; i<GFname.size(); i++){
pw.println("(int "+GFname.get(i)+" 0 1)");
}
pw.println("(imp (= "+parentFname+" 0) (= (+"+currentFlist+") 0))");
pw.println("(imp (= "+parentFname+" 1) (>= (+"+currentFlist+") "+min_value+"))");
pw.println("(imp (= "+parentFname+" 1) (<= (+"+currentFlist+") "+max_value+"))");
}
}else if(child.getNodeName().equals("requires")){
//requires
String mainF = child.getAttributes().getNamedItem("feature").getNodeValue();
String requiresF = child.getAttributes().getNamedItem("requires").getNodeValue();
System.out.println("=====requires=====");
System.out.println(mainF+", "+requiresF);
pw.println("(imp (= "+mainF+" 1) (= "+requiresF+" 1))");
}else if(child.getNodeName().equals("excludes")){
//excludes
String excludesF1 = child.getAttributes().getNamedItem("feature").getNodeValue();
String excludesF2 = child.getAttributes().getNamedItem("excludes").getNodeValue();
System.out.println("=====excludes=====");
System.out.println(excludesF1+", "+excludesF2);
pw.println("(imp (= "+excludesF1+" 1) (= "+excludesF2+" 0))");
pw.println("(imp (= "+excludesF2+" 1) (= "+excludesF1+" 0))");
}
}
Walk(child); //再帰
}
tab--;
}
void WriteCSP(String outFileName) {
try{
File outFile = new File(dirPathR + outFileName);
pw = new PrintWriter(new BufferedWriter(new FileWriter(outFile)));
//ラスト一行を消してから、
pw.println("; Product");
pw.println("(int root 1)");
pw.println("(= root 1)");
Walk(root);
pw.println("; END");
pw.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
以下で実行
package dom;
public class Run {
public static void main(String[] args){
String dirPath = "/Users/Korefumi/Desktop/FM1/";
String outFileName = "outFM.csp";
Dom dm = new Dom(dirPath);
dm.WriteCSP(outFileName);
}
}