source: cows/trunk/cows/model/domain.py @ 3553

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/cows/trunk/cows/model/domain.py@4060
Revision 3553, 5.1 KB checked in by spascoe, 12 years ago (diff)

Moved all the model classes into their own sub-module.

Line 
1# Copyright (C) 2007 STFC & NERC (Science and Technology Facilities Council).
2# This software may be distributed under the terms of the
3# Q Public License, version 1.0 or later.
4# http://ndg.nerc.ac.uk/public_docs/QPublic_license.txt
5"""
6Classes modelling the OWS Domain package v1.1.0.
7
8@author: Stephen Pascoe
9"""
10
11class Domain(object):
12    """
13    @note: It seems unnecessary to model Domain and UnNamedDomain seperately.
14        This class models both.
15
16    @ivar defaultValue
17    @type defaultValue: None or str
18    @ivar metadata
19    @type metadata: iterable of Metadata
20    @ivar meaning
21    @type meaning: None, DomainMetadata or str
22    @ivar dataType
23    @type dataType: None, DomainMetadata or str
24    @ivar valuesUnit: The units of measure or reverence System.  This is a
25        simplification of the schema that defines valuesUnit to be a union
26        of either referenceSystems or UOM.  It's not clear how this should
27        be implemented yet.
28    @type valuesUnit: None or DomainMetadata
29    @ivar possibleValues
30    @type possibleValues: PossibleValues
31
32    """
33    def __init__(self,  defaultValue=None, possibleValues=None, metadata=[],
34                 meaning=None, dataType=None, valuesUnit=None):
35        if possibleValues is None:
36            possibleValues = PossibleValues.fromAnyValue()
37        self.possibleValues = possibleValues
38        self.defaultValue = defaultValue
39        self.metadata = metadata
40        self.meaning = meaning
41        self.dataType = dataType
42        self.valuesUnit = valuesUnit
43
44    def isValidValue(self, value):
45        return self.possibleValues.isValidValue(value)
46
47class PossibleValues(object):
48    """
49    @note: All members of the OWS PossibleValues Union are modelled in this
50        class.
51
52    @cvar ANY_VALUE: Flag selecting anyValue union attribute.
53    @cvar NO_VALUES: Flag selecting noValues union attribute.
54    @cvar ALLOWED_VALUES: Flag selecting AllowedValues union attribute.
55    @cvar VALUES_REFERENCE: Flag selecting valuesListReference union attribute
56    @ivar type: set to one of the above flags to select union attribute.
57
58    @ivar allowedValues: A collection of either values or ranges
59    @type allowedValues: Iterable of str or Range objects
60    @ivar valuesRefName
61    @type valuesRefName: None or str
62    @ivar valuesRefURI
63    @type valuesRefURI: None or str
64
65    @todo: Range checking
66    @todo: Converting into numeric types
67   
68    """
69    ANY_VALUE = 1
70    NO_VALUES = 2
71    ALLOWED_VALUES = 3
72    VALUES_REFERENCE = 4
73   
74    def __init__(self, type, allowedValues=[], valuesRefName=None,
75                 valuesRefURI=None):
76        self.type = type
77        self.allowedValues = allowedValues
78        self.valuesRefName = valuesRefName
79        self.valuesRefURI = valuesRefURI
80
81    # The union is implemented by providing a class method for each member.
82    @classmethod
83    def fromAnyValue(klass):
84        k = klass(klass.ANY_VALUE)
85        return k
86
87    @classmethod
88    def fromNoValues(klass):
89        k = klass(klass.NO_VALUES)
90        return k
91
92    @classmethod
93    def fromAllowedValues(klass, valueOrRanges):
94        k = klass(klass.ALLOWED_VALUES, allowedValues=valueOrRanges)
95        return k
96
97    @classmethod
98    def fromValuesReference(klass, name, uri):
99        k = klass(klass.VALUES_REFERENCE, valuesRefName=name, valuesRefURI=uri)
100        return k
101
102    def isValidValue(self, value):
103        """
104        Check that value is valid within domain.
105
106        """
107        if self.type == self.ANY_VALUE:
108            return True
109
110        if self.type == self.NO_VALUES:
111            return not value
112
113        if self.type == self.ALLOWED_VALUES:
114            for vr in self.allowedValues:
115                if isinstance(vr, Range) and vr.isInRange(value):
116                    return True
117                if value == vr:
118                    return True
119            return False
120               
121        if self.type == self.VALUES_REFERENCE:
122            raise NotImplementedError
123       
124
125class Range(object):
126    """
127    @ivar minimumValue
128    @type minimumValue: None or str
129    @ivar maximumValue
130    @type maximumValue: None or str
131    @ivar spacing
132    @type spacing: None or str
133    @ivar rangeClosure
134    @type rangeClosure: One of Range._rangeClosureValues
135
136    """
137    _rangeClosureValues = [None, 'open', 'closed', 'open-closed',
138                           'closed-open']
139   
140    def __init__(self, minumumValue=None, maximumValue=None, spacing=None,
141                 rangeClosure=None):
142        if rangeClosure not in Range._rangeClosureValues:
143            raise ValueError, 'Incorrect rangeClosure value'
144
145        self.minimumValue = minimumValue
146        self.maximumValue = maximumValue
147        self.spacing = spacing
148        self.rangeClosure = rangeClosure
149
150    def isInRange(self, value):
151        raise NotImplementedError
152
153class DomainMetadata(str):
154    """
155    If you wish to attach a URI to DomainMetadata use this class, otherwise
156    you can substitute it with str.
157   
158    @ivar reference: A URI
159    @type reference: None or str
160
161    """
162
163    def __init__(self, name, reference=None):
164        super(DomainMetadata, self).__init__(name)
165        self.reference = reference
Note: See TracBrowser for help on using the repository browser.