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/02 04:24:08 UTC

svn commit: r1538133 - in /subversion/trunk: ./ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindings/javahl/src/org/apache/subversion/javahl/util/ subversion/bindings/javahl/tests/org/apach...

Author: brane
Date: Sat Nov  2 03:24:07 2013
New Revision: 1538133

URL: http://svn.apache.org/r1538133
Log:
Expose the node property validation utility in JavaHL.

* build.conf (private-built-includes):
   Added org_apache_subversion_javahl_util_PropLib.h.

[in subversion/bindings/javahl/src/org/apache/subversion/javahl]
* SVNUtil.java (SVNUtil.canonicalizeNodeProperty): New static methods.
* util/PropLib.java (PropLib): New class.

[in subversion/bindings/javahl/native]
* org_apache_subversion_javahl_util_PropLib.cpp: New.
   Native implementation of class Proplib.

[in subversion/bindings/javahl/tests/org/apache/subversion/javahl]
* UtilTests.java (UtilTests.testValidateProp): New test case.

Added:
    subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_PropLib.cpp
    subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/PropLib.java
Modified:
    subversion/trunk/build.conf
    subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java
    subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java

Modified: subversion/trunk/build.conf
URL: http://svn.apache.org/viewvc/subversion/trunk/build.conf?rev=1538133&r1=1538132&r2=1538133&view=diff
==============================================================================
--- subversion/trunk/build.conf (original)
+++ subversion/trunk/build.conf Sat Nov  2 03:24:07 2013
@@ -79,6 +79,7 @@ private-built-includes =
         subversion/bindings/javahl/include/org_apache_subversion_javahl_util_ConfigImpl_Category.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_util_ConfigLib.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_util_DiffLib.h
+        subversion/bindings/javahl/include/org_apache_subversion_javahl_util_PropLib.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_util_TunnelChannel.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_util_RequestChannel.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_util_ResponseChannel.h

Added: 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=1538133&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_PropLib.cpp (added)
+++ subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_PropLib.cpp Sat Nov  2 03:24:07 2013
@@ -0,0 +1,134 @@
+/**
+ * @copyright
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ * @endcopyright
+ *
+ * @file org_apache_subversion_javahl_util_PropLib.cpp
+ * @brief Implementation of the native methods in the Java class PropLib
+ */
+
+#include "../include/org_apache_subversion_javahl_util_PropLib.h"
+
+#include "JNIStackElement.h"
+#include "JNIStringHolder.h"
+#include "JNIByteArray.h"
+#include "JNIUtil.h"
+#include "InputStream.h"
+#include "EnumMapper.h"
+#include "Path.h"
+#include "Pool.h"
+
+#include "svn_props.h"
+#include "svn_wc.h"
+
+
+namespace {
+class PropGetter
+{
+public:
+  PropGetter(const char* mime_type, svn_stream_t* contents)
+    : m_mime_type(mime_type),
+      m_contents(contents)
+    {}
+
+  static svn_error_t* callback(const svn_string_t** mime_type,
+                               svn_stream_t* stream, void* baton,
+                               apr_pool_t* pool)
+    {
+      PropGetter* self = static_cast<PropGetter*>(baton);
+      if (mime_type)
+        {
+          if (self->m_mime_type)
+            *mime_type = svn_string_create(self->m_mime_type, pool);
+          else
+            *mime_type = svn_string_create_empty(pool);
+        }
+
+      if (stream && self->m_contents)
+        {
+          SVN_ERR(svn_stream_copy3(self->m_contents,
+                                   svn_stream_disown(stream, pool),
+                                   NULL, NULL, pool));
+        }
+
+      return SVN_NO_ERROR;
+    }
+
+private:
+  const char* m_mime_type;
+  svn_stream_t* m_contents;
+};
+} // anonymous namespace
+
+
+JNIEXPORT jbyteArray JNICALL
+Java_org_apache_subversion_javahl_util_PropLib_checkNodeProp(
+    JNIEnv* env, jobject jthis,
+    jstring jname, jbyteArray jvalue, jstring jpath, jobject jkind,
+    jstring jmime_type, jobject jfile_contents,
+    jboolean jskip_some_checks)
+{
+  JNIEntry(PropLib, checkLocalProp);
+
+  JNIStringHolder name(jname);
+  if (JNIUtil::isJavaExceptionThrown())
+    return NULL;
+
+  JNIByteArray value(jvalue);
+  if (JNIUtil::isJavaExceptionThrown())
+    return NULL;
+
+  JNIStringHolder path(jpath);
+  if (JNIUtil::isJavaExceptionThrown())
+    return NULL;
+
+  svn_node_kind_t kind = EnumMapper::toNodeKind(jkind);
+  if (JNIUtil::isJavaExceptionThrown())
+    return NULL;
+
+  JNIStringHolder mime_type(jmime_type);
+  if (JNIUtil::isJavaExceptionThrown())
+    return NULL;
+
+  InputStream contents(jfile_contents);
+  if (JNIUtil::isJavaExceptionThrown())
+    return NULL;
+
+  // Using a "global" request pool since we don't keep a context with
+  // its own pool around for these functions.
+  SVN::Pool pool;
+
+  PropGetter getter(mime_type.c_str(),
+                    (jfile_contents ? contents.getStream(pool) : NULL));
+
+  svn_string_t propval;
+  propval.data = reinterpret_cast<const char*>(value.getBytes());
+  propval.len = value.getLength();
+
+  const svn_string_t* canonval;
+  SVN_JNI_ERR(svn_wc_canonicalize_svn_prop(
+                  &canonval, name.c_str(), &propval, path.c_str(),
+                  kind, svn_boolean_t(jskip_some_checks),
+                  PropGetter::callback, &getter,
+                  pool.getPool()),
+              NULL);
+
+  return JNIUtil::makeJByteArray(canonval->data, int(canonval->len));
+}

Modified: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java?rev=1538133&r1=1538132&r2=1538133&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java (original)
+++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java Sat Nov  2 03:24:07 2013
@@ -24,8 +24,10 @@
 package org.apache.subversion.javahl;
 
 import org.apache.subversion.javahl.callback.*;
+import org.apache.subversion.javahl.types.*;
 import org.apache.subversion.javahl.util.*;
 
+import java.io.InputStream;
 import java.io.OutputStream;
 
 public class SVNUtil
@@ -281,4 +283,61 @@ public class SVNUtil
                                        conflictLatest, conflictSeparator,
                                        conflictStyle, resultStream);
     }
+
+    //
+    // Property validation and parsing
+    //
+
+    /**
+     * Validate the value of an <code>svn:</code> property on file or
+     * directory and return a canonical representation of its value.
+     * @param name The name of the property (must be a valid svn: property)
+     * @param value The property's value
+     * @param path The path or URL of the file or directory that
+     *        owns the property; only used for error messages
+     * @param kind The node kind of the file or dir that owns the property
+     * @param mimeType If <code>kind</code> is {@link NodeKind.file}, this is
+     *        tye file's mime-type, used for extra validation for the
+     *        <code>svn:eol-style</code> property. If it is <code>null</code>,
+     *        the extra validation will be skipped.
+     * @return a canonicalized representation of the property value
+     * @see http://subversion.apache.org/docs/api/latest/group__svn__wc__properties.html#ga83296313ec59cc825176224ac8282ec2
+     */
+    public static byte[] canonicalizeNodeProperty(
+        String name, byte[] value, String path, NodeKind kind,
+        String mimeType)
+        throws ClientException
+    {
+        return new PropLib().canonicalizeNodeProperty(
+            name, value, path, kind, mimeType, null);
+    }
+
+    /**
+     * Validate the value of an <code>svn:</code> property on file or
+     * directory and return a canonical representation of its value.
+     * @param name The name of the property (must be a valid svn: property)
+     * @param value The property's value
+     * @param path The path or URL of the file or directory that
+     *        owns the property; only used for error messages
+     * @param kind The node kind of the file or dir that owns the property
+     * @param mimeType If <code>kind</code> is {@link NodeKind.file}, this is
+     *        tye file's mime-type, used for extra validation for the
+     *        <code>svn:eol-style</code> property. If it is <code>null</code>,
+     *        the extra validation will be skipped.
+     * @param fileContents A stream with the file's contents. Only used
+     *        to check for line-ending consistency when validating the
+     *        <code>svn:eol-style</code> property, and only when
+     *        <code>kind</code> is {@link NodeKind.file} and
+     *        <code>mimeType</code> is not <code>null</code>.
+     * @return a canonicalized representation of the property value
+     * @see http://subversion.apache.org/docs/api/latest/group__svn__wc__properties.html#ga83296313ec59cc825176224ac8282ec2
+     */
+    public static byte[] canonicalizeNodeProperty(
+        String name, byte[] value, String path, NodeKind kind,
+        String mimeType, InputStream fileContents)
+        throws ClientException
+    {
+        return new PropLib().canonicalizeNodeProperty(
+            name, value, path, kind, mimeType, fileContents);
+    }
 }

Added: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/PropLib.java
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/PropLib.java?rev=1538133&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/PropLib.java (added)
+++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/PropLib.java Sat Nov  2 03:24:07 2013
@@ -0,0 +1,67 @@
+/**
+ * @copyright
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ * @endcopyright
+ */
+
+package org.apache.subversion.javahl.util;
+
+import org.apache.subversion.javahl.SVNUtil;
+import org.apache.subversion.javahl.ClientException;
+import org.apache.subversion.javahl.NativeResources;
+import org.apache.subversion.javahl.types.NodeKind;
+import org.apache.subversion.javahl.types.Revision;
+
+import java.io.InputStream;
+
+/**
+ * Encapsulates utility functions for properties provided by libsvn_wc.
+ * @since 1.9
+ */
+public class PropLib
+{
+    /**
+     * Load the required native library.
+     */
+    static
+    {
+        NativeResources.loadNativeLibrary();
+    }
+
+    /** @see SVNUtil.canonicalizeSvnProperty */
+    public byte[] canonicalizeNodeProperty(String name, byte[] value,
+                                           String path, NodeKind kind,
+                                           String mimeType,
+                                           InputStream fileContents)
+        throws ClientException
+    {
+        if (!name.startsWith("svn:"))
+            throw new IllegalArgumentException("Property name: " + name);
+        return checkNodeProp(name, value, path, kind, mimeType, fileContents,
+                             (kind != NodeKind.file || mimeType == null));
+    }
+
+    private native byte[] checkNodeProp(String name, byte[] value,
+                                        String path, NodeKind kind,
+                                        String mimeType,
+                                        InputStream fileContents,
+                                        boolean skipSomeChecks)
+        throws ClientException;
+}

Modified: subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java?rev=1538133&r1=1538132&r2=1538133&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java (original)
+++ subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java Sat Nov  2 03:24:07 2013
@@ -23,7 +23,10 @@
 
 package org.apache.subversion.javahl;
 
+import org.apache.subversion.javahl.types.NodeKind;
+
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.ByteArrayOutputStream;
 import java.util.Arrays;
@@ -135,4 +138,54 @@ public class UtilTests extends SVNTests
                                  "\nN-3\nN-2\nN-1\nN\n").getBytes();
         assertTrue(Arrays.equals(expected, result.toByteArray()));
     }
+
+    public void testValidateProp() throws Throwable
+    {
+        File temp = File.createTempFile("propcheck", ".file", localTmp);
+        FileOutputStream out = new FileOutputStream(temp);
+        out.write("normal text\n".getBytes());
+        out.close();
+
+        byte[] prop = SVNUtil.canonicalizeNodeProperty(
+                           "svn:eol-style", "  native".getBytes(),
+                           "propcheck.file", NodeKind.file,
+                           "text/plain");
+        assertEquals("native", new String(prop));
+
+        prop = SVNUtil.canonicalizeNodeProperty(
+                    "svn:eol-style", " native  ".getBytes(),
+                    "propcheck.file", NodeKind.file,
+                    "text/plain", new FileInputStream(temp));
+        assertEquals("native", new String(prop));
+
+        boolean caught_exception = false;
+        try {
+            prop = SVNUtil.canonicalizeNodeProperty(
+                        "svn:eol-style", " weird  ".getBytes(),
+                        "propcheck.file", NodeKind.file,
+                        "text/plain");
+        } catch (ClientException ex) {
+            assertEquals("Unrecognized line ending style",
+                         ex.getAllMessages().get(0).getMessage());
+            caught_exception = true;
+        }
+        assertTrue(caught_exception);
+
+        out = new FileOutputStream(temp);
+        out.write("inconsistent\r\ntext\n".getBytes());
+        out.close();
+
+        caught_exception = false;
+        try {
+            prop = SVNUtil.canonicalizeNodeProperty(
+                        "svn:eol-style", " native  ".getBytes(),
+                        "propcheck.file", NodeKind.file,
+                        "text/plain", new FileInputStream(temp));
+        } catch (ClientException ex) {
+            assertEquals("Inconsistent line ending style",
+                         ex.getAllMessages().get(2).getMessage());
+            caught_exception = true;
+        }
+        assertTrue(caught_exception);
+    }
 }