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