You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2012/05/11 02:05:43 UTC

svn commit: r1336974 [3/4] - in /subversion/branches/ev2-export: ./ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/lib...

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/log.c?rev=1336974&r1=1336973&r2=1336974&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/log.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/log.c Fri May 11 00:05:41 2012
@@ -639,7 +639,7 @@ svn_ra_serf__get_log(svn_ra_session_t *r
   svn_boolean_t want_custom_revprops;
   svn_revnum_t peg_rev;
   svn_error_t *err;
-  const char *relative_url, *basecoll_url, *req_url;
+  const char *req_url;
 
   log_ctx = apr_pcalloc(pool, sizeof(*log_ctx));
   log_ctx->pool = pool;
@@ -694,10 +694,10 @@ svn_ra_serf__get_log(svn_ra_session_t *r
    */
   peg_rev = (start > end) ? start : end;
 
-  SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
-                                         NULL, NULL, peg_rev, NULL, pool));
-
-  req_url = svn_path_url_add_component2(basecoll_url, relative_url, pool);
+  SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
+                                      session, NULL /* conn */,
+                                      NULL /* url */, peg_rev,
+                                      pool, pool));
 
   handler = apr_pcalloc(pool, sizeof(*handler));
 

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/mergeinfo.c?rev=1336974&r1=1336973&r2=1336974&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/mergeinfo.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/mergeinfo.c Fri May 11 00:05:41 2012
@@ -245,15 +245,14 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
   svn_ra_serf__session_t *session = ra_session->priv;
   svn_ra_serf__handler_t *handler;
   svn_ra_serf__xml_parser_t *parser_ctx;
-  const char *relative_url, *basecoll_url;
   const char *path;
 
   *catalog = NULL;
 
-  SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
-                                         NULL, NULL, revision, NULL, pool));
-
-  path = svn_path_url_add_component2(basecoll_url, relative_url, pool);
+  SVN_ERR(svn_ra_serf__get_stable_url(&path, NULL /* latest_revnum */,
+                                      session, NULL /* conn */,
+                                      NULL /* url */, revision,
+                                      pool, pool));
 
   mergeinfo_ctx = apr_pcalloc(pool, sizeof(*mergeinfo_ctx));
   mergeinfo_ctx->pool = pool;

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c?rev=1336974&r1=1336973&r2=1336974&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c Fri May 11 00:05:41 2012
@@ -62,7 +62,7 @@ typedef struct options_state_list_t {
   struct options_state_list_t *prev;
 } options_state_list_t;
 
-struct svn_ra_serf__options_context_t {
+typedef struct options_context_t {
   /* pool to allocate memory from */
   apr_pool_t *pool;
 
@@ -85,14 +85,14 @@ struct svn_ra_serf__options_context_t {
   svn_ra_serf__handler_t *handler;
   svn_ra_serf__xml_parser_t *parser_ctx;
 
-  const char *path;
-
   const char *activity_collection;
   svn_revnum_t youngest_rev;
-};
+
+} options_context_t;
+
 
 static void
-push_state(svn_ra_serf__options_context_t *options_ctx, options_state_e state)
+push_state(options_context_t *options_ctx, options_state_e state)
 {
   options_state_list_t *new_state;
 
@@ -112,7 +112,7 @@ push_state(svn_ra_serf__options_context_
   options_ctx->state = new_state;
 }
 
-static void pop_state(svn_ra_serf__options_context_t *options_ctx)
+static void pop_state(options_context_t *options_ctx)
 {
   options_state_list_t *free_state;
   free_state = options_ctx->state;
@@ -128,7 +128,7 @@ start_options(svn_ra_serf__xml_parser_t 
               const char **attrs,
               apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__options_context_t *options_ctx = parser->user_data;
+  options_context_t *options_ctx = parser->user_data;
 
   if (!options_ctx->state && strcmp(name.name, "options-response") == 0)
     {
@@ -159,7 +159,7 @@ end_options(svn_ra_serf__xml_parser_t *p
             svn_ra_serf__dav_props_t name,
             apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__options_context_t *options_ctx = parser->user_data;
+  options_context_t *options_ctx = parser->user_data;
   options_state_list_t *cur_state;
 
   if (!options_ctx->state)
@@ -197,7 +197,7 @@ cdata_options(svn_ra_serf__xml_parser_t 
               apr_size_t len,
               apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__options_context_t *ctx = parser->user_data;
+  options_context_t *ctx = parser->user_data;
 
   if (ctx->collect_cdata)
     svn_stringbuf_appendbytes(ctx->acbuf, data, len);
@@ -224,24 +224,6 @@ create_options_body(serf_bucket_t **body
   return SVN_NO_ERROR;
 }
 
-svn_boolean_t*
-svn_ra_serf__get_options_done_ptr(svn_ra_serf__options_context_t *ctx)
-{
-  return &ctx->done;
-}
-
-const char *
-svn_ra_serf__options_get_activity_collection(svn_ra_serf__options_context_t *ctx)
-{
-  return ctx->activity_collection;
-}
-
-svn_revnum_t
-svn_ra_serf__options_get_youngest_rev(svn_ra_serf__options_context_t *ctx)
-{
-  return ctx->youngest_rev;
-}
-
 
 /* We use these static pointers so we can employ pointer comparison
  * of our capabilities hash members instead of strcmp()ing all over
@@ -262,7 +244,7 @@ capabilities_headers_iterator_callback(v
                                        const char *key,
                                        const char *val)
 {
-  svn_ra_serf__options_context_t *opt_ctx = baton;
+  options_context_t *opt_ctx = baton;
   svn_ra_serf__session_t *session = opt_ctx->session;
 
   if (svn_cstring_casecmp(key, "dav") == 0)
@@ -367,10 +349,7 @@ capabilities_headers_iterator_callback(v
         }
       else if (svn_cstring_casecmp(key, SVN_DAV_YOUNGEST_REV_HEADER) == 0)
         {
-          struct svn_ra_serf__options_context_t *user_data;
-
-          user_data = opt_ctx->parser_ctx->user_data;
-          user_data->youngest_rev = SVN_STR_TO_REV(val);
+          opt_ctx->youngest_rev = SVN_STR_TO_REV(val);
         }
     }
 
@@ -388,7 +367,7 @@ options_response_handler(serf_request_t 
                          void *baton,
                          apr_pool_t *pool)
 {
-  svn_ra_serf__options_context_t *opt_ctx = baton;
+  options_context_t *opt_ctx = baton;
 
   if (!opt_ctx->headers_processed)
     {
@@ -420,14 +399,13 @@ options_response_handler(serf_request_t 
 }
 
 
-svn_error_t *
-svn_ra_serf__create_options_req(svn_ra_serf__options_context_t **opt_ctx,
-                                svn_ra_serf__session_t *session,
-                                svn_ra_serf__connection_t *conn,
-                                const char *path,
-                                apr_pool_t *pool)
+static svn_error_t *
+create_options_req(options_context_t **opt_ctx,
+                   svn_ra_serf__session_t *session,
+                   svn_ra_serf__connection_t *conn,
+                   apr_pool_t *pool)
 {
-  svn_ra_serf__options_context_t *new_ctx;
+  options_context_t *new_ctx;
   svn_ra_serf__handler_t *handler;
   svn_ra_serf__xml_parser_t *parser_ctx;
 
@@ -436,8 +414,6 @@ svn_ra_serf__create_options_req(svn_ra_s
   new_ctx->pool = pool;
 
   new_ctx->acbuf = svn_stringbuf_create_empty(pool);
-
-  new_ctx->path = path;
   new_ctx->youngest_rev = SVN_INVALID_REVNUM;
 
   new_ctx->session = session;
@@ -447,7 +423,7 @@ svn_ra_serf__create_options_req(svn_ra_s
 
   handler->handler_pool = pool;
   handler->method = "OPTIONS";
-  handler->path = path;
+  handler->path = session->session_url.path;
   handler->body_delegate = create_options_body;
   handler->body_type = "text/xml";
   handler->conn = conn;
@@ -476,6 +452,48 @@ svn_ra_serf__create_options_req(svn_ra_s
 }
 
 
+svn_error_t *
+svn_ra_serf__v2_get_youngest_revnum(svn_revnum_t *youngest,
+                                    svn_ra_serf__connection_t *conn,
+                                    apr_pool_t *scratch_pool)
+{
+  svn_ra_serf__session_t *session = conn->session;
+  options_context_t *opt_ctx;
+
+  SVN_ERR_ASSERT(SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session));
+
+  SVN_ERR(create_options_req(&opt_ctx, session, conn, scratch_pool));
+  SVN_ERR(svn_ra_serf__context_run_wait(&opt_ctx->done, session,
+                                        scratch_pool));
+
+  *youngest = opt_ctx->youngest_rev;
+
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_ra_serf__v1_get_activity_collection(const char **activity_url,
+                                        svn_ra_serf__connection_t *conn,
+                                        apr_pool_t *result_pool,
+                                        apr_pool_t *scratch_pool)
+{
+  svn_ra_serf__session_t *session = conn->session;
+  options_context_t *opt_ctx;
+
+  SVN_ERR_ASSERT(!SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session));
+
+  SVN_ERR(create_options_req(&opt_ctx, session, conn, scratch_pool));
+  SVN_ERR(svn_ra_serf__context_run_wait(&opt_ctx->done, session,
+                                        scratch_pool));
+
+  *activity_url = apr_pstrdup(result_pool, opt_ctx->activity_collection);
+
+  return SVN_NO_ERROR;
+
+}
+
+
 
 /** Capabilities exchange. */
 
@@ -484,16 +502,13 @@ svn_ra_serf__exchange_capabilities(svn_r
                                    const char **corrected_url,
                                    apr_pool_t *pool)
 {
-  svn_ra_serf__options_context_t *opt_ctx;
+  options_context_t *opt_ctx;
   svn_error_t *err;
 
   /* This routine automatically fills in serf_sess->capabilities */
-  SVN_ERR(svn_ra_serf__create_options_req(&opt_ctx, serf_sess,
-                                          serf_sess->conns[0],
-                                          serf_sess->session_url.path, pool));
+  SVN_ERR(create_options_req(&opt_ctx, serf_sess, serf_sess->conns[0], pool));
 
-  err = svn_ra_serf__context_run_wait(
-            svn_ra_serf__get_options_done_ptr(opt_ctx), serf_sess, pool);
+  err = svn_ra_serf__context_run_wait(&opt_ctx->done, serf_sess, pool);
 
   /* If our caller cares about server redirections, and our response
      carries such a thing, report as much.  We'll disregard ERR --

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c?rev=1336974&r1=1336973&r2=1336974&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c Fri May 11 00:05:41 2012
@@ -109,6 +109,7 @@ struct svn_ra_serf__propfind_context_t {
   svn_ra_serf__list_t done_item;
 };
 
+
 const svn_string_t *
 svn_ra_serf__get_ver_prop_string(apr_hash_t *props,
                                  const char *path,
@@ -644,32 +645,50 @@ svn_ra_serf__retrieve_props(apr_hash_t *
 
 
 svn_error_t *
-svn_ra_serf__walk_all_props(apr_hash_t *props,
-                            const char *name,
-                            svn_revnum_t rev,
-                            svn_ra_serf__walker_visitor_t walker,
-                            void *baton,
-                            apr_pool_t *scratch_pool)
+svn_ra_serf__fetch_node_props(apr_hash_t **results,
+                              svn_ra_serf__connection_t *conn,
+                              const char *url,
+                              svn_revnum_t revision,
+                              const svn_ra_serf__dav_props_t *which_props,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool)
 {
-  apr_hash_index_t *ns_hi;
+  apr_hash_t *multiprops;
   apr_hash_t *ver_props;
-  apr_hash_t *path_props;
-  apr_pool_t *iterpool;
 
-  ver_props = apr_hash_get(props, &rev, sizeof(rev));
-  if (!ver_props)
-    {
-      return SVN_NO_ERROR;
-    }
+  /* Note: a couple extra hash tables and whatnot get into RESULT_POOL.
+     Not a big deal at this point. Theoretically, we could fetch all
+     props into SCRATCH_POOL, then copy just the REVISION/URL props
+     into RESULT_POOL. Too much work for too little gain...  */
+  SVN_ERR(svn_ra_serf__retrieve_props(&multiprops, conn->session, conn,
+                                      url, revision, "0", which_props,
+                                      result_pool, scratch_pool));
+
+  ver_props = apr_hash_get(multiprops, &revision, sizeof(revision));
+  if (ver_props != NULL)
+    {
+      *results = apr_hash_get(ver_props, url, APR_HASH_KEY_STRING);
+      if (*results != NULL)
+        return SVN_NO_ERROR;
+    }
+
+  return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
+                          _("The PROPFIND response did not include "
+                            "the requested properties"));
+}
 
-  path_props = apr_hash_get(ver_props, name, APR_HASH_KEY_STRING);
-  if (!path_props)
-    {
-      return SVN_NO_ERROR;
-    }
+
+svn_error_t *
+svn_ra_serf__walk_node_props(apr_hash_t *props,
+                             svn_ra_serf__walker_visitor_t walker,
+                             void *baton,
+                             apr_pool_t *scratch_pool)
+{
+  apr_pool_t *iterpool;
+  apr_hash_index_t *ns_hi;
 
   iterpool = svn_pool_create(scratch_pool);
-  for (ns_hi = apr_hash_first(scratch_pool, path_props); ns_hi;
+  for (ns_hi = apr_hash_first(scratch_pool, props); ns_hi;
        ns_hi = apr_hash_next(ns_hi))
     {
       void *ns_val;
@@ -703,6 +722,31 @@ svn_ra_serf__walk_all_props(apr_hash_t *
 
 
 svn_error_t *
+svn_ra_serf__walk_all_props(apr_hash_t *props,
+                            const char *name,
+                            svn_revnum_t rev,
+                            svn_ra_serf__walker_visitor_t walker,
+                            void *baton,
+                            apr_pool_t *scratch_pool)
+{
+  apr_hash_t *ver_props;
+  apr_hash_t *path_props;
+
+  ver_props = apr_hash_get(props, &rev, sizeof(rev));
+  if (!ver_props)
+    return SVN_NO_ERROR;
+
+  path_props = apr_hash_get(ver_props, name, APR_HASH_KEY_STRING);
+  if (!path_props)
+    return SVN_NO_ERROR;
+
+  return svn_error_trace(svn_ra_serf__walk_node_props(path_props,
+                                                      walker, baton,
+                                                      scratch_pool));
+}
+
+
+svn_error_t *
 svn_ra_serf__walk_all_paths(apr_hash_t *props,
                             svn_revnum_t rev,
                             svn_ra_serf__path_rev_walker_t walker,
@@ -824,15 +868,13 @@ set_flat_props(void *baton,
 svn_error_t *
 svn_ra_serf__flatten_props(apr_hash_t **flat_props,
                            apr_hash_t *props,
-                           const char *path,
-                           svn_revnum_t revision,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
 {
   *flat_props = apr_hash_make(result_pool);
 
-  return svn_error_trace(svn_ra_serf__walk_all_props(
-                            props, path, revision,
+  return svn_error_trace(svn_ra_serf__walk_node_props(
+                            props,
                             set_flat_props,
                             *flat_props /* baton */,
                             scratch_pool));
@@ -891,7 +933,7 @@ svn_ra_serf__select_revprops(apr_hash_t 
 
 
 /*
- * Contact the server (using SESSION and CONN) to calculate baseline
+ * Contact the server (using CONN) to calculate baseline
  * information for BASELINE_URL at REVISION (which may be
  * SVN_INVALID_REVNUM to query the HEAD revision).
  *
@@ -903,71 +945,144 @@ svn_ra_serf__select_revprops(apr_hash_t 
 static svn_error_t *
 retrieve_baseline_info(svn_revnum_t *actual_revision,
                        const char **basecoll_url_p,
-                       svn_ra_serf__session_t *session,
                        svn_ra_serf__connection_t *conn,
                        const char *baseline_url,
                        svn_revnum_t revision,
-                       apr_pool_t *pool)
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
 {
   apr_hash_t *props;
+  apr_hash_t *dav_props;
   const char *basecoll_url;
-  const char *version_name;
-
-  SVN_ERR(svn_ra_serf__retrieve_props(&props, session, conn,
-                                      baseline_url, revision, "0",
-                                      baseline_props,
-                                      pool, pool));
 
-  basecoll_url = svn_ra_serf__get_ver_prop(props, baseline_url, revision,
-                                           "DAV:", "baseline-collection");
+  SVN_ERR(svn_ra_serf__fetch_node_props(&props, conn,
+                                        baseline_url, revision,
+                                        baseline_props,
+                                        scratch_pool, scratch_pool));
+  dav_props = apr_hash_get(props, "DAV:", 4);
+  /* If DAV_PROPS is NULL, then svn_prop_get_value() will return NULL.  */
 
+  basecoll_url = svn_prop_get_value(dav_props, "baseline-collection");
   if (!basecoll_url)
     {
       return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
                               _("The PROPFIND response did not include "
                                 "the requested baseline-collection value"));
     }
-
-  *basecoll_url_p = svn_urlpath__canonicalize(basecoll_url, pool);
-
-  version_name = svn_ra_serf__get_ver_prop(props, baseline_url, revision,
-                                           "DAV:", SVN_DAV__VERSION_NAME);
-  if (!version_name)
-    {
-      return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
-                              _("The PROPFIND response did not include "
-                                "the requested version-name value"));
-    }
+  *basecoll_url_p = svn_urlpath__canonicalize(basecoll_url, result_pool);
 
   if (actual_revision)
     {
+      const char *version_name;
+
+      version_name = svn_prop_get_value(dav_props, SVN_DAV__VERSION_NAME);
+      if (!version_name)
+        return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
+                                _("The PROPFIND response did not include "
+                                  "the requested version-name value"));
+
       *actual_revision = SVN_STR_TO_REV(version_name);
     }
 
   return SVN_NO_ERROR;
 }
 
+
+/* For HTTPv1 servers, do a PROPFIND dance on the VCC to fetch the youngest
+   revnum. If BASECOLL_URL is non-NULL, then the corresponding baseline
+   collection URL is also returned.
+
+   Do the work over CONN.
+
+   *BASECOLL_URL (if requested) will be allocated in RESULT_POOL. All
+   temporary allocations will be made in SCRATCH_POOL.  */
+static svn_error_t *
+v1_get_youngest_revnum(svn_revnum_t *youngest,
+                       const char **basecoll_url,
+                       svn_ra_serf__connection_t *conn,
+                       const char *vcc_url,
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
+{
+  const char *baseline_url;
+  const char *bc_url;
+
+  /* Fetching DAV:checked-in from the VCC (with no Label: to specify a
+     revision) will return the latest Baseline resource's URL.  */
+  SVN_ERR(svn_ra_serf__fetch_dav_prop(&baseline_url, conn, vcc_url,
+                                      SVN_INVALID_REVNUM,
+                                      "checked-in",
+                                      scratch_pool, scratch_pool));
+  if (!baseline_url)
+    {
+      return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL,
+                              _("The OPTIONS response did not include "
+                                "the requested checked-in value"));
+    }
+  baseline_url = svn_urlpath__canonicalize(baseline_url, scratch_pool);
+
+  /* From the Baseline resource, we can fetch the DAV:baseline-collection
+     and DAV:version-name properties. The latter is the revision number,
+     which is formally the name used in Label: headers.  */
+
+  /* First check baseline information cache. */
+  SVN_ERR(svn_ra_serf__blncache_get_baseline_info(&bc_url,
+                                                  youngest,
+                                                  conn->session->blncache,
+                                                  baseline_url,
+                                                  scratch_pool));
+  if (!bc_url)
+    {
+      SVN_ERR(retrieve_baseline_info(youngest, &bc_url, conn,
+                                     baseline_url, SVN_INVALID_REVNUM,
+                                     scratch_pool, scratch_pool));
+      SVN_ERR(svn_ra_serf__blncache_set(conn->session->blncache,
+                                        baseline_url, *youngest,
+                                        bc_url, scratch_pool));
+    }
+
+  if (basecoll_url != NULL)
+    *basecoll_url = apr_pstrdup(result_pool, bc_url);
+
+  return SVN_NO_ERROR;
+}
+
+
 svn_error_t *
-svn_ra_serf__get_baseline_info(const char **bc_url,
-                               const char **bc_relative,
-                               svn_ra_serf__session_t *session,
-                               svn_ra_serf__connection_t *conn,
-                               const char *url,
-                               svn_revnum_t revision,
-                               svn_revnum_t *latest_revnum,
-                               apr_pool_t *pool)
+svn_ra_serf__get_youngest_revnum(svn_revnum_t *youngest,
+                                 svn_ra_serf__session_t *session,
+                                 apr_pool_t *scratch_pool)
 {
-  const char *vcc_url, *relative_url, *basecoll_url, *baseline_url;
+  const char *vcc_url;
 
-  /* No URL?  No sweat.  We'll use the session URL. */
-  if (! url)
-    url = session->session_url.path;
+  if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session))
+    return svn_error_trace(svn_ra_serf__v2_get_youngest_revnum(
+                             youngest, session->conns[0], scratch_pool));
+
+  SVN_ERR(svn_ra_serf__discover_vcc(&vcc_url, session, NULL, scratch_pool));
+
+  return svn_error_trace(v1_get_youngest_revnum(youngest, NULL,
+                                                session->conns[0], vcc_url,
+                                                scratch_pool, scratch_pool));
+}
 
-  /* If the caller didn't provide a specific connection for us to use,
-     we'll use the default one.  */
-  if (! conn)
-    conn = session->conns[0];
 
+/* Set *BC_URL to the baseline collection url for REVISION. If REVISION
+   is SVN_INVALID_REVNUM, then the youngest revnum ("HEAD") is used.
+
+   *REVNUM_USED will be set to the revision used.
+
+   Uses the specified CONN, which is part of SESSION.
+
+   All allocations (results and temporary) are performed in POOL.  */
+static svn_error_t *
+get_baseline_info(const char **bc_url,
+                  svn_revnum_t *revnum_used,
+                  svn_ra_serf__session_t *session,
+                  svn_ra_serf__connection_t *conn,
+                  svn_revnum_t revision,
+                  apr_pool_t *pool)
+{
   /* If we detected HTTP v2 support on the server, we can construct
      the baseline collection URL ourselves, and fetch the latest
      revision (if needed) with an OPTIONS request.  */
@@ -977,125 +1092,109 @@ svn_ra_serf__get_baseline_info(const cha
 
       if (SVN_IS_VALID_REVNUM(revision))
         {
-          actual_revision = revision;
+          *revnum_used = revision;
         }
       else
         {
-          svn_ra_serf__options_context_t *opt_ctx;
-
-          SVN_ERR(svn_ra_serf__create_options_req(&opt_ctx, session, conn,
-                                                  session->session_url.path,
-                                                  pool));
-          SVN_ERR(svn_ra_serf__context_run_wait(
-                svn_ra_serf__get_options_done_ptr(opt_ctx), session, pool));
-
-          actual_revision = svn_ra_serf__options_get_youngest_rev(opt_ctx);
+          SVN_ERR(svn_ra_serf__v2_get_youngest_revnum(
+                    revnum_used, conn, pool));
           if (! SVN_IS_VALID_REVNUM(actual_revision))
             return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL,
                                     _("The OPTIONS response did not include "
                                       "the youngest revision"));
         }
 
-      basecoll_url = apr_psprintf(pool, "%s/%ld",
-                                  session->rev_root_stub, actual_revision);
-      if (latest_revnum)
-        *latest_revnum = actual_revision;
+      *bc_url = apr_psprintf(pool, "%s/%ld",
+                             session->rev_root_stub, *revnum_used);
     }
 
   /* Otherwise, we fall back to the old VCC_URL PROPFIND hunt.  */
   else
     {
+      const char *vcc_url;
+
       SVN_ERR(svn_ra_serf__discover_vcc(&vcc_url, session, conn, pool));
 
       if (SVN_IS_VALID_REVNUM(revision))
         {
           /* First check baseline information cache. */
-          SVN_ERR(svn_ra_serf__blncache_get_bc_url(&basecoll_url,
+          SVN_ERR(svn_ra_serf__blncache_get_bc_url(bc_url,
                                                    session->blncache,
                                                    revision, pool));
-
-          if (!basecoll_url)
+          if (!*bc_url)
             {
-              SVN_ERR(retrieve_baseline_info(NULL, &basecoll_url, session,
-                                             conn, vcc_url, revision, pool));
+              SVN_ERR(retrieve_baseline_info(NULL, bc_url, conn,
+                                             vcc_url, revision, pool, pool));
               SVN_ERR(svn_ra_serf__blncache_set(session->blncache, NULL,
-                                                revision, basecoll_url, pool));
+                                                revision, *bc_url, pool));
             }
 
-          if (latest_revnum)
-            {
-              *latest_revnum = revision;
-            }
+          *revnum_used = revision;
         }
       else
         {
-          apr_hash_t *props;
-          svn_revnum_t actual_revision;
+          SVN_ERR(v1_get_youngest_revnum(revnum_used, bc_url,
+                                         conn, vcc_url,
+                                         pool, pool));
+        }
+    }
 
-          SVN_ERR(svn_ra_serf__retrieve_props(&props, session, conn,
-                                              vcc_url, revision, "0",
-                                              checked_in_props,
-                                              pool, pool));
-          baseline_url = svn_ra_serf__get_ver_prop(props, vcc_url, revision,
-                                                   "DAV:", "checked-in");
-          if (!baseline_url)
-            {
-              return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL,
-                                      _("The OPTIONS response did not include "
-                                        "the requested checked-in value"));
-            }
+  return SVN_NO_ERROR;
+}
 
-          baseline_url = svn_urlpath__canonicalize(baseline_url, pool);
 
-          /* First check baseline information cache. */
-          SVN_ERR(svn_ra_serf__blncache_get_baseline_info(&basecoll_url,
-                                                          &actual_revision,
-                                                          session->blncache,
-                                                          baseline_url,
-                                                          pool));
-          if (!basecoll_url)
-            {
-              SVN_ERR(retrieve_baseline_info(&actual_revision, &basecoll_url,
-                                             session, conn,
-                                             baseline_url, revision, pool));
-              SVN_ERR(svn_ra_serf__blncache_set(session->blncache,
-                                                baseline_url, actual_revision,
-                                                basecoll_url, pool));
-            }
+svn_error_t *
+svn_ra_serf__get_stable_url(const char **stable_url,
+                            svn_revnum_t *latest_revnum,
+                            svn_ra_serf__session_t *session,
+                            svn_ra_serf__connection_t *conn,
+                            const char *url,
+                            svn_revnum_t revision,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
+{
+  const char *basecoll_url;
+  const char *repos_relpath;
+  svn_revnum_t revnum_used;
 
-          if (latest_revnum)
-            {
-              *latest_revnum = actual_revision;
-            }
-        }
-    }
+  /* No URL? No sweat. We'll use the session URL.  */
+  if (! url)
+    url = session->session_url.path;
+
+  /* If the caller didn't provide a specific connection for us to use,
+     we'll use the default connection.  */
+  if (! conn)
+    conn = session->conns[0];
 
-  /* And let's not forget to calculate our relative path. */
-  SVN_ERR(svn_ra_serf__get_relative_path(&relative_url, url, session,
-                                         conn, pool));
+  SVN_ERR(get_baseline_info(&basecoll_url, &revnum_used,
+                            session, conn, revision, scratch_pool));
+  SVN_ERR(svn_ra_serf__get_relative_path(&repos_relpath, url,
+                                         session, conn, scratch_pool));
+
+  *stable_url = svn_path_url_add_component2(basecoll_url, repos_relpath,
+                                            result_pool);
+  if (latest_revnum)
+    *latest_revnum = revnum_used;
 
-  *bc_url = basecoll_url;
-  *bc_relative = relative_url;
   return SVN_NO_ERROR;
 }
 
 
 svn_error_t *
 svn_ra_serf__get_resource_type(svn_kind_t *kind,
-                               apr_hash_t *props,
-                               const char *url,
-                               svn_revnum_t revision)
+                               apr_hash_t *props)
 {
+  apr_hash_t *dav_props;
   const char *res_type;
 
-  res_type = svn_ra_serf__get_ver_prop(props, url, revision,
-                                       "DAV:", "resourcetype");
+  dav_props = apr_hash_get(props, "DAV:", 4);
+  res_type = svn_prop_get_value(dav_props, "resourcetype");
   if (!res_type)
     {
       /* How did this happen? */
       return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
                               _("The PROPFIND response did not include the "
-                              "requested resourcetype value"));
+                                "requested resourcetype value"));
     }
 
   if (strcmp(res_type, "collection") == 0)
@@ -1109,3 +1208,34 @@ svn_ra_serf__get_resource_type(svn_kind_
 
   return SVN_NO_ERROR;
 }
+
+
+svn_error_t *
+svn_ra_serf__fetch_dav_prop(const char **value,
+                            svn_ra_serf__connection_t *conn,
+                            const char *url,
+                            svn_revnum_t revision,
+                            const char *propname,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
+{
+  apr_hash_t *props;
+  apr_hash_t *dav_props;
+
+  SVN_ERR(svn_ra_serf__fetch_node_props(&props, conn, url, revision,
+                                        checked_in_props,
+                                        scratch_pool, scratch_pool));
+  dav_props = apr_hash_get(props, "DAV:", 4);
+  if (dav_props == NULL)
+    return svn_error_create(SVN_ERR_RA_DAV_PROPS_NOT_FOUND, NULL,
+                            _("The PROPFIND response did not include "
+                              "the requested 'DAV:' properties"));
+
+  /* We wouldn't get here if the resource was not found (404), so the
+     property should be present.
+
+     Note: it is okay to call apr_pstrdup() with NULL.  */
+  *value = apr_pstrdup(result_pool, svn_prop_get_value(dav_props, propname));
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h?rev=1336974&r1=1336973&r2=1336974&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h Fri May 11 00:05:41 2012
@@ -280,36 +280,12 @@ static const svn_ra_serf__dav_props_t al
   { NULL }
 };
 
-static const svn_ra_serf__dav_props_t vcc_props[] =
-{
-  { "DAV:", "version-controlled-configuration" },
-  { NULL }
-};
-
 static const svn_ra_serf__dav_props_t check_path_props[] =
 {
   { "DAV:", "resourcetype" },
   { NULL }
 };
 
-static const svn_ra_serf__dav_props_t uuid_props[] =
-{
-  { SVN_DAV_PROP_NS_DAV, "repository-uuid" },
-  { NULL }
-};
-
-static const svn_ra_serf__dav_props_t repos_root_props[] =
-{
-  { SVN_DAV_PROP_NS_DAV, "baseline-relative-path" },
-  { NULL }
-};
-
-static const svn_ra_serf__dav_props_t href_props[] =
-{
-  { "DAV:", "href" },
-  { NULL }
-};
-
 /* WC props compatibility with ra_neon. */
 #define SVN_RA_SERF__WC_CHECKED_IN_URL SVN_PROP_WC_PREFIX "ra_dav:version-url"
 
@@ -919,6 +895,50 @@ svn_ra_serf__retrieve_props(apr_hash_t *
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool);
 
+
+/* Using CONN, fetch the properties specified by WHICH_PROPS using CONN
+   for URL at REVISION. The resulting properties are placed into a 2-level
+   hash in RESULTS, mapping NAMESPACE -> hash<PROPNAME, PROPVALUE>, which
+   is allocated in RESULT_POOL.
+
+   If REVISION is SVN_INVALID_REVNUM, then the properties are fetched
+   from HEAD for URL.
+
+   This function performs the request synchronously.
+
+   Temporary allocations are made in SCRATCH_POOL.  */
+svn_error_t *
+svn_ra_serf__fetch_node_props(apr_hash_t **results,
+                              svn_ra_serf__connection_t *conn,
+                              const char *url,
+                              svn_revnum_t revision,
+                              const svn_ra_serf__dav_props_t *which_props,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool);
+
+
+/* Using CONN, fetch a DAV: property from the resource identified by URL
+   within REVISION. The PROPNAME may be one of:
+
+     "checked-in"
+     "href"
+
+   The resulting value will be allocated in RESULT_POOL, and may be NULL
+   if the property does not exist (note: "href" always exists).
+
+   This function performs the request synchronously.
+
+   Temporary allocations are made in SCRATCH_POOL.  */
+svn_error_t *
+svn_ra_serf__fetch_dav_prop(const char **value,
+                            svn_ra_serf__connection_t *conn,
+                            const char *url,
+                            svn_revnum_t revision,
+                            const char *propname,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
+
+
 /* Set PROPS for PATH at REV revision with a NS:NAME VAL.
  *
  * The POOL governs allocation.
@@ -947,6 +967,15 @@ svn_ra_serf__walk_all_props(apr_hash_t *
                             void *baton,
                             apr_pool_t *pool);
 
+
+/* Like walk_all_props(), but a 2-level hash.  */
+svn_error_t *
+svn_ra_serf__walk_node_props(apr_hash_t *props,
+                             svn_ra_serf__walker_visitor_t walker,
+                             void *baton,
+                             apr_pool_t *scratch_pool);
+
+
 typedef svn_error_t *
 (*svn_ra_serf__path_rev_walker_t)(void *baton,
                                   const char *path, apr_ssize_t path_len,
@@ -985,9 +1014,8 @@ svn_ra_serf__select_revprops(apr_hash_t 
                              apr_pool_t *scratch_pool);
 
 
-/* PROPS is nested hash tables mapping REV -> PATH -> NS -> NAME -> VALUE.
-   This function takes the tree of tables identified by PATH and REVISION
-   (resulting in NS:NAME:VALUE hashes) and flattens them into a set of
+/* PROPS is nested hash tables mapping NS -> NAME -> VALUE.
+   This function takes the NS:NAME:VALUE hashes and flattens them into a set of
    names to VALUE. The names are composed of NS:NAME, with specific
    rewrite from wire names (DAV) to SVN names. This mapping is managed
    by the svn_ra_serf__set_baton_props() function.
@@ -1000,8 +1028,6 @@ svn_ra_serf__select_revprops(apr_hash_t 
 svn_error_t *
 svn_ra_serf__flatten_props(apr_hash_t **flat_props,
                            apr_hash_t *props,
-                           const char *path,
-                           svn_revnum_t revision,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool);
 
@@ -1042,9 +1068,7 @@ svn_ra_serf__set_prop(apr_hash_t *props,
 
 svn_error_t *
 svn_ra_serf__get_resource_type(svn_kind_t *kind,
-                               apr_hash_t *props,
-                               const char *url,
-                               svn_revnum_t revision);
+                               apr_hash_t *props);
 
 
 /** MERGE-related functions **/
@@ -1083,28 +1107,35 @@ svn_ra_serf__merge_create_req(svn_ra_ser
 
 /** OPTIONS-related functions **/
 
-typedef struct svn_ra_serf__options_context_t svn_ra_serf__options_context_t;
+/* On HTTPv2 connections, run an OPTIONS request over CONN to fetch the
+   current youngest revnum, returning it in *YOUNGEST.
 
-/* Is this OPTIONS-request done yet? */
-svn_boolean_t*
-svn_ra_serf__get_options_done_ptr(svn_ra_serf__options_context_t *ctx);
+   (the revnum is headers of the OPTIONS response)
 
-const char *
-svn_ra_serf__options_get_activity_collection(svn_ra_serf__options_context_t *ctx);
+   This function performs the request synchronously.
 
-svn_revnum_t
-svn_ra_serf__options_get_youngest_rev(svn_ra_serf__options_context_t *ctx);
+   All temporary allocations will be made in SCRATCH_POOL.  */
+svn_error_t *
+svn_ra_serf__v2_get_youngest_revnum(svn_revnum_t *youngest,
+                                    svn_ra_serf__connection_t *conn,
+                                    apr_pool_t *scratch_pool);
+
+
+/* On HTTPv1 connections, run an OPTIONS request over CONN to fetch the
+   activity collection set and return it in *ACTIVITY_URL, allocated
+   from RESULT_POOL.
+
+   (the activity-collection-set is in the body of the OPTIONS response)
+
+   This function performs the request synchronously.
+
+   All temporary allocations will be made in SCRATCH_POOL.  */
+svn_error_t *
+svn_ra_serf__v1_get_activity_collection(const char **activity_url,
+                                        svn_ra_serf__connection_t *conn,
+                                        apr_pool_t *result_pool,
+                                        apr_pool_t *scratch_pool);
 
-/* Create an OPTIONS request.  When run, ask for an
-   activity-collection-set in the request body (retrievable via
-   accessor above) and also parse the server's capability headers into
-   the SESSION->capabilites hash. */
-svn_error_t *
-svn_ra_serf__create_options_req(svn_ra_serf__options_context_t **opt_ctx,
-                                svn_ra_serf__session_t *session,
-                                svn_ra_serf__connection_t *conn,
-                                const char *path,
-                                apr_pool_t *pool);
 
 /* Set @a VCC_URL to the default VCC for our repository based on @a
  * ORIG_PATH for the session @a SESSION, ensuring that the VCC URL and
@@ -1144,31 +1175,59 @@ svn_ra_serf__get_relative_path(const cha
                                svn_ra_serf__connection_t *conn,
                                apr_pool_t *pool);
 
-/* Set *BC_URL to the baseline collection url, and set *BC_RELATIVE to
- * the path relative to that url for URL in REVISION using SESSION.
- * BC_RELATIVE will be URI decoded.
- *
- * REVISION may be SVN_INVALID_REVNUM (to mean "the current HEAD
- * revision").  If URL is NULL, use SESSION's session url.
- *
- * If LATEST_REVNUM is not NULL, set it to the baseline revision. If
- * REVISION was set to SVN_INVALID_REVNUM, this will return the current
- * HEAD revision.
- *
- * If non-NULL, use CONN for communications with the server;
- * otherwise, use the default connection.
- *
- * Use POOL for all allocations.
- */
+
+/* Using the default connection in SESSION (conns[0]), get the youngest
+   revnum from the server, returning it in *YOUNGEST.
+
+   This function operates synchronously.
+
+   All temporary allocations are performed in SCRATCH_POOL.  */
 svn_error_t *
-svn_ra_serf__get_baseline_info(const char **bc_url,
-                               const char **bc_relative,
-                               svn_ra_serf__session_t *session,
-                               svn_ra_serf__connection_t *conn,
-                               const char *url,
-                               svn_revnum_t revision,
-                               svn_revnum_t *latest_revnum,
-                               apr_pool_t *pool);
+svn_ra_serf__get_youngest_revnum(svn_revnum_t *youngest,
+                                 svn_ra_serf__session_t *session,
+                                 apr_pool_t *scratch_pool);
+
+
+/* Generate a revision-stable URL.
+
+   The RA APIs all refer to user/public URLs that float along with the
+   youngest revision. In many cases, we do NOT want to work with that URL
+   since it can change from one moment to the next. Especially if we
+   attempt to operation against multiple floating URLs -- we could end up
+   referring to two separate revisions.
+
+   The DAV RA provider(s) solve this by generating a URL that is specific
+   to a revision by using a URL into a "baseline collection".
+
+   For a specified SESSION, with an optional CONN (if NULL, then the
+   session's default connection will be used; specifically SESSION->conns[0]),
+   generate a revision-stable URL for URL at REVISION. If REVISION is
+   SVN_INVALID_REVNUM, then the stable URL will refer to the youngest
+   revision at the time this function was called.
+
+   If URL is NULL, then the session root will be used.
+
+   The stable URL will be placed into *STABLE_URL, allocated from RESULT_POOL.
+
+   If LATEST_REVNUM is not NULL, then the revision used will be placed into
+   *LATEST_REVNUM. That will be equal to youngest, or the given REVISION.
+
+   This function operates synchronously, if any communication to the server
+   is required. Communication is needed if REVISION is SVN_INVALID_REVNUM
+   (to get the current youngest revnum), or if the specified REVISION is not
+   (yet) in our cache of baseline collections.
+
+   All temporary allocations are performed in SCRATCH_POOL.  */
+svn_error_t *
+svn_ra_serf__get_stable_url(const char **stable_url,
+                            svn_revnum_t *latest_revnum,
+                            svn_ra_serf__session_t *session,
+                            svn_ra_serf__connection_t *conn,
+                            const char *url,
+                            svn_revnum_t revision,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
+
 
 /** RA functions **/
 

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c?rev=1336974&r1=1336973&r2=1336974&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c Fri May 11 00:05:41 2012
@@ -198,13 +198,12 @@ start_replay(svn_ra_serf__xml_parser_t *
       ctx->dst_rev_pool = svn_pool_create(ctx->src_rev_pool);
       ctx->file_pool = svn_pool_create(ctx->dst_rev_pool);
 
-      /* ### it would be nice to have a proper scratch_pool.  */
       SVN_ERR(svn_ra_serf__select_revprops(&ctx->props,
                                            ctx->revprop_target,
                                            ctx->revprop_rev,
                                            ctx->revs_props,
                                            ctx->dst_rev_pool,
-                                           ctx->dst_rev_pool));
+                                           scratch_pool));
 
       if (ctx->revstart_func)
         {
@@ -228,7 +227,7 @@ start_replay(svn_ra_serf__xml_parser_t *
 
       SVN_ERR(ctx->editor->set_target_revision(ctx->editor_baton,
                                                SVN_STR_TO_REV(rev),
-                                               ctx->dst_rev_pool));
+                                               scratch_pool));
     }
   else if (state == REPORT &&
            strcmp(name.name, "open-root") == 0)
@@ -273,7 +272,7 @@ start_replay(svn_ra_serf__xml_parser_t *
       info = push_state(parser, ctx, DELETE_ENTRY);
 
       SVN_ERR(ctx->editor->delete_entry(file_name, SVN_STR_TO_REV(rev),
-                                        info->baton, ctx->dst_rev_pool));
+                                        info->baton, scratch_pool));
 
       svn_ra_serf__xml_pop_state(parser);
     }
@@ -334,7 +333,7 @@ start_replay(svn_ra_serf__xml_parser_t *
     {
       replay_info_t *info = parser->state->private;
 
-      SVN_ERR(ctx->editor->close_directory(info->baton, ctx->dst_rev_pool));
+      SVN_ERR(ctx->editor->close_directory(info->baton, scratch_pool));
 
       svn_ra_serf__xml_pop_state(parser);
     }
@@ -426,8 +425,7 @@ start_replay(svn_ra_serf__xml_parser_t *
 
       checksum = svn_xml_get_attr_value("checksum", attrs);
 
-      SVN_ERR(ctx->editor->close_file(info->baton, checksum,
-                                      ctx->file_pool));
+      SVN_ERR(ctx->editor->close_file(info->baton, checksum, scratch_pool));
 
       svn_ra_serf__xml_pop_state(parser);
     }

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c?rev=1336974&r1=1336973&r2=1336974&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c Fri May 11 00:05:41 2012
@@ -498,13 +498,10 @@ svn_ra_serf__get_latest_revnum(svn_ra_se
                                svn_revnum_t *latest_revnum,
                                apr_pool_t *pool)
 {
-  const char *relative_url, *basecoll_url;
   svn_ra_serf__session_t *session = ra_session->priv;
 
-  return svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
-                                        NULL, session->session_url.path,
-                                        SVN_INVALID_REVNUM, latest_revnum,
-                                        pool);
+  return svn_error_trace(svn_ra_serf__get_youngest_revnum(
+                           latest_revnum, session, pool));
 }
 
 static svn_error_t *
@@ -533,6 +530,7 @@ svn_ra_serf__rev_proplist(svn_ra_session
       SVN_ERR(svn_ra_serf__discover_vcc(&propfind_path, session, NULL, pool));
     }
 
+  /* ### fix: fetch hash of *just* the PATH@REV props. no nested hash.  */
   SVN_ERR(svn_ra_serf__retrieve_props(&props, session, session->conns[0],
                                       propfind_path, rev, "0", all_props,
                                       pool, pool));
@@ -560,67 +558,38 @@ svn_ra_serf__rev_prop(svn_ra_session_t *
 }
 
 static svn_error_t *
-fetch_path_props(svn_ra_serf__propfind_context_t **ret_prop_ctx,
-                 apr_hash_t **ret_props,
-                 const char **ret_path,
-                 svn_revnum_t *ret_revision,
+fetch_path_props(apr_hash_t **props,
                  svn_ra_serf__session_t *session,
-                 const char *rel_path,
+                 const char *session_relpath,
                  svn_revnum_t revision,
                  const svn_ra_serf__dav_props_t *desired_props,
-                 apr_pool_t *pool)
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
 {
-  svn_ra_serf__propfind_context_t *prop_ctx;
-  apr_hash_t *props;
-  const char *path;
+  const char *url;
 
-  path = session->session_url.path;
+  url = session->session_url.path;
 
   /* If we have a relative path, append it. */
-  if (rel_path)
-    {
-      path = svn_path_url_add_component2(path, rel_path, pool);
-    }
-
-  props = apr_hash_make(pool);
-
-  /* If we were given a specific revision, we have to fetch the VCC and
-   * do a PROPFIND off of that.
-   */
-  if (!SVN_IS_VALID_REVNUM(revision))
-    {
-      SVN_ERR(svn_ra_serf__deliver_props(&prop_ctx, props, session,
-                                         session->conns[0], path, revision,
-                                         "0", desired_props, NULL,
-                                         pool));
-    }
-  else
-    {
-      const char *relative_url, *basecoll_url;
+  if (session_relpath)
+    url = svn_path_url_add_component2(url, session_relpath, scratch_pool);
 
-      SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url,
-                                             session, NULL, path,
-                                             revision, NULL, pool));
-
-      /* We will try again with our new path; however, we're now
-       * technically an unversioned resource because we are accessing
-       * the revision's baseline-collection.
-       */
-      path = svn_path_url_add_component2(basecoll_url, relative_url, pool);
-      revision = SVN_INVALID_REVNUM;
-      SVN_ERR(svn_ra_serf__deliver_props(&prop_ctx, props, session,
-                                         session->conns[0], path, revision,
-                                         "0", desired_props, NULL,
-                                         pool));
-    }
-
-  /* ### switch to svn_ra_serf__retrieve_props?  */
-  SVN_ERR(svn_ra_serf__wait_for_props(prop_ctx, session, pool));
-
-  *ret_path = path;
-  *ret_prop_ctx = prop_ctx;
-  *ret_props = props;
-  *ret_revision = revision;
+  /* If we were given a specific revision, get a URL that refers to that
+     specific revision (rather than floating with HEAD).  */
+  if (SVN_IS_VALID_REVNUM(revision))
+    {
+      SVN_ERR(svn_ra_serf__get_stable_url(&url, NULL /* latest_revnum */,
+                                          session, NULL /* conn */,
+                                          url, revision,
+                                          scratch_pool, scratch_pool));
+    }
+
+  /* URL is stable, so we use SVN_INVALID_REVNUM since it is now irrelevant.
+     Or we started with SVN_INVALID_REVNUM and URL may be floating.  */
+  SVN_ERR(svn_ra_serf__fetch_node_props(props, session->conns[0],
+                                        url, SVN_INVALID_REVNUM,
+                                        desired_props,
+                                        result_pool, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -634,13 +603,10 @@ svn_ra_serf__check_path(svn_ra_session_t
 {
   svn_ra_serf__session_t *session = ra_session->priv;
   apr_hash_t *props;
-  svn_ra_serf__propfind_context_t *prop_ctx;
-  const char *path;
-  svn_revnum_t fetched_rev;
 
-  svn_error_t *err = fetch_path_props(&prop_ctx, &props, &path, &fetched_rev,
-                                      session, rel_path,
-                                      revision, check_path_props, pool);
+  svn_error_t *err = fetch_path_props(&props, session, rel_path,
+                                      revision, check_path_props,
+                                      pool, pool);
 
   if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
     {
@@ -653,10 +619,9 @@ svn_ra_serf__check_path(svn_ra_session_t
 
       /* Any other error, raise to caller. */
       if (err)
-        return err;
+        return svn_error_trace(err);
 
-      SVN_ERR(svn_ra_serf__get_resource_type(&res_kind, props, path,
-                                             fetched_rev));
+      SVN_ERR(svn_ra_serf__get_resource_type(&res_kind, props));
       *kind = svn__node_kind_from_kind(res_kind);
     }
 
@@ -876,17 +841,14 @@ svn_ra_serf__stat(svn_ra_session_t *ra_s
 {
   svn_ra_serf__session_t *session = ra_session->priv;
   apr_hash_t *props;
-  svn_ra_serf__propfind_context_t *prop_ctx;
-  const char *path;
-  svn_revnum_t fetched_rev;
   svn_error_t *err;
   struct dirent_walker_baton_t dwb;
   svn_tristate_t deadprop_count = svn_tristate_unknown;
 
-  err = fetch_path_props(&prop_ctx, &props, &path, &fetched_rev,
+  err = fetch_path_props(&props,
                          session, rel_path, revision,
                          get_dirent_props(SVN_DIRENT_ALL, session, pool),
-                         pool);
+                         pool, pool);
   if (err)
     {
       if (err->apr_err == SVN_ERR_FS_NOT_FOUND)
@@ -902,9 +864,7 @@ svn_ra_serf__stat(svn_ra_session_t *ra_s
   dwb.entry = apr_pcalloc(pool, sizeof(*dwb.entry));
   dwb.supports_deadprop_count = &deadprop_count;
   dwb.result_pool = pool;
-  SVN_ERR(svn_ra_serf__walk_all_props(props, path, fetched_rev,
-                                      dirent_walker, &dwb,
-                                      pool));
+  SVN_ERR(svn_ra_serf__walk_node_props(props, dirent_walker, &dwb, pool));
 
   if (deadprop_count == svn_tristate_false
       && session->supports_deadprop_count == svn_tristate_unknown
@@ -914,14 +874,12 @@ svn_ra_serf__stat(svn_ra_session_t *ra_s
          information */
       session->supports_deadprop_count = svn_tristate_false;
 
-      SVN_ERR(fetch_path_props(&prop_ctx, &props, &path, &fetched_rev,
-                               session, rel_path, fetched_rev,
+      SVN_ERR(fetch_path_props(&props,
+                               session, rel_path, SVN_INVALID_REVNUM,
                                get_dirent_props(SVN_DIRENT_ALL, session, pool),
-                               pool));
+                               pool, pool));
 
-      SVN_ERR(svn_ra_serf__walk_all_props(props, path, fetched_rev,
-                                      dirent_walker, &dwb,
-                                      pool));
+      SVN_ERR(svn_ra_serf__walk_node_props(props, dirent_walker, &dwb, pool));
     }
 
   if (deadprop_count != svn_tristate_unknown)
@@ -937,13 +895,11 @@ svn_ra_serf__stat(svn_ra_session_t *ra_s
  * SVN_ERR_FS_NOT_DIRECTORY if not.
  */
 static svn_error_t *
-resource_is_directory(apr_hash_t *props,
-                      const char *path,
-                      svn_revnum_t revision)
+resource_is_directory(apr_hash_t *props)
 {
   svn_kind_t kind;
 
-  SVN_ERR(svn_ra_serf__get_resource_type(&kind, props, path, revision));
+  SVN_ERR(svn_ra_serf__get_resource_type(&kind, props));
 
   if (kind != svn_kind_dir)
     {
@@ -980,34 +936,37 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
      public url. */
   if (SVN_IS_VALID_REVNUM(revision) || fetched_rev)
     {
-      const char *relative_url, *basecoll_url;
-
-      SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url,
-                                             session, NULL, path, revision,
-                                             fetched_rev, pool));
-
-      path = svn_path_url_add_component2(basecoll_url, relative_url, pool);
+      SVN_ERR(svn_ra_serf__get_stable_url(&path, fetched_rev,
+                                          session, NULL /* conn */,
+                                          path, revision,
+                                          pool, pool));
       revision = SVN_INVALID_REVNUM;
     }
+  /* REVISION is always SVN_INVALID_REVNUM  */
+  SVN_ERR_ASSERT(!SVN_IS_VALID_REVNUM(revision));
 
   /* If we're asked for children, fetch them now. */
   if (dirents)
     {
       struct path_dirent_visitor_t dirent_walk;
       apr_hash_t *props;
+      const char *rtype;
 
       /* Always request node kind to check that path is really a
        * directory.
        */
       dirent_fields |= SVN_DIRENT_KIND;
       SVN_ERR(svn_ra_serf__retrieve_props(&props, session, session->conns[0],
-                                          path, revision, "1",
+                                          path, SVN_INVALID_REVNUM, "1",
                                           get_dirent_props(dirent_fields,
                                                            session, pool),
                                           pool, pool));
 
       /* Check if the path is really a directory. */
-      SVN_ERR(resource_is_directory(props, path, revision));
+      rtype = svn_ra_serf__get_prop(props, path, "DAV:", "resourcetype");
+      if (rtype == NULL || strcmp(rtype, "collection") != 0)
+        return svn_error_create(SVN_ERR_FS_NOT_DIRECTORY, NULL,
+                                _("Can't get entries of non-directory"));
 
       /* We're going to create two hashes to help the walker along.
        * We're going to return the 2nd one back to the caller as it
@@ -1019,8 +978,9 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
       dirent_walk.supports_deadprop_count = svn_tristate_unknown;
       dirent_walk.result_pool = pool;
 
-      SVN_ERR(svn_ra_serf__walk_all_paths(props, revision, path_dirent_walker,
-                                          &dirent_walk, pool));
+      SVN_ERR(svn_ra_serf__walk_all_paths(props, SVN_INVALID_REVNUM,
+                                          path_dirent_walker, &dirent_walk,
+                                          pool));
 
       if (dirent_walk.supports_deadprop_count == svn_tristate_false
           && session->supports_deadprop_count == svn_tristate_unknown
@@ -1031,7 +991,7 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
           session->supports_deadprop_count = svn_tristate_false;
           SVN_ERR(svn_ra_serf__retrieve_props(&props, session,
                                               session->conns[0],
-                                              path, revision, "1",
+                                              path, SVN_INVALID_REVNUM, "1",
                                               get_dirent_props(dirent_fields,
                                                                session, pool),
                                               pool, pool));
@@ -1039,7 +999,7 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
           SVN_ERR(svn_hash__clear(dirent_walk.full_paths, pool));
           SVN_ERR(svn_hash__clear(dirent_walk.base_paths, pool));
 
-          SVN_ERR(svn_ra_serf__walk_all_paths(props, revision,
+          SVN_ERR(svn_ra_serf__walk_all_paths(props, SVN_INVALID_REVNUM,
                                               path_dirent_walker,
                                               &dirent_walk, pool));
         }
@@ -1055,14 +1015,17 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
     {
       apr_hash_t *props;
 
-      SVN_ERR(svn_ra_serf__retrieve_props(&props, session, session->conns[0],
-                                          path, revision, "0", all_props,
-                                          pool, pool));
+      SVN_ERR(svn_ra_serf__fetch_node_props(&props, session->conns[0],
+                                            path, SVN_INVALID_REVNUM,
+                                            all_props,
+                                            pool, pool));
+
       /* Check if the path is really a directory. */
-      SVN_ERR(resource_is_directory(props, path, revision));
+      SVN_ERR(resource_is_directory(props));
 
-      SVN_ERR(svn_ra_serf__flatten_props(ret_props, props, path, revision,
-                                         pool, pool));
+      /* ### flatten_props() does not copy PROPVALUE, but fetch_node_props()
+         ### put them into POOL, so we're okay.  */
+      SVN_ERR(svn_ra_serf__flatten_props(ret_props, props, pool, pool));
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c?rev=1336974&r1=1336973&r2=1336974&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c Fri May 11 00:05:41 2012
@@ -126,17 +126,10 @@ typedef struct report_dir_t
   /* Our base revision - SVN_INVALID_REVNUM if we're adding this dir. */
   svn_revnum_t base_rev;
 
-  /* The target revision we're retrieving. */
-  svn_revnum_t target_rev;
-
   /* controlling dir baton - this is only created in open_dir() */
   void *dir_baton;
   apr_pool_t *dir_baton_pool;
 
-  /* Our master update editor and baton. */
-  const svn_delta_editor_t *update_editor;
-  void *update_baton;
-
   /* How many references to this directory do we still have open? */
   apr_size_t ref_count;
 
@@ -200,9 +193,6 @@ typedef struct report_info_t
   /* Our base revision - SVN_INVALID_REVNUM if we're adding this file. */
   svn_revnum_t base_rev;
 
-  /* The target revision we're retrieving. */
-  svn_revnum_t target_rev;
-
   /* our delta base, if present (NULL if we're adding the file) */
   const char *delta_base;
 
@@ -414,9 +404,6 @@ push_state(svn_ra_serf__xml_parser_t *pa
       new_info->props = new_info->dir->props;
       new_info->dir->removed_props = apr_hash_make(new_info->pool);
 
-      /* Point to the update_editor */
-      new_info->dir->update_editor = ctx->update_editor;
-      new_info->dir->update_baton = ctx->update_baton;
       new_info->dir->report_context = ctx;
 
       if (info)
@@ -474,7 +461,7 @@ set_file_props(void *baton,
                apr_pool_t *scratch_pool)
 {
   report_info_t *info = baton;
-  const svn_delta_editor_t *editor = info->dir->update_editor;
+  const svn_delta_editor_t *editor = info->dir->report_context->update_editor;
   const char *prop_name;
 
   if (strcmp(name, "md5-checksum") == 0
@@ -499,7 +486,7 @@ set_dir_props(void *baton,
               apr_pool_t *scratch_pool)
 {
   report_dir_t *dir = baton;
-  const svn_delta_editor_t *editor = dir->update_editor;
+  const svn_delta_editor_t *editor = dir->report_context->update_editor;
   const char *prop_name;
 
   prop_name = svn_ra_serf__svnname_from_wirename(ns, name, scratch_pool);
@@ -520,7 +507,7 @@ remove_file_props(void *baton,
                   apr_pool_t *scratch_pool)
 {
   report_info_t *info = baton;
-  const svn_delta_editor_t *editor = info->dir->update_editor;
+  const svn_delta_editor_t *editor = info->dir->report_context->update_editor;
   const char *prop_name;
 
   prop_name = svn_ra_serf__svnname_from_wirename(ns, name, scratch_pool);
@@ -541,7 +528,7 @@ remove_dir_props(void *baton,
                  apr_pool_t *scratch_pool)
 {
   report_dir_t *dir = baton;
-  const svn_delta_editor_t *editor = dir->update_editor;
+  const svn_delta_editor_t *editor = dir->report_context->update_editor;
   const char *prop_name;
 
   prop_name = svn_ra_serf__svnname_from_wirename(ns, name, scratch_pool);
@@ -559,6 +546,8 @@ remove_dir_props(void *baton,
 static svn_error_t*
 open_dir(report_dir_t *dir)
 {
+  report_context_t *ctx = dir->report_context;
+
   /* if we're already open, return now */
   if (dir->dir_baton)
     {
@@ -569,16 +558,16 @@ open_dir(report_dir_t *dir)
     {
       dir->dir_baton_pool = svn_pool_create(dir->pool);
 
-      if (dir->report_context->destination &&
-          dir->report_context->sess->wc_callbacks->invalidate_wc_props)
+      if (ctx->destination
+          && ctx->sess->wc_callbacks->invalidate_wc_props)
         {
-          SVN_ERR(dir->report_context->sess->wc_callbacks->invalidate_wc_props(
-                      dir->report_context->sess->wc_callback_baton,
-                      dir->report_context->update_target,
+          SVN_ERR(ctx->sess->wc_callbacks->invalidate_wc_props(
+                      ctx->sess->wc_callback_baton,
+                      ctx->update_target,
                       SVN_RA_SERF__WC_CHECKED_IN_URL, dir->pool));
         }
 
-      SVN_ERR(dir->update_editor->open_root(dir->update_baton, dir->base_rev,
+      SVN_ERR(ctx->update_editor->open_root(ctx->update_baton, dir->base_rev,
                                             dir->dir_baton_pool,
                                             &dir->dir_baton));
     }
@@ -590,7 +579,7 @@ open_dir(report_dir_t *dir)
 
       if (SVN_IS_VALID_REVNUM(dir->base_rev))
         {
-          SVN_ERR(dir->update_editor->open_directory(dir->name,
+          SVN_ERR(ctx->update_editor->open_directory(dir->name,
                                                      dir->parent_dir->dir_baton,
                                                      dir->base_rev,
                                                      dir->dir_baton_pool,
@@ -598,7 +587,7 @@ open_dir(report_dir_t *dir)
         }
       else
         {
-          SVN_ERR(dir->update_editor->add_directory(dir->name,
+          SVN_ERR(ctx->update_editor->add_directory(dir->name,
                                                     dir->parent_dir->dir_baton,
                                                     NULL, SVN_INVALID_REVNUM,
                                                     dir->dir_baton_pool,
@@ -632,12 +621,13 @@ close_dir(report_dir_t *dir)
   if (dir->fetch_props)
     {
       SVN_ERR(svn_ra_serf__walk_all_props(dir->props, dir->url,
-                                          dir->target_rev,
+                                          dir->report_context->target_rev,
                                           set_dir_props, dir,
                                           scratch_pool));
     }
 
-  SVN_ERR(dir->update_editor->close_directory(dir->dir_baton, scratch_pool));
+  SVN_ERR(dir->report_context->update_editor->close_directory(
+            dir->dir_baton, scratch_pool));
 
   /* remove us from our parent's children list */
   if (dir->parent_dir)
@@ -701,7 +691,7 @@ check_lock(report_info_t *info)
   const char *lock_val;
 
   lock_val = svn_ra_serf__get_ver_prop(info->props, info->url,
-                                       info->target_rev,
+                                       info->dir->report_context->target_rev,
                                        "DAV:", "lockdiscovery");
 
   if (lock_val)
@@ -820,7 +810,8 @@ open_updated_file(report_info_t *info,
                   svn_boolean_t force_apply_textdelta,
                   apr_pool_t *scratch_pool)
 {
-  const svn_delta_editor_t *update_editor = info->dir->update_editor;
+  report_context_t *ctx = info->dir->report_context;
+  const svn_delta_editor_t *update_editor = ctx->update_editor;
 
   /* Ensure our parent is open. */
   SVN_ERR(open_dir(info->dir));
@@ -871,7 +862,7 @@ open_updated_file(report_info_t *info,
     {
       SVN_ERR(svn_ra_serf__walk_all_props(info->props,
                                           info->url,
-                                          info->target_rev,
+                                          ctx->target_rev,
                                           set_file_props, info,
                                           scratch_pool));
     }
@@ -897,9 +888,8 @@ close_updated_file(report_info_t *info,
                    apr_pool_t *scratch_pool)
 {
   /* Close the file via the editor. */
-  SVN_ERR(info->dir->update_editor->close_file(info->file_baton,
-                                               info->final_checksum,
-                                               scratch_pool));
+  SVN_ERR(info->dir->report_context->update_editor->close_file(
+            info->file_baton, info->final_checksum, scratch_pool));
 
   /* We're done with our editor pool. */
   svn_pool_destroy(info->editor_pool);
@@ -1300,7 +1290,7 @@ fetch_file(report_context_t *ctx, report
     {
       SVN_ERR(svn_ra_serf__deliver_props(&info->propfind, info->props,
                                          ctx->sess, conn, info->url,
-                                         info->target_rev, "0", all_props,
+                                         ctx->target_rev, "0", all_props,
                                          &ctx->done_propfinds,
                                          info->dir->pool));
       SVN_ERR_ASSERT(info->propfind);
@@ -1487,7 +1477,6 @@ start_report(svn_ra_serf__xml_parser_t *
 
       info->base_rev = SVN_STR_TO_REV(rev);
       info->dir->base_rev = info->base_rev;
-      info->dir->target_rev = ctx->target_rev;
       info->fetch_props = TRUE;
 
       info->dir->base_name = "";
@@ -1540,7 +1529,6 @@ start_report(svn_ra_serf__xml_parser_t *
 
       info->base_rev = SVN_STR_TO_REV(rev);
       dir->base_rev = info->base_rev;
-      dir->target_rev = ctx->target_rev;
 
       info->fetch_props = FALSE;
 
@@ -1594,7 +1582,6 @@ start_report(svn_ra_serf__xml_parser_t *
       /* Mark that we don't have a base. */
       info->base_rev = SVN_INVALID_REVNUM;
       dir->base_rev = info->base_rev;
-      dir->target_rev = ctx->target_rev;
       dir->fetch_props = TRUE;
 
       dir->repos_relpath = svn_relpath_join(dir->parent_dir->repos_relpath,
@@ -1627,7 +1614,6 @@ start_report(svn_ra_serf__xml_parser_t *
       info = push_state(parser, ctx, OPEN_FILE);
 
       info->base_rev = SVN_STR_TO_REV(rev);
-      info->target_rev = ctx->target_rev;
       info->fetch_props = FALSE;
 
       info->base_name = apr_pstrdup(info->pool, file_name);
@@ -1653,7 +1639,6 @@ start_report(svn_ra_serf__xml_parser_t *
       info = push_state(parser, ctx, ADD_FILE);
 
       info->base_rev = SVN_INVALID_REVNUM;
-      info->target_rev = ctx->target_rev;
       info->fetch_props = TRUE;
       info->fetch_file = TRUE;
 
@@ -1700,10 +1685,10 @@ start_report(svn_ra_serf__xml_parser_t *
 
       full_path = svn_relpath_join(info->dir->name, file_name, tmppool);
 
-      SVN_ERR(info->dir->update_editor->delete_entry(full_path,
-                                                     delete_rev,
-                                                     info->dir->dir_baton,
-                                                     tmppool));
+      SVN_ERR(ctx->update_editor->delete_entry(full_path,
+                                               delete_rev,
+                                               info->dir->dir_baton,
+                                               tmppool));
 
       svn_pool_destroy(tmppool);
     }
@@ -1966,7 +1951,7 @@ end_report(svn_ra_serf__xml_parser_t *pa
                                              info->dir->props, ctx->sess,
                                              ctx->sess->conns[ctx->sess->cur_conn],
                                              info->dir->url,
-                                             info->dir->target_rev, "0",
+                                             ctx->target_rev, "0",
                                              all_props,
                                              &ctx->done_propfinds,
                                              info->dir->pool));
@@ -2915,23 +2900,22 @@ svn_ra_serf__get_file(svn_ra_session_t *
    */
   if (SVN_IS_VALID_REVNUM(revision) || fetched_rev)
     {
-      const char *baseline_url, *rel_path;
-
-      SVN_ERR(svn_ra_serf__get_baseline_info(&baseline_url, &rel_path,
-                                             session, conn, fetch_url,
-                                             revision, fetched_rev, pool));
-      fetch_url = svn_path_url_add_component2(baseline_url, rel_path, pool);
+      SVN_ERR(svn_ra_serf__get_stable_url(&fetch_url, fetched_rev,
+                                          session, conn,
+                                          fetch_url, revision,
+                                          pool, pool));
       revision = SVN_INVALID_REVNUM;
     }
+  /* REVISION is always SVN_INVALID_REVNUM  */
+  SVN_ERR_ASSERT(!SVN_IS_VALID_REVNUM(revision));
+
+  SVN_ERR(svn_ra_serf__fetch_node_props(&fetch_props, conn, fetch_url,
+                                        SVN_INVALID_REVNUM,
+                                        props ? all_props : check_path_props,
+                                        pool, pool));
 
-  SVN_ERR(svn_ra_serf__retrieve_props(&fetch_props, session, conn, fetch_url,
-                                      revision, "0",
-                                      props ? all_props : check_path_props,
-                                      pool, pool));
-
-  /* Verify that resource type is not colelction. */
-  SVN_ERR(svn_ra_serf__get_resource_type(&res_kind, fetch_props, fetch_url,
-                                         revision));
+  /* Verify that resource type is not collection. */
+  SVN_ERR(svn_ra_serf__get_resource_type(&res_kind, fetch_props));
   if (res_kind != svn_kind_file)
     {
       return svn_error_create(SVN_ERR_FS_NOT_FILE, NULL,
@@ -2941,8 +2925,10 @@ svn_ra_serf__get_file(svn_ra_session_t *
   /* TODO Filter out all of our props into a usable format. */
   if (props)
     {
-      SVN_ERR(svn_ra_serf__flatten_props(props, fetch_props, fetch_url,
-                                         revision, pool, pool));
+      /* ### flatten_props() does not copy PROPVALUE, but fetch_node_props()
+         ### put them into POOL, so we're okay.  */
+      SVN_ERR(svn_ra_serf__flatten_props(props, fetch_props,
+                                         pool, pool));
     }
 
   if (stream)

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c?rev=1336974&r1=1336973&r2=1336974&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c Fri May 11 00:05:41 2012
@@ -38,6 +38,7 @@
 #include "svn_private_config.h"
 #include "svn_string.h"
 #include "svn_xml.h"
+#include "svn_props.h"
 
 #include "../libsvn_ra/ra_loader.h"
 #include "private/svn_dep_compat.h"
@@ -2038,6 +2039,7 @@ svn_ra_serf__request_create(svn_ra_serf_
                                         setup_request_cb, handler);
 }
 
+
 svn_error_t *
 svn_ra_serf__discover_vcc(const char **vcc_url,
                           svn_ra_serf__session_t *session,
@@ -2070,26 +2072,22 @@ svn_ra_serf__discover_vcc(const char **v
       apr_hash_t *props;
       svn_error_t *err;
 
-      err = svn_ra_serf__retrieve_props(&props, session, conn,
-                                        path, SVN_INVALID_REVNUM,
-                                        "0", base_props, pool, pool);
+      err = svn_ra_serf__fetch_node_props(&props, conn,
+                                          path, SVN_INVALID_REVNUM,
+                                          base_props, pool, pool);
       if (! err)
         {
-          *vcc_url =
-              svn_ra_serf__get_ver_prop(props, path,
-                                        SVN_INVALID_REVNUM,
-                                        "DAV:",
+          apr_hash_t *ns_props;
+
+          ns_props = apr_hash_get(props, "DAV:", 4);
+          *vcc_url = svn_prop_get_value(ns_props,
                                         "version-controlled-configuration");
 
-          relative_path = svn_ra_serf__get_ver_prop(props, path,
-                                                    SVN_INVALID_REVNUM,
-                                                    SVN_DAV_PROP_NS_DAV,
-                                                    "baseline-relative-path");
-
-          uuid = svn_ra_serf__get_ver_prop(props, path,
-                                           SVN_INVALID_REVNUM,
-                                           SVN_DAV_PROP_NS_DAV,
-                                           "repository-uuid");
+          ns_props = apr_hash_get(props,
+                                  SVN_DAV_PROP_NS_DAV, APR_HASH_KEY_STRING);
+          relative_path = svn_prop_get_value(ns_props,
+                                             "baseline-relative-path");
+          uuid = svn_prop_get_value(ns_props, "repository-uuid");
           break;
         }
       else

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/stream.c?rev=1336974&r1=1336973&r2=1336974&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/stream.c Fri May 11 00:05:41 2012
@@ -1747,8 +1747,8 @@ close_handler_lazyopen(void *baton)
 {
   lazyopen_baton_t *b = baton;
 
-  SVN_ERR(lazyopen_if_unopened(b));
-  SVN_ERR(svn_stream_close(b->real_stream));
+  if (b->real_stream != NULL)
+    SVN_ERR(svn_stream_close(b->real_stream));
 
   return SVN_NO_ERROR;
 }
@@ -1780,27 +1780,26 @@ seek_handler_lazyopen(void *baton,
   return SVN_NO_ERROR;
 }
 
-/* Implements svn_stream_stream_fn_t */
-svn_error_t *
-svn_stream_lazyopen_create(svn_stream_t **stream,
-                           svn_stream_lazyopen_func_t open_func,
+svn_stream_t *
+svn_stream_lazyopen_create(svn_stream_lazyopen_func_t open_func,
                            void *open_baton,
                            apr_pool_t *result_pool)
 {
   lazyopen_baton_t *lob = apr_pcalloc(result_pool, sizeof(*lob));
+  svn_stream_t *stream;
 
   lob->open_func = open_func;
   lob->open_baton = open_baton;
   lob->real_stream = NULL;
   lob->pool = result_pool;
 
-  *stream = svn_stream_create(lob, result_pool);
-  svn_stream_set_read(*stream, read_handler_lazyopen);
-  svn_stream_set_skip(*stream, skip_handler_lazyopen);
-  svn_stream_set_write(*stream, write_handler_lazyopen);
-  svn_stream_set_close(*stream, close_handler_lazyopen);
-  svn_stream_set_mark(*stream, mark_handler_lazyopen);
-  svn_stream_set_seek(*stream, seek_handler_lazyopen);
-
-  return SVN_NO_ERROR;
+  stream = svn_stream_create(lob, result_pool);
+  svn_stream_set_read(stream, read_handler_lazyopen);
+  svn_stream_set_skip(stream, skip_handler_lazyopen);
+  svn_stream_set_write(stream, write_handler_lazyopen);
+  svn_stream_set_close(stream, close_handler_lazyopen);
+  svn_stream_set_mark(stream, mark_handler_lazyopen);
+  svn_stream_set_seek(stream, seek_handler_lazyopen);
+  
+  return stream;
 }

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/adm_files.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/adm_files.c?rev=1336974&r1=1336973&r2=1336974&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/adm_files.c Fri May 11 00:05:41 2012
@@ -634,3 +634,16 @@ svn_wc_create_tmp_file2(apr_file_t **fp,
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_wc__get_tmpdir(const char **tmpdir_abspath,
+                   svn_wc_context_t *wc_ctx,
+                   const char *wri_abspath,
+                   apr_pool_t *result_pool,
+                   apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_wc__db_temp_wcroot_tempdir(tmpdir_abspath,
+                                         wc_ctx->db, wri_abspath,
+                                         result_pool, scratch_pool));
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c?rev=1336974&r1=1336973&r2=1336974&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c Fri May 11 00:05:41 2012
@@ -2250,6 +2250,31 @@ svn_wc_get_pristine_contents2(svn_stream
                                                        scratch_pool));
 }
 
+
+typedef struct get_pristine_lazyopen_baton_t
+{
+  svn_wc_context_t *wc_ctx;
+  const char *wri_abspath;
+  const svn_checksum_t *sha1_checksum;
+
+} get_pristine_lazyopen_baton_t;
+
+
+/* Implements svn_stream_lazyopen_func_t */
+static svn_error_t *
+get_pristine_lazyopen_func(svn_stream_t **stream,
+                           void *baton,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool)
+{
+  get_pristine_lazyopen_baton_t *b = baton;
+
+  SVN_ERR(svn_wc__db_pristine_read(stream, NULL, b->wc_ctx->db,
+                                   b->wri_abspath, b->sha1_checksum,
+                                   result_pool, scratch_pool));
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_wc__get_pristine_contents_by_checksum(svn_stream_t **contents,
                                           svn_wc_context_t *wc_ctx,
@@ -2258,9 +2283,27 @@ svn_wc__get_pristine_contents_by_checksu
                                           apr_pool_t *result_pool,
                                           apr_pool_t *scratch_pool)
 {
-  return svn_error_trace(svn_wc__db_pristine_read(contents, NULL, wc_ctx->db,
-                                                  wri_abspath, sha1_checksum,
-                                                  result_pool, scratch_pool));
+  svn_boolean_t present;
+  
+  *contents = NULL;
+
+  SVN_ERR(svn_wc__db_pristine_check(&present, wc_ctx->db, wri_abspath,
+                                    sha1_checksum, scratch_pool));
+
+  if (present)
+    {
+      get_pristine_lazyopen_baton_t *gpl_baton;
+
+      gpl_baton = apr_pcalloc(result_pool, sizeof(*gpl_baton));
+      gpl_baton->wc_ctx = wc_ctx;
+      gpl_baton->wri_abspath = wri_abspath;
+      gpl_baton->sha1_checksum = sha1_checksum;
+      
+      *contents = svn_stream_lazyopen_create(get_pristine_lazyopen_func,
+                                             gpl_baton, result_pool);
+    }
+
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *