
xsd.2.0.docs.generate_tables.xco-domain.xqm Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ojp-java-model Show documentation
Show all versions of ojp-java-model Show documentation
Generates Java model from OJP xsds using jaxb.
The newest version!
(:
: Functions evaluating domains defined by the customization document.
:)
module namespace dm="http://www.parsqube.de/ns/xco/domain";
import module namespace co="http://www.parsqube.de/ns/xco/constants"
at "xco-constants.xqm";
import module namespace dg="http://www.parsqube.de/ns/xco/debug"
at "xco-debug.xqm";
import module namespace fu="http://www.parsqube.de/ns/xco/file-util"
at "xco-file-util.xqm";
import module namespace sd="http://www.parsqube.de/ns/xco/simple-type-description"
at "xco-stype-description.xqm";
import module namespace sf="http://www.parsqube.de/ns/xco/string-filter"
at "xco-sfilter.xqm";
import module namespace u="http://www.parsqube.de/ns/xco/util"
at "xco-util.xqm";
declare namespace z="http://www.parsqube.de/ns/xco/structure";
declare variable $dm:findComps :=
map{
'type': function($domain, $namespace, $name) {
$domain//xsd[@targetNamespace eq $namespace]
//(simpleTypes/simpleType, complexTypes/complexType)[@name eq $name]},
'group': function($domain, $namespace, $name) {
$domain//xsd[@targetNamespace eq $namespace]
//groups/group[@name eq $name]},
'attributeGroup': function($domain, $namespace, $name) {
$domain//xsd[@targetNamespace eq $namespace]
//attributeGroups/attributeGroup[@name eq $name]},
'element': function($domain, $namespace, $name) {
$domain//xsd[@targetNamespace eq $namespace]
//elements/element[@name eq $name]},
'attribute': function($domain, $namespace, $name) {
$domain//xsd[@targetNamespace eq $namespace]
//attributes/attribute[@name eq $name]}
};
(:
:
: I n t e r f a c e f u n c t i o n s
:)
(:~
: Returns the file system path of a report with a given report type.
: The file path refers to the main report with that type. In order to
: retrieve the file system path of other parts of a report (e.g. the
: enum dictionary), call 'getReportPartPath'.
:
: @param reportType a report type
: @param an optional domain element
: @param options options controlling the processing
: @return file system path of the main report with that type
:)
declare function dm:getReportPath($reportType as xs:string,
$domain as element()?,
$options as map(xs:string, item()*))
as xs:string {
(: Explicit 'ofile' parameter overwrites any domain settings :)
let $ofile := $options?ofile
let $reportTypeFinal := $options?reportType
let $path :=
if ($ofile and $reportType eq $reportTypeFinal) then $ofile
(: No domain - default path depending on 'odir' and the report type :)
else if (not($domain)) then
let $odir := $options?odir
let $fname := dm:reportTypeDefaultFileName($reportType)
return $odir||'/'||$reportType||'/'||$fname
(: File path is retrieved from the compiled domain element :)
else
let $odir := $options?odir
let $reportDirRelPath := $domain/processing/reportDirRelPath[string()]
let $reportFileBaseName := $domain/processing/reportFileBaseName
let $fileExtension := dm:reportTypeFileNameExtension($reportType)
let $relPath := $reportDirRelPath ! concat(., '/')
return $odir||'/'||$reportType||'/'||$relPath||
$reportFileBaseName||'.'||$fileExtension
(: let $_DEBUG := trace($path, 'RPATH FOR: ***RTYPE='||$reportType||';DOM='||$domain/@name||': ') :)
return $path
};
(:~
: Returns the file system path of a report with a given report type
: and containing a part of the report with a given part name.
:
: @param reportType a report type
: @param reportPart a named part of the reporgt, e.g. 'enum-dict'
: @param an optional domain element
: @param options options controlling the processing
: @return file system path of the main report with that type
:)
declare function dm:getReportPartPath($reportType as xs:string,
$reportPart as xs:string?,
$domain as element()?,
$options as map(xs:string, item()*))
as xs:string {
let $mainReportPath := dm:getReportPath($reportType, $domain, $options)
return
if (not($reportPart)) then $mainReportPath
else fu:insertLabelBeforeFileNameExtension($mainReportPath, '.'||$reportPart)
};
(:~
: Returns the file system path of an input report file.
:)
declare function dm:getInputReportPath($inputReportType as xs:string,
$inputReportBaseDir as xs:string,
$domain as element(),
$options as map(xs:string, item()*))
as xs:string {
let $reportDirRelPath := $domain/processing/reportDirRelPath
let $reportFileBaseName := $domain/processing/reportFileBaseName
let $reportFileExtension := dm:reportTypeFileNameExtension($inputReportType)
return fu:applyRelPath($inputReportBaseDir, $reportDirRelPath)
||'/'||$reportFileBaseName||'.'||$reportFileExtension
};
(:~
: Returns the default file name for a given report type.
:
: @param reportType a report type
: @return the default file name
:)
declare function dm:reportTypeDefaultFileName($reportType as xs:string)
as xs:string {
switch($reportType)
case 'contab' return 'contab.html'
default return $reportType||'.xml'
};
(:~
: Returns the default file name for a given report type.
:
: @param reportType a report type
: @return the default file name
:)
declare function dm:reportTypeFileNameExtension($reportType as xs:string)
as xs:string {
switch($reportType)
case 'contab' return 'html'
default return 'xml'
};
(:
:
: C o n s t r u c t d o m a i n e l e m e n t s
:)
(:~
: Evaluates the definition of domains, returning an extended
: representation.
:
: @param custom the customization document
: @param schemas the schema elements to be reported
: @return an element describing all domains
:)
declare function dm:constructDomains($customDomains as element()?,
$schemas as element(xs:schema)*,
$options as map(xs:string, item()*))
as element(domains)? {
let $domainsParam := $options?domains
return if (not($domainsParam) and not($customDomains)) then () else
let $schemaDescriptors := $schemas/dm:xsdDescriptor(.)
let $domainElems := $customDomains/*
let $tnsDomains := $domainElems[content/foreach = 'targetNamespace']
let $xsdDomains := $domainElems[content/foreach = 'xsd']
let $filterDomains := $domainElems except ($tnsDomains, $xsdDomains)
return
if ($tnsDomains) then
error((), 'Customized target namespace domains not yet supported.')
else if ($xsdDomains) then
error((), 'Customized XSD domains not yet supported.')
else
if ($domainsParam eq 'xsd') then
dm:createXsdDomains($schemaDescriptors, $options)
else
let $domains :=
if (not($filterDomains)) then () else
dm:compileFilterDomains($schemaDescriptors, $filterDomains, $options)
return
{$domains}
};
(:
:
: C o m p i l e f i l t e r d o m a i n s
:)
(:~
: Compiles custom domain definitions, type "filter domain".
:)
declare function dm:compileFilterDomains(
$schemaDescriptors as element()*,
$customDomains as element()+,
$options as map(xs:string, item()*))
as element(domain)* {
let $activeDomains := $options?activeDomains
for $domain at $pos in $customDomains
where empty($activeDomains) or $domain/@name = $activeDomains
let $tnsPlus :=
$domain/content/targetNamespace/
dm:filterSchemaDescriptorsByTns(., $schemaDescriptors)
let $tnsMinus :=
$domain/content/exceptTargetNamespace/
dm:filterSchemaDescriptorsByTns(., $schemaDescriptors)
let $filesPlus := $domain/content/files/
dm:filterSchemaDescriptorsByFiles(., $schemaDescriptors)
let $filesMinus := $domain/content/exceptFiles/
dm:filterSchemaDescriptorsByFiles(., $schemaDescriptors)
let $selected := ($tnsPlus, $filesPlus)
[not(. = ($tnsMinus, $filesMinus))]
(: Remove repeated selections (2024-05-22, hjr) :)
let $selectedDedup :=
for $xsdd in $selected
group by $filePath := $xsdd/@filePath/lower-case(.)
return $xsdd[1]
let $selectedOrdered :=
dm:sortSchemaDescriptors($selectedDedup, $domain)
let $id := 'd'||$pos
let $name := ($domain/@name, $id)[1]
let $summary := $domain/dm:filterDomainSummary(.)
return
{
{
$selectedOrdered
} ,
dm:compileProcessingElem($domain/processing, $options)
}
};
(:~
: Filters schema descriptors by target namespace.
:)
declare function dm:filterSchemaDescriptorsByTns(
$tns as xs:string,
$schemaDescriptors as element()*)
as element()* {
let $sfilter := sf:compileStringFilter($tns)
return
$schemaDescriptors
[sf:matchesStringFilter(string(@targetNamespace), $sfilter)]
};
(:~
: Filters schema descriptors by file name/path constraints.
:)
declare function dm:filterSchemaDescriptorsByFiles(
$files as element(),
$schemaDescriptors as element()*)
as element()* {
let $dir := $files/@dir
let $name := $files/@name
let $nameFilter := sf:compileStringFilter($name)
let $deep := $files/@deep/xs:boolean(.)
let $dirFilter :=
if (starts-with($dir, '/')) then
if ($deep) then $dir||'(/.*)?$'
else $dir||'$'
else if ($deep) then '(.*/)?'||$dir||'(/.*/)?$'
else '(.*/)?'||$dir||'$'
return
for $schemaDesc in $schemaDescriptors
where sf:matchesStringFilter($schemaDesc/@fileName, $nameFilter)
let $folder := $schemaDesc/@filePath ! file:parent(.) ! u:normalizeUri(., ())
where matches($folder, $dirFilter, 'i')
return $schemaDesc
};
declare function dm:filterDomainSummary($domain as element())
as xs:string {
let $tns := $domain/content/targetNamespace/concat('tns=', .) => string-join(', ')
let $etns := $domain/content/exceptTargetNamespace/concat('~tns=', .) => string-join(', ')
let $files := $domain/content/files/
concat('files=[dir=', @dir, ', name=', @name, ', deep=', (@deep, 'false')[1], ']')
=> string-join(', ')
let $efiles := $domain/content/exceptFiles/
concat('~files=[dir=', @dir, ', name=', @name, ', deep=', (@deep, 'false')[1], ']')
=> string-join(', ')
return string-join(($tns, $etns, $files, $efiles)[string()], '; ')
};
(:
:
: C o m p i l e c u s t o m d o m a i n s
:)
(:~
: Copiles the processing element of custom domain elements.
:)
declare function dm:compileProcessingElem($processing as element(processing),
$options as map(xs:string, item()*))
as element(processing) {
$processing ! dm:compileProcessingElemREC(., $options)
};
(:~
: Recursive helper function of `compileProcessingElem`.
:)
declare function dm:compileProcessingElemREC($n as node(),
$options as map(xs:string, item()*))
as node()* {
typeswitch($n)
case document-node() return document {$n/node() ! dm:compileProcessingElemREC(., $options)}
(: Add elements: , :)
case element(processing) return
let $reportType := $options?reportType
let $reportDirRelPath := ($n/reportDirRelPath, '')[1]
let $forEachDomain := ($options?forEachDomain, false())[1]
return
element {node-name($n)} {
$n/@* ! dm:compileProcessingElemREC(., $options),
$n/node() ! dm:compileProcessingElemREC(., $options),
{$forEachDomain} ,
{$reportDirRelPath}
}
case element(reportDirRelPath) return () (: already processed :)
case element(title) return
let $value := normalize-space($n)
let $title :=
if (starts-with($value, '#')) then
let $key := $value ! substring(., 2)
return $options($key)
else $value
return {$title}
case element() return
element {node-name($n)} {
$n/@* ! dm:compileProcessingElemREC(., $options),
$n/node() ! dm:compileProcessingElemREC(., $options)
}
case attribute() return $n
default return $n
};
(:
:
: C r e a t e X S D d o m a i n s
:)
(:~
: Creates XSD domains, one for each XSD.
:
: @param schemaDescriptors schema descriptors
: @param options options controlling the processing
: @return XSD domains
:)
declare function dm:createXsdDomains($schemaDescriptors as element()*,
$options as map(xs:string, item()*))
as element() {
let $odir := $options?odir
let $dir := $options?dir
return
(: Check should have been performed before - here only minimal check :)
if (not($odir) or not($dir)) then error() else
let $sortedSchemaDescriptors :=
for $schemaDesc in $schemaDescriptors
let $filePath := $schemaDesc/@filePath
order by $filePath
return $schemaDesc
let $domains :=
for $schemaDesc at $pos in $sortedSchemaDescriptors
let $id := 'd'||$pos
let $filePath := $schemaDesc/@filePath
let $fileRelPath := fu:getRelPath($dir, $filePath)
let $fileName := $filePath ! file:name(.)
let $relParentPath := $fileRelPath ! fu:getRelParentPath(.)
let $dirInfo := $relParentPath[string()] ! {.||'/ '}
let $dirPath := $filePath ! fu:getParentPath(.)
let $dirRelPath := fu:getRelPath($dir, $dirPath)
let $fname := $schemaDesc/@fileName
let $fileBaseName := $fname ! fu:removeFileExtension(.)
return
{
{$schemaDesc} ,
{'Contents: ', $dirInfo, $fileName}
{'Enumeration dictionary: '||$fileRelPath}
{$fileBaseName}
{$dirRelPath}
}
return
{
$domains
}
};
(:
: D o m a i n r e l a t e d u t i l i t i e s
:)
(:~
: Maps the domains to a sequence of maps, each one containing
: a domain element and the components belonging to that domain.
:
: Map structure:
: {
: 'domain': ...
: 'comps': ... , ... , ...
: }
:
: @param comps schema components
: @param domains domain elements, defining domains
: @param schemas the schemas to be evaluated
: @param options options controlling the processing
: @return a sequence of maps
:)
declare function dm:getDomainComponentMaps(
$comps as element()*,
$domains as element(domain)*,
$schemas as element(xs:schema)*,
$options as map(xs:string, item()*))
as map(xs:string, item()*)* {
let $xsdDict :=
map:merge(
for $comp in $comps
let $xsdpath := $comp/base-uri(.) ! u:normalizeUri(., ())
group by $xsdpath
return map:entry($xsdpath, $comp)
)
for $domain in $domains
let $domainComps :=
for $xsd in $domain/content/xsd
let $filePath := $xsd/@filePath ! u:normalizeUri(., ())
let $xsdComps := $xsdDict($filePath)
return $xsdComps
return
map{'domain': $domain, 'comps': $domainComps}
};
(:~
: Maps the domains to a sequence of maps, each one containing
: a domain element and the corresponding components, grouped
: by containing XSD.
:
: Map structure:
: {
: 'domain': ...
: 'xsds':
: $filePath: ... , ... , ...
: }
:
: @param comps schema components
: @param domains domain elements, defining domains
: @param schemas the schemas to be evaluated
: @param options options controlling the processing
: @return a sequence of maps
:)
declare function dm:getDomainXsdComponentMaps(
$comps as element()*,
$domains as element(domain)*,
$schemas as element(xs:schema)*,
$options as map(xs:string, item()*))
as map(xs:string, item()*)* {
(: map: xsd-path => components :)
let $xsdDict :=
map:merge(
for $comp in $comps
let $xsdpath := $comp/base-uri(.) ! u:normalizeUri(., ())
group by $xsdpath
return map:entry($xsdpath, $comp)
)
for $domain in $domains
let $xsdComps := map:merge(
for $xsd in $domain/content/xsd
let $filePath := $xsd/@filePath ! u:normalizeUri(., ())
let $xsdComps := $xsdDict($filePath)
return map:entry($filePath, $xsdComps))
return
map{'domain': $domain, 'xsds': $xsdComps}
};
(:
:
: U t i l i t y f u n c t i o n s
:)
(:~
: Maps an XSD to an element summarizing XSD properties and
: content.
:)
declare function dm:xsdDescriptor($schema as element(xs:schema))
as element() {
let $filePath := $schema/base-uri(.) ! u:normalizeUri(., ())
let $fileName := $filePath ! file:name(.)
let $tns := $schema/@targetNamespace
let $stypes := $schema/xs:simpleType/@name/string() => sort()
let $ctypes := $schema/xs:complexType/@name/string() => sort()
let $elements := $schema/xs:element/@name/string() => sort()
let $attributes := $schema/xs:attribute/@name/string() => sort()
let $groups := $schema/xs:group/@name/string() => sort()
let $attributeGroups := $schema/xs:attributeGroup/@name/string() => sort()
return
{
{
$elements !
} ,
{
$attributes !
} ,
{
$stypes !
} ,
{
$ctypes !
} ,
{
$groups !
} ,
{
$attributeGroups !
}
}
};
(:~
: Sort schema descriptors. A schema descriptor is an element
: with an attribute @filePath, containing the file path of
: a schema.
:)
declare function dm:sortSchemaDescriptors(
$schemaDescriptors as element()*,
$domain as element(domain))
as element()* {
let $first := $domain/processing/order/first
let $last := $domain/processing/order/last
return
if (not(($first, $last))) then
for $sd in $schemaDescriptors
order by $sd/@filePath/lower-case(.)
return $sd
else
$schemaDescriptors
=> dm:sortSchemaDescriptorsFirstOrLast($first)
=> dm:sortSchemaDescriptorsFirstOrLast($last)
};
(:~
: Sorts a sequence of schema descriptors (1) by the position of
: a matching file path in $firstOrLast, (2) by file path.
:)
declare function dm:sortSchemaDescriptorsFirstOrLast(
$schemaDescriptors as element()*,
$firstOrLast as element()?)
as element()* {
if (not($firstOrLast)) then $schemaDescriptors else
let $defaultPos := if ($firstOrLast/self::first) then 100000 else 0
for $sd in $schemaDescriptors
let $filePath := $sd/@filePath
let $pos :=
let $match := $firstOrLast/xsd[matches($filePath, '(^|/)'||@filePath, 'i')]
return
if (not($match)) then $defaultPos
else count($match/preceding-sibling::xsd) + 1
(: let $_DEBUG := trace('pos='||$pos||' filePath='||$filePath) :)
order by $pos, $filePath
return $sd
};
© 2015 - 2025 Weber Informatics LLC | Privacy Policy