34ff8d66a16616d39396f3c5be2d9f26fe125589
[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         def asTerm(self):
33                 if self.isUri():
34                         return self.variant
35                 elif self.isNull():
36                         return None
37                 else:
38                         return Literal(self.variant)
39
40         @classmethod
41         def parse(cls, element, custom_classes = None):
42                 # get predicate and object
43                 if isinstance(element, Resource):
44                         if element.isLiteral():
45                                 return cls.parse(element.getNode())
46                         elif element.isUri():
47                                 return cls.parse(element.getNode())
48                         else:
49                                 klass = Tools().getResourceClass(element, default = Obj, custom_classes = custom_classes)
50                                 if klass is not None:
51                                         v = klass().parse(element, custom_classes = custom_classes)
52                                 else:
53                                         # None found, resort to Variant
54                                         v = cls()
55                                         propsNum = 0
56                                         for stmt in element.findProperties():
57                                                 propsNum = propsNum + 1
58                                                 v.parse(stmt, custom_classes = custom_classes)
59                                         if (propsNum == 0):
60                                                 v = Variant(URIRef(element.getNode().toPython()))
61                                 return v
62                 elif isinstance(element, URIRef):
63                         return Variant(element)
64                 elif isinstance(element, Literal):
65                         return Variant(element.toPython())
66                 else:
67                         predicate = str(element.getPredicate())
68                         objectNode = element.getObject()
69         
70                         # if literal object
71                         dataType = None
72                         if isinstance(objectNode, Literal):
73                                 return Variant(objectNode.toPython())
74                         
75                         elif (element.getResource() is not None):
76                                 resource = element.getResource()
77                                 klass = Tools().getResourceClass(resource, default = Obj, custom_classes = custom_classes)
78                                 if klass is not None:
79                                         v = klass().parse(resource, custom_classes = custom_classes)
80                                 else:
81                                         # None found, resort to Obj (the base class)
82                                         v = Obj().parse(resource, custom_classes = custom_classes)
83                                 
84                                 return v
85                                 
86                         elif isinstance(objectNode, BNode):
87                                 l = []
88                                 element.getResource().getModel().parse_list(l, objectNode, None)
89                                 return l
90                         
91                         elif isinstance(objectNode, URIRef):
92                                 return Variant(objectNode)
93                         
94                         # could not identify datatype
95                         print "Parsing variant failed. Unable to detect RDFDatatype (" + str(dataType) + ") for literal."
96                         return Variant("");
97
98         def isNull(self):
99                 return self.variant is None
100
101         def isUri(self):
102                 return isinstance(self.variant, URIRef)
103         
104         def isString(self):
105                 return isinstance(self.variant, str)
106         
107         def isInteger(self):
108                 return isinstance(self.variant, int) or isinstance(self.variant, long)
109
110         def isDouble(self):
111                 return isinstance(self.variant, float)
112                 
113         def isFloat(self):
114                 import decimal
115                 if isinstance(self.variant, decimal.Decimal):
116                         self.variant = float(self.variant)
117                 return isinstance(self.variant, float)
118
119         def isBoolean(self):
120                 return isinstance(self.variant, bool)
121
122         def isDate(self):
123                 return isinstance(self.variant, datetime.date)
124
125         def isTime(self):
126                 return isinstance(self.variant, datetime.time)
127         
128         def isDateTime(self):
129                 return isinstance(self.variant, datetime.datetime)
130         
131         def isDuration(self):
132                 return (isinstance(self.variant, Duration) or isinstance(self.variant, datetime.timedelta)) 
133         
134         def isMap(self):
135                 from SmartAPI.model.Map import Map
136                 return isinstance(self.variant, Map)
137         
138         def isObj(self):
139                 return isinstance(self.variant, Obj)
140         
141         def isList(self):
142                 return isinstance(self.variant, List)
143         
144         def isVariant(self):
145                 return isinstance(self.variant, Variant)
146
147         def getValue(self):
148                 if isinstance(self.variant, Literal):
149                         return self.variant.toPython()
150                 return self.variant
151
152         def getType(self):
153                 if self.isNull():
154                         return "Null"
155                 elif self.isUri():
156                         return "Uri"
157                 elif self.isString():
158                         return "string"
159                 elif self.isInteger():
160                         return "int"
161                 elif self.isDouble():
162                         return "double"
163                 elif self.isFloat():
164                         return "float"
165                 elif self.isBoolean():
166                         return "boolean"
167                 elif self.isDate():
168                         return "date"
169                 elif self.isTime():
170                         return "time"
171                 elif self.isDateTime():
172                         return "datetime"
173                 elif self.isDuration():
174                         return 'duration'
175                 elif self.isMap():
176                         return "Map"
177                 elif self.isObj():
178                         return "Obj"
179                 elif self.isList():
180                         return "List"
181                 elif self.isVariant():
182                         return "Variant"
183                 else:
184                         return None
185
186         def getAsString(self):
187                 return str(self.variant)
188
189         # Most method 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 asDate(self):
231                 try:
232                         return self.variant.date()
233                 except:
234                         return None
235                 
236         def asTime(self):
237                 try:
238                         return self.variant.time()
239                 except:
240                         return None     
241         
242         def hasSameValue(self, other):
243                 return self.variant==other.variant
244         
245         def __repr__(self):
246                 return "<Variant:: type: %s, value: %s>"%(self.getType(), self.getValue())
247