1 /**
2  * @copyright
3  * ====================================================================
4  *    Licensed to the Apache Software Foundation (ASF) under one
5  *    or more contributor license agreements.  See the NOTICE file
6  *    distributed with this work for additional information
7  *    regarding copyright ownership.  The ASF licenses this file
8  *    to you under the Apache License, Version 2.0 (the
9  *    "License"); you may not use this file except in compliance
10  *    with the License.  You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  *    Unless required by applicable law or agreed to in writing,
15  *    software distributed under the License is distributed on an
16  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  *    KIND, either express or implied.  See the License for the
18  *    specific language governing permissions and limitations
19  *    under the License.
20  * ====================================================================
21  * @endcopyright
22  *
23  * @file ListCallback.cpp
24  * @brief Implementation of the class ListCallback
25  */
26 
27 #include "ListCallback.h"
28 #include "EnumMapper.h"
29 #include "CreateJ.h"
30 #include "JNIUtil.h"
31 #include "svn_time.h"
32 
33 /**
34  * Create a ListCallback object
35  * @param jcallback the Java callback object.
36  */
ListCallback(jobject jcallback)37 ListCallback::ListCallback(jobject jcallback)
38 {
39   m_callback = jcallback;
40 }
41 
42 /**
43  * Destroy a ListCallback object
44  */
~ListCallback()45 ListCallback::~ListCallback()
46 {
47   // The m_callback does not need to be destroyed, because it is the passed
48   // in parameter to the Java SVNClient.list method.
49 }
50 
51 svn_error_t *
callback(void * baton,const char * path,const svn_dirent_t * dirent,const svn_lock_t * lock,const char * abs_path,const char * external_parent_url,const char * external_target,apr_pool_t * scratch_pool)52 ListCallback::callback(void *baton,
53                        const char *path,
54                        const svn_dirent_t *dirent,
55                        const svn_lock_t *lock,
56                        const char *abs_path,
57                        const char *external_parent_url,
58                        const char *external_target,
59                        apr_pool_t *scratch_pool)
60 {
61   if (baton)
62     return static_cast<ListCallback *>(baton)->doList(
63             path, dirent, lock, abs_path,
64             external_parent_url, external_target,
65             scratch_pool);
66 
67   return SVN_NO_ERROR;
68 }
69 
70 /**
71  * Callback called for each directory entry.
72  */
73 svn_error_t *
doList(const char * path,const svn_dirent_t * dirent,const svn_lock_t * lock,const char * abs_path,const char * external_parent_url,const char * external_target,apr_pool_t * pool)74 ListCallback::doList(const char *path,
75                      const svn_dirent_t *dirent,
76                      const svn_lock_t *lock,
77                      const char *abs_path,
78                      const char *external_parent_url,
79                      const char *external_target,
80                      apr_pool_t *pool)
81 {
82   JNIEnv *env = JNIUtil::getEnv();
83 
84   // Create a local frame for our references
85   env->PushLocalFrame(LOCAL_FRAME_SIZE);
86   if (JNIUtil::isJavaExceptionThrown())
87     return SVN_NO_ERROR;
88 
89   // The method id will not change during the time this library is
90   // loaded, so it can be cached.
91   static jmethodID mid = 0;
92   if (mid == 0)
93     {
94       jclass clazz = env->FindClass(JAVAHL_CLASS("/callback/ListItemCallback"));
95       if (JNIUtil::isJavaExceptionThrown())
96         POP_AND_RETURN(SVN_NO_ERROR);
97 
98       mid = env->GetMethodID(clazz, "doEntry",
99                              "("
100                              JAVAHL_ARG("/types/DirEntry;")
101                              JAVAHL_ARG("/types/Lock;")
102                              "Ljava/lang/String;"
103                              "Ljava/lang/String;"
104                              ")V");
105       if (JNIUtil::isJavaExceptionThrown() || mid == 0)
106         POP_AND_RETURN(SVN_NO_ERROR);
107     }
108 
109   // convert the parameters to their Java relatives
110   jobject jdirentry = createJavaDirEntry(path, abs_path, dirent);
111   if (JNIUtil::isJavaExceptionThrown())
112     POP_AND_RETURN(SVN_NO_ERROR);
113 
114   jobject jlock = NULL;
115   if (lock != NULL)
116     {
117       jlock = CreateJ::Lock(lock);
118       if (JNIUtil::isJavaExceptionThrown())
119         POP_AND_RETURN(SVN_NO_ERROR);
120     }
121 
122   jstring jexternalParentURL = JNIUtil::makeJString(external_parent_url);
123   if (JNIUtil::isJavaExceptionThrown())
124     POP_AND_RETURN(SVN_NO_ERROR);
125 
126   jstring jexternalTarget = JNIUtil::makeJString(external_target);
127   if (JNIUtil::isJavaExceptionThrown())
128     POP_AND_RETURN(SVN_NO_ERROR);
129 
130   // call the Java method
131   env->CallVoidMethod(m_callback, mid, jdirentry, jlock, jexternalParentURL, jexternalTarget);
132 
133   POP_AND_RETURN_EXCEPTION_AS_SVNERROR();
134 }
135 
136 /**
137  * Create a DirEntry Java object from the svn_dirent_t structure.
138  */
139 jobject
createJavaDirEntry(const char * path,const char * absPath,const svn_dirent_t * dirent)140 ListCallback::createJavaDirEntry(const char *path, const char *absPath,
141                                  const svn_dirent_t *dirent)
142 {
143   return CreateJ::DirEntry(path, absPath, dirent);
144 }
145