|
1 /** |
|
2 * Landmarks.js |
|
3 * |
|
4 * Nokia Web Runtime Service API emulation |
|
5 * WRT v1.1 |
|
6 * |
|
7 * Copyright 2009 Nokia Corporation. All rights reserved. |
|
8 */ |
|
9 |
|
10 |
|
11 (function(){ |
|
12 |
|
13 var provider = 'Service.Landmarks', |
|
14 Interface = 'IDataSource'; |
|
15 |
|
16 /** |
|
17 * Landmark service |
|
18 */ |
|
19 var LandmarkService = function(){ |
|
20 this.New = __New; |
|
21 this.GetList = __GetList; |
|
22 this.Add = __Add; |
|
23 this.Delete = __Delete; |
|
24 this.Import = __Import; |
|
25 this.Export = __Export; |
|
26 this.Organise = __Organise; |
|
27 this.Cancel = __Cancel; |
|
28 } |
|
29 |
|
30 device.implementation.extend(provider, Interface, new LandmarkService() ); |
|
31 |
|
32 |
|
33 /******************************************************/ |
|
34 /******************************************************/ |
|
35 /******************************************************/ |
|
36 |
|
37 var context = device.implementation.context, |
|
38 _t = context._t, |
|
39 method = '', |
|
40 result = false, |
|
41 DBase = null; |
|
42 |
|
43 /** |
|
44 * Landmarks: New |
|
45 * @param {Object} criteria |
|
46 */ |
|
47 function __New(criteria){ |
|
48 if ((result = validator.apply('New', arguments)) !== false) |
|
49 return result; |
|
50 |
|
51 if (typeof criteria.Type == 'undefined') |
|
52 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingType); |
|
53 |
|
54 if (!/^(Landmark|Category)$/i.test(criteria.Type)) |
|
55 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType); |
|
56 |
|
57 var returnValue; |
|
58 |
|
59 if(criteria.Type == 'Landmark') |
|
60 { |
|
61 returnValue = { |
|
62 'LandmarkName' : '', |
|
63 'id' : '', |
|
64 'CategoryInfo' : '', |
|
65 'LandmarkDesc' : '', |
|
66 'LandmarkPosition' : { |
|
67 'Latitude' : '', |
|
68 'Longitude' : '', |
|
69 'Altitude' : '', |
|
70 'HAccuracy' : '', |
|
71 'VAccuracy' : '', |
|
72 'VAccuracy' : '' |
|
73 }, |
|
74 'CoverageRadius' : '', |
|
75 'IconFile' : '', |
|
76 'IconIndex' : '', |
|
77 'IconMaskIndex' : '', |
|
78 'LandmarkFields' : { |
|
79 'Street' : '', |
|
80 'BuildingName' : '', |
|
81 'District' : '', |
|
82 'City' : '', |
|
83 'AreaCode' : '', |
|
84 'Telephone' : '', |
|
85 'Country' : '' |
|
86 } |
|
87 }; |
|
88 } |
|
89 else //Category |
|
90 { |
|
91 returnValue = { |
|
92 'CategoryName' : '', |
|
93 'id' : '', |
|
94 'GlobalId' : '', |
|
95 'IconFile' : '', |
|
96 'IconIndex' : '', |
|
97 'IconMaskIndex' : '' |
|
98 }; |
|
99 } |
|
100 |
|
101 return context.Result(returnValue); |
|
102 } |
|
103 |
|
104 /** |
|
105 * Landmarks: GetList |
|
106 * @param {Object} criteria |
|
107 * @param {Function} [callback] function for async call (optional) |
|
108 */ |
|
109 function __GetList(criteria, callback){ |
|
110 |
|
111 if ((result = validator.apply('GetList', arguments)) !== false) |
|
112 return result; |
|
113 |
|
114 if (typeof criteria.Type == 'undefined') |
|
115 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingType); |
|
116 |
|
117 if (!/^(Landmark|Category|Database)$/i.test(criteria.Type)) |
|
118 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType); |
|
119 |
|
120 if (criteria.Filter) |
|
121 context.notify(_t('%s:: GetList : filter not implemented in preview').arg(provider)); |
|
122 |
|
123 if(criteria.Sort) |
|
124 context.notify(_t('%s:: GetList : Sort is not implemented in preview').arg(provider)); |
|
125 |
|
126 if (typeof callback == 'function') { |
|
127 return context.callAsync(this, arguments.callee, criteria, callback); |
|
128 } |
|
129 |
|
130 var returnValue = [], |
|
131 match = null, |
|
132 filter = criteria.Filter || null; |
|
133 |
|
134 DBase = context.getData(provider); |
|
135 |
|
136 |
|
137 if (/Database/i.test(criteria.Type)) { // Type = Database |
|
138 |
|
139 returnValue = context.Iterator( DBase.Database || [] ); |
|
140 |
|
141 } else if (/Landmark/i.test(criteria.Type)){ // Type = Landmark |
|
142 |
|
143 returnValue = context.Iterator( DBase[criteria.Type] || [] ); |
|
144 |
|
145 } else { // Type = Category |
|
146 |
|
147 // @todo: apply filter criteria |
|
148 returnValue = context.Iterator( DBase[criteria.Type] || [] ); |
|
149 } |
|
150 return context.Result(returnValue); |
|
151 } |
|
152 |
|
153 /** |
|
154 * Landmarks: Add |
|
155 * @param {Object} criteria |
|
156 */ |
|
157 function __Add(criteria){ |
|
158 |
|
159 if ((result = validator.apply('Add', arguments)) !== false) |
|
160 return result; |
|
161 |
|
162 if (!/^(Landmark|Category)$/i.test(criteria.Type)) |
|
163 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType); |
|
164 |
|
165 |
|
166 var Data = criteria.Data || false; |
|
167 if(!Data){ |
|
168 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingData); |
|
169 } |
|
170 |
|
171 DBase = context.getData(provider); |
|
172 |
|
173 // unsupported! |
|
174 if (Data.DatabaseURI) { |
|
175 context.notify(_t('%s:: Add : Data.DatabaseURI not implemented in preview').arg(provider)); |
|
176 } |
|
177 |
|
178 var item; |
|
179 |
|
180 // Type = Landmark |
|
181 if (/Landmark/i.test(criteria.Type)){ |
|
182 |
|
183 if (!Data.LandmarkName) |
|
184 Data.LandmarkName=""; |
|
185 |
|
186 var landmarkPos = Data.LandmarkPosition; |
|
187 if (typeof landmarkPos != 'undefined') { |
|
188 if ((typeof landmarkPos.Latitude == 'undefined' || typeof landmarkPos.Latitude != 'number') && |
|
189 (typeof landmarkPos.Longitude == 'undefined' || typeof landmarkPos.Longitude != 'number') && |
|
190 (typeof landmarkPos.Altitude == 'undefined' || typeof landmarkPos.Altitude != 'number') && |
|
191 (typeof landmarkPos.HAccuracy == 'undefined' || typeof landmarkPos.HAccuracy != 'number') && |
|
192 (typeof landmarkPos.VAccuracy == 'undefined' || typeof landmarkPos.VAccuracy != 'number')) { |
|
193 |
|
194 return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badType); |
|
195 } |
|
196 } |
|
197 // update |
|
198 if (typeof Data.id != 'undefined') { |
|
199 if(typeof Data.id != 'string') |
|
200 return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.invalidId); |
|
201 |
|
202 var retIndex = findById(DBase.Landmark, Data.id); |
|
203 if (retIndex == -1) |
|
204 return error(device.implementation.ERR_NOT_FOUND); |
|
205 DBase.Landmark[retIndex] = Data; |
|
206 item = Data; |
|
207 } |
|
208 // new |
|
209 else { |
|
210 item = context.extend({}, Data); |
|
211 item.id = String(context.getUniqueID()); |
|
212 DBase.Landmark.push(item); |
|
213 } |
|
214 } else { // Type = Category |
|
215 // alert(typeof Data.CategoryName); |
|
216 |
|
217 //alert("Data.id : "+Data.id); |
|
218 // update |
|
219 if (typeof Data.id != 'undefined') { |
|
220 if(typeof Data.id != 'string') |
|
221 return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.invalidId); |
|
222 |
|
223 var retIndex = findById(DBase.Category, Data.id); |
|
224 if (retIndex == -1) |
|
225 return error(device.implementation.ERR_NOT_FOUND); |
|
226 |
|
227 DBase.Category[retIndex] = Data; |
|
228 item = Data; |
|
229 } |
|
230 // new |
|
231 else { |
|
232 if (typeof Data.CategoryName == 'undefined') |
|
233 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingCategoryName); |
|
234 |
|
235 if(typeof Data.CategoryName != 'string' || Data.CategoryName.length <= 0) |
|
236 return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badType); |
|
237 |
|
238 var retIndex = findByName(DBase.Category, Data.CategoryName); |
|
239 if (retIndex != -1) |
|
240 return error(device.implementation.ERR_ENTRY_EXISTS); |
|
241 |
|
242 item = context.extend({}, Data); |
|
243 item.id = String(context.getUniqueID()); |
|
244 DBase.Category.push(item); |
|
245 } |
|
246 } |
|
247 // return success |
|
248 return context.Result(item.id, device.implementation.ERR_SUCCESS); |
|
249 } |
|
250 |
|
251 /** |
|
252 * Landmarks: Delete |
|
253 * @param {Object} criteria |
|
254 */ |
|
255 function __Delete(criteria){ |
|
256 |
|
257 if ((result = validator.apply('Delete', arguments)) !== false) |
|
258 return result; |
|
259 |
|
260 if (!/^(Landmark|Category)$/i.test(criteria.Type)) |
|
261 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType); |
|
262 |
|
263 var Data = criteria.Data || false; |
|
264 if(!Data){ |
|
265 return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.missingData); |
|
266 } |
|
267 |
|
268 if (typeof Data.id == 'undefined') { |
|
269 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingId); |
|
270 } |
|
271 |
|
272 if (typeof Data.id != 'undefined' && typeof Data.id != 'string') { |
|
273 return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.invalidId); |
|
274 } |
|
275 if(Data.id.length <= 0 ) |
|
276 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.invalidId); |
|
277 |
|
278 DBase = context.getData(provider); |
|
279 |
|
280 var type = criteria.Type; |
|
281 |
|
282 // unsupported! |
|
283 if (Data.DBUri) { |
|
284 context.notify(_t('%s:: Delete : Data.DBUri not implemented in preview').arg(provider)); |
|
285 } |
|
286 |
|
287 // for both Landmark & Category: |
|
288 var i,item; |
|
289 |
|
290 for (i in DBase[type]) { |
|
291 item = DBase[type][i]; |
|
292 if (Data.id == item.id) { |
|
293 DBase[type].splice(i, 1); |
|
294 } |
|
295 } |
|
296 |
|
297 // return success |
|
298 return error(device.implementation.ERR_SUCCESS); |
|
299 } |
|
300 |
|
301 /** |
|
302 * Landmarks: Import |
|
303 * @param {Object} criteria |
|
304 */ |
|
305 function __Import(criteria){ |
|
306 |
|
307 if ((result = validator.apply('Import', arguments)) !== false) |
|
308 return result; |
|
309 |
|
310 if (!/^(Landmark)$/i.test(criteria.Type)) |
|
311 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType); |
|
312 |
|
313 context.notify(_t('%s:: Import : not implemented in preview.').arg(provider)); |
|
314 |
|
315 var Data = criteria.Data || false; |
|
316 if(!Data) |
|
317 return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.missingData); |
|
318 |
|
319 if (!Data.SourceFile) |
|
320 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingSourceFile); |
|
321 |
|
322 if (!Data.MimeType) |
|
323 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingMimeType); |
|
324 |
|
325 if (!/^(application\/vnd.nokia.landmarkcollection\+xml|application\/vnd.nokia.landmark\+wbxml)$/i.test(Data.MimeType)) |
|
326 return error(device.implementation.ERR_SERVICE_NOT_SUPPORTED, msg.invalidMime); |
|
327 |
|
328 return error(device.implementation.ERR_SUCCESS); |
|
329 } |
|
330 |
|
331 |
|
332 /** |
|
333 * Landmarks: Export |
|
334 * @param {Object} criteria |
|
335 */ |
|
336 function __Export(criteria){ |
|
337 |
|
338 if ((result = validator.apply('Export', arguments)) !== false) |
|
339 return result; |
|
340 |
|
341 context.notify(_t('%s:: Export : not implemented in preview.').arg(provider)); |
|
342 if (!/^(Landmark)$/i.test(criteria.Type)) |
|
343 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType); |
|
344 |
|
345 var Data = criteria.Data || false; |
|
346 if(!Data){ |
|
347 return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.missingData); |
|
348 } |
|
349 |
|
350 if (!Data.DestinationFile) |
|
351 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingDestFile); |
|
352 |
|
353 if (!Data.MimeType) |
|
354 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingMimeType); |
|
355 |
|
356 if (!Data.IdList) |
|
357 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingIdList); |
|
358 |
|
359 return error(device.implementation.ERR_SUCCESS); |
|
360 } |
|
361 |
|
362 |
|
363 /** |
|
364 * Landmarks: Organise |
|
365 * @param {Object} criteria |
|
366 */ |
|
367 function __Organise(criteria){ |
|
368 |
|
369 if ((result = validator.apply('Organise', arguments)) !== false) |
|
370 return result; |
|
371 |
|
372 if (!/^(Landmark)$/i.test(criteria.Type)) |
|
373 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType); |
|
374 |
|
375 var Data = criteria.Data || false; |
|
376 if(!Data){ |
|
377 return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.missingData); |
|
378 } |
|
379 |
|
380 if (!Data.id || Data.id == "") |
|
381 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.invalidId); |
|
382 |
|
383 DBase = context.getData(provider); |
|
384 var categories = DBase['Category']; |
|
385 var landmarks = DBase['Landmark']; |
|
386 var found = false; |
|
387 |
|
388 |
|
389 for(var i=0;i<categories.length;i++) |
|
390 { |
|
391 var category = categories[i]; |
|
392 if (category.id == Data.id) { |
|
393 found = true; |
|
394 break; |
|
395 } |
|
396 } |
|
397 if(!found) |
|
398 return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.invalidId); |
|
399 |
|
400 try{ |
|
401 if(!Data.IdList || Data.IdList.length <=0) |
|
402 { |
|
403 return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.invalidId); |
|
404 } |
|
405 }catch(e){ |
|
406 return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.invalidId); |
|
407 } |
|
408 |
|
409 if (!/^(Associate|Disassociate)$/i.test(criteria.OperationType)) |
|
410 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.invalidOpType); |
|
411 |
|
412 context.notify(_t('%s:: Organise : not implemented in preview.').arg(provider)); |
|
413 if(/^Associate$/i.test(criteria.OperationType)) |
|
414 { |
|
415 for(var i=0;i<landmarks.length;i++) |
|
416 { |
|
417 for(var j=0;j<Data.IdList.length;j++) |
|
418 { |
|
419 if(landmarks[i] == Data.IdList[j]) |
|
420 { |
|
421 if(!landmarks[i].CategoryInfo) |
|
422 { |
|
423 landmarks[i].CategoryInfo = new Array(); |
|
424 landmarks[i].CategoryInfo.push(Data.id); |
|
425 } |
|
426 else{ |
|
427 var landmark = landmarks[i]; |
|
428 var found = false; |
|
429 for(var k=0;k<landmark.CategoryInfo.length;k++) |
|
430 { |
|
431 if(landmark.CategoryInfo[k] == Data.id) |
|
432 found = true; |
|
433 } |
|
434 if(!found) |
|
435 landmark.CategoryInfo.push(Data.id); |
|
436 } |
|
437 |
|
438 } |
|
439 } |
|
440 } |
|
441 } |
|
442 else |
|
443 { |
|
444 for(var i=0;i<landmarks.length;i++) |
|
445 { |
|
446 for(var j=0;j<Data.IdList.length;j++) |
|
447 { |
|
448 if(landmarks[i] == Data.IdList[j] && landmarks[i].CategoryInfo != undefined) |
|
449 { |
|
450 var landmark = landmarks[i]; |
|
451 for(var k=0;k<landmark.CategoryInfo.length;k++) |
|
452 { |
|
453 if(landmark.CategoryInfo[k] == Data.id) |
|
454 landmark.CategoryInfo.splice(k,1); |
|
455 } |
|
456 } |
|
457 } |
|
458 } |
|
459 } |
|
460 |
|
461 return error(device.implementation.ERR_SUCCESS); |
|
462 } |
|
463 |
|
464 |
|
465 /** |
|
466 * Landmarks: Cancel |
|
467 * @param {Object} criteria |
|
468 */ |
|
469 function __Cancel(criteria){ |
|
470 method = 'Cancel'; |
|
471 |
|
472 if ((result = validator.apply('Cancel', arguments)) !== false) |
|
473 return result; |
|
474 |
|
475 if (!criteria.TransactionID) |
|
476 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingTID); |
|
477 |
|
478 clearTimeout(criteria.TransactionID); |
|
479 return context.ErrorResult(device.implementation.ERR_SUCCESS); |
|
480 } |
|
481 |
|
482 |
|
483 |
|
484 /******************************* |
|
485 * helper functions |
|
486 *******************************/ |
|
487 function error(code, msg /*, args...*/){ |
|
488 |
|
489 var args = ['Landmarks',method].concat([].slice.call(arguments,2)); |
|
490 msg = msg ? _t().arg.apply(msg,args) : undefined; |
|
491 return context.ErrorResult(code, msg); |
|
492 } |
|
493 |
|
494 /** |
|
495 * validate common input arguments |
|
496 * 'this' is string (object) name of calling function |
|
497 * |
|
498 * @param {arguments} arguments of calling function |
|
499 * @return {Result} Result object if error, false if no error. |
|
500 */ |
|
501 function validator() { |
|
502 method = ''+this; |
|
503 var failed = false, |
|
504 criteria = arguments[0] || false; |
|
505 |
|
506 if (!criteria || typeof criteria != 'object') |
|
507 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingType); |
|
508 |
|
509 return failed; |
|
510 } |
|
511 |
|
512 function findById(dbase, id){ |
|
513 for (var i in dbase) { |
|
514 if (id == dbase[i]['id']) { |
|
515 return i; |
|
516 } |
|
517 } |
|
518 return -1; |
|
519 } |
|
520 |
|
521 function findByName(dbase, name){ |
|
522 for (var i in dbase) { |
|
523 if (name == dbase[i]['CategoryName']) { |
|
524 return i; |
|
525 } |
|
526 } |
|
527 return -1; |
|
528 } |
|
529 |
|
530 |
|
531 /** |
|
532 * error messages |
|
533 * order of %s args: Service name, method name, parameter name |
|
534 */ |
|
535 var msg = { |
|
536 missingType : '%s%s : Type is missing', |
|
537 badType : '%s%s : Type is invalid', |
|
538 missingData : '%s%s : Type or Data is missing', |
|
539 missingId : '%s%s : Id is missing', |
|
540 invalidId : '%s%s : id is invalid', |
|
541 missingLandmarkName : '%s%s : Landmrak name Missing', |
|
542 missingCategoryName : '%s%s : CategoryName is missing', |
|
543 missingSourceFile : '%s%s : Import Source Filename is Missing', |
|
544 missingMimeType : '%s%s : MIME type for source file is Missing', |
|
545 missingDestFile : '%s%s : DestinationFile is missing', |
|
546 invalidOpType : '%s%s : OperationType is invalid', |
|
547 missingIdList : '%s%s : Id list is Missing', |
|
548 missingTID : '%s%s : TransactionID is missing', |
|
549 invalidMime : '%s%s : MimeType is missing', |
|
550 msgNoMsg : '', |
|
551 |
|
552 }; |
|
553 |
|
554 |
|
555 }) () |
|
556 |