1 /*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "stdafx.h"
17
18 #include "api/collectionimpl.h"
19
20 #include <vector>
21 #include <zorba/item.h>
22 #include <zorba/item_factory.h>
23 #include <zorba/diagnostic_handler.h>
24 #include <zorba/item_sequence.h>
25 #include <zorba/static_context.h>
26 #include <zorba/iterator.h>
27 #include <zorba/singleton_item_sequence.h>
28 #include <zorba/typeident.h>
29
30 #include "api/zorbaimpl.h"
31 #include "api/unmarshaller.h"
32
33 #include "diagnostics/assert.h"
34 #include "diagnostics/xquery_diagnostics.h"
35 #include "diagnostics/zorba_exception.h"
36
37 // The following includes are needed for getAnnotations and getType
38 // might later be done using invoke
39 #include "system/globalenv.h"
40
41 #include "store/api/store.h"
42 #include "store/api/collection.h"
43 #include "store/api/annotation.h"
44 #include "annotations/annotations.h"
45 #include "api/annotationimpl.h"
46
47 #include "context/static_context.h"
48
49 #include "types/typeimpl.h"
50 #include "types/typeops.h"
51
52 #include "compiler/xqddf/collection_decl.h"
53
54 namespace zorba {
55
56 #define ZORBA_DM_TRY \
57 try
58
59 #define ZORBA_DM_CATCH \
60 catch (ZorbaException const& e) \
61 { \
62 ZorbaImpl::notifyError(theDiagnosticHandler, e); \
63 } \
64 catch (std::exception const& e) \
65 { \
66 ZorbaImpl::notifyError(theDiagnosticHandler, e.what()); \
67 } \
68 catch (...) \
69 { \
70 ZorbaImpl::notifyError(theDiagnosticHandler); \
71 }
72
73
74 /*******************************************************************************
75
76 ********************************************************************************/
CollectionImpl(const StaticContext_t & aSctx,ItemFactory * aFactory,const Item & aQName,DiagnosticHandler * aDiagnosticHandler,const std::string & aDMLNS)77 CollectionImpl::CollectionImpl(
78 const StaticContext_t& aSctx,
79 ItemFactory* aFactory,
80 const Item& aQName,
81 DiagnosticHandler* aDiagnosticHandler,
82 const std::string& aDMLNS)
83 :
84 theContext(aSctx->createChildContext()),
85 theFactory(aFactory),
86 theQName(aQName),
87 theDiagnosticHandler(aDiagnosticHandler),
88 theNS(aDMLNS)
89 {
90 initStaticContext();
91 }
92
93
94 /*******************************************************************************
95
96 ********************************************************************************/
~CollectionImpl()97 CollectionImpl::~CollectionImpl()
98 {
99 }
100
101
102 /*******************************************************************************
103
104 ********************************************************************************/
105 void
initStaticContext()106 CollectionImpl::initStaticContext()
107 {
108 Zorba_CompilerHints_t lHints;
109 std::ostringstream lProlog;
110 lProlog << "import module namespace d = '" << theNS << "';";
111 theContext->loadProlog(lProlog.str(), lHints);
112 }
113
114
115 /*******************************************************************************
116
117 ********************************************************************************/
118 void
invoke(const char * aLocalName,const std::vector<ItemSequence_t> & aArgs) const119 CollectionImpl::invoke(
120 const char* aLocalName,
121 const std::vector<ItemSequence_t>& aArgs) const
122 {
123 Item lFunc = theFactory->createQName(theNS, aLocalName);
124
125 ItemSequence_t lSeq = theContext->invoke(lFunc, aArgs);
126 Iterator_t lIter = lSeq->getIterator();
127 lIter->open();
128 Item lRes;
129 lIter->next(lRes);
130 }
131
132
133 /*******************************************************************************
134
135 ********************************************************************************/
136 void
insertNodesFirst(const ItemSequence_t & aNodes)137 CollectionImpl::insertNodesFirst(const ItemSequence_t& aNodes)
138 {
139 ZORBA_DM_TRY
140 {
141 std::vector<ItemSequence_t> lArgs;
142 lArgs.push_back(new SingletonItemSequence(theQName));
143 lArgs.push_back(aNodes);
144
145 invoke("insert-nodes-first", lArgs);
146 }
147 ZORBA_DM_CATCH
148 }
149
150
151 /*******************************************************************************
152
153 ********************************************************************************/
154 void
insertNodesLast(const ItemSequence_t & aNodes)155 CollectionImpl::insertNodesLast(const ItemSequence_t& aNodes)
156 {
157 ZORBA_DM_TRY
158 {
159 std::vector<ItemSequence_t> lArgs;
160 lArgs.push_back(new SingletonItemSequence(theQName));
161 lArgs.push_back(aNodes);
162
163 invoke("insert-nodes-last", lArgs);
164 }
165 ZORBA_DM_CATCH
166 }
167
168
169 /*******************************************************************************
170
171 ********************************************************************************/
172 void
insertNodesBefore(const Item & aTarget,const ItemSequence_t & aNodes)173 CollectionImpl::insertNodesBefore(
174 const Item& aTarget,
175 const ItemSequence_t& aNodes)
176 {
177 ZORBA_DM_TRY
178 {
179 std::vector<ItemSequence_t> lArgs;
180 lArgs.push_back(new SingletonItemSequence(theQName));
181 lArgs.push_back(new SingletonItemSequence(aTarget));
182 lArgs.push_back(aNodes);
183
184 invoke("insert-nodes-before", lArgs);
185 }
186 ZORBA_DM_CATCH
187 }
188
189
190 /*******************************************************************************
191
192 ********************************************************************************/
193 void
insertNodesAfter(const Item & aTarget,const ItemSequence_t & aNodes)194 CollectionImpl::insertNodesAfter(
195 const Item& aTarget,
196 const ItemSequence_t& aNodes)
197 {
198 ZORBA_DM_TRY
199 {
200 std::vector<ItemSequence_t> lArgs;
201 lArgs.push_back(new SingletonItemSequence(theQName));
202 lArgs.push_back(new SingletonItemSequence(aTarget));
203 lArgs.push_back(aNodes);
204
205 invoke("insert-nodes-after", lArgs);
206 }
207 ZORBA_DM_CATCH
208 }
209
210
211 /*******************************************************************************
212
213 ********************************************************************************/
214 void
deleteNodes(const ItemSequence_t & aNodes)215 CollectionImpl::deleteNodes(const ItemSequence_t& aNodes)
216 {
217 ZORBA_DM_TRY
218 {
219 std::vector<ItemSequence_t> lArgs;
220 lArgs.push_back(new SingletonItemSequence(theQName));
221 lArgs.push_back(aNodes);
222
223 invoke("delete-nodes", lArgs);
224 }
225 ZORBA_DM_CATCH
226 }
227
228
229 /*******************************************************************************
230
231 ********************************************************************************/
232 void
deleteNodeFirst()233 CollectionImpl::deleteNodeFirst()
234 {
235 ZORBA_DM_TRY
236 {
237 std::vector<ItemSequence_t> lArgs;
238 lArgs.push_back(new SingletonItemSequence(theQName));
239
240 invoke("delete-node-first", lArgs);
241 }
242 ZORBA_DM_CATCH
243 }
244
245
246 /*******************************************************************************
247
248 ********************************************************************************/
249 void
deleteNodesFirst(unsigned long aNumNodes)250 CollectionImpl::deleteNodesFirst(unsigned long aNumNodes)
251 {
252 ZORBA_DM_TRY
253 {
254 std::vector<ItemSequence_t> lArgs;
255 lArgs.push_back(new SingletonItemSequence(theQName));
256 lArgs.push_back(new SingletonItemSequence(theFactory->createUnsignedLong(aNumNodes)));
257
258 invoke("delete-nodes-first", lArgs);
259 }
260 ZORBA_DM_CATCH
261 }
262
263
264 /*******************************************************************************
265
266 ********************************************************************************/
267 void
deleteNodeLast()268 CollectionImpl::deleteNodeLast()
269 {
270 ZORBA_DM_TRY
271 {
272 std::vector<ItemSequence_t> lArgs;
273 lArgs.push_back(new SingletonItemSequence(theQName));
274
275 invoke("delete-node-last", lArgs);
276 }
277 ZORBA_DM_CATCH
278 }
279
280
281 /*******************************************************************************
282
283 ********************************************************************************/
284 void
deleteNodesLast(unsigned long aNumNodes)285 CollectionImpl::deleteNodesLast(unsigned long aNumNodes)
286 {
287 ZORBA_DM_TRY
288 {
289 std::vector<ItemSequence_t> lArgs;
290 lArgs.push_back(new SingletonItemSequence(theQName));
291 lArgs.push_back(new SingletonItemSequence(theFactory->createUnsignedLong(aNumNodes)));
292
293 invoke("delete-nodes-last", lArgs);
294 }
295 ZORBA_DM_CATCH
296 }
297
298
299 /*******************************************************************************
300
301 ********************************************************************************/
302 long long
indexOf(const Item & aNode)303 CollectionImpl::indexOf(const Item& aNode)
304 {
305 ZORBA_DM_TRY
306 {
307 // some consistency checking
308 // (1) given node needs to be in a collection and
309 // (2) the collection needs to be the same as the given collection
310 store::Item_t lNode = Unmarshaller::getInternalItem(aNode);
311 const store::Collection* aColl = lNode->getCollection();
312 if (!aColl)
313 {
314 throw ZORBA_EXCEPTION(zerr::ZSTR0009_COLLECTION_NOT_FOUND);
315 }
316 store::Item_t lName1 = Unmarshaller::getInternalItem(aNode.getCollectionName());
317 store::Item_t lName2 = Unmarshaller::getInternalItem(theQName);
318 if (lName1 != lName2)
319 {
320 throw ZORBA_EXCEPTION(zerr::ZDDY0011_COLLECTION_NODE_NOT_FOUND,
321 ERROR_PARAMS(lName1->getStringValue()));
322 }
323
324 Item lFunc = theFactory->createQName(theNS, "index-of");
325
326 std::vector<ItemSequence_t> lArgs;
327 lArgs.push_back(new SingletonItemSequence(aNode));
328
329 ItemSequence_t lSeq = theContext->invoke(lFunc, lArgs);
330 Iterator_t lIter = lSeq->getIterator();
331 lIter->open();
332 Item lRes;
333 lIter->next(lRes);
334
335 return lRes.getLongValue();
336 }
337 ZORBA_DM_CATCH
338 return -1;
339 }
340
341
342 /*******************************************************************************
343
344 ********************************************************************************/
345 ItemSequence_t
contents()346 CollectionImpl::contents()
347 {
348 ZORBA_DM_TRY
349 {
350 Item lFunc = theFactory->createQName(theNS, "collection");
351
352 std::vector<ItemSequence_t> lArgs;
353 lArgs.push_back(new SingletonItemSequence(theQName));
354
355 return theContext->invoke(lFunc, lArgs);
356 }
357 ZORBA_DM_CATCH
358 return 0;
359 }
360
361
362 /*******************************************************************************
363
364 ********************************************************************************/
365 const Item
getName() const366 CollectionImpl::getName() const
367 {
368 return theQName;
369 }
370
371
372 /*******************************************************************************
373
374 ********************************************************************************/
375 TypeIdentifier_t
getType() const376 CollectionImpl::getType() const
377 {
378 ZORBA_DM_TRY
379 {
380 store::Item* lQName = Unmarshaller::getInternalItem(theQName);
381
382 static_context* lCtx = Unmarshaller::getInternalStaticContext(theContext);
383
384 const StaticallyKnownCollection* lColl = lCtx->lookup_collection(lQName);
385 if (!lColl)
386 {
387 return 0;
388 }
389
390 const XQType* lType = lColl->getCollectionType();
391
392 return TypeOps::get_type_identifier(lCtx->get_typemanager(), *lType);
393
394 }
395 ZORBA_DM_CATCH
396 return 0;
397 }
398
399
400 /*******************************************************************************
401
402 ********************************************************************************/
403 bool
isStatic() const404 CollectionImpl::isStatic() const
405 {
406 ZORBA_DM_TRY
407 {
408 store::Item* lQName = Unmarshaller::getInternalItem(theQName);
409
410 static_context* lCtx = Unmarshaller::getInternalStaticContext(theContext);
411
412 const StaticallyKnownCollection* lColl = lCtx->lookup_collection(lQName);
413 return (lColl != NULL);
414 }
415 ZORBA_DM_CATCH
416 return false;
417 }
418
419
420 /*******************************************************************************
421
422 ********************************************************************************/
423 void
getAnnotations(std::vector<Annotation_t> & aAnnotations) const424 CollectionImpl::getAnnotations(std::vector<Annotation_t>& aAnnotations) const
425 {
426 ZORBA_DM_TRY
427 {
428 store::Item* lQName = Unmarshaller::getInternalItem(theQName);
429
430 store::Store* lStore = & GENV_STORE;
431
432 store::Collection_t lColl = lStore->getCollection(lQName, false);
433
434 if (!lColl)
435 lColl = lStore->getCollection(lQName, true);
436
437 // must exist because otherwise we wouldn't have an instance of this class
438 ZORBA_ASSERT(lColl);
439
440 std::vector<store::Annotation_t> lAnns;
441 std::vector<store::Annotation_t>::const_iterator lIter;
442 lColl->getAnnotations(lAnns);
443
444 for (lIter = lAnns.begin(); lIter != lAnns.end(); ++lIter)
445 {
446 store::Annotation_t lSAnn = *lIter;
447
448 std::vector<store::Item_t> lLiterals = lSAnn->theLiterals;
449
450 aAnnotations.push_back(
451 new AnnotationImpl(new AnnotationInternal(lSAnn->theName, lLiterals)));
452 }
453 }
454 ZORBA_DM_CATCH
455 }
456
457
458 /*******************************************************************************
459
460 ********************************************************************************/
461 void
registerDiagnosticHandler(DiagnosticHandler * aDiagnosticHandler)462 CollectionImpl::registerDiagnosticHandler(
463 DiagnosticHandler* aDiagnosticHandler)
464 {
465 theDiagnosticHandler = aDiagnosticHandler;
466 }
467
468
469 } // namespace zorba
470 /* vim:set et sw=2 ts=2: */
471