############################################################################### ## ## ## ALEXANDRIA DIGITAL LIBRARY ## ## University of California at Santa Barbara ## ## ## ## ------------------------------------------------------------------------- ## ## ## ## Copyright (c) 2003 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/bucket99/paradigms/RCS/Adaptor_TemporalIsContainedInRewriter.py,v 1.1 2003/10/23 21:20:53 gjanee Exp $ # SYNOPSIS # # Adaptor_TemporalIsContainedInRewriter (paradigm, # minDate=101, maxDate=99991231) # # paradigm # The underlying temporal paradigm. # # minDate # The earliest supported date, expressed as an integer in # the encoding YYYYMMDD. The default value of 101 # corresponds to 0000-01-01, i.e., to January 1, 0000. # Notice that leading zeros have been stripped off to # suppress Python's octal interpretation! # # maxDate # The latest supported date, expressed as an integer in # the encoding YYYYMMDD. The default value of 99991231 # corresponds to December 31, 9999. # # DESCRIPTION # # Adds support for the "is-contained-in" operator to a temporal # paradigm (the "underlying" paradigm) that doesn't otherwise # support it. # # Several of the temporal paradigms, such as Temporal_BeginEnd and # Temporal_SingleDate, do not support the "is-contained-in" # operator if the table cardinality is "0+" or "1+". This # paradigm adds support by rewriting a temporal constraint # # C("is-contained-in", begin, end) # # as three constraints, # # C("is-contained-in", begin, end) AND NOT # (C("overlaps", minDate, begin-1) OR # C("overlaps", end+1, maxDate)) # # The underlying paradigm is then used to individually translate # the three new constraints. # # Exceptions thrown: # # begin date precedes earliest supported date # end date follows latest supported date # # AUTHOR # # Greg Janee # gjanee@alexandria.ucsb.edu # # HISTORY # # $Log: Adaptor_TemporalIsContainedInRewriter.py,v $ # Revision 1.1 2003/10/23 21:20:53 gjanee # Initial revision # import types import edu.ucsb.adl.middleware M = edu.ucsb.adl.middleware import UniversalTranslator UT = UniversalTranslator _monthLengths = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] def _increment (date): y = date/10000 m = (date%10000)/100 d = date%100 d += 1 if d > _monthLengths[m] and\ (d != 29 or y%4 != 0 or (y%100 == 0 and y%400 != 0)): d = 1 m += 1 if m > 12: m = 1 y += 1 return y*10000 + m*100 + d def _decrement (date): y = date/10000 m = (date%10000)/100 d = date%100 if d > 1: d -= 1 elif m > 1: m -= 1 d = _monthLengths[m] if m == 2 and y%4 == 0 and (y%100 != 0 or y%400 == 0): d = 29 else: d = 31 m = 12 y -= 1 return y*10000 + m*100 + d class Adaptor_TemporalIsContainedInRewriter (UT.Paradigm): def __init__ (self, paradigm, minDate=101, maxDate=99991231): UT.assertType(paradigm, UT.Paradigm) UT.assertType(minDate, types.IntType) assert minDate >= 101, "invalid minimum date: " + str(minDate) # i.e., '0000-01-01' UT.assertType(maxDate, types.IntType) assert maxDate <= 99991231, "invalid maximum date: " + str(maxDate) assert minDate < maxDate, "invalid date limits" self.paradigm = paradigm self.minDate = minDate self.maxDate = maxDate def translateBucketAtomic (self, constraint, vocabularies): UT.assertType(constraint, M.Query.TemporalConstraint) assert constraint.getOperator() in UT.standardTemporalOperators,\ "unsupported operator: " + constraint.getOperator() if constraint.getBegin() < self.minDate: raise UT.QueryError, "temporal constraint target range begin " +\ "date precedes earliest supported date" if constraint.getEnd() > self.maxDate: raise UT.QueryError, "temporal constraint target range end " +\ "date follows latest supported date" if constraint.getOperator() == "is-contained-in" and\ (constraint.getBegin() > self.minDate or\ constraint.getEnd() < self.maxDate): exclusions = [] if constraint.getBegin() > self.minDate: c = M.Query.TemporalConstraint(constraint.getBucket(), constraint.getField(), "overlaps", self.minDate, _decrement(constraint.getBegin())) q = self.paradigm.translateBucketAtomic(c, vocabularies) UT.assertPolytype(q, [UT.Select, UT.Query]) exclusions += [q] if constraint.getEnd() < self.maxDate: c = M.Query.TemporalConstraint(constraint.getBucket(), constraint.getField(), "overlaps", _increment(constraint.getEnd()), self.maxDate) q = self.paradigm.translateBucketAtomic(c, vocabularies) UT.assertPolytype(q, [UT.Select, UT.Query]) exclusions += [q] query = self.paradigm.translateBucketAtomic(constraint, vocabularies) UT.assertPolytype(query, [UT.Select, UT.Query]) return UT._unify("AND NOT", [query, UT._unify("OR", exclusions)]) else: return self.paradigm.translateBucketAtomic(constraint, vocabularies)