Created
November 25, 2018 12:47
-
-
Save naoto-ogawa/3da93c7dcea0cd3ed90798c1fa571648 to your computer and use it in GitHub Desktop.
joox example 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.xml; | |
import org.joox.Match; | |
import org.w3c.dom.DOMImplementation; | |
import org.w3c.dom.Document; | |
import org.w3c.dom.DocumentType; | |
import javax.xml.parsers.DocumentBuilder; | |
import javax.xml.parsers.DocumentBuilderFactory; | |
import javax.xml.transform.OutputKeys; | |
import javax.xml.transform.Transformer; | |
import javax.xml.transform.TransformerFactory; | |
import javax.xml.transform.dom.DOMSource; | |
import javax.xml.transform.stream.StreamResult; | |
import java.io.File; | |
import java.io.PrintStream; | |
import java.nio.file.Files; | |
import java.nio.file.Paths; | |
import java.util.HashMap; | |
import java.util.Map; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
import static org.joox.JOOX.*; | |
/* | |
https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api | |
https://mvnrepository.com/artifact/org.jooq/joox | |
*/ | |
public class Main2 { | |
public static void main(String[] args) throws Exception { | |
String path = "./data/"; | |
Files.walk(Paths.get(path)) | |
.filter(Files::isRegularFile) | |
.map(x -> x.toFile()) | |
.filter(x -> x.getName().endsWith("xml")) | |
.forEach(x -> new Main2(x).analyze()); | |
} | |
private static Pattern VAR = Pattern.compile("#[{](.*)[}]"); | |
private static Pattern TBL_COL = Pattern.compile("[.]([a-zA-Z0-9_]*) *= "); | |
private static Pattern COL = Pattern.compile(" *([a-zA-Z0-9_]*) *="); | |
private Document document; | |
private Map<String, Integer> bindNames; | |
public Main2(File file) { | |
log(file); | |
document = getDocument(file); | |
bindNames = new HashMap<String, Integer>(); | |
} | |
private void analyze() { | |
Match tags = $(document).find("select, sql"); | |
for (int i = 0; i < tags.size(); i++) { | |
Match m1 = $(tags.get(i)); | |
addBindTag(m1, "x_n_1","x_v_1"); | |
addBindTag(m1, "x_n_2","x_v_2"); | |
bindNames.clear(); | |
Match ifs = m1.find("if"); | |
for (int j = 0; j < ifs.size(); j++) { | |
Match m2 = $(ifs.get(j)); | |
changeIfTag(m2); | |
} | |
} | |
writeXML(System.out); | |
} | |
private Match addBindTag(Match m, String key, String value) { | |
if (m.find(key).size() > 0) { | |
m.find(key).remove(); | |
} | |
Match child = makeBindTag(key, value); | |
m.prepend(child); | |
return m; | |
} | |
private Match changeIfTag(Match m) { | |
String attr = m.attr("test"); | |
if (attr.indexOf("#") > -1) { | |
log("alredy changed :" + m.toString()); | |
return m; | |
} | |
if (contains("[!][=] *''", attr)) { | |
changeOneItem(m); | |
} | |
if (contains("size[(][)] *[>] *0", attr)) { | |
changeListItem(m); | |
} | |
return m; | |
} | |
private boolean contains(String regrex, String str) { | |
return Pattern.compile(regrex).matcher(str).find(); | |
} | |
private void changeListItem(Match ret) { | |
// if -> foreach | |
Match foreach = ret.children("foreach"); | |
String collectionName = foreach.attr("collection"); | |
String[] names = collectionName.split("[.]"); | |
ret.attr("test", "#exists " + names[1]); | |
Match m3 = $("bind").attr("name", names[1]).attr("value", collectionName); | |
ret.before(m3); | |
foreach.attr("collection", names[1]); | |
} | |
private void changeOneItem(Match ret) { | |
String texttext = ret.text(); | |
String ref = getRef(texttext); | |
String var = getVar(texttext); | |
if (bindNames.keySet().contains(var)) { | |
bindNames.put(var, (bindNames.get(var) + 1)); | |
var = ref + "_" + (bindNames.get(var)); | |
log("same name, " + var + ", " + ref); | |
}else { | |
bindNames.put(var, 1); | |
} | |
ret.attr("test", "#exists " + var); | |
ret.text(texttext.replace("#{" + ref + "}", "#{" + var + "}")); | |
Match m3 = $("bind").attr("name",var).attr("value", ref); | |
ret.before(m3); | |
} | |
private String getRef(String str) { | |
Matcher m = VAR.matcher(str); | |
if (m.find()) { | |
return m.group(1); | |
}else { | |
throw new RuntimeException("getVar str=" + str); | |
} | |
} | |
private String getVar(String str) { | |
Matcher m = TBL_COL.matcher(str); | |
if(m.find()) { | |
return m.group(1); | |
} | |
Matcher m1 = COL.matcher(str); | |
if (m1.find()) { | |
return m1.group(1); | |
}else { | |
throw new RuntimeException("getVar str=" + str); | |
} | |
} | |
private Match makeBindTag(String name, String value) { | |
return $("bind").attr("name", name).attr("value",value); | |
} | |
private void writeXML(PrintStream out) { | |
document.setXmlStandalone(true); | |
try { | |
Transformer transformer = TransformerFactory.newInstance().newTransformer(); | |
transformer.setOutputProperty(OutputKeys.METHOD, "xml"); | |
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); | |
DOMImplementation domImpl = document.getImplementation(); | |
DocumentType doctype = domImpl.createDocumentType("doctype", | |
"-//mybatis.org//DTD Mapper 3.0//EN", | |
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"); | |
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doctype.getPublicId()); | |
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doctype.getSystemId()); | |
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); | |
DOMSource source = new DOMSource(document); | |
StreamResult console = new StreamResult(out); | |
transformer.transform(source, console); | |
} catch (Exception e) { | |
throw new RuntimeException(e); | |
} | |
} | |
private Document getDocument(File f) { | |
try { | |
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | |
DocumentBuilder builder = factory.newDocumentBuilder(); | |
return builder.parse(f); | |
} catch (Exception e) { | |
throw new RuntimeException(e); | |
} | |
} | |
private void log(Object obj) { | |
System.out.println(obj); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment