diff --git a/README.md b/README.md index 03c89f1e384784ca984125357810ad518dad7b40..cd256eaafdb6a37c495c0249e4a3aac19277df81 100644 --- a/README.md +++ b/README.md @@ -68,26 +68,31 @@ technology depenent packages * A domain component has to depends on nothing. -## v1.0.0 +## v0.1.0 from object database meta representation as input apply kotlin transformer vertical or horizontal obtain a second database meta representation as output -## v2.0.0 +## v0.2.0 from xml object database meta representation as input apply kotlin transformer vertical or horizontal obtain a changeset representation as output -## v3.0.0 +## v0.3.0 from xml object database meta representation as input a generic xpath engine extraction plus freemarker template to generate obtain a database meta representation as output +## v0.4.0 + +from xml object database meta representation as input +a xml transfomer descriptor + ### to do * horizontal simple decomposition to remove null columns diff --git a/src/main/kotlin/unibz.cs.semint.kprime/adapter/service/XMLSerializerJacksonAdapter.kt b/src/main/kotlin/unibz.cs.semint.kprime/adapter/service/XMLSerializerJacksonAdapter.kt index 53030129f42ba24bdce88234f9cab65c1e117229..62aadce373a8adb903cb56e816ab86c4a3fb627e 100644 --- a/src/main/kotlin/unibz.cs.semint.kprime/adapter/service/XMLSerializerJacksonAdapter.kt +++ b/src/main/kotlin/unibz.cs.semint.kprime/adapter/service/XMLSerializerJacksonAdapter.kt @@ -77,4 +77,18 @@ class XMLSerializerJacksonAdapter : IXMLSerializerService { return writer.writeValueAsString(table) } + override fun serializeTransfomer(transformer: Transformer): String { + val mapper = XmlMapper().registerModule(KotlinModule()) + val writer = mapper.writerWithDefaultPrettyPrinter() + return writer.writeValueAsString(transformer) + + } + + override fun deserializeTransformer(transformerXml: String): Transformer { + println(transformerXml) + val mapper = XmlMapper() + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + return mapper.readValue(transformerXml,Transformer::class.java) + } + } \ No newline at end of file diff --git a/src/main/kotlin/unibz.cs.semint.kprime/domain/Composer.kt b/src/main/kotlin/unibz.cs.semint.kprime/domain/Composer.kt new file mode 100644 index 0000000000000000000000000000000000000000..7bbbde9b530925e097e545e56321fba3f7a46ce9 --- /dev/null +++ b/src/main/kotlin/unibz.cs.semint.kprime/domain/Composer.kt @@ -0,0 +1,9 @@ +package unibz.cs.semint.kprime.domain + + + +class Composer { + var xman = Xmen() + var template = Template() + +} \ No newline at end of file diff --git a/src/main/kotlin/unibz.cs.semint.kprime/domain/Splitter.kt b/src/main/kotlin/unibz.cs.semint.kprime/domain/Splitter.kt new file mode 100644 index 0000000000000000000000000000000000000000..49c55b2dfed0992682a6de25ef4bbd4d8e1edd3b --- /dev/null +++ b/src/main/kotlin/unibz.cs.semint.kprime/domain/Splitter.kt @@ -0,0 +1,15 @@ +package unibz.cs.semint.kprime.domain + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText +import java.util.* + + +@JacksonXmlRootElement(localName = "splitter") +class Splitter { + + var xman = Xmen() + var template = Template() +} diff --git a/src/main/kotlin/unibz.cs.semint.kprime/domain/Template.kt b/src/main/kotlin/unibz.cs.semint.kprime/domain/Template.kt new file mode 100644 index 0000000000000000000000000000000000000000..4f83a589f98dbdaadbcc5fc8370ab411dce392d8 --- /dev/null +++ b/src/main/kotlin/unibz.cs.semint.kprime/domain/Template.kt @@ -0,0 +1,11 @@ +package unibz.cs.semint.kprime.domain + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement +import java.util.* + +@JacksonXmlRootElement(localName = "template") +class Template { + @JacksonXmlProperty(isAttribute = true) + var filename="" +} \ No newline at end of file diff --git a/src/main/kotlin/unibz.cs.semint.kprime/domain/Transformer.kt b/src/main/kotlin/unibz.cs.semint.kprime/domain/Transformer.kt new file mode 100644 index 0000000000000000000000000000000000000000..6230b33f64a6bf853019f3c12d7c25f510650384 --- /dev/null +++ b/src/main/kotlin/unibz.cs.semint.kprime/domain/Transformer.kt @@ -0,0 +1,13 @@ +package unibz.cs.semint.kprime.domain + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement + +@JacksonXmlRootElement(localName = "transformer") +class Transformer { + @JacksonXmlProperty(isAttribute = true) + var name: String ="" + + var composer = Composer() + var splitter = Splitter() +} \ No newline at end of file diff --git a/src/main/kotlin/unibz.cs.semint.kprime/domain/Xmen.kt b/src/main/kotlin/unibz.cs.semint.kprime/domain/Xmen.kt new file mode 100644 index 0000000000000000000000000000000000000000..c06e042a34c9b64c6fb4da37a312755bbe99eb53 --- /dev/null +++ b/src/main/kotlin/unibz.cs.semint.kprime/domain/Xmen.kt @@ -0,0 +1,8 @@ +package unibz.cs.semint.kprime.domain + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement + +@JacksonXmlRootElement(localName = "xmen") +class Xmen { + var xrules = ArrayList<Xrule>() +} \ No newline at end of file diff --git a/src/main/kotlin/unibz.cs.semint.kprime/domain/Xrule.kt b/src/main/kotlin/unibz.cs.semint.kprime/domain/Xrule.kt new file mode 100644 index 0000000000000000000000000000000000000000..6829a7abba6e68079b405cc62c28995e0c722995 --- /dev/null +++ b/src/main/kotlin/unibz.cs.semint.kprime/domain/Xrule.kt @@ -0,0 +1,15 @@ +package unibz.cs.semint.kprime.domain + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText + +@JacksonXmlRootElement(localName = "xrule") +class Xrule() { + + @JacksonXmlProperty(isAttribute = true) + var name = "" + @JacksonXmlText + var rule = "" + +} \ No newline at end of file diff --git a/src/main/kotlin/unibz.cs.semint.kprime/usecase/XMLSerializeUseCase.kt b/src/main/kotlin/unibz.cs.semint.kprime/usecase/XMLSerializeUseCase.kt index 36475d22163ea08ea9ccf3dd05b00253fe0b1f26..7f3ff5e1afe8508d3d860c5e949a506d49e3fb9d 100644 --- a/src/main/kotlin/unibz.cs.semint.kprime/usecase/XMLSerializeUseCase.kt +++ b/src/main/kotlin/unibz.cs.semint.kprime/usecase/XMLSerializeUseCase.kt @@ -58,4 +58,14 @@ class XMLSerializeUseCase(val xmlSerializerService: IXMLSerializerService) { return UseCaseResult("done",xmlSerializerService.prettyChangeSet(changeset)) } + // trasnfomer + + fun serializeTransformer(transformer: Transformer): UseCaseResult<String> { + return UseCaseResult("done",xmlSerializerService.serializeTransfomer(transformer)) + } + + fun deserializeTransformer(transformerXml: String): UseCaseResult<Transformer> { + return UseCaseResult("done",xmlSerializerService.deserializeTransformer(transformerXml)) + } + } \ No newline at end of file diff --git a/src/main/kotlin/unibz.cs.semint.kprime/usecase/XPathTransformUseCase.kt b/src/main/kotlin/unibz.cs.semint.kprime/usecase/XPathTransformUseCase.kt index b26cfd09b5ce0c3766de8d301f2244fd9b7de1ad..23de0c56a6b2fdf5afd6974a0d7df2d3c64dc394 100644 --- a/src/main/kotlin/unibz.cs.semint.kprime/usecase/XPathTransformUseCase.kt +++ b/src/main/kotlin/unibz.cs.semint.kprime/usecase/XPathTransformUseCase.kt @@ -13,15 +13,16 @@ import javax.xml.xpath.XPathFactory class XPathTransformUseCase { - fun transform(dbFilePath: String, trasformerName: String, trasformerDirection: String, trasformerVersion: String, tranformerParmeters: MutableMap<String, Any>) { - + fun transform(dbFilePath: String, trasformerName: String, trasformerDirection: String, trasformerVersion: String, tranformerParmeters: MutableMap<String, Any>,outWriter:OutputStreamWriter) { 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 xPaths = Properties() xPaths.load(personProperties) + return transform(dbFilePath,vdecomposeTemplatePath,xPaths, tranformerParmeters,outWriter) + } + fun transform(dbFilePath: String, templateFilePath: String, xPaths: Properties, tranformerParmeters: MutableMap<String, Any>,outWriter:OutputStreamWriter) { var dbStream : InputStream if (dbFilePath.startsWith("/")) dbStream = FileInputStream(dbFilePath) @@ -77,8 +78,8 @@ class XPathTransformUseCase { // = = 0 xpath val templ = //Template.getPlainTextTemplate("templ1",personTemplate,templConfig) - templConfig.getTemplate(vdecomposeTemplatePath) - templ.process(templModel, OutputStreamWriter(System.out)) + templConfig.getTemplate(templateFilePath) + templ.process(templModel, outWriter) } private fun parametrized(line: String, tranformerParmeters: MutableMap<String, Any>): String { diff --git a/src/main/kotlin/unibz.cs.semint.kprime/usecase/service/IXMLSerializerService.kt b/src/main/kotlin/unibz.cs.semint.kprime/usecase/service/IXMLSerializerService.kt index f8dd2d7bac1a81297ed6114d2a198e222617b050..faf0edc5c3bf008b4ce6bc05bed6262184f226fd 100644 --- a/src/main/kotlin/unibz.cs.semint.kprime/usecase/service/IXMLSerializerService.kt +++ b/src/main/kotlin/unibz.cs.semint.kprime/usecase/service/IXMLSerializerService.kt @@ -1,9 +1,6 @@ package unibz.cs.semint.kprime.usecase.service -import unibz.cs.semint.kprime.domain.ChangeSet -import unibz.cs.semint.kprime.domain.Constraint -import unibz.cs.semint.kprime.domain.Database -import unibz.cs.semint.kprime.domain.Table +import unibz.cs.semint.kprime.domain.* interface IXMLSerializerService { fun serializeTable(table: Table): String @@ -17,4 +14,6 @@ interface IXMLSerializerService { fun serializeChangeSet(changeset: ChangeSet): String fun deserializeChangeSet(changeset: String): ChangeSet fun prettyChangeSet(table: ChangeSet): String + fun serializeTransfomer(transformer: Transformer): String + fun deserializeTransformer(transformer: String): Transformer } \ No newline at end of file diff --git a/src/test/kotlin/unibz.cs.semint.kprime/domain/TransfomerTest.kt b/src/test/kotlin/unibz.cs.semint.kprime/domain/TransfomerTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..0751281ed81f18ee2185c55e80b8bdd6ab8c6ca1 --- /dev/null +++ b/src/test/kotlin/unibz.cs.semint.kprime/domain/TransfomerTest.kt @@ -0,0 +1,38 @@ +package unibz.cs.semint.kprime.domain + +import org.junit.Test +import unibz.cs.semint.kprime.adapter.service.XMLSerializerJacksonAdapter +import unibz.cs.semint.kprime.usecase.XMLSerializeUseCase + +class TransfomerTest { + + @Test + fun test_empty_trasfomer_xml(){ + + // given + val transformer = Transformer() + // when + val serializedTransformer = XMLSerializeUseCase(XMLSerializerJacksonAdapter()).serializeTransformer(transformer) + // then + println(serializedTransformer) + + } + + + @Test + fun test_vsplit_trasfomer_xml(){ + + // given + val transformer = Transformer() + val xrule = Xrule() + xrule.name="all" + xrule.rule="/database/schema/tables/tables[@name='%%table%%']/columns/columns/@name = 4" + transformer.splitter.xman.xrules.add(xrule) + // when + val serializedTransformer = XMLSerializeUseCase(XMLSerializerJacksonAdapter()).serializeTransformer(transformer) + // then + println(serializedTransformer) + + } + +} \ No newline at end of file diff --git a/src/test/kotlin/unibz.cs.semint.kprime/scenario/PersonTransfomerScenarioTI.kt b/src/test/kotlin/unibz.cs.semint.kprime/scenario/PersonTransfomerScenarioTI.kt new file mode 100644 index 0000000000000000000000000000000000000000..004db182139c68793d81e3622201348d9a334f39 --- /dev/null +++ b/src/test/kotlin/unibz.cs.semint.kprime/scenario/PersonTransfomerScenarioTI.kt @@ -0,0 +1,56 @@ +package unibz.cs.semint.kprime.scenario + +import org.junit.Test +import unibz.cs.semint.kprime.adapter.service.XMLSerializerJacksonAdapter +import unibz.cs.semint.kprime.domain.Xrule +import unibz.cs.semint.kprime.usecase.XMLSerializeUseCase +import unibz.cs.semint.kprime.usecase.XPathTransformUseCase +import java.io.OutputStreamWriter +import java.util.* + +class PersonTransfomerScenarioTI { + + @Test + fun test_xpath_vertical_decomposition_on_person_db() { + // given + val dbFilePath = "db/person.xml" + val transfomerXml = PersonTransfomerScenarioTI::class.java.getResource("/transformer/verticalTransfomer.xml").readText() + val vTransfomer = XMLSerializeUseCase(XMLSerializerJacksonAdapter()).deserializeTransformer(transfomerXml).ok + val templateFilePath = vTransfomer!!.splitter.template.filename + val xrules = toProperties(vTransfomer!!.splitter.xman.xrules) + val tranformerParmeters = mutableMapOf<String,Any>() + tranformerParmeters["table"]="person" + println(templateFilePath) + // when + XPathTransformUseCase().transform(dbFilePath, templateFilePath, xrules,tranformerParmeters, OutputStreamWriter(System.out)) + // then + // print to console output + } + + private fun toProperties(xrules: ArrayList<Xrule>): Properties { + var pros = Properties() + for (xrule in xrules) { + pros[xrule.name]=xrule.rule + } + return pros + } + + @Test + fun test_xpath_horizontal_decomposition_on_person_db() { + /* + // given + val dbFilePath = "db/person.xml" + val trasformerName = "horizontal" + val trasformerDirection = "decompose" + val trasformerVersion = "1" + val tranformerParmeters = mutableMapOf<String,Any>() + tranformerParmeters["table"]="person" + // when + XPathTransformUseCase().transform(dbFilePath, trasformerName, trasformerDirection, trasformerVersion,tranformerParmeters,OutputStreamWriter(System.out)) + // then + // print to console output + */ + } + + +} \ 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 cf29a8114d8ad2395cef4457a0fb8fd8788c8394..aba56752469aa51b3fb532a29bce332eb1d26fa9 100644 --- a/src/test/kotlin/unibz.cs.semint.kprime/scenario/PersonXPathScenarioTI.kt +++ b/src/test/kotlin/unibz.cs.semint.kprime/scenario/PersonXPathScenarioTI.kt @@ -2,6 +2,7 @@ package unibz.cs.semint.kprime.scenario import org.junit.Test import unibz.cs.semint.kprime.usecase.XPathTransformUseCase +import java.io.OutputStreamWriter class PersonXPathScenarioTI { @@ -15,7 +16,7 @@ class PersonXPathScenarioTI { val tranformerParmeters = mutableMapOf<String,Any>() tranformerParmeters["table"]="person" // when - XPathTransformUseCase().transform(dbFilePath, trasformerName, trasformerDirection, trasformerVersion,tranformerParmeters) + XPathTransformUseCase().transform(dbFilePath, trasformerName, trasformerDirection, trasformerVersion,tranformerParmeters, OutputStreamWriter(System.out)) // then // print to console output } @@ -30,7 +31,7 @@ class PersonXPathScenarioTI { val tranformerParmeters = mutableMapOf<String,Any>() tranformerParmeters["table"]="person" // when - XPathTransformUseCase().transform(dbFilePath, trasformerName, trasformerDirection, trasformerVersion,tranformerParmeters) + XPathTransformUseCase().transform(dbFilePath, trasformerName, trasformerDirection, trasformerVersion,tranformerParmeters,OutputStreamWriter(System.out)) // then // print to console output } diff --git a/src/test/resources/transformer/verticalTransfomer.xml b/src/test/resources/transformer/verticalTransfomer.xml new file mode 100644 index 0000000000000000000000000000000000000000..229dbfa8d473b5e5ad211f84715132642f1b1d7d --- /dev/null +++ b/src/test/resources/transformer/verticalTransfomer.xml @@ -0,0 +1,23 @@ +<transformer name=""> + <composer> + <xman> + <xrules> + <xrules name="all">/database/schema/tables/tables[@name='%%table%%']/columns/columns/@name = 4</xrules> + </xrules> + </xman> + <template filename=""/> + </composer> + <splitter> + <xman> + <xrules> + <xrules name="all">/database/schema/tables/tables[@name='%%table%%']/columns/columns/@name = 4</xrules> + <xrules name="keys">/database/schema/constraints/constraints[@type='PRIMARY_KEY']/source[@table='%%table%%']/columns/columns/@name > 0</xrules> + <xrules name="lhss">/database/schema/constraints/constraints[@type='FUNCTIONAL']/source[@table='%%table%%']/columns/columns/@name</xrules> + <xrules name="rhss">/database/schema/constraints/constraints[@type='FUNCTIONAL']/target[@table='%%table%%']/columns/columns/@name</xrules> + <xrules name="rests">- all keys lhss rhss</xrules> + <xrules name="table">/database/schema/tables/tables[@name='%%table%%']/@name = 1</xrules> + </xrules> + </xman> + <template filename="transformer/vertical/decompose/vertical_decompose_1.template"/> + </splitter> +</transformer> \ No newline at end of file