diff --git a/.attach_pid21233 b/.attach_pid21233 deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/main/kotlin/unibz.cs.semint.kprime/usecase/XPathTransformUseCase.kt b/src/main/kotlin/unibz.cs.semint.kprime/usecase/XPathTransformUseCase.kt new file mode 100644 index 0000000000000000000000000000000000000000..bf410f3e1c5708b6382b05759af19009d0b309c4 --- /dev/null +++ b/src/main/kotlin/unibz.cs.semint.kprime/usecase/XPathTransformUseCase.kt @@ -0,0 +1,101 @@ +package unibz.cs.semint.kprime.usecase + +import freemarker.cache.ClassTemplateLoader +import freemarker.template.Configuration +import org.w3c.dom.NodeList +import java.io.FileInputStream +import java.io.InputStream +import java.io.OutputStreamWriter +import java.util.* +import javax.xml.parsers.DocumentBuilderFactory +import javax.xml.xpath.XPathConstants +import javax.xml.xpath.XPathFactory + +class XPathTransformUseCase { + + fun transform(dbFilePath: String, trasformerName: String, trasformerDirection: String, trasformerVersion: String) { + + val vdecomposeFilePath = "/transformer/${trasformerName}/${trasformerDirection}/${trasformerName}_${trasformerDirection}_${trasformerVersion}.paths" + val vdecomposeTemplatePath = "transformer/${trasformerName}/${trasformerDirection}/${trasformerName}_${trasformerDirection}_${trasformerVersion}.template" + + val personProperties = XPathTransformUseCase::class.java.getResourceAsStream(vdecomposeFilePath) + val personPaths = Properties() + personPaths.load(personProperties) + + var dbStream : InputStream + if (dbFilePath.startsWith("/")) + dbStream = FileInputStream(dbFilePath) + else + dbStream = XPathTransformUseCase::class.java.getResourceAsStream("/${dbFilePath}") + val docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder() + val doc = docBuilder.parse(dbStream) + + // extract vars as value attributes via xpaths + // use vars in template + val templConfig = Configuration(Configuration.VERSION_2_3_29) + val classTemplLoader = ClassTemplateLoader(XPathTransformUseCase::javaClass.javaClass, "/") + templConfig.templateLoader = classTemplLoader + val templModel = mutableMapOf<String, Any>() + + // compute xpath lists + val xpath = XPathFactory.newInstance().newXPath() + for (entryNameas in personPaths.propertyNames()) { + val name = entryNameas as String + val value = personPaths.getProperty(name) + if (!(value.startsWith("-") || value.startsWith("+"))) { + templModel[name] = asValueList(xpath.compile(value).evaluate(doc, XPathConstants.NODESET) as NodeList) + println(" ${name} = ${value}") + println(" ${name} = ${templModel[name]}") + } + } + // compute derived list sum and minus + for (entryNameas in personPaths.propertyNames()) { + val name = entryNameas as String + val value = personPaths.getProperty(name) + if (value.startsWith("-") || value.startsWith("+")) { + println(" ${name} = ${value}") + templModel[name] = computeDerivedList(templModel, value) + } + } + val templ = //Template.getPlainTextTemplate("templ1",personTemplate,templConfig) + templConfig.getTemplate(vdecomposeTemplatePath) + templ.process(templModel, OutputStreamWriter(System.out)) + } + + + private fun computeDerivedList(templModel: MutableMap<String, Any>, derivationRule: String): Any { + var derivedList = mutableListOf<String>() + // if derivationRule starts with + then compute union + val splittedRule = derivationRule.split(" ") + if (splittedRule[0]=="+") { + val sourceLists = splittedRule.drop(1) + println(sourceLists) + derivedList.addAll(templModel[sourceLists[0]] as List<String>) + for (i in 1..(sourceLists.size-1)) { + derivedList = derivedList.plus(templModel[sourceLists[i]] as MutableList<String>) as MutableList<String> + } + println(derivedList) + } + if (splittedRule[0]=="-") { + //println(splittedRule) + val sourceLists = splittedRule.drop(1) + //println(sourceLists) + derivedList.addAll(templModel[sourceLists[0]] as List<String>) + for (i in 1..(sourceLists.size-1)) { + derivedList = derivedList.minus(templModel[sourceLists[i]] as MutableList<String>) as MutableList<String> + } + println(" $derivedList") + } + // if derivationRule starts with - then compute intersection + return derivedList + } + + private fun asValueList(xpathResultNodes: NodeList): MutableList<String> { + val listNodeValues = mutableListOf<String>() + for (nodeId in 0..xpathResultNodes.length) { + val item = xpathResultNodes.item(nodeId) + if (item==null) continue + listNodeValues.add(item.nodeValue) + } + return listNodeValues + }} \ No newline at end of file diff --git a/src/test/kotlin/unibz.cs.semint.kprime/scenario/PersonXPathScenarioTI.kt b/src/test/kotlin/unibz.cs.semint.kprime/scenario/PersonXPathScenarioTI.kt index 743b8c76dd975288775a68c0c3e91cb3df3a0ee2..953cf05ccbdd9f26878d5ebc4616db44951333e3 100644 --- a/src/test/kotlin/unibz.cs.semint.kprime/scenario/PersonXPathScenarioTI.kt +++ b/src/test/kotlin/unibz.cs.semint.kprime/scenario/PersonXPathScenarioTI.kt @@ -4,6 +4,7 @@ import freemarker.cache.ClassTemplateLoader import freemarker.template.Configuration import org.junit.Test import org.w3c.dom.NodeList +import unibz.cs.semint.kprime.usecase.XPathTransformUseCase import java.io.OutputStreamWriter import java.util.* import javax.xml.parsers.DocumentBuilderFactory @@ -15,96 +16,15 @@ class PersonXPathScenarioTI { @Test fun test_xpath_extraction_on_person_db() { // given - // input person db - val personDbXml = PersonXPathScenarioTI::class.java.getResource("/db/person.xml").readText() - val personDbStream = PersonXPathScenarioTI::class.java.getResourceAsStream("/db/person.xml") - val personProperties = PersonXPathScenarioTI::class.java.getResourceAsStream("/transformer/vertical/decompose/person.paths") - //println(personDbXml) - // input person out template - //val personTemplate = PersonXPathScenarioTI::class.java.getResource("<database name=\"\" id=\"\">\n <schema name=\"\" id=\"\">\n <tables>\n <tables name=\"person1\" id=\"\" view=\"\" condition=\"\">\n <columns>\n <#list keys as key>\n <columns name=${key} id=\"id.${key}\" nullable=\"false\" dbtype=\"\"/>\n </#list>\n <#list lhss as lhs>\n <columns name=\"${lhs}\" id=\"id.${lhs}\" nullable=\"false\" dbtype=\"\"/>\n </#list>\n <#list rests as rest>\n <columns name=\"${rest}\" id=\"id.${rest}\" nullable=\"true\" dbtype=\"\"/>\n </#list>\n </columns>\n </tables>\n <tables name=\"person2\" id=\"\" view=\"\" condition=\"\">\n <columns>\n <#list lhss as lhs>\n <columns name=\"${lhs}\" id=\"id.${lhs}\" nullable=\"false\" dbtype=\"\"/>\n </#list>\n <#list rhss as rhs>\n <columns name=\"${rhs}\" id=\"id.${rhs}\" nullable=\"false\" dbtype=\"\"/>\n </#list>\n </columns>\n </tables>\n </tables>\n <constraints>\n <constraints name=\"primaryKey.person\" id=\"\" type=\"PRIMARY_KEY\">\n <source name=\"\" id=\"\" table=\"person\">\n <columns>\n <columns name=\"SSN\" id=\"id.SSN\" dbname=\"dbname.SSN\" nullable=\"false\" dbtype=\"\"/>\n </columns>\n </source>\n <target name=\"\" id=\"\" table=\"\">\n <columns/>\n </target>\n </constraints>\n <constraints name=\"functional.person\" id=\"\" type=\"FUNCTIONAL\">\n <source name=\"\" id=\"\" table=\"person\">\n <columns>\n <columns name=\"T\" id=\"id.T\" dbname=\"dbname.T\" nullable=\"false\" dbtype=\"\"/>\n </columns>\n </source>\n <target name=\"\" id=\"\" table=\"person\">\n <columns>\n <columns name=\"S\" id=\"id.S\" dbname=\"dbname.S\" nullable=\"true\" dbtype=\"\"/>\n </columns>\n </target>\n </constraints>\n </constraints>\n </schema>\n</database>\n").readText() - //println(personTemplate) - val personPaths = Properties() - personPaths.load(personProperties) - - val docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder() - val doc = docBuilder.parse(personDbStream) - val xpath = XPathFactory.newInstance().newXPath() - - val xpathResult = xpath.compile("/database/schema/tables/tables/columns/columns[2]/@name").evaluate(doc) - println(xpathResult) - - val xpathResultNodes = asValueList(xpath.compile("/database/schema/tables/tables[@name='person1']/columns/columns/@name").evaluate(doc, XPathConstants.NODESET) as NodeList) - println(xpathResultNodes) - - // extract vars as value attributes via xpaths - // use vars in template - val templConfig = Configuration(Configuration.VERSION_2_3_29) - val classTemplLoader = ClassTemplateLoader(PersonXPathScenarioTI::javaClass.javaClass,"/") - templConfig.templateLoader= classTemplLoader - val templModel = mutableMapOf<String,Any>() - - // compute xpath lists - for (entryNameas in personPaths.propertyNames() ) - { - val name = entryNameas as String - val value = personPaths.getProperty(name) - if (!(value.startsWith("-") || value.startsWith("+"))) { - templModel[name] = asValueList(xpath.compile(value).evaluate(doc, XPathConstants.NODESET) as NodeList) - println(" ${name} = ${value}") - println(" ${name} = ${templModel[name]}") - } - } - // compute derived list sum and minus - for (entryNameas in personPaths.propertyNames() ) - { - val name = entryNameas as String - val value = personPaths.getProperty(name) - if (value.startsWith("-") || value.startsWith("+")) { - println(" ${name} = ${value}") - templModel[name] = computeDerivedList(templModel,value) - } - } - val templ = //Template.getPlainTextTemplate("templ1",personTemplate,templConfig) - templConfig.getTemplate("transformer/vertical/decompose/person_out.template") - val out = OutputStreamWriter(System.out) - templ.process(templModel,out) + val dbFilePath = "db/person.xml" + val trasformerName = "vertical" + val trasformerDirection = "decompose" + val trasformerVersion = "1" + // when + XPathTransformUseCase().transform(dbFilePath, trasformerName, trasformerDirection, trasformerVersion) + // then + // print to console output } - private fun computeDerivedList(templModel: MutableMap<String, Any>, derivationRule: String): Any { - var derivedList = mutableListOf<String>() - // if derivationRule starts with + then compute union - val splittedRule = derivationRule.split(" ") - if (splittedRule[0]=="+") { - val sourceLists = splittedRule.drop(1) - println(sourceLists) - derivedList.addAll(templModel[sourceLists[0]] as List<String>) - for (i in 1..(sourceLists.size-1)) { - derivedList = derivedList.plus(templModel[sourceLists[i]] as MutableList<String>) as MutableList<String> - } - println(derivedList) - } - if (splittedRule[0]=="-") { - //println(splittedRule) - val sourceLists = splittedRule.drop(1) - //println(sourceLists) - derivedList.addAll(templModel[sourceLists[0]] as List<String>) - for (i in 1..(sourceLists.size-1)) { - derivedList = derivedList.minus(templModel[sourceLists[i]] as MutableList<String>) as MutableList<String> - } - println(" $derivedList") - } - // if derivationRule starts with - then compute intersection - return derivedList - } - - private fun asValueList(xpathResultNodes: NodeList): MutableList<String> { - val listNodeValues = mutableListOf<String>() - for (nodeId in 0..xpathResultNodes.length) { - val item = xpathResultNodes.item(nodeId) - if (item==null) continue - listNodeValues.add(item.nodeValue) - } - return listNodeValues - } } \ No newline at end of file diff --git a/src/test/resources/transformer/vertical/decompose/person.paths b/src/test/resources/transformer/vertical/decompose/vertical_decompose_1.paths similarity index 100% rename from src/test/resources/transformer/vertical/decompose/person.paths rename to src/test/resources/transformer/vertical/decompose/vertical_decompose_1.paths diff --git a/src/test/resources/transformer/vertical/decompose/person_out.template b/src/test/resources/transformer/vertical/decompose/vertical_decompose_1.template similarity index 100% rename from src/test/resources/transformer/vertical/decompose/person_out.template rename to src/test/resources/transformer/vertical/decompose/vertical_decompose_1.template