@@ -1,13 +1,20 @@
package com.bogovich

import com.bogovich.NamespaceEnum.*
import com.bogovich.XbrlPeriodAttr.*
import com.bogovich.XbrlPeriodType.*
import com.bogovich.XbrlSubstitutionGroup.*
import com.bogovich.model.Account
import com.bogovich.xml.writer.dsl.DslXMLStreamWriter
import com.bogovich.xml.writer.dsl.EmptyElementDsl
import com.bogovich.xml.writer.dsl.model.*
import com.bogovich.xml.writer.dsl.model.ArcRole.*
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import java.io.FileOutputStream
import java.io.FileReader
import java.nio.file.Path
import java.nio.file.Paths
import javax.xml.stream.XMLOutputFactory

fun DslXMLStreamWriter.arcroleRef(arcroleURI: String, href: String): Unit {
@@ -77,11 +84,130 @@ fun DslXMLStreamWriter.writeArrayOfAccounts(domain: Location, accounts: List<Acc
}
}

fun DslXMLStreamWriter.namespace(ns: NamespaceEnum) = this.namespace(ns.prefix, ns.link)

fun DslXMLStreamWriter.defaultNamespace(ns: NamespaceEnum) = this.defaultNamespace(ns.link)

fun DslXMLStreamWriter.targetNamespace(ns: NamespaceEnum) = this.targetNamespace(ns.link)

fun DslXMLStreamWriter.targetNamespace(ns: String) {
this.writeAttribute("targetNamespace", ns)
this.schemaNamespace = ns
}

fun DslXMLStreamWriter.import(ns: NamespaceEnum){
"import" emptyElement {
"namespace" attr ns.link
if (ns.location.isNotEmpty()) {
"schemaLocation" attr ns.location
}
}
}

fun DslXMLStreamWriter.import(nsList: List<NamespaceEnum>) {
nsList.forEach {
import(it)
}
}

fun DslXMLStreamWriter.namespace(nsList: List<NamespaceEnum>) {
nsList.forEach {
this.namespace(it.prefix, it.link)
}
}

fun main(args: Array<String>) {
getAccountsXsdElements()
println("abc")
// generateAccountXsd()
// generateDefinitionForAccountXsd()
}


fun DslXMLStreamWriter.xsdElement(name: String, lambda: EmptyElementDsl.() -> Unit): XsdElement {
return this.xsdElement(name, name, lambda)
}

fun DslXMLStreamWriter.xsdElement(id: String, name: String, lambda: EmptyElementDsl.() -> Unit): XsdElement {
"element" emptyElement {
this.lambda()
}
return XsdElement(id, name, path, schemaNamespace)
}

enum class XbrlPeriodAttr(val value: String) {
INSTANT("instant"),
DURATION("duration")
}

enum class XbrlPeriodType(val value: String) {
DOMAIN_ITEM_TYPE("nonnum:domainItemType"),
}

fun EmptyElementDsl.periodType(period: XbrlPeriodAttr) {
"xbrli:periodType" attr period.value
}

fun EmptyElementDsl.type(type: XbrlPeriodType) {
this.type(type.value)
}

fun EmptyElementDsl.type(type: String) {
"xbrli:periodType" attr type
}

fun EmptyElementDsl.substitutionGroup(type: XbrlSubstitutionGroup) {
this.substitutionGroup(type.value)
}

fun EmptyElementDsl.substitutionGroup(type: String) {
"substitutionGroup" attr type
}

fun EmptyElementDsl.isNillable() {
"nillable" attr "true"
}

fun EmptyElementDsl.isAbstract() {
"abstract" attr "true"
}


fun generateAccountXsd() {
val accountXsdPath: Path = Paths.get("C:/staff/accountV2.xsd")
println("create ${accountXsdPath.toAbsolutePath()}")
if (!accountXsdPath.toFile().exists()) {
accountXsdPath.toFile().createNewFile()
}
val accountXsdWriter = DslXMLStreamWriter(accountXsdPath)

accountXsdWriter.document {
"schema" {
println("start schema")
namespace(listOf(XSI, XLINK, LINK, XBRLI, MODEL, NONNUM))
defaultNamespace(XSD)
targetNamespace(XSD)
import(listOf(XBRLI, MODEL, NONNUM))

val incomingBalance = xsdElement("IncomingBalance") {
periodType(INSTANT); type(DOMAIN_ITEM_TYPE); substitutionGroup(ITEM); isNillable(); isAbstract()
}

val outgoingBalance = xsdElement("OutgoingBalance") {
periodType(INSTANT); type(DOMAIN_ITEM_TYPE); substitutionGroup(ITEM); isNillable(); isAbstract()
}

val revenueDebit = xsdElement("RevenueDebit") {
periodType(INSTANT); type(DOMAIN_ITEM_TYPE); substitutionGroup(ITEM); isNillable(); isAbstract()
}

val revenueCredit = xsdElement("RevenueCredit") {
periodType(INSTANT); type(DOMAIN_ITEM_TYPE); substitutionGroup(ITEM); isNillable(); isAbstract()
}
}
}
}

fun getAccountsXsdElements() {
fun generateDefinitionForAccountXsd() {

val gson = GsonBuilder().setPrettyPrinting().create()
var personList: List<Account> = listOf()
@@ -2,14 +2,31 @@ package com.bogovich.xml.writer.dsl

import com.sun.xml.txw2.output.IndentingXMLStreamWriter
import mu.KLogging
import java.io.OutputStream
import java.nio.file.Files
import java.nio.file.Path
import java.util.zip.CheckedOutputStream
import javax.xml.stream.XMLOutputFactory
import javax.xml.stream.XMLStreamWriter



class DslXMLStreamWriter(writer: XMLStreamWriter?) : IndentingXMLStreamWriter(writer), EmptyElementDsl {

constructor(path: Path):
this(Files.newOutputStream(path)) {
this.path = path
}

constructor(outputStream: OutputStream):
this(XMLOutputFactory.newInstance().createXMLStreamWriter(outputStream,"UTF-8"))

companion object : KLogging()

private val namespaceMapping = HashMap<String, String>()
lateinit var path: Path

lateinit var schemaNamespace: String

fun document(init: xmlStreamLambda): DslXMLStreamWriter {
this.writeStartDocument()
@@ -0,0 +1,26 @@
package com.bogovich.xml.writer.dsl.model

enum class ArcRole(val url: String) {
DOMAIN_MEMBER("http://xbrl.org/int/dim/arcrole/domain-member"),
DIMENSION_DOMAIN("http://xbrl.org/int/dim/arcrole/dimension-domain")
}

enum class ArcroleRef(val arcroleURI: String, val href: String) {
ALL("http://xbrl.org/int/dim/arcrole/all",
"http://www.xbrl.org/2005/xbrldt-2005.xsd#all"),
NOT_ALL("http://xbrl.org/int/dim/arcrole/notAll",
"http://www.xbrl.org/2005/xbrldt-2005.xsd#notAll"),
DIMENSION_DEFAULT("http://xbrl.org/int/dim/arcrole/dimension-default",
"http://www.xbrl.org/2005/xbrldt-2005.xsd#dimension-default"),
DIMENSION_DOMAIN("http://xbrl.org/int/dim/arcrole/dimension-domain",
"http://www.xbrl.org/2005/xbrldt-2005.xsd#dimension-domain"),
DOMAIN_MEMBER("http://xbrl.org/int/dim/arcrole/domain-member",
"http://www.xbrl.org/2005/xbrldt-2005.xsd#domain-member"),
HYPERCUBE_DIMENSION("http://xbrl.org/int/dim/arcrole/hypercube-dimension",
"http://www.xbrl.org/2005/xbrldt-2005.xsd#hypercube-dimension")
}

data class Location(val href: String, val label: String)
data class DefinitionArc(val arcrole: ArcRole, val from: String, val to: String, val order: String = "", val targetRole: String = "")
data class DefinitionLink(val role: String, val id: String)
data class RoleRef(val href: String, val roleURI: String) // use URI?