Return-Path: X-Original-To: apmail-subversion-commits-archive@minotaur.apache.org Delivered-To: apmail-subversion-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id DA80318CFB for ; Mon, 29 Jun 2015 17:48:11 +0000 (UTC) Received: (qmail 6112 invoked by uid 500); 29 Jun 2015 17:48:11 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 6087 invoked by uid 500); 29 Jun 2015 17:48:11 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 6077 invoked by uid 99); 29 Jun 2015 17:48:11 -0000 Received: from eris.apache.org (HELO hades.apache.org) (140.211.11.105) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 29 Jun 2015 17:48:11 +0000 Received: from hades.apache.org (localhost [127.0.0.1]) by hades.apache.org (ASF Mail Server at hades.apache.org) with ESMTP id 9B49BAC0043 for ; Mon, 29 Jun 2015 17:48:11 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1688273 - in /subversion/trunk/subversion/bindings/javahl: native/ src/org/apache/subversion/javahl/ src/org/apache/subversion/javahl/callback/ tests/org/apache/subversion/javahl/ Date: Mon, 29 Jun 2015 17:48:11 -0000 To: commits@subversion.apache.org From: brane@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20150629174811.9B49BAC0043@hades.apache.org> Author: brane Date: Mon Jun 29 17:48:10 2015 New Revision: 1688273 URL: http://svn.apache.org/r1688273 Log: Follow up to r1687769: Implement semantics equivalent to the new svn_repos_verify_fs3 in JavaHL. [in subversion/bindings/javahl] * src/org/apache/subversion/javahl/callback/ReposVerifyCallback.java (ReposVerifyCallback): New callback interface. * src/org/apache/subversion/javahl/ISVNRepos.java (ISVNRepos.verify): Add the verification callback and update the documentation of both versions of this method. * src/org/apache/subversion/javahl/SVNRepos.java (ISVNRepos.verify): Update native method signature and wrapper method implementation. * src/org/apache/subversion/javahl/ReposNotifyInformation.java (ReposNotifyInformation): Update serial version UID after 1.9 API change. * native/ReposVerifyCallback.h, native/ReposVerifyCallback.cpp: New files. * native/JNIUtil.h (JNIUtil::createClientException): New. (JNIUtil::wrappedCreateClientException): Renamed from wrappedHandleSVNError and changed the the return type. * native/JNIUtil.cpp (JNIUtil::wrappedCreateClientException): Return the created exception instead of throwing it. (JNIUtil::createClientException): Implement. (JNIUtil::handleSVNError): Reimplement to call createClientException. * native/SVNRepos.h: Include ReposVerifyCallback.h. (SVNRepos::Verify): Add the repository verification callback. * native/SVNRepos.cpp: Do not include ReposNotifyCallback.h. (SVNRepos::Verify): Use the repository verification callback. * native/org_apache_subversion_javahl_SVNRepos.cpp (Java_org_apache_subversion_javahl_SVNRepos_verify): Add the repository verification callback and update the implementation. * tests/org/apache/subversion/javahl/SVNReposTests.java (SVNReposTests.testVerify): Tweak repository creation. (SVNReposTests.VerifyCallback, SVNReposTests.trytobreakrepo): New helpers. (SVNReposTests.testVerifyBrokenRepo, SVNReposTests.testVerifyBrokenRepo_KeepGoing): New test cases. Added: subversion/trunk/subversion/bindings/javahl/native/ReposVerifyCallback.cpp (with props) subversion/trunk/subversion/bindings/javahl/native/ReposVerifyCallback.h (with props) subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/ReposVerifyCallback.java (with props) Modified: subversion/trunk/subversion/bindings/javahl/native/JNIUtil.cpp subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h subversion/trunk/subversion/bindings/javahl/native/SVNRepos.cpp subversion/trunk/subversion/bindings/javahl/native/SVNRepos.h subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRepos.java subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNRepos.java subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNReposTests.java Modified: subversion/trunk/subversion/bindings/javahl/native/JNIUtil.cpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/JNIUtil.cpp?rev=1688273&r1=1688272&r2=1688273&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/JNIUtil.cpp (original) +++ subversion/trunk/subversion/bindings/javahl/native/JNIUtil.cpp Mon Jun 29 17:48:10 2015 @@ -570,13 +570,13 @@ std::string JNIUtil::makeSVNErrorMessage return buffer; } -void JNIUtil::wrappedHandleSVNError(svn_error_t *err, jthrowable jcause) +jthrowable JNIUtil::wrappedCreateClientException(svn_error_t *err, jthrowable jcause) { jstring jmessage; jobject jstack; std::string msg = makeSVNErrorMessage(err, &jmessage, &jstack); if (JNIUtil::isJavaExceptionThrown()) - return; + return NULL; const char *source = NULL; #ifdef SVN_DEBUG @@ -604,11 +604,11 @@ void JNIUtil::wrappedHandleSVNError(svn_ // Create a local frame for our references env->PushLocalFrame(LOCAL_FRAME_SIZE); if (JNIUtil::isJavaExceptionThrown()) - return; + return NULL; jclass clazz = env->FindClass(JAVAHL_CLASS("/ClientException")); if (isJavaExceptionThrown()) - POP_AND_RETURN_NOTHING(); + POP_AND_RETURN_NULL; if (getLogLevel() >= exceptionLog) { @@ -622,11 +622,11 @@ void JNIUtil::wrappedHandleSVNError(svn_ g_logStream << std::endl; } if (isJavaExceptionThrown()) - POP_AND_RETURN_NOTHING(); + POP_AND_RETURN_NULL; jstring jsource = makeJString(source); if (isJavaExceptionThrown()) - POP_AND_RETURN_NOTHING(); + POP_AND_RETURN_NULL; jmethodID mid = env->GetMethodID(clazz, "", "(Ljava/lang/String;" @@ -634,12 +634,12 @@ void JNIUtil::wrappedHandleSVNError(svn_ "Ljava/lang/String;I" "Ljava/util/List;)V"); if (isJavaExceptionThrown()) - POP_AND_RETURN_NOTHING(); + POP_AND_RETURN_NULL; jobject nativeException = env->NewObject(clazz, mid, jmessage, jcause, jsource, jint(err->apr_err), jstack); if (isJavaExceptionThrown()) - POP_AND_RETURN_NOTHING(); + POP_AND_RETURN_NULL; #ifdef SVN_ERR__TRACING // Add all the C error stack trace information to the Java Exception @@ -651,7 +651,7 @@ void JNIUtil::wrappedHandleSVNError(svn_ mid_gst = env->GetMethodID(clazz, "getStackTrace", "()[Ljava/lang/StackTraceElement;"); if (isJavaExceptionThrown()) - POP_AND_RETURN_NOTHING(); + POP_AND_RETURN_NULL; } Array stackTraceArray((jobjectArray) env->CallObjectMethod(nativeException, mid_gst)); @@ -670,18 +670,18 @@ void JNIUtil::wrappedHandleSVNError(svn_ jclass stClazz = env->FindClass("java/lang/StackTraceElement"); if (isJavaExceptionThrown()) - POP_AND_RETURN_NOTHING(); + POP_AND_RETURN_NULL; const jsize stSize = static_cast(newStackTrace.size()); if (stSize < 0 || stSize != newStackTrace.size()) { env->ThrowNew(env->FindClass("java.lang.ArithmeticException"), "Overflow converting C size_t to JNI jsize"); - POP_AND_RETURN_NOTHING(); + POP_AND_RETURN_NULL; } jobjectArray jStackTrace = env->NewObjectArray(stSize, stClazz, NULL); if (isJavaExceptionThrown()) - POP_AND_RETURN_NOTHING(); + POP_AND_RETURN_NULL; int i = 0; for (std::vector::const_iterator it = newStackTrace.begin(); @@ -698,25 +698,34 @@ void JNIUtil::wrappedHandleSVNError(svn_ mid_sst = env->GetMethodID(clazz, "setStackTrace", "([Ljava/lang/StackTraceElement;)V"); if (isJavaExceptionThrown()) - POP_AND_RETURN_NOTHING(); + POP_AND_RETURN_NULL; } env->CallVoidMethod(nativeException, mid_sst, jStackTrace); if (isJavaExceptionThrown()) - POP_AND_RETURN_NOTHING(); + POP_AND_RETURN_NULL; #endif - env->Throw(static_cast(env->PopLocalFrame(nativeException))); + return static_cast(env->PopLocalFrame(nativeException)); } -void JNIUtil::handleSVNError(svn_error_t *err, jthrowable jcause) +jthrowable JNIUtil::createClientException(svn_error_t *err, jthrowable jcause) { + jthrowable jexc = NULL; try { - wrappedHandleSVNError(err, jcause); + jexc = wrappedCreateClientException(err, jcause); } catch (...) { svn_error_clear(err); throw; } svn_error_clear(err); + return jexc; +} + +void JNIUtil::handleSVNError(svn_error_t *err, jthrowable jcause) +{ + jthrowable jexc = createClientException(err, jcause); + if (jexc) + getEnv()->Throw(jexc); } void JNIUtil::putFinalizedClient(SVNBase *object) Modified: subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h?rev=1688273&r1=1688272&r2=1688273&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h (original) +++ subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h Mon Jun 29 17:48:10 2015 @@ -136,6 +136,13 @@ class JNIUtil static svn_error_t* checkJavaException(apr_status_t errorcode); /** + * Create a Java exception corresponding to err, and run + * svn_error_clear() on err. + */ + static jthrowable createClientException(svn_error_t *err, + jthrowable jcause = NULL); + + /** * Throw a Java exception corresponding to err, and run * svn_error_clear() on err. */ @@ -178,7 +185,8 @@ class JNIUtil friend bool initialize_jni_util(JNIEnv *env); static bool JNIGlobalInit(JNIEnv *env); - static void wrappedHandleSVNError(svn_error_t *err, jthrowable jcause); + static jthrowable wrappedCreateClientException(svn_error_t *err, + jthrowable jcause); static void putErrorsInTrace(svn_error_t *err, std::vector &stackTrace); Added: subversion/trunk/subversion/bindings/javahl/native/ReposVerifyCallback.cpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/ReposVerifyCallback.cpp?rev=1688273&view=auto ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/ReposVerifyCallback.cpp (added) +++ subversion/trunk/subversion/bindings/javahl/native/ReposVerifyCallback.cpp Mon Jun 29 17:48:10 2015 @@ -0,0 +1,92 @@ +/** + * @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 ReposVerifyCallback.cpp + * @brief Implementation of the class ReposVerifyCallback + */ + +#include "ReposVerifyCallback.h" +#include "JNIUtil.h" + +/** + * Create a new object and store the Java object. + * @param notify global reference to the Java object + */ +ReposVerifyCallback::ReposVerifyCallback(jobject verify_cb) + : m_verify_cb(verify_cb) +{} + +ReposVerifyCallback::~ReposVerifyCallback() +{ + // Don't need to destroy the reference, since it was given us by Java +} + +svn_error_t * +ReposVerifyCallback::callback(void *baton, + svn_revnum_t revision, + svn_error_t *verify_err, + apr_pool_t *scratch_pool) +{ + if (!baton) + return SVN_NO_ERROR; + + static_cast(baton) + ->onVerifyError(revision, verify_err, scratch_pool); + if (JNIUtil::isJavaExceptionThrown()) + return JNIUtil::wrapJavaException(); + return SVN_NO_ERROR; +} + +void +ReposVerifyCallback::onVerifyError(svn_revnum_t revision, + svn_error_t *verify_err, + apr_pool_t *scratch_pool) +{ + JNIEnv *env = JNIUtil::getEnv(); + + // Java method id will not change during the time this library is + // loaded, so it can be cached. + static jmethodID mid = 0; + if (mid == 0) + { + jclass clazz = env->FindClass(JAVAHL_CLASS("/callback/ReposVerifyCallback")); + if (JNIUtil::isJavaExceptionThrown()) + return; + + mid = env->GetMethodID(clazz, "onVerifyError", + "(J" JAVAHL_ARG("/ClientException;") ")V"); + if (JNIUtil::isJavaExceptionThrown() || mid == 0) + return; + + env->DeleteLocalRef(clazz); + } + + jthrowable jverify_err = NULL; + if (verify_err) + jverify_err = JNIUtil::createClientException(svn_error_dup(verify_err), NULL); + if (JNIUtil::isJavaExceptionThrown()) + return; + + env->CallVoidMethod(m_verify_cb, mid, jlong(revision), jverify_err); + if (verify_err) + env->DeleteLocalRef(jverify_err); +} Propchange: subversion/trunk/subversion/bindings/javahl/native/ReposVerifyCallback.cpp ------------------------------------------------------------------------------ svn:eol-style = native Added: subversion/trunk/subversion/bindings/javahl/native/ReposVerifyCallback.h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/ReposVerifyCallback.h?rev=1688273&view=auto ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/ReposVerifyCallback.h (added) +++ subversion/trunk/subversion/bindings/javahl/native/ReposVerifyCallback.h Mon Jun 29 17:48:10 2015 @@ -0,0 +1,69 @@ +/** + * @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 ReposVerifyCallback.h + * @brief Interface of the class ReposVerifyCallback + */ + +#ifndef SVN_JAVAHL_REPOS_VERIFY_CALLBACK_H +#define SVN_JAVAHL_REPOS_VERIFY_CALLBACK_H + +#include +#include "svn_repos.h" + +/** + * This class passes notification from subversion to a Java object + * (1.2 version). + */ +class ReposVerifyCallback +{ + private: + /** + * The local reference to the Java object. + */ + jobject m_verify_cb; + + public: + ReposVerifyCallback(jobject verify_cb); + ~ReposVerifyCallback(); + + /** + * Implementation of the svn_repos_verify_callback_t API. + * + * @param baton notification instance is passed using this parameter + * @param notify all the information about the event + * @param pool An APR pool from which to allocate memory. + */ + static svn_error_t * callback(void *baton, + svn_revnum_t revision, + svn_error_t *verify_err, + apr_pool_t *scratch_pool); + + /** + * Handler for Subversion notifications. + */ + void onVerifyError(svn_revnum_t revision, + svn_error_t *verify_err, + apr_pool_t *scratch_pool); +}; + +#endif // SVN_JAVAHL_REPOS_VERIFY_CALLBACK_H Propchange: subversion/trunk/subversion/bindings/javahl/native/ReposVerifyCallback.h ------------------------------------------------------------------------------ svn:eol-style = native Modified: subversion/trunk/subversion/bindings/javahl/native/SVNRepos.cpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/SVNRepos.cpp?rev=1688273&r1=1688272&r2=1688273&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/SVNRepos.cpp (original) +++ subversion/trunk/subversion/bindings/javahl/native/SVNRepos.cpp Mon Jun 29 17:48:10 2015 @@ -26,7 +26,6 @@ #include "SVNRepos.h" #include "CreateJ.h" -#include "ReposNotifyCallback.h" #include "JNIUtil.h" #include "svn_error_codes.h" #include "svn_repos.h" @@ -595,7 +594,8 @@ SVNRepos::getRevnum(svn_revnum_t *revnum void SVNRepos::verify(File &path, Revision &revisionStart, Revision &revisionEnd, bool checkNormalization, bool metadataOnly, - ReposNotifyCallback *notifyCallback) + ReposNotifyCallback *notifyCallback, + ReposVerifyCallback *verifyCallback) { SVN::Pool requestPool; svn_repos_t *repos; @@ -641,11 +641,12 @@ SVNRepos::verify(File &path, Revision &r SVN_JNI_ERR(svn_repos_verify_fs3(repos, lower, upper, checkNormalization, metadataOnly, - notifyCallback != NULL - ? ReposNotifyCallback::notify - : NULL, + (!notifyCallback ? NULL + : ReposNotifyCallback::notify), notifyCallback, - NULL, NULL, /* verify callback/baton */ + (!verifyCallback ? NULL + : ReposVerifyCallback::callback), + verifyCallback, checkCancel, this /* cancel callback/baton */, requestPool.getPool()), ); } Modified: subversion/trunk/subversion/bindings/javahl/native/SVNRepos.h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/SVNRepos.h?rev=1688273&r1=1688272&r2=1688273&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/SVNRepos.h (original) +++ subversion/trunk/subversion/bindings/javahl/native/SVNRepos.h Mon Jun 29 17:48:10 2015 @@ -35,6 +35,7 @@ #include "InputStream.h" #include "MessageReceiver.h" #include "ReposNotifyCallback.h" +#include "ReposVerifyCallback.h" #include "ReposFreezeAction.h" #include "StringArray.h" #include "File.h" @@ -46,7 +47,8 @@ class SVNRepos : public SVNBase jobject lslocks(File &path, svn_depth_t depth); void verify(File &path, Revision &revisionStart, Revision &revisionEnd, bool checkNormalization, bool metadataOnly, - ReposNotifyCallback *notifyCallback); + ReposNotifyCallback *notifyCallback, + ReposVerifyCallback *verifyCallback); void setRevProp(File &path, Revision &revision, const char *propName, const char *propValue, bool usePreRevPropChangeHook, Modified: subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp?rev=1688273&r1=1688272&r2=1688273&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp (original) +++ subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp Mon Jun 29 17:48:10 2015 @@ -420,7 +420,7 @@ Java_org_apache_subversion_javahl_SVNRep JNIEnv *env, jobject jthis, jobject jpath, jobject jrevisionStart, jobject jrevisionEnd, jboolean jcheckNormalization, jboolean jmetadataOnly, - jobject jcallback) + jobject jnotifyCallback, jobject jverifyCallback) { JNIEntry(SVNRepos, verify); SVNRepos *cl = SVNRepos::getCppObject(jthis); @@ -442,13 +442,18 @@ Java_org_apache_subversion_javahl_SVNRep if (JNIUtil::isExceptionThrown()) return; - ReposNotifyCallback callback(jcallback); + ReposNotifyCallback notify_cb(jnotifyCallback); + if (JNIUtil::isExceptionThrown()) + return; + + ReposVerifyCallback verify_cb(jverifyCallback); if (JNIUtil::isExceptionThrown()) return; cl->verify(path, revisionStart, revisionEnd, jcheckNormalization, jmetadataOnly, - jcallback != NULL ? &callback : NULL); + jnotifyCallback != NULL ? ¬ify_cb : NULL, + jverifyCallback != NULL ? &verify_cb : NULL); } JNIEXPORT jobject JNICALL Modified: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRepos.java URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRepos.java?rev=1688273&r1=1688272&r2=1688273&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRepos.java (original) +++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRepos.java Mon Jun 29 17:48:10 2015 @@ -29,6 +29,7 @@ import java.io.InputStream; import java.io.File; import org.apache.subversion.javahl.callback.ReposNotifyCallback; +import org.apache.subversion.javahl.callback.ReposVerifyCallback; import org.apache.subversion.javahl.callback.ReposFreezeAction; import org.apache.subversion.javahl.types.*; @@ -295,30 +296,44 @@ public interface ISVNRepos { /** * Verify the repository at path between revisions * start and end. + *

+ * If verifyCallback is null, verification + * will stop at the first encountered error. Otherwise, the verification + * process may continue, depending on the value returned from the + * invocation of verifyCallback. * * @param path the path to the repository * @param start the first revision * @param end the last revision - * @param checkNormalization report directory entry and mergeinfo name collisions - * caused by denormalized Unicode representations - * @param metadataOnly check only metadata, not file contents - * @param callback the callback to receive notifications + * @param checkNormalization report directory entry and mergeinfo name collisions + * caused by denormalized Unicode representations + * @param metadataOnly check only metadata, not file contents + * @param notifyCallback the callback to receive notifications + * @param verifyCallback the callback to receive verification status * @throws ClientException If an error occurred. - * @since 1.9 + * @since 1.9 */ public abstract void verify(File path, Revision start, Revision end, - boolean checkNormalization, boolean metadataOnly, - ReposNotifyCallback callback) + boolean checkNormalization, + boolean metadataOnly, + ReposNotifyCallback notifyCallback, + ReposVerifyCallback verifyCallback) throws ClientException; /** * Verify the repository at path between revisions * start and end. + *

+ *Note: Behaves like the 1.9 version with + * checkNormailzation and + * metadataOnly set to false + * and verifyCallback set to + * null. * * @param path the path to the repository * @param start the first revision * @param end the last revision - * @param callback the callback to receive notifications + * @param callback the callback to receive notifications * @throws ClientException If an error occurred. */ public abstract void verify(File path, Revision start, Revision end, Modified: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java?rev=1688273&r1=1688272&r2=1688273&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java (original) +++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ReposNotifyInformation.java Mon Jun 29 17:48:10 2015 @@ -35,7 +35,7 @@ public class ReposNotifyInformation exte // Update the serialVersionUID when there is a incompatible change made to // this class. See the java documentation for when a change is incompatible. // http://java.sun.com/javase/7/docs/platform/serialization/spec/version.html#6678 - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 2L; /** * The {@link Action} which triggered this event. Modified: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNRepos.java URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNRepos.java?rev=1688273&r1=1688272&r2=1688273&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNRepos.java (original) +++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNRepos.java Mon Jun 29 17:48:10 2015 @@ -29,6 +29,7 @@ import java.io.InputStream; import java.io.File; import org.apache.subversion.javahl.callback.ReposNotifyCallback; +import org.apache.subversion.javahl.callback.ReposVerifyCallback; import org.apache.subversion.javahl.callback.ReposFreezeAction; import org.apache.subversion.javahl.types.*; @@ -238,12 +239,14 @@ public class SVNRepos implements ISVNRep ReposNotifyCallback callback) throws ClientException { - verify(path, start, end, false, false, callback); + verify(path, start, end, false, false, callback, null); } public native void verify(File path, Revision start, Revision end, - boolean checkNormalization, boolean metadataOnly, - ReposNotifyCallback callback) + boolean checkNormalization, + boolean metadataOnly, + ReposNotifyCallback notifyCallback, + ReposVerifyCallback verifyCallback) throws ClientException; /** Added: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/ReposVerifyCallback.java URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/ReposVerifyCallback.java?rev=1688273&view=auto ============================================================================== --- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/ReposVerifyCallback.java (added) +++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/ReposVerifyCallback.java Mon Jun 29 17:48:10 2015 @@ -0,0 +1,60 @@ +/** + * @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.callback; + +import org.apache.subversion.javahl.ClientException; +import org.apache.subversion.javahl.types.Revision; +import org.apache.subversion.javahl.callback.ReposNotifyCallback; +import org.apache.subversion.javahl.callback.ReposVerifyCallback; + +import java.util.EventListener; + +/** + * Error notifications from + * {@link ISVNRepos#verify(File,Revision,Revision,boolean,boolean,ReposNotifyCallback,ReposVerifyCallback)}. + * + * @since 1.9 + */ +public interface ReposVerifyCallback extends EventListener +{ + /** + * This callback method is invoked every time {@link ISVNRepos#verify} + * encounters and error. + *

+ * The implementation can either consume verifyError + * and return normally to continue verifying the repository after + * an error, or throw verifyError (or some other + * exception) to indicate that verification should stop. In the + * second case, the thrown exception will propagate to the caller + * of {@link ISVNRepos#verify}. + * + * @param revision The revision that caused the error. + * If revision is {@link Revision#SVN_INVALID_REVNUM}, + * the error occurred during metadata verification. + * @param verifyError The verification error. + * @throws ClientException + */ + void onVerifyError(long revision, ClientException verifyError) + throws ClientException; +} Propchange: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/ReposVerifyCallback.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNReposTests.java URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNReposTests.java?rev=1688273&r1=1688272&r2=1688273&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNReposTests.java (original) +++ subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNReposTests.java Mon Jun 29 17:48:10 2015 @@ -26,6 +26,7 @@ import org.apache.subversion.javahl.call import org.apache.subversion.javahl.types.*; import java.io.File; +import java.io.FileWriter; import java.io.FileInputStream; import java.io.OutputStream; import java.io.InputStream; @@ -99,12 +100,103 @@ public class SVNReposTests extends SVNTe public void testVerify() throws SubversionException, IOException { - OneTest thisTest = new OneTest(false); + OneTest thisTest = new OneTest(false, true); admin.verify(thisTest.getRepository(), Revision.getInstance(0), Revision.HEAD, null); } - /* This test only tests the call down to the C++ layer. */ + private class VerifyCallback implements ReposVerifyCallback + { + public int mderr = 0; + public int reverr = 0; + public boolean keepGoing = false; + + public void onVerifyError(long revision, ClientException verifyError) + throws ClientException + { + if (revision == Revision.SVN_INVALID_REVNUM) + ++mderr; + else + ++reverr; + if (keepGoing) + return; + else + throw verifyError; + } + + } + + private boolean trytobreakrepo(OneTest test) throws IOException + { + File repo = test.getRepository(); + + // Check for a sharded repo first + File rev1 = new File(repo, "db/revs/0/1"); + if (!rev1.exists() || !rev1.setWritable(true)) + { + // Try non-sharded + rev1 = new File(repo, "db/revs/1"); + } + if (!rev1.exists() || !rev1.setWritable(true)) + return false; + + FileWriter fd = new FileWriter(rev1); + fd.write("inserting junk to corrupt the rev"); + fd.close(); + return true; + } + + public void testVerifyBrokenRepo() throws Throwable + { + OneTest thisTest = new OneTest(false); + + if (!trytobreakrepo(thisTest)) { + // We don't support the repos format + System.err.print("Cannot break repository for verify test."); + return; + } + + VerifyCallback cb = new VerifyCallback(); + cb.keepGoing = false; + + try { + admin.verify(thisTest.getRepository(), + Revision.getInstance(0), + Revision.HEAD, + false, false, null, cb); + } + catch(ClientException ex) { + assertEquals(cb.mderr, 1); + assertEquals(cb.reverr, 0); + return; + } + + assert("Verify did not catch repository corruption." == ""); + } + + public void testVerifyBrokenRepo_KeepGoing() throws Throwable + { + OneTest thisTest = new OneTest(false); + + if (!trytobreakrepo(thisTest)) { + // We don't support the repos format + System.err.print("Cannot break repository for verify test."); + return; + } + + VerifyCallback cb = new VerifyCallback(); + cb.keepGoing = true; + + admin.verify(thisTest.getRepository(), + Revision.getInstance(0), + Revision.HEAD, + false, false, null, cb); + + assertEquals(cb.mderr, 1); + assertEquals(cb.reverr, 1); + } + + /* this test only tests the call down to the C++ layer. */ public void testUpgrade() throws SubversionException, IOException {