Python: add asDateTime to Variant
[smartapi.git] / Common / Python / SmartAPI / rdf / Variant.py
1 from SmartAPI.common.PROPERTY import PROPERTY
2 from SmartAPI.common.RESOURCE import RESOURCE
3 from SmartAPI.common.VARIANT import VARIANT
4 from SmartAPI.model.Obj import Obj
5 from SmartAPI.rdf.Resource import Resource
6 from SmartAPI.rdf.List import List
7 from SmartAPI.common.Tools import Tools
8
9 from rdflib import Literal, BNode, URIRef, XSD
10
11 import datetime
12 import isodate
13 from isodate.duration import Duration
14 import traceback
15
16 class Variant(object):
17
18         def __init__(self, value = None):
19                 self.variant = value
20         
21         def set(self, value):
22                 self.variant = value
23         
24         def serialize(self, model):
25                 if self.isObj() or self.isVariant():
26                         return self.variant.serialize(model)
27                 elif self.isDuration():
28                         return model.createTypedLiteral(isodate.duration_isoformat(self.variant), XSD.duration)
29                 else:
30                         return self.asTerm()
31
32         @classmethod
33         def parse(cls, element, custom_classes = None):
34                 # get predicate and object
35                 if isinstance(element, Resource):
36                         if element.isLiteral():
37                                 return cls.parse(element.getNode())
38                         elif element.isUri():
39                                 return cls.parse(element.getNode())
40                         else:
41                                 klass = Tools().getResourceClass(element, default = Obj, custom_classes = custom_classes)
42                                 if klass is not None:
43                                         v = klass().parse(element, custom_classes = custom_classes)
44                                 else:
45                                         # None found, resort to Variant
46                                         v = cls()
47                                         propsNum = 0
48                                         for stmt in element.findProperties():
49                                                 propsNum = propsNum + 1
50                                                 v.parse(stmt, custom_classes = custom_classes)
51                                         if (propsNum == 0):
52                                                 v = Variant(URIRef(element.getNode().toPython()))
53                                 return v
54                 elif isinstance(element, URIRef):
55                         return Variant(element)
56                 elif isinstance(element, Literal):
57                         return Variant(element.toPython())
58                 else:
59                         predicate = str(element.getPredicate())
60                         objectNode = element.getObject()
61         
62                         # if literal object
63                         dataType = None
64                         if isinstance(objectNode, Literal):
65                                 return Variant(objectNode.toPython())
66                         
67                         elif (element.getResource() is not None):
68                                 resource = element.getResource()
69                                 klass = Tools().getResourceClass(resource, default = Obj, custom_classes = custom_classes)
70                                 if klass is not None:
71                                         v = klass().parse(resource, custom_classes = custom_classes)
72                                 else:
73                                         # None found, resort to Obj (the base class)
74                                         v = Obj().parse(resource, custom_classes = custom_classes)
75                                 
76                                 return v
77                                 
78                         elif isinstance(objectNode, BNode):
79                                 l = []
80                                 element.getResource().getModel().parse_list(l, objectNode, None)
81                                 return l
82                         
83                         elif isinstance(objectNode, URIRef):
84                                 return Variant(objectNode)
85                         
86                         # could not identify datatype
87                         print "Parsing variant failed. Unable to detect RDFDatatype (" + str(dataType) + ") for literal."
88                         return Variant("");
89
90         def isNull(self):
91                 return self.variant is None
92
93         def isUri(self):
94                 return isinstance(self.variant, URIRef)
95         
96         def isString(self):
97                 return isinstance(self.variant, str)
98         
99         def isInteger(self):
100                 return isinstance(self.variant, int) or isinstance(self.variant, long)
101
102         def isDouble(self):
103                 return isinstance(self.variant, float)
104                 
105         def isFloat(self):
106                 import decimal
107                 if isinstance(self.variant, decimal.Decimal):
108                         self.variant = float(self.variant)
109                 return isinstance(self.variant, float)
110
111         def isBoolean(self):
112                 return isinstance(self.variant, bool)
113
114         def isDate(self):
115                 return isinstance(self.variant, datetime.date)
116
117         def isTime(self):
118                 return isinstance(self.variant, datetime.time)
119         
120         def isDateTime(self):
121                 return isinstance(self.variant, datetime.datetime)
122         
123         def isDuration(self):
124                 return (isinstance(self.variant, Duration) or isinstance(self.variant, datetime.timedelta)) 
125         
126         def isMap(self):
127                 from SmartAPI.model.Map import Map
128                 return isinstance(self.variant, Map)
129         
130         def isObj(self):
131                 return isinstance(self.variant, Obj)
132         
133         def isList(self):
134                 return isinstance(self.variant, List)
135         
136         def isVariant(self):
137                 return isinstance(self.variant, Variant)
138
139         def getValue(self):
140                 if isinstance(self.variant, Literal):
141                         return self.variant.toPython()
142                 return self.variant
143
144         def getType(self):
145                 if self.isNull():
146                         return "Null"
147                 elif self.isUri():
148                         return "Uri"
149                 elif self.isString():
150                         return "string"
151                 elif self.isInteger():
152                         return "int"
153                 elif self.isDouble():
154                         return "double"
155                 elif self.isFloat():
156                         return "float"
157                 elif self.isBoolean():
158                         return "boolean"
159                 elif self.isDate():
160                         return "date"
161                 elif self.isTime():
162                         return "time"
163                 elif self.isDateTime():
164                         return "datetime"
165                 elif self.isDuration():
166                         return 'duration'
167                 elif self.isMap():
168                         return "Map"
169                 elif self.isObj():
170                         return "Obj"
171                 elif self.isList():
172                         return "List"
173                 elif self.isVariant():
174                         return "Variant"
175                 else:
176                         return None
177
178         def getAsString(self):
179                 return str(self.variant)
180
181         def asTerm(self):
182                 if self.isUri():
183                         return self.variant
184                 elif self.isNull():
185                         return None
186                 else:
187                         return Literal(self.variant)
188                 
189         # Most methods below have no significance in Python as the language
190         # is not strongly typed. They are however offered as convenience
191         # to make implementions between different languages as similar
192         # as possible
193         def asString(self):
194                 return self.getAsString()
195         
196         def asObj(self):
197                 return self.variant
198
199         def asList(self):
200                 return self.variant
201         
202         def asInt(self):
203                 try:
204                         return int(self.variant)
205                 except:
206                         return 0
207                 
208         def asDouble(self):
209                 try:
210                         return float(self.variant)
211                 except:
212                         return 0
213         
214         def asDuration(self):
215                 '''
216                 @return a isodate.Duration or datetime.timedelta value if valid, otherwise None
217                 '''
218                 if isinstance(self.variant, datetime.timedelta) or isinstance(self.variant, Duration):
219                         return self.variant
220                 
221         def asFloat(self):
222                 try:
223                         return float(self.variant)
224                 except:
225                         return 0
226
227         def asBoolean(self):
228                 return self.variant
229         
230         def asDateTime(self):
231                 return self.variant
232                 
233         def asDate(self):
234                 try:
235                         return self.variant.date()
236                 except:
237                         return None
238                 
239         def asTime(self):
240                 try:
241                         return self.variant.time()
242                 except:
243                         return None     
244         
245         def hasSameValue(self, other):
246                 return self.variant==other.variant
247         
248         def __repr__(self):
249                 return "<Variant:: type: %s, value: %s>"%(self.getType(), self.getValue())
250