/subversion/trunk/subversion/bindings/javahl: native/ src/org/apache/subversion/javahl/ src/org/apache/subversion/javahl/remote/ MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable
Does a Java Map allow mapping something to Null? As that is how a property deletion would be described in a property change Apr array. Bert From: br...@apache.org Sent: =E2=80=8E05/=E2=80=8E08/=E2=80=8E2013 16:27 To: comm...@subversion.apache.org Subject: svn commit: r1510494 - in /subversion/trunk/subversion/bindings/javahl: native/ src/org/apache/subversion/javahl/ src/org/apache/subversion/javahl/remote/ Author: brane Date: Mon Aug 5 14:26:36 2013 New Revision: 1510494 URL: http://svn.apache.org/r1510494 Log: Implement svn_ra_get_file_revs in JavaHL. [in subversion/bindings/javahl/src/org/apache/subversion/javahl] * ISVNRemote.java (ISVNRemote.FileRevision): New nested class. (ISVNRemote.getFileRevisions): New. * remote/RemoteSession.java (ISVNRemote.getFileRevisions): Declare native. [in subversion/bindings/javahl/native] * RemoteSession.h (RemoteSession::getFileRevisions): New prototype. * RemoteSession.cpp (FileRevisionHandler): New helper class. (RemoteSession::getFileRevisions): Implement. * org_apache_subversion_javahl_remote_RemoteSession.cpp (Java_org_apache_subversion_javahl_remote_RemoteSession_getFileRevisions) Native wrapper for ISVNRemote.getFileRevisions. Modified: subversion/trunk/subversion/bindings/javahl/native/RemoteSession.cpp subversion/trunk/subversion/bindings/javahl/native/RemoteSession.h subversion/trunk/subversion/bindings/javahl/native/org_apache_subversio= n_javahl_remote_RemoteSession.cpp subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/j= avahl/ISVNRemote.java subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/j= avahl/remote/RemoteSession.java Modified: subversion/trunk/subversion/bindings/javahl/native/RemoteSession.= cpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/java= hl/native/RemoteSession.cpp?rev=3D1510494&r1=3D1510493&r2=3D1510494&view=3D= diff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- subversion/trunk/subversion/bindings/javahl/native/RemoteSession.cpp (o= riginal) +++ subversion/trunk/subversion/bindings/javahl/native/RemoteSession.cpp Mo= n Aug 5 14:26:36 2013 @@ -1183,7 +1183,136 @@ RemoteSession::getLocationSegments(jstri return handler.get(); } =20 -// TODO: getFileRevisions +namespace { +class FileRevisionHandler +{ +public: + static svn_error_t* callback(void* baton, + const char* path, svn_revnum_t revision, + apr_hash_t* revision_props, + // We ignore the deltas as they're not + // exposed in the JavaHL API. + svn_boolean_t result_of_merge, + svn_txdelta_window_handler_t*, void**, + apr_array_header_t* prop_diffs, + apr_pool_t* scratch_pool) + { + FileRevisionHandler* const self =3D + static_cast<FileRevisionHandler*>(baton); + SVN_ERR_ASSERT(self->m_jresult_list !=3D NULL); + self->add(path, revision, revision_props, + result_of_merge, prop_diffs, scratch_pool); + SVN_ERR(JNIUtil::checkJavaException(SVN_ERR_BASE)); + return SVN_NO_ERROR; + } + + FileRevisionHandler() + : m_jresult_list(NULL) + { + JNIEnv* env =3D JNIUtil::getEnv(); + jclass cls =3D env->FindClass("java/util/ArrayList"); + if (JNIUtil::isJavaExceptionThrown()) + return; + + static jmethodID mid =3D 0; + if (mid =3D=3D 0) + { + mid =3D env->GetMethodID(cls, "<init>", "()V"); + if (JNIUtil::isJavaExceptionThrown()) + return; + } + + jobject jresult_list =3D env->NewObject(cls, mid); + if (!JNIUtil::isJavaExceptionThrown() && jresult_list) + m_jresult_list =3D jresult_list; + } + + jobject get() const { return m_jresult_list; } + +private: + void add(const char* path, svn_revnum_t revision, + apr_hash_t* revision_props, + svn_boolean_t result_of_merge, + apr_array_header_t* prop_diffs, + apr_pool_t* scratch_pool) + { + JNIEnv* env =3D JNIUtil::getEnv(); + jclass cls =3D env->FindClass(JAVA_PACKAGE"/ISVNRemote$FileRevision"= ); + if (JNIUtil::isJavaExceptionThrown()) + return; + + static jmethodID mid =3D 0; + if (mid =3D=3D 0) + { + mid =3D env->GetMethodID(cls, "<init>", + "(Ljava/lang/String;JZ" + "Ljava/util/Map;Ljava/util/Map;)V"); + if (JNIUtil::isJavaExceptionThrown()) + return; + } + + static jmethodID mid_add =3D 0; + if (mid_add =3D=3D 0) + { + jclass list_cls =3D env->FindClass("java/util/ArrayList"); + if (JNIUtil::isJavaExceptionThrown()) + return; + mid_add =3D env->GetMethodID(list_cls, "add", + "(Ljava/lang/Object;)Z"); + if (JNIUtil::isJavaExceptionThrown()) + return; + } + + jstring jpath =3D JNIUtil::makeJString(path); + if (JNIUtil::isJavaExceptionThrown()) + return; + jobject jrevprops =3D CreateJ::PropertyMap(revision_props, scratch_p= ool); + if (JNIUtil::isJavaExceptionThrown()) + return; + jobject jpropdelta =3D CreateJ::PropertyMap(prop_diffs, scratch_pool= ); + if (JNIUtil::isJavaExceptionThrown()) + return; + + env->CallBooleanMethod(m_jresult_list, mid_add, + env->NewObject(cls, mid, jpath, jlong(revisio= n), + jboolean(result_of_merge), + jrevprops, jpropdelta)); + if (JNIUtil::isJavaExceptionThrown()) + return; + env->DeleteLocalRef(jpath); + env->DeleteLocalRef(jrevprops); + env->DeleteLocalRef(jpropdelta); + } + + jobject m_jresult_list; +}; +} // anonymous namespace + +jobject +RemoteSession::getFileRevisions(jstring jpath, + jlong jstart_revision, jlong jend_revision= , + jboolean jinclude_merged_revisions) +{ + SVN::Pool subPool(pool); + Relpath path(jpath, subPool); + if (JNIUtil::isExceptionThrown()) + return NULL; + SVN_JNI_ERR(path.error_occurred(), NULL); + + FileRevisionHandler handler; + if (JNIUtil::isExceptionThrown()) + return NULL; + + SVN_JNI_ERR(svn_ra_get_file_revs2(m_session, path.c_str(), + svn_revnum_t(jstart_revision), + svn_revnum_t(jend_revision), + bool(jinclude_merged_revisions), + handler.callback, &handler, + subPool.getPool()), + NULL); + return handler.get(); +} + // TODO: lock // TODO: unlock // TODO: getLock Modified: subversion/trunk/subversion/bindings/javahl/native/RemoteSession.= h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/java= hl/native/RemoteSession.h?rev=3D1510494&r1=3D1510493&r2=3D1510494&view=3Ddi= ff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- subversion/trunk/subversion/bindings/javahl/native/RemoteSession.h (ori= ginal) +++ subversion/trunk/subversion/bindings/javahl/native/RemoteSession.h Mon = Aug 5 14:26:36 2013 @@ -97,6 +97,9 @@ class RemoteSession : public SVNBase jobject jlocation_revisions); jobject getLocationSegments(jstring jpath, jlong jpeg_revision, jlong jstart_revision, jlong jend_revision= ); + jobject getFileRevisions(jstring jpath, + jlong jstart_revision, jlong jend_revision, + jboolean jinclude_merged_revisions); // TODO: getFileRevisions // TODO: lock // TODO: unlock Modified: subversion/trunk/subversion/bindings/javahl/native/org_apache_sub= version_javahl_remote_RemoteSession.cpp URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/java= hl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp?rev=3D15104= 94&r1=3D1510493&r2=3D1510494&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- subversion/trunk/subversion/bindings/javahl/native/org_apache_subversio= n_javahl_remote_RemoteSession.cpp (original) +++ subversion/trunk/subversion/bindings/javahl/native/org_apache_subversio= n_javahl_remote_RemoteSession.cpp Mon Aug 5 14:26:36 2013 @@ -308,7 +308,20 @@ Java_org_apache_subversion_javahl_remote jstart_revision, jend_revision); } =20 -// TODO: getFileRevisions +JNIEXPORT jobject JNICALL +Java_org_apache_subversion_javahl_remote_RemoteSession_getFileRevisions( + JNIEnv *env, jobject jthis, jstring jpath, + jlong jstart_revision, jlong jend_revision, + jboolean jinclude_merged_revisions) +{ + JNIEntry(SVNReposAccess, getFileRevisions); + RemoteSession *ras =3D RemoteSession::getCppObject(jthis); + CPPADDR_NULL_PTR(ras, NULL); + + return ras->getFileRevisions(jpath, jstart_revision, jend_revision, + jinclude_merged_revisions); +} + // TODO: lock // TODO: unlock // TODO: getLock Modified: subversion/trunk/subversion/bindings/javahl/src/org/apache/subver= sion/javahl/ISVNRemote.java URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/java= hl/src/org/apache/subversion/javahl/ISVNRemote.java?rev=3D1510494&r1=3D1510= 493&r2=3D1510494&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/j= avahl/ISVNRemote.java (original) +++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/j= avahl/ISVNRemote.java Mon Aug 5 14:26:36 2013 @@ -470,7 +470,7 @@ public interface ISVNRemote throws ClientException; =20 /** - * The object returned from {@link getLocationSegments}. + * The object returned from {@link #getLocationSegments}. */ public static class LocationSegment implements java.io.Serializable { @@ -532,18 +532,119 @@ public interface ISVNRemote long endRevision) throws ClientException; =20 - // TODO: getFileRevisions + /** + * The object returned by {@link #getFileRevisions}. + */ + public final class FileRevision implements java.io.Serializable + { + // Update the serialVersionUID when there is a incompatible change + // made to this class. + private static final long serialVersionUID =3D 1L; + + /** + * Private constructor called by the native implementation. + */ + private FileRevision(String path, long revision, + boolean resultOfMerge, + Map<String, byte[]> revisionProperties, + Map<String, byte[]> propertiesDelta) + { + this.path =3D path; + this.revision =3D revision; + this.resultOfMerge =3D resultOfMerge; + this.revisionProperties =3D revisionProperties; + this.propertiesDelta =3D propertiesDelta; + } + + /** + * @return The path of the file in this revision. + */ + public String getPath() { return path; } + + /** + * @return The revision associated with the path. + */ + public long getRevision() { return revision; } + + /** + * @return A flag indicating that this revision was the result + * of a merge. + */ + public boolean isResultOfMerge() { return resultOfMerge; } + + /** + * @return The list of revision properties. + */ + public Map<String, byte[]> getRevisionProperties() + { + return revisionProperties; + } + + /** + * @return The changes that were made to the node's properties + * in this revision. This map will contain only added, + * modified and deleted properties. Deleted properties will + * have <code>null</code> values. + */ + public Map<String, byte[]> getPropertiesDelta() + { + return propertiesDelta; + } + + private String path; + private long revision; + private boolean resultOfMerge; + private Map<String, byte[]> revisionProperties; + private Map<String, byte[]> propertiesDelta; + } + + /** + * Retrieve a subset of the interesting revisions of a file + * <code>path</code> as seen in revision <code>endRevision</code>. + * <p> + * If there is an interesting revision of the file that is less + * than or equal to <code>startRevision</code>, the iteration will + * begin at that revision. Otherwise the iteration will begin at + * the first revision of the file in the repository, which has to + * be less than or equal to <code>endRevision</code>. Note that + * if the function succeeds, the returned list will contain at + * least one element. + * <p> + * <b>Note:</b> This functionality is not available in pre-1.1 + * servers. If the server doesn't implement it, an alternative + * (but much slower) implementation based on {@link #getLog} is + * used. + * <p> + * <b>Note:</b> With Subversion 1.8 and newer servers this + * function supports reversion of the revision range for when + * <code>includeMergedRevisions</code> is <code>false</code>. + * + * @param path A path relative to the session URL. + * @param startRevision The lower bound of the revision interval. + * @param endRevision the upper bound of the revision interval. + * @param includeMergedRevisions When <code>true</code>, revisions tha= t + * contributed to a merge are included in the result. + * @throws ClientException + */ + List<FileRevision> getFileRevisions(String path, + long startRevision, long endRevisi= on, + boolean includeMergedRevisions) + throws ClientException; + + // TODO: lock // TODO: unlock // TODO: getLock =20 /** * Return a dictionary containing all locks on or below the given path= . + * <p> + * <b>Note:</b> It is not considered an error if <code>path</code> doe= s + * not exist in HEAD. Such a search will simply return no locks. + * <p> + * <b>Note:</b>This functionality is not available in pre-1.2 servers. * @param path A path relative to the sessionn URL * @param depth The recursion depth - * @note It is not considered an error for the path to not exist in HE= AD. - * Such a search will simply return no locks. - * @note This functionality is not available in pre-1.2 servers. * @throws ClientException */ Map<String, Lock> getLocks(String path, Depth depth) Modified: subversion/trunk/subversion/bindings/javahl/src/org/apache/subver= sion/javahl/remote/RemoteSession.java URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/java= hl/src/org/apache/subversion/javahl/remote/RemoteSession.java?rev=3D1510494= &r1=3D1510493&r2=3D1510494&view=3Ddiff =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D --- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/j= avahl/remote/RemoteSession.java (original) +++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/j= avahl/remote/RemoteSession.java Mon Aug 5 14:26:36 2013 @@ -213,7 +213,13 @@ public class RemoteSession extends JNIOb long endRevision) throws ClientException; =20 - // TODO: getFileRevisions + public native + List<FileRevision> getFileRevisions(String path, + long startRevision, + long endRevision, + boolean includeMergedRevisions= ) + throws ClientException; + // TODO: lock // TODO: unlock // TODO: getLock