############################################################################### ## ## ## ALEXANDRIA DIGITAL LIBRARY ## ## University of California at Santa Barbara ## ## ## ## ------------------------------------------------------------------------- ## ## ## ## Copyright (c) 2005 by the Regents of the University of California ## ## All rights reserved ## ## ## ## Redistribution and use in source and binary forms, with or without ## ## modification, are permitted provided that the following conditions are ## ## met: ## ## ## ## 1. Redistributions of source code must retain the above copyright ## ## notice, this list of conditions, and the following disclaimer. ## ## ## ## 2. Redistributions in binary form must reproduce the above copyright ## ## notice, this list of conditions, and the following disclaimer in ## ## the documentation and/or other materials provided with the ## ## distribution. ## ## ## ## 3. All advertising materials mentioning features or use of this ## ## software must display the following acknowledgement: This product ## ## includes software developed by the Alexandria Digital Library, ## ## University of California at Santa Barbara, and its contributors. ## ## ## ## 4. Neither the name of the University nor the names of its ## ## contributors may be used to endorse or promote products derived ## ## from this software without specific prior written permission. ## ## ## ## THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY ## ## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ## ## WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE ## ## DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ## ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ## ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ## ## OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ## ## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ## ## STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ## ## ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ## ## POSSIBILITY OF SUCH DAMAGE. ## ## ## ############################################################################### # $Header: /export/home/gjanee/mm/bucket_types/RCS/temporal.py,v 1.1 2005/02/10 23:54:19 gjanee Exp $ # DESCRIPTION # # The "temporal" bucket type. # # AUTHOR # # Greg Janee # gjanee@alexandria.ucsb.edu # # HISTORY # # $Log: temporal.py,v $ # Revision 1.1 2005/02/10 23:54:19 gjanee # Initial revision # import re from ADL_mapper import bucketType, fatal from bucket_types.utils import checkValue, encodeField, fieldErrorClause def _validate (bucket, field, value, strict): value = checkValue(bucket, "temporal", ["!", "!!"], field, value, strict) if value == None: return None for date in value: if _validateDate(bucket, field, date, strict) == None: return None if len(value) == 1: return (field, value) else: begin = value[0] end = value[1] while len(begin) < len(end): begin += "-01" while len(begin) > len(end): if len(end) == 4: end += "-12" else: end += "-31" if begin > end: if strict: fatal(("invalid value mapped to temporal bucket '%s'%s: " +\ "range end date precedes begin date: [%s, %s]") %\ (bucket, fieldErrorClause(field), begin, end)) else: return None if begin == end: return (field, (begin,)) else: return (field, (begin, end)) _monthLengths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] _dateParser = re.compile("(\d{4})(-\d{2})?(-\d{2})?$") def _validateDate (bucket, field, date, strict): match = _dateParser.match(date) if match: year = int(match.group(1)) if match.group(2) != None: month = int(match.group(2)[1:]) if month < 1 or month > 12: if strict: fatal(("invalid value mapped to temporal bucket '%s'%s:" +\ " month out of range: %s") % (bucket, fieldErrorClause(field), date)) else: return None if match.group(3) != None: day = int(match.group(3)[1:]) if day < 1 or day > _monthLengths[month-1]: if month == 2 and day == 29: if year%4 != 0 or (year%100 == 0 and year%400 != 0): if strict: fatal(("invalid value mapped to temporal " +\ "bucket '%s'%s: not a leap year: %s") %\ (bucket, fieldErrorClause(field), date)) else: return None else: if strict: fatal(("invalid value mapped to temporal " +\ "bucket '%s'%s: day out of range: %s") %\ (bucket, fieldErrorClause(field), date)) else: return None return date else: if strict: fatal(("invalid value mapped to temporal bucket '%s'%s: invalid" +\ " date: %s") % (bucket, fieldErrorClause(field), date)) else: return None def _encode (document, field, value): tv = document.createElement("temporal-value") encodeField(document, tv, field) if len(value) == 1: d = document.createElement("date") d.appendChild(document.createTextNode(value[0])) tv.appendChild(d) else: r = document.createElement("range") b = document.createElement("begin") b.appendChild(document.createTextNode(value[0])) r.appendChild(b) e = document.createElement("end") e.appendChild(document.createTextNode(value[1])) r.appendChild(e) tv.appendChild(r) return tv bucketType("temporal", _validate, _encode)