Skip to content

Instantly share code, notes, and snippets.

@naoto-ogawa
Created November 25, 2018 12:47
Show Gist options
  • Save naoto-ogawa/3da93c7dcea0cd3ed90798c1fa571648 to your computer and use it in GitHub Desktop.
Save naoto-ogawa/3da93c7dcea0cd3ed90798c1fa571648 to your computer and use it in GitHub Desktop.
joox example 2
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