PageRenderTime 19ms CodeModel.GetById 10ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/xquery/utils.xqm

http://transcriptstudio4isha.googlecode.com/
Unknown | 278 lines | 247 code | 31 blank | 0 comment | 0 complexity | 30f4bd38633214f73675d0be5afa200b MD5 | raw file
  1xquery version "1.0";
  2
  3module namespace utils = "http://www.ishafoundation.org/ts4isha/xquery/utils";
  4
  5import module namespace functx = "http://www.functx.com" at "functx.xqm";
  6import module namespace transform = "http://exist-db.org/xquery/transform";
  7
  8declare namespace xmldb = "http://exist-db.org/xquery/xmldb";
  9declare namespace util = "http://exist-db.org/xquery/util";
 10
 11declare variable $utils:MAX_FILENAME_LENGTH := 200;
 12
 13declare variable $utils:ts4ishaCollectionPath := '/db/ts4isha';
 14declare variable $utils:dataCollectionPath := concat($utils:ts4ishaCollectionPath, '/data');
 15declare variable $utils:dataCollection := collection($utils:dataCollectionPath);
 16declare variable $utils:referenceCollectionPath := concat($utils:ts4ishaCollectionPath, '/reference');
 17declare variable $utils:referenceCollection := collection($utils:referenceCollectionPath);
 18declare variable $utils:xsltCollectionPath := concat($utils:ts4ishaCollectionPath, '/xslt');
 19declare variable $utils:tempCollectionPath := concat($utils:ts4ishaCollectionPath, '/temp');
 20
 21declare function utils:create-collection($path as xs:string, $dbaOnly as xs:boolean) as xs:string
 22{
 23	if ($dbaOnly and not(utils:is-current-user-admin())) then
 24		error(xs:QName('illegal-access-exception'), concat('Only dba allowed to create collection: ', $path))
 25	else
 26		utils:create-collection-internal('/', tokenize($path, '/'))
 27};
 28
 29declare function utils:create-collection-internal($baseCollection as xs:string, $seq as xs:string*) as xs:string
 30{
 31	if (empty($seq)) then
 32		$baseCollection
 33	else
 34		let $newBaseCollection :=
 35			if ($seq[1] = '') then
 36				$baseCollection
 37			else
 38				xmldb:create-collection($baseCollection, $seq[1])
 39		let $newSeq := $seq[position() > 1]
 40		return utils:create-collection-internal($newBaseCollection, $newSeq)
 41};
 42
 43declare function utils:transform($doc as element(), $xsltDocName as xs:string, $params as element()?) as node()?
 44{
 45	transform:transform($doc, utils:xsltDoc($xsltDocName), $params)
 46};
 47
 48declare function utils:xsltDoc($docName as xs:string) as node()?
 49{
 50	doc(concat($utils:xsltCollectionPath, '/', $docName))
 51};
 52
 53declare function utils:is-current-user-admin() as xs:boolean?
 54{
 55	let $currentUser := xmldb:get-current-user()
 56	return
 57		xmldb:is-admin-user($currentUser)
 58};
 59declare function utils:is-current-user-in-group($group as xs:string) as xs:boolean?
 60{ 
 61	let $currentUser := xmldb:get-current-user()
 62	let $groups := xmldb:get-user-groups($currentUser) 
 63	return
 64		contains($groups, $group)
 65};
 66
 67declare function utils:get-event($eventId as xs:string) as element()?
 68{
 69	$utils:dataCollection/event[@id = $eventId]
 70};
 71
 72declare function utils:get-session($sessionId as xs:string) as element()?
 73{
 74	$utils:dataCollection/session[@id = $sessionId]
 75};
 76
 77declare function utils:get-event-type($eventTypeId as xs:string?) as element()?
 78{
 79	if (not(exists($eventTypeId))) then
 80		()
 81	else
 82		$utils:referenceCollection/reference//eventType[@id = $eventTypeId]
 83};
 84
 85declare function utils:get-device-code-element($deviceCode as xs:string) as element()?
 86{
 87	$utils:referenceCollection/reference//deviceCode[@id = $deviceCode]
 88};
 89
 90declare function utils:set-child-element($existingParentElement as element(), $newChildElement as element()) as element()?
 91{
 92	let $childTagName := local-name($newChildElement)
 93	let $existingChildElement := $existingParentElement/*[local-name(.) eq $childTagName]
 94	return
 95		if (empty($existingChildElement)) then
 96			let $null := update insert $newChildElement into $existingParentElement 
 97			return ()
 98		else if (exactly-one($existingChildElement)) then
 99			let $null := update replace $existingChildElement with $newChildElement
100			return $existingChildElement
101		else
102			error((), concat('More the one child element named: ', $childTagName))
103};
104
105declare function utils:store($documentURI as xs:string, $xml as element()) as xs:string
106{
107	let $xml := utils:remove-attributes($xml, '_document-uri')
108	let $docName := tokenize($documentURI, '/')[last()]
109	let $collectionName := substring-before($documentURI, concat('/', $docName))
110	return
111		xmldb:store($collectionName, $docName, $xml)
112};
113
114(: modified because there seems to be a bug in eXist usign the QName - https://sourceforge.net/tracker/index.php?func=detail&aid=1992594&group_id=17691&atid=117691 :)
115declare function utils:add-attributes($elements as element()*, $attrNames as xs:string*, $attrValues as xs:anyAtomicType*) as element()? {
116	for $element in $elements
117	return element { node-name($element)}
118	{
119		for $attrName at $seq in $attrNames
120		return if ($element/@*[local-name(.) = $attrNames])
121		       then ()
122		       else attribute {$attrName}
123		                      {$attrValues[$seq]},
124		$element/@*,
125		$element/node()
126	}
127};
128
129declare function utils:remove-attributes ($elements as element()*, $attrNames as xs:string*) as element() {
130	for $element in $elements
131	return element
132		{node-name($element)}
133		{$element/@*[not(local-name(.) = $attrNames)],
134		$element/node() }
135};
136 
137declare function utils:is-valid-date-string($dateString as xs:string?) as xs:boolean
138{
139	if (not(exists($dateString))) then
140		false()
141	else
142	(
143		let $dateString := replace($dateString, '[^\d]', '')
144		return
145			if (string-length($dateString) < 8) then
146				false()
147			else
148				let $year := xs:integer(substring($dateString, 1, 4))
149				let $month := xs:integer(substring($dateString, 5, 2))
150				let $day := xs:integer(substring($dateString, 7, 2))
151				return
152					$year >= 1 and $month >= 1 and $month <= 12 and $day >= 1 and $day <= 31 
153	)		
154};
155
156(:
157	$dateString can be in various formats but must be in order (year(4), month(2), date(2)) with no digits in between
158	            e.g. '20090320', '2009/03/20', '2009-03-20T18:30:00'
159:)
160declare function utils:date-string-to-date($dateString as xs:string?) as xs:date?
161{
162	if (not(utils:is-valid-date-string($dateString))) then
163	()
164	else
165	(
166		(: make sure it doesnt have separators (but keep the 'x' which represents unknown) :)
167		let $dateString := replace($dateString, '[^\d]', '')
168		let $standardDateString :=
169			concat(substring($dateString, 1, 4), '-', 
170			       substring($dateString, 5, 2), '-',
171			       substring($dateString, 7, 2))
172		return
173			xs:date($standardDateString)
174	)
175};
176
177declare function utils:left-pad-string($stringToPad as xs:string, $minLength as xs:integer) as xs:string
178{
179	let $numExtra := $minLength - string-length($stringToPad)
180	return
181		if ($numExtra > 0) then
182		(
183			string-join((for $i in (1 to $numExtra) return '0', $stringToPad), '')
184		)
185		else
186		(
187			$stringToPad
188		)
189};
190
191(: if either (or both) args are empty then empty sequence is returned :)
192declare function utils:days-diff($date1 as xs:date?, $date2 as xs:date?) as xs:integer?
193{
194	if (count(($date1, $date2)) < 2) then
195		()
196	else
197		let $days := days-from-duration($date2 - $date1)
198		return $days
199};
200
201declare function utils:make-filename-friendly($rawFilename as xs:string) as xs:string
202{
203	utils:make-filename-friendly($rawFilename, ())
204};
205
206declare function utils:make-filename-friendly($rawFilename as xs:string, $maxLength as xs:integer?) as xs:string
207{
208	let $maxLength := ($maxLength, $utils:MAX_FILENAME_LENGTH)[1]
209	return
210		substring(replace(replace($rawFilename, '\s+', '-'), '[^a-z0-9\-_]', ''), 0, $maxLength)
211};
212
213declare function utils:build-event-path($event as element()) as xs:string
214{
215	let $collectionName := concat($utils:dataCollectionPath, '/', $event/@type)
216	let $docName := string-join(($event/@id, utils:build-event-full-name($event)), '_')
217	return concat($collectionName, '/', $docName, '.xml')
218};
219
220declare function utils:build-event-full-name($event as element()) as xs:string?
221{
222	utils:build-event-full-name($event, ())
223};
224
225declare function utils:build-event-full-name($event as element(), $maxLength as xs:integer?) as xs:string?
226{
227	let $fullName := lower-case(string-join(($event/metadata/@startAt, $event/metadata/@subTitle, $event/metadata/@location, $event/metadata/@venue), '_'))
228	let $fullName := utils:make-filename-friendly($fullName, $maxLength)
229	return
230		if (string-length($fullName) > 0) then
231			$fullName
232		else
233			()
234};
235
236declare function utils:build-session-path($sessionXML as element()) as xs:string
237{
238	let $eventXML := utils:get-event($sessionXML/@eventId)
239	let $collectionName := util:collection-name($eventXML)
240	let $docName := string-join(($sessionXML/@id, utils:build-session-full-name($sessionXML, $eventXML)), '_')
241	return concat($collectionName, '/', $docName, '.xml')
242};
243
244declare function utils:build-session-full-name($sessionXML as element(), $eventXML as element()) as xs:string?
245{
246	utils:build-session-full-name($sessionXML, $eventXML, ())
247};
248
249declare function utils:build-session-full-name($sessionXML as element(), $eventXML as element(), $maxLength as xs:integer?) as xs:string?
250{
251	let $metadataXML := $sessionXML/metadata[1]
252	let $fullName :=
253		lower-case(string-join( 
254			(
255				utils:build-event-full-name($eventXML, max(($maxLength idiv 2, $maxLength - 50)))
256				,
257				let $eventDate := utils:date-string-to-date($eventXML/metadata/@startAt)
258				let $sessionDate := utils:date-string-to-date($metadataXML/@startAt)
259				let $daysDiff := utils:days-diff($eventDate, $sessionDate)
260				return
261					if (exists($daysDiff) and $daysDiff >= 0) then
262						concat('day-', $daysDiff + 1)
263					else
264						()
265				,
266				$metadataXML/@subTitle
267			)
268			,
269			'_'
270		))
271	let $fullName := utils:make-filename-friendly($fullName, $maxLength)
272	return
273		if (exists($fullName) and string-length($fullName) > 0) then
274			$fullName
275		else
276			()
277};
278