Ghislain Fourny has proposed merging lp:~zorba-coders/zorba/bug-1039284 into 
lp:zorba.

Commit message:
Fixes bug 1039284 (json-doc).

Requested reviews:
  Till Westmann (tillw)
  Matthias Brantner (matthias-brantner)
Related bugs:
  Bug #1039284 in Zorba: "Implement jn:json-doc()"
  https://bugs.launchpad.net/zorba/+bug/1039284

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/bug-1039284/+merge/129677

Fixes bug 1039284 (json-doc).
-- 
https://code.launchpad.net/~zorba-coders/zorba/bug-1039284/+merge/129677
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/functions/pregenerated/func_jsoniq_functions.cpp'
--- src/functions/pregenerated/func_jsoniq_functions.cpp	2012-10-08 12:09:36 +0000
+++ src/functions/pregenerated/func_jsoniq_functions.cpp	2012-10-15 13:52:21 +0000
@@ -141,6 +141,16 @@
 }
 
 #endif
+
+PlanIter_t fn_jsoniq_json_doc::codegen(
+  CompilerCB*,
+  static_context* sctx,
+  const QueryLoc& loc,
+  std::vector<PlanIter_t>& argv,
+  expr& ann) const
+{
+  return new JSONDocIterator(sctx, loc, argv);
+}
 #ifdef ZORBA_WITH_JSON
 PlanIter_t op_zorba_json_item_accessor::codegen(
   CompilerCB*,
@@ -470,6 +480,18 @@
 #endif
 
 
+
+      {
+    DECL_WITH_KIND(sctx, fn_jsoniq_json_doc,
+        (createQName("http://jsoniq.org/functions","","json-doc";), 
+        GENV_TYPESYSTEM.STRING_TYPE_QUESTION, 
+        GENV_TYPESYSTEM.JSON_ITEM_TYPE_STAR),
+        FunctionConsts::FN_JSONIQ_JSON_DOC_1);
+
+  }
+
+
+
 #ifdef ZORBA_WITH_JSON
 
 

=== modified file 'src/functions/pregenerated/func_jsoniq_functions.h'
--- src/functions/pregenerated/func_jsoniq_functions.h	2012-10-08 12:09:36 +0000
+++ src/functions/pregenerated/func_jsoniq_functions.h	2012-10-15 13:52:21 +0000
@@ -236,6 +236,25 @@
   CODEGEN_DECL();
 };
 #endif
+
+
+//fn-jsoniq:json-doc
+class fn_jsoniq_json_doc : public function
+{
+public:
+  fn_jsoniq_json_doc(const signature& sig, FunctionConsts::FunctionKind kind)
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  bool accessesDynCtx() const { return true; }
+
+  bool isSource() const { return true; }
+
+  CODEGEN_DECL();
+};
 #ifdef ZORBA_WITH_JSON
 
 //op-zorba:json-item-accessor

=== modified file 'src/functions/pregenerated/function_enum.h'
--- src/functions/pregenerated/function_enum.h	2012-10-08 12:09:36 +0000
+++ src/functions/pregenerated/function_enum.h	2012-10-15 13:52:21 +0000
@@ -240,6 +240,7 @@
   FN_JSONIQ_MEMBER_2,
   FN_JSONIQ_MEMBERS_1,
   FN_JSONIQ_FLATTEN_1,
+  FN_JSONIQ_JSON_DOC_1,
   OP_ZORBA_JSON_ITEM_ACCESSOR_2,
   FN_JSONIQ_NULL_0,
   FN_JSONIQ_IS_NULL_1,

=== modified file 'src/runtime/json/jsoniq_functions_impl.cpp'
--- src/runtime/json/jsoniq_functions_impl.cpp	2012-10-08 12:09:36 +0000
+++ src/runtime/json/jsoniq_functions_impl.cpp	2012-10-15 13:52:21 +0000
@@ -46,13 +46,16 @@
 #include "types/typeops.h"
 #include "types/root_typemanager.h"
 
-#include "store/api/pul.h"
-#include "store/api/item.h"
-#include "store/api/item_factory.h"
-#include "store/api/store.h"
-#include "store/api/copymode.h"
+#include <store/api/pul.h>
+#include <store/api/item.h>
+#include <store/api/item_factory.h>
+#include <store/api/store.h>
+#include <store/api/copymode.h>
 
+#include <util/uri_util.h>
 #include <zorba/store_consts.h>
+#include <zorbatypes/URI.h>
+
 
 namespace zorba {
 
@@ -1597,6 +1600,152 @@
   STACK_END(state);
 }
 
+/**
+ * Utility method for jn:json-doc(). Given an input string,
+ * use a few heuristics to create a valid URI, assuming that the input might
+ * be an absolute or relative filesystem path, etc.
+ */
+static zstring normalizeInput(zstring const& aUri, static_context* aSctx,
+                              QueryLoc const& loc)
+{
+  zstring const aBaseUri = aSctx->get_base_uri();
+  zstring lResolvedURI;
+
+  try
+  {
+    // To support the very common (if technically incorrect) use
+    // case of users passing local filesystem paths to fn:doc(),
+    // we use the following heuristic: IF the base URI has a file:
+    // scheme AND the incoming URI has no scheme, we will assume
+    // the incoming URI is actually a filesystem path.  QQQ For
+    // the moment, we assume any "unknown" schemes are probably
+    // Windows drive letters.
+    if ((uri::get_scheme(aUri) == uri::none ||
+         uri::get_scheme(aUri) == uri::unknown) &&
+        uri::get_scheme(aBaseUri) == uri::file)
+    {
+      // Ok, we assume it's a filesystem path. First normalize it.
+      zstring lNormalizedPath =
+        fs::get_normalized_path(aUri, zstring(""));
+      // QQQ For now, get_normalized_path() doesn't do what we
+      // want when base URI represents a file. So, when the
+      // normalized path is relative, we pretend it's a relative
+      // URI and resolve it as such.
+      if (fs::is_absolute(lNormalizedPath))
+      {
+        URI::encode_file_URI(lNormalizedPath, lResolvedURI);
+      }
+      else
+      {
+#ifdef WIN32
+        ascii::replace_all(lNormalizedPath, '\\', '/');
+#endif
+        lResolvedURI = aSctx->resolve_relative_uri(lNormalizedPath, true);
+      }
+    }
+    else
+    {
+      // We do NOT assume it's a filesystem path; just resolve it.
+      lResolvedURI = aSctx->resolve_relative_uri(aUri, true);
+    }
+  }
+  catch (ZorbaException& e)
+  {
+    if (e.diagnostic() == err::XQST0046)
+      // the value of a URILiteral is of nonzero length and is not in the
+      // lexical space of xs:anyURI.
+      e.set_diagnostic(err::FODC0005);
+    else
+      e.set_diagnostic(err::FODC0002);
+
+    set_source(e, loc);
+    throw;
+  }
+
+  return lResolvedURI;
+}
+
+/*******************************************************************************
+
+********************************************************************************/
+bool JSONDocIterator::nextImpl(store::Item_t& result, PlanState& planState) const
+{
+  store::Item_t uriItem;
+  JSONDocIteratorState* state;
+  zstring uriString;
+  zstring lErrorMessage;
+  internal::StreamResource* lStreamResource;
+  zstring lNormUri;
+  DEFAULT_STACK_INIT(JSONDocIteratorState, state, planState);
+
+  if (consumeNext(uriItem, theChildren[0].getp(), planState))
+  {
+    uriItem->getStringValue2(uriString);
+    // Normalize input to handle filesystem paths, etc.
+    lNormUri = normalizeInput(uriString, theSctx, loc);
+
+    // Resolve URI to a stream
+    state->theResource = theSctx->resolve_uri(
+        lNormUri,
+        internal::EntityData::DOCUMENT,
+        lErrorMessage);
+
+    lStreamResource =
+        dynamic_cast<internal::StreamResource*>(state->theResource.get());
+    if (lStreamResource == NULL) {
+      throw XQUERY_EXCEPTION(
+          err::FODC0002,
+          ERROR_PARAMS(uriString, lErrorMessage),
+          ERROR_LOC(loc));
+    }
+
+    state->theStream = lStreamResource->getStream();
+    if (state->theStream == NULL) {
+      throw XQUERY_EXCEPTION(
+          err::FODC0002,
+          ERROR_PARAMS( uriString ),
+          ERROR_LOC(loc));
+    }
+
+    state->theGotOne = false;
+
+    while (true)
+    {
+      try
+      {
+        result = GENV_STORE.parseJSON(*state->theStream, 0);
+      }
+      catch (zorba::XQueryException& e)
+      {
+        // rethrow with JNDY0021
+        XQueryException xq = XQUERY_EXCEPTION(
+            jerr::JNDY0021,
+            ERROR_PARAMS(e.what()),
+            ERROR_LOC(loc));
+
+        // use location of e in case of literal string
+        throw xq;
+      }
+      if (result != NULL)
+      {
+        if (!state->theGotOne)
+        {
+          state->theGotOne = true;
+          STACK_PUSH(true, state);
+        } else {
+          RAISE_ERROR(
+              jerr::JNDY0021,
+              loc,
+              ERROR_PARAMS(ZED(JSON_UNEXPECTED_EXTRA_CONTENT)));
+        }
+      } else {
+        break;
+      }
+    }
+  }
+  
+  STACK_END(state);
+}
 
 } /* namespace zorba */
 /* vim:set et sw=2 ts=2: */

=== modified file 'src/runtime/json/pregenerated/jsoniq_functions.cpp'
--- src/runtime/json/pregenerated/jsoniq_functions.cpp	2012-10-08 12:09:36 +0000
+++ src/runtime/json/pregenerated/jsoniq_functions.cpp	2012-10-15 13:52:21 +0000
@@ -357,6 +357,46 @@
 // </JSONArrayFlattenIterator>
 
 #endif
+// <JSONDocIterator>
+SERIALIZABLE_CLASS_VERSIONS(JSONDocIterator)
+
+void JSONDocIterator::serialize(::zorba::serialization::Archiver& ar)
+{
+  serialize_baseclass(ar,
+  (NaryBaseIterator<JSONDocIterator, JSONDocIteratorState>*)this);
+}
+
+
+void JSONDocIterator::accept(PlanIterVisitor& v) const
+{
+  v.beginVisit(*this);
+
+  std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
+  std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
+  for ( ; lIter != lEnd; ++lIter ){
+    (*lIter)->accept(v);
+  }
+
+  v.endVisit(*this);
+}
+
+JSONDocIterator::~JSONDocIterator() {}
+
+JSONDocIteratorState::JSONDocIteratorState() {}
+
+JSONDocIteratorState::~JSONDocIteratorState() {}
+
+
+void JSONDocIteratorState::init(PlanState& planState) {
+  PlanIteratorState::init(planState);
+}
+
+void JSONDocIteratorState::reset(PlanState& planState) {
+  PlanIteratorState::reset(planState);
+}
+// </JSONDocIterator>
+
+
 #ifdef ZORBA_WITH_JSON
 // <JSONItemAccessorIterator>
 SERIALIZABLE_CLASS_VERSIONS(JSONItemAccessorIterator)

=== modified file 'src/runtime/json/pregenerated/jsoniq_functions.h'
--- src/runtime/json/pregenerated/jsoniq_functions.h	2012-10-08 12:09:36 +0000
+++ src/runtime/json/pregenerated/jsoniq_functions.h	2012-10-15 13:52:21 +0000
@@ -29,6 +29,7 @@
 #include "runtime/base/binarybase.h"
 #include "runtime/base/noarybase.h"
 #include "runtime/base/narybase.h"
+#include <context/uri_resolver.h>
 
 
 namespace zorba {
@@ -457,6 +458,51 @@
 
 #endif
 
+/**
+ * jn:json-doc
+ * Author: Zorba Team
+ */
+class JSONDocIteratorState : public PlanIteratorState
+{
+public:
+  std::auto_ptr<internal::Resource> theResource; //
+  std::istream* theStream; //
+  bool theGotOne; //
+
+  JSONDocIteratorState();
+
+  ~JSONDocIteratorState();
+
+  void init(PlanState&);
+  void reset(PlanState&);
+};
+
+class JSONDocIterator : public NaryBaseIterator<JSONDocIterator, JSONDocIteratorState>
+{ 
+public:
+  SERIALIZABLE_CLASS(JSONDocIterator);
+
+  SERIALIZABLE_CLASS_CONSTRUCTOR2T(JSONDocIterator,
+    NaryBaseIterator<JSONDocIterator, JSONDocIteratorState>);
+
+  void serialize( ::zorba::serialization::Archiver& ar);
+
+  JSONDocIterator(
+    static_context* sctx,
+    const QueryLoc& loc,
+    std::vector<PlanIter_t>& children)
+    : 
+    NaryBaseIterator<JSONDocIterator, JSONDocIteratorState>(sctx, loc, children)
+  {}
+
+  virtual ~JSONDocIterator();
+
+  void accept(PlanIterVisitor& v) const;
+
+  bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
 #ifdef ZORBA_WITH_JSON
 /**
  * 

=== modified file 'src/runtime/pregenerated/iterator_enum.h'
--- src/runtime/pregenerated/iterator_enum.h	2012-10-08 12:09:36 +0000
+++ src/runtime/pregenerated/iterator_enum.h	2012-10-15 13:52:21 +0000
@@ -161,6 +161,7 @@
   TYPE_JSONArrayMemberIterator,
   TYPE_JSONArrayMembersIterator,
   TYPE_JSONArrayFlattenIterator,
+  TYPE_JSONDocIterator,
   TYPE_JSONItemAccessorIterator,
   TYPE_JSONNullIterator,
   TYPE_JSONIsNullIterator,

=== modified file 'src/runtime/spec/json/jsoniq_functions.xml'
--- src/runtime/spec/json/jsoniq_functions.xml	2012-10-08 12:09:36 +0000
+++ src/runtime/spec/json/jsoniq_functions.xml	2012-10-15 13:52:21 +0000
@@ -9,6 +9,10 @@
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
   xsi:schemaLocation="http://www.zorba-xquery.com ../runtime.xsd">
 
+<zorba:header>
+  <zorba:include form="Angle-bracket">context/uri_resolver.h</zorba:include>
+</zorba:header>
+  
 <!--
 /*******************************************************************************
 ********************************************************************************/
@@ -377,6 +381,35 @@
 
 </zorba:iterator>
 
+<!--
+/*******************************************************************************
+********************************************************************************/
+-->
+<zorba:iterator name="JSONDocIterator">
+  
+  <zorba:description author="Zorba Team">jn:json-doc</zorba:description>
+  
+  <zorba:function>
+    
+    <zorba:signature localname="json-doc" prefix="fn-jsoniq">
+      <zorba:param>xs:string?</zorba:param>
+      <zorba:output>json-item()*</zorba:output>
+    </zorba:signature>
+    
+    <zorba:methods>
+      <zorba:accessesDynCtx returnValue="true"/>
+      <zorba:isSource returnValue="true"/>
+    </zorba:methods>
+    
+  </zorba:function>
+  
+  <zorba:state>
+    <zorba:member type="std::auto_ptr&lt;internal::Resource&gt;" name="theResource" brief=""/>
+    <zorba:member type="std::istream*" name="theStream" brief=""/>
+    <zorba:member type="bool" name="theGotOne" brief=""/>
+  </zorba:state>
+  
+</zorba:iterator>
 
 <!--
 /*******************************************************************************
@@ -659,4 +692,5 @@
 
 </zorba:iterator>
 
+
 </zorba:iterators>

=== modified file 'src/runtime/visitors/pregenerated/planiter_visitor.h'
--- src/runtime/visitors/pregenerated/planiter_visitor.h	2012-10-08 12:09:36 +0000
+++ src/runtime/visitors/pregenerated/planiter_visitor.h	2012-10-15 13:52:21 +0000
@@ -338,6 +338,8 @@
 #ifdef ZORBA_WITH_JSON
     class JSONArrayFlattenIterator;
 #endif
+    class JSONDocIterator;
+
 #ifdef ZORBA_WITH_JSON
     class JSONItemAccessorIterator;
 #endif
@@ -1188,6 +1190,9 @@
     virtual void beginVisit ( const JSONArrayFlattenIterator& ) = 0;
     virtual void endVisit   ( const JSONArrayFlattenIterator& ) = 0;
 #endif
+    virtual void beginVisit ( const JSONDocIterator& ) = 0;
+    virtual void endVisit   ( const JSONDocIterator& ) = 0;
+
 #ifdef ZORBA_WITH_JSON
     virtual void beginVisit ( const JSONItemAccessorIterator& ) = 0;
     virtual void endVisit   ( const JSONItemAccessorIterator& ) = 0;

=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.cpp'
--- src/runtime/visitors/pregenerated/printer_visitor.cpp	2012-10-08 12:09:36 +0000
+++ src/runtime/visitors/pregenerated/printer_visitor.cpp	2012-10-15 13:52:21 +0000
@@ -1973,6 +1973,20 @@
 // </JSONArrayFlattenIterator>
 
 #endif
+
+// <JSONDocIterator>
+void PrinterVisitor::beginVisit ( const JSONDocIterator& a) {
+  thePrinter.startBeginVisit("JSONDocIterator", ++theId);
+  printCommons( &a, theId );
+  thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const JSONDocIterator& ) {
+  thePrinter.startEndVisit();
+  thePrinter.endEndVisit();
+}
+// </JSONDocIterator>
+
 #ifdef ZORBA_WITH_JSON
 // <JSONItemAccessorIterator>
 void PrinterVisitor::beginVisit ( const JSONItemAccessorIterator& a) {

=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.h'
--- src/runtime/visitors/pregenerated/printer_visitor.h	2012-10-08 12:09:36 +0000
+++ src/runtime/visitors/pregenerated/printer_visitor.h	2012-10-15 13:52:21 +0000
@@ -522,6 +522,9 @@
     void endVisit  ( const JSONArrayFlattenIterator& );
 #endif
 
+    void beginVisit( const JSONDocIterator& );
+    void endVisit  ( const JSONDocIterator& );
+
 #ifdef ZORBA_WITH_JSON
     void beginVisit( const JSONItemAccessorIterator& );
     void endVisit  ( const JSONItemAccessorIterator& );

=== added file 'test/rbkt/ExpQueryResults/zorba/jsoniq/json_doc_1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/json_doc_1.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/json_doc_1.xml.res	2012-10-15 13:52:21 +0000
@@ -0,0 +1,1 @@
+{ "foo" : "bar" }

=== added file 'test/rbkt/ExpQueryResults/zorba/jsoniq/json_doc_2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/jsoniq/json_doc_2.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/jsoniq/json_doc_2.xml.res	2012-10-15 13:52:21 +0000
@@ -0,0 +1,1 @@
+[ "bar" ]

=== added file 'test/rbkt/ExpQueryResults/zorba/jsoniq/json_doc_4.xml.res'
=== added file 'test/rbkt/Queries/zorba/jsoniq/input1.json'
--- test/rbkt/Queries/zorba/jsoniq/input1.json	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/input1.json	2012-10-15 13:52:21 +0000
@@ -0,0 +1,1 @@
+{ "foo" : "bar" }

=== added file 'test/rbkt/Queries/zorba/jsoniq/input2.json'
--- test/rbkt/Queries/zorba/jsoniq/input2.json	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/input2.json	2012-10-15 13:52:21 +0000
@@ -0,0 +1,1 @@
+{ "foo" : "bar" } { "bar" : "foo" }

=== added file 'test/rbkt/Queries/zorba/jsoniq/input3.json'
--- test/rbkt/Queries/zorba/jsoniq/input3.json	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/input3.json	2012-10-15 13:52:21 +0000
@@ -0,0 +1,1 @@
+{ "foo" : "bar" } { "bar" : "foo"

=== added file 'test/rbkt/Queries/zorba/jsoniq/json_doc_1.xq'
--- test/rbkt/Queries/zorba/jsoniq/json_doc_1.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/json_doc_1.xq	2012-10-15 13:52:21 +0000
@@ -0,0 +1,1 @@
+jn:json-doc("input1.json")
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/jsoniq/json_doc_2.xq'
--- test/rbkt/Queries/zorba/jsoniq/json_doc_2.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/json_doc_2.xq	2012-10-15 13:52:21 +0000
@@ -0,0 +1,1 @@
+[ jn:json-doc("input1.json")("foo") ]
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/jsoniq/json_doc_3.spec'
--- test/rbkt/Queries/zorba/jsoniq/json_doc_3.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/json_doc_3.spec	2012-10-15 13:52:21 +0000
@@ -0,0 +1,1 @@
+Error: http://jsoniq.org/errors:JNDY0021

=== added file 'test/rbkt/Queries/zorba/jsoniq/json_doc_3.xq'
--- test/rbkt/Queries/zorba/jsoniq/json_doc_3.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/json_doc_3.xq	2012-10-15 13:52:21 +0000
@@ -0,0 +1,1 @@
+jn:json-doc("input2.json")
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/jsoniq/json_doc_4.xq'
--- test/rbkt/Queries/zorba/jsoniq/json_doc_4.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/json_doc_4.xq	2012-10-15 13:52:21 +0000
@@ -0,0 +1,1 @@
+jn:json-doc(())
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/jsoniq/json_doc_5.spec'
--- test/rbkt/Queries/zorba/jsoniq/json_doc_5.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/json_doc_5.spec	2012-10-15 13:52:21 +0000
@@ -0,0 +1,1 @@
+Error: http://jsoniq.org/errors:JNDY0021

=== added file 'test/rbkt/Queries/zorba/jsoniq/json_doc_5.xq'
--- test/rbkt/Queries/zorba/jsoniq/json_doc_5.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/jsoniq/json_doc_5.xq	2012-10-15 13:52:21 +0000
@@ -0,0 +1,1 @@
+jn:json-doc("input3.json")
\ No newline at end of file

-- 
Mailing list: https://launchpad.net/~zorba-coders
Post to     : zorba-coders@lists.launchpad.net
Unsubscribe : https://launchpad.net/~zorba-coders
More help   : https://help.launchpad.net/ListHelp

Reply via email to