You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2013/11/15 11:40:19 UTC

svn commit: r1542219 - in /subversion/trunk/subversion/bindings/javahl/native: jniwrapper/jni_list.hpp org_apache_subversion_javahl_util_PropLib.cpp

Author: brane
Date: Fri Nov 15 10:40:18 2013
New Revision: 1542219

URL: http://svn.apache.org/r1542219
Log:
Add a generic iteration method to the immutable List abstraction in JavaHL,
and allow for lists containing more subtypes of jobject.

[in subversion/bindings/javahl/native]
* jniwrapper/jni_list.hpp
  (BaseList::m_contents): Make protected so that the template can use it.
  (List, MutableList): Add a NativeT template parameter that defaults to
   jobject, and use it to convert the stored type in indexing operators.
  (List::for_each): New template method; uses std::for_each.
  (List::FunctorAdapter): Adapter for the for_each functor parameter.

* org_apache_subversion_javahl_util_PropLib.cpp
  (UnparseFunctor): New; functor class for unparsing externals.
  (Java_org_apache_subversion_javahl_util_PropLib_unparseExternals):
   Use List::for_each with UnparseFunctor instead of explicitly
   iterating over the list.

Modified:
    subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_list.hpp
    subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_PropLib.cpp

Modified: subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_list.hpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_list.hpp?rev=1542219&r1=1542218&r2=1542219&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_list.hpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/jniwrapper/jni_list.hpp Fri Nov 15 10:40:18 2013
@@ -69,10 +69,11 @@ protected:
       return m_contents[ovector::size_type(index)];
     }
 
+  const ovector m_contents;
+
 private:
   static const char* const m_class_name;
   static ovector convert_to_vector(Env env, jclass cls, jobject jlist);
-  const ovector m_contents;
 };
 
 /**
@@ -80,7 +81,7 @@ private:
  *
  * @since New in 1.9.
  */
-template <typename T>
+template <typename T, typename NativeT=jobject>
 class List : public BaseList
 {
 public:
@@ -97,8 +98,40 @@ public:
    */
   T operator[](jint index) const
     {
-      return T(m_env, BaseList::operator[](index));
+      return T(m_env, NativeT(BaseList::operator[](index)));
+    }
+
+  /**
+   * Iterates over the items in the list, calling @a function for
+   * each item.
+   * @see std::for_each
+   */
+  template<typename F>
+  F for_each(F function) const
+    {
+      const FunctorAdapter<F> adapter(m_env, function);
+      std::for_each(m_contents.begin(), m_contents.end(), adapter);
+      return function;
     }
+
+private:
+  template<typename F>
+  struct FunctorAdapter
+  {
+    explicit FunctorAdapter(const Env& env, F& function)
+      : m_env(env),
+        m_function(function)
+      {}
+
+    void operator()(const jobject& obj) const
+      {
+        T item(m_env, NativeT(obj));
+        m_function(item);
+      }
+
+    const Env& m_env;
+    F& m_function;
+  };
 };
 
 /**
@@ -164,7 +197,7 @@ private:
  *
  * @since New in 1.9.
  */
-template <typename T>
+template <typename T, typename NativeT=jobject>
 class MutableList : public BaseMutableList
 {
 public:
@@ -196,7 +229,7 @@ public:
    */
   T operator[](jint index) const
     {
-      return T(m_env, BaseMutableList::operator[](index));
+      return T(m_env, NativeT(BaseMutableList::operator[](index)));
     }
 };
 

Modified: subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_PropLib.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_PropLib.cpp?rev=1542219&r1=1542218&r2=1542219&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_PropLib.cpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_PropLib.cpp Fri Nov 15 10:40:18 2013
@@ -199,6 +199,82 @@ inline bool operator!=(const svn_opt_rev
 {
   return !(a == b);
 }
+
+class UnparseFunctor
+{
+public:
+  explicit UnparseFunctor(std::ostringstream& buffer, bool old_format,
+                          SVN::Pool& iterpool)
+    : m_buffer(buffer),
+      m_old_format(old_format),
+      m_iterpool(iterpool)
+    {}
+
+  void operator()(const JavaHL::ExternalItem& item)
+    {
+      m_iterpool.clear();
+
+      const Java::Env env(item.get_env());
+      const Java::LocalFrame frame(env);
+
+      if (!m_old_format)
+        {
+          if (item.revision()->kind != svn_opt_revision_head
+              && *item.revision() != *item.peg_revision())
+            {
+              m_buffer << "-r"
+                       << FormatRevision(item.revision(), m_iterpool)
+                       << ' ';
+            }
+          if (item.peg_revision()->kind == svn_opt_revision_head)
+            m_buffer << item.url() << ' ';
+          else
+            {
+              m_buffer << item.url() << '@'
+                       << FormatRevision(item.peg_revision(), m_iterpool)
+                       << ' ';
+            }
+          m_buffer << item.target_dir() << '\n';
+        }
+      else
+        {
+          // Sanity check: old format does not support peg revisions
+          if (item.peg_revision()->kind != svn_opt_revision_head
+              && *item.revision() != *item.peg_revision())
+            {
+              JavaHL::SubversionException(env)
+                .raise(_("Clients older than Subversion 1.5"
+                         " do not support peg revision syntax"
+                         " in the svn:externals property"));
+            }
+
+          // Sanity check: old format does not support relative URLs
+          const std::string url = item.url();
+          if (   (url.size() >= 1 && (url[0] == '.' || url[0] == '/'))
+                 || (url.size() >= 2 && (url[0] == '^' && url[1] == '/')))
+            {
+              JavaHL::SubversionException(env)
+                .raise(_("Clients older than Subversion 1.5"
+                         " do not support relative URLs"
+                         " in the svn:externals property"));
+            }
+
+          m_buffer << item.target_dir() << ' ';
+          if (item.revision()->kind != svn_opt_revision_head)
+            {
+              m_buffer << "-r"
+                       << FormatRevision(item.revision(), m_iterpool)
+                       << ' ';
+            }
+          m_buffer << url << '\n';
+        }
+    }
+
+private:
+  std::ostringstream& m_buffer;
+  const bool m_old_format;
+  SVN::Pool& m_iterpool;
+};
 } // anoymous namespace
 
 
@@ -274,70 +350,11 @@ Java_org_apache_subversion_javahl_util_P
       SVN::Pool iterpool;
 
       std::ostringstream buffer;
-      const jint items_length = items.length();
-      for (jint i = 0; i < items_length; ++i)
-        {
-          iterpool.clear();
-
-          const Java::LocalFrame frame(env);
-          const JavaHL::ExternalItem item(items[i]);
-
-          if (!jold_format)
-            {
-              if (item.revision()->kind != svn_opt_revision_head
-                  && *item.revision() != *item.peg_revision())
-                {
-                  buffer << "-r"
-                         << FormatRevision(item.revision(), iterpool)
-                         << ' ';
-                }
-              if (item.peg_revision()->kind == svn_opt_revision_head)
-                buffer << item.url() << ' ';
-              else
-                {
-                  buffer << item.url() << '@'
-                         << FormatRevision(item.peg_revision(), iterpool)
-                         << ' ';
-                }
-              buffer << item.target_dir() << '\n';
-            }
-          else
-            {
-              // Sanity check: old format does not support peg revisions
-              if (item.peg_revision()->kind != svn_opt_revision_head
-                  && *item.revision() != *item.peg_revision())
-                {
-                  JavaHL::SubversionException(env)
-                    .raise(_("Clients older than Subversion 1.5"
-                             " do not support peg revision syntax"
-                             " in the svn:externals property"));
-                }
-
-              // Sanity check: old format does not support relative URLs
-              const std::string url = item.url();
-              if (   (url.size() >= 1 && (url[0] == '.' || url[0] == '/'))
-                  || (url.size() >= 2 && (url[0] == '^' && url[1] == '/')))
-                {
-                  JavaHL::SubversionException(env)
-                    .raise(_("Clients older than Subversion 1.5"
-                             " do not support relative URLs"
-                             " in the svn:externals property"));
-                }
-
-              buffer << item.target_dir() << ' ';
-              if (item.revision()->kind != svn_opt_revision_head)
-                {
-                  buffer << "-r"
-                         << FormatRevision(item.revision(), iterpool)
-                         << ' ';
-                }
-              buffer << url << '\n';
-            }
-        }
+      items.for_each(UnparseFunctor(buffer, jold_format, iterpool));
+      const std::string description(buffer.str());
 
       // Validate the result. Even though we generated the string
       // ourselves, we did not validate the input paths and URLs.
-      const std::string description(buffer.str());
       SVN_JAVAHL_CHECK(svn_wc_parse_externals_description3(
                            NULL,
                            Java::String::Contents(parent_dir).c_str(),