~ubuntu-branches/debian/sid/subversion/sid

« back to all changes in this revision

Viewing changes to subversion/bindings/javahl/native/EditorProxy.cpp

  • Committer: Package Import Robot
  • Author(s): James McCoy
  • Date: 2015-08-07 21:32:47 UTC
  • mfrom: (0.2.15) (4.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20150807213247-ozyewtmgsr6tkewl
Tags: 1.9.0-1
* Upload to unstable
* New upstream release.
  + Security fixes
    - CVE-2015-3184: Mixed anonymous/authenticated path-based authz with
      httpd 2.4
    - CVE-2015-3187: svn_repos_trace_node_locations() reveals paths hidden
      by authz
* Add >= 2.7 requirement for python-all-dev Build-Depends, needed to run
  tests.
* Remove Build-Conflicts against ruby-test-unit.  (Closes: #791844)
* Remove patches/apache_module_dependency in favor of expressing the
  dependencies in authz_svn.load/dav_svn.load.
* Build-Depend on apache2-dev (>= 2.4.16) to ensure ap_some_authn_required()
  is available when building mod_authz_svn and Depend on apache2-bin (>=
  2.4.16) for runtime support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 EditorProxy.h
 
24
 * @brief Interface of all editor proxy classes
 
25
 */
 
26
#include <apr_pools.h>
 
27
 
 
28
#include "JNIUtil.h"
 
29
#include "JNIStackElement.h"
 
30
#include "EditorProxy.h"
 
31
#include "CreateJ.h"
 
32
#include "EnumMapper.h"
 
33
 
 
34
// Newstyle: stream wrapper
 
35
#include <memory>
 
36
#include "NativeStream.hpp"
 
37
#include "jniwrapper/jni_stack.hpp"
 
38
 
 
39
#include "svn_error.h"
 
40
#include "svn_private_config.h"
 
41
 
 
42
EditorProxy::EditorProxy(jobject jeditor, apr_pool_t* edit_pool,
 
43
                         const char* repos_root_url, const char* base_relpath,
 
44
                         svn_cancel_func_t cancel_func, void* cancel_baton,
 
45
                         const EditorProxyCallbacks& callbacks)
 
46
  : m_valid(false),
 
47
    m_jeditor(JNIUtil::getEnv()->NewGlobalRef(jeditor)),
 
48
    m_edit_pool(edit_pool),
 
49
    m_repos_root_url(NULL),
 
50
    m_base_relpath(NULL),
 
51
    m_found_paths(false),
 
52
    m_editor(NULL),
 
53
    m_delta_editor(NULL),
 
54
    m_delta_baton(NULL),
 
55
    m_proxy_callbacks(callbacks)
 
56
{
 
57
  //DEBUG:fprintf(stderr, "  (n) EditorProxy::EditorProxy(...)\n");
 
58
 
 
59
  static const svn_editor_cb_many_t editor_many_cb = {
 
60
    cb_add_directory, cb_add_file, cb_add_symlink, cb_add_absent,
 
61
    cb_alter_directory, cb_alter_file, cb_alter_symlink,
 
62
    cb_delete, cb_copy, cb_move,
 
63
    cb_complete, cb_abort
 
64
  };
 
65
 
 
66
  SVN::Pool scratchPool(edit_pool);
 
67
  apr_pool_t* scratch_pool = scratchPool.getPool();
 
68
 
 
69
  svn_error_t* err = svn_editor_create(&m_editor, this,
 
70
                                       cancel_func, cancel_baton,
 
71
                                       edit_pool, scratch_pool);
 
72
  if (!err)
 
73
    err = svn_editor_setcb_many(m_editor, &editor_many_cb, scratch_pool);
 
74
  if (!err)
 
75
    {
 
76
      m_repos_root_url =
 
77
        static_cast<const char*>(apr_pstrdup(edit_pool, repos_root_url));
 
78
      m_base_relpath =
 
79
        static_cast<const char*>(apr_pstrdup(edit_pool, base_relpath));
 
80
 
 
81
      svn_boolean_t found_paths;
 
82
      err = svn_delta__delta_from_editor(&m_delta_editor,
 
83
                                         &m_delta_baton,
 
84
                                         m_editor,
 
85
                                         m_proxy_callbacks.m_unlock_func,
 
86
                                         m_proxy_callbacks.m_baton,
 
87
                                         &found_paths,
 
88
                                         repos_root_url, base_relpath,
 
89
                                         m_proxy_callbacks.m_fetch_props_func,
 
90
                                         m_proxy_callbacks.m_baton,
 
91
                                         m_proxy_callbacks.m_fetch_base_func,
 
92
                                         m_proxy_callbacks.m_baton,
 
93
                                         &m_proxy_callbacks.m_extra_baton,
 
94
                                         edit_pool);
 
95
      m_found_paths = found_paths;
 
96
    }
 
97
 
 
98
  if (err)
 
99
    JNIUtil::handleSVNError(err);
 
100
  else
 
101
    m_valid = true;
 
102
}
 
103
 
 
104
EditorProxy::~EditorProxy()
 
105
{
 
106
  //DEBUG:fprintf(stderr, "  (n) EditorProxy::~EditorProxy()\n");
 
107
 
 
108
  if (m_jeditor)
 
109
    JNIUtil::getEnv()->DeleteGlobalRef(m_jeditor);
 
110
}
 
111
 
 
112
namespace {
 
113
inline svn_error_t* invalid_editor()
 
114
{
 
115
  return svn_error_create(SVN_ERR_RA_SVN_EDIT_ABORTED, NULL,
 
116
                          _("The editor is not valid"));
 
117
}
 
118
 
 
119
svn_error_t*
 
120
get_editor_method(jmethodID& mid, const char* name, const char* sig)
 
121
{
 
122
  if (0 != mid)
 
123
    return SVN_NO_ERROR;        // Already known.
 
124
 
 
125
  JNIEnv* env = JNIUtil::getEnv();
 
126
  jclass cls = env->FindClass(JAVAHL_CLASS("/ISVNEditor"));
 
127
  SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
 
128
  SVN_JNI_CATCH(mid = env->GetMethodID(cls, name, sig),
 
129
                 SVN_ERR_RA_SVN_EDIT_ABORTED);
 
130
  return SVN_NO_ERROR;
 
131
}
 
132
 
 
133
jobject wrap_input_stream(svn_stream_t* stream)
 
134
{
 
135
  std::auto_ptr<JavaHL::NativeInputStream>
 
136
    wrapped(new JavaHL::NativeInputStream());
 
137
  apr_pool_t* const wrapped_pool = wrapped->get_pool().getPool();
 
138
  wrapped->set_stream(svn_stream_disown(stream, wrapped_pool));
 
139
  const jobject jstream = wrapped->create_java_wrapper();
 
140
  wrapped.release();
 
141
  return jstream;
 
142
}
 
143
} // anonymous namespace
 
144
 
 
145
svn_error_t*
 
146
EditorProxy::cb_add_directory(void *baton,
 
147
                              const char *relpath,
 
148
                              const apr_array_header_t *children,
 
149
                              apr_hash_t *props,
 
150
                              svn_revnum_t replaces_rev,
 
151
                              apr_pool_t *scratch_pool)
 
152
{
 
153
  //DEBUG:fprintf(stderr, "  (n) EditorProxy::cb_add_directory('%s')\n", relpath);
 
154
  const ::Java::Env env;
 
155
  SVN_JAVAHL_CATCH(env, SVN_ERR_RA_SVN_EDIT_ABORTED,
 
156
    {
 
157
      ::Java::LocalFrame frame(env);
 
158
 
 
159
      EditorProxy* const ep = static_cast<EditorProxy*>(baton);
 
160
      if (!ep->m_valid)
 
161
        return invalid_editor();
 
162
 
 
163
      static jmethodID mid = 0;
 
164
      SVN_ERR(get_editor_method(mid, "addDirectory",
 
165
                                "(Ljava/lang/String;"
 
166
                                "Ljava/lang/Iterable;"
 
167
                                "Ljava/util/Map;J)V"));
 
168
 
 
169
      jstring jrelpath = JNIUtil::makeJString(relpath);
 
170
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
171
      jobject jchildren = (!children ? NULL : CreateJ::StringSet(children));
 
172
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
173
      jobject jprops = CreateJ::PropertyMap(props, scratch_pool);
 
174
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
175
 
 
176
      env.CallVoidMethod(ep->m_jeditor, mid,
 
177
                         jrelpath, jchildren, jprops,
 
178
                         jlong(replaces_rev));
 
179
    });
 
180
  return SVN_NO_ERROR;
 
181
}
 
182
 
 
183
svn_error_t*
 
184
EditorProxy::cb_add_file(void *baton,
 
185
                         const char *relpath,
 
186
                         const svn_checksum_t *checksum,
 
187
                         svn_stream_t *contents,
 
188
                         apr_hash_t *props,
 
189
                         svn_revnum_t replaces_rev,
 
190
                         apr_pool_t *scratch_pool)
 
191
{
 
192
  //DEBUG:fprintf(stderr, "  (n) EditorProxy::cb_add_file('%s')\n", relpath);
 
193
  const ::Java::Env env;
 
194
  SVN_JAVAHL_CATCH(env, SVN_ERR_RA_SVN_EDIT_ABORTED,
 
195
    {
 
196
      ::Java::LocalFrame frame(env);
 
197
 
 
198
      EditorProxy* const ep = static_cast<EditorProxy*>(baton);
 
199
      if (!ep || !ep->m_valid)
 
200
        return invalid_editor();
 
201
 
 
202
      static jmethodID mid = 0;
 
203
      SVN_ERR(get_editor_method(mid, "addFile",
 
204
                                "(Ljava/lang/String;"
 
205
                                JAVAHL_ARG("/types/Checksum;")
 
206
                                "Ljava/io/InputStream;"
 
207
                                "Ljava/util/Map;J)V"));
 
208
 
 
209
      jstring jrelpath = JNIUtil::makeJString(relpath);
 
210
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
211
      jobject jchecksum = CreateJ::Checksum(checksum);
 
212
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
213
      jobject jprops = CreateJ::PropertyMap(props, scratch_pool);
 
214
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
215
 
 
216
      jobject jcontents = NULL;
 
217
      if (contents != NULL)
 
218
        jcontents = wrap_input_stream(contents);
 
219
 
 
220
      env.CallVoidMethod(ep->m_jeditor, mid,
 
221
                         jrelpath, jchecksum, jcontents,
 
222
                         jprops, jlong(replaces_rev));
 
223
    });
 
224
  return SVN_NO_ERROR;
 
225
}
 
226
 
 
227
svn_error_t*
 
228
EditorProxy::cb_add_symlink(void *baton,
 
229
                            const char *relpath,
 
230
                            const char *target,
 
231
                            apr_hash_t *props,
 
232
                            svn_revnum_t replaces_rev,
 
233
                            apr_pool_t *scratch_pool)
 
234
{
 
235
  //DEBUG:fprintf(stderr, "  (n) EditorProxy::cb_add_symlink('%s')\n", relpath);
 
236
  const ::Java::Env env;
 
237
  SVN_JAVAHL_CATCH(env, SVN_ERR_RA_SVN_EDIT_ABORTED,
 
238
    {
 
239
      ::Java::LocalFrame frame(env);
 
240
 
 
241
      EditorProxy* const ep = static_cast<EditorProxy*>(baton);
 
242
      if (!ep || !ep->m_valid)
 
243
        return invalid_editor();
 
244
 
 
245
      static jmethodID mid = 0;
 
246
      SVN_ERR(get_editor_method(mid, "addSymlink",
 
247
                                "(Ljava/lang/String;"
 
248
                                "Ljava/lang/String;"
 
249
                                "Ljava/util/Map;J)V"));
 
250
 
 
251
      jstring jrelpath = JNIUtil::makeJString(relpath);
 
252
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
253
      jstring jtarget = JNIUtil::makeJString(target);
 
254
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
255
      jobject jprops = CreateJ::PropertyMap(props, scratch_pool);
 
256
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
257
 
 
258
      env.CallVoidMethod(ep->m_jeditor, mid,
 
259
                         jrelpath, jtarget, jprops,
 
260
                         jlong(replaces_rev));
 
261
    });
 
262
  return SVN_NO_ERROR;
 
263
}
 
264
 
 
265
svn_error_t*
 
266
EditorProxy::cb_add_absent(void *baton,
 
267
                           const char *relpath,
 
268
                           svn_node_kind_t kind,
 
269
                           svn_revnum_t replaces_rev,
 
270
                           apr_pool_t *scratch_pool)
 
271
{
 
272
  //DEBUG:fprintf(stderr, "  (n) EditorProxy::cb_add_absent('%s')\n", relpath);
 
273
  const ::Java::Env env;
 
274
  SVN_JAVAHL_CATCH(env, SVN_ERR_RA_SVN_EDIT_ABORTED,
 
275
    {
 
276
      ::Java::LocalFrame frame(env);
 
277
 
 
278
      EditorProxy* const ep = static_cast<EditorProxy*>(baton);
 
279
      if (!ep || !ep->m_valid)
 
280
        return invalid_editor();
 
281
 
 
282
      static jmethodID mid = 0;
 
283
      SVN_ERR(get_editor_method(mid, "addAbsent",
 
284
                                "(Ljava/lang/String;"
 
285
                                JAVAHL_ARG("/types/NodeKind;")
 
286
                                "J)V"));
 
287
 
 
288
      jstring jrelpath = JNIUtil::makeJString(relpath);
 
289
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
290
      jobject jkind = EnumMapper::mapNodeKind(kind);
 
291
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
292
 
 
293
      env.CallVoidMethod(ep->m_jeditor, mid,
 
294
                         jrelpath, jkind,
 
295
                         jlong(replaces_rev));
 
296
    });
 
297
  return SVN_NO_ERROR;
 
298
}
 
299
 
 
300
svn_error_t*
 
301
EditorProxy::cb_alter_directory(void *baton,
 
302
                                const char *relpath,
 
303
                                svn_revnum_t revision,
 
304
                                const apr_array_header_t *children,
 
305
                                apr_hash_t *props,
 
306
                                apr_pool_t *scratch_pool)
 
307
{
 
308
  //DEBUG:fprintf(stderr, "  (n) EditorProxy::cb_alter_directory('%s', r%lld)\n",
 
309
  //DEBUG:        relpath, static_cast<long long>(revision));
 
310
  const ::Java::Env env;
 
311
  SVN_JAVAHL_CATCH(env, SVN_ERR_RA_SVN_EDIT_ABORTED,
 
312
    {
 
313
      ::Java::LocalFrame frame(env);
 
314
 
 
315
      EditorProxy* const ep = static_cast<EditorProxy*>(baton);
 
316
      if (!ep || !ep->m_valid)
 
317
        return invalid_editor();
 
318
 
 
319
      static jmethodID mid = 0;
 
320
      SVN_ERR(get_editor_method(mid, "alterDirectory",
 
321
                                "(Ljava/lang/String;J"
 
322
                                "Ljava/lang/Iterable;"
 
323
                                "Ljava/util/Map;)V"));
 
324
 
 
325
      jstring jrelpath = JNIUtil::makeJString(relpath);
 
326
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
327
      jobject jchildren = (!children ? NULL : CreateJ::StringSet(children));
 
328
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
329
      jobject jprops = CreateJ::PropertyMap(props, scratch_pool);
 
330
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
331
 
 
332
      env.CallVoidMethod(ep->m_jeditor, mid,
 
333
                         jrelpath, jlong(revision),
 
334
                         jchildren, jprops);
 
335
    });
 
336
  return SVN_NO_ERROR;
 
337
}
 
338
 
 
339
svn_error_t*
 
340
EditorProxy::cb_alter_file(void *baton,
 
341
                           const char *relpath,
 
342
                           svn_revnum_t revision,
 
343
                           const svn_checksum_t *checksum,
 
344
                           svn_stream_t *contents,
 
345
                           apr_hash_t *props,
 
346
                           apr_pool_t *scratch_pool)
 
347
{
 
348
  //DEBUG:fprintf(stderr, "  (n) EditorProxy::cb_alter_file('%s', r%lld)\n",
 
349
  //DEBUG:        relpath, static_cast<long long>(revision));
 
350
  const ::Java::Env env;
 
351
  SVN_JAVAHL_CATCH(env, SVN_ERR_RA_SVN_EDIT_ABORTED,
 
352
    {
 
353
      ::Java::LocalFrame frame(env);
 
354
 
 
355
      EditorProxy* const ep = static_cast<EditorProxy*>(baton);
 
356
      if (!ep || !ep->m_valid)
 
357
        return invalid_editor();
 
358
 
 
359
      static jmethodID mid = 0;
 
360
      SVN_ERR(get_editor_method(mid, "alterFile",
 
361
                                "(Ljava/lang/String;J"
 
362
                                JAVAHL_ARG("/types/Checksum;")
 
363
                                "Ljava/io/InputStream;"
 
364
                                "Ljava/util/Map;)V"));
 
365
 
 
366
      jstring jrelpath = JNIUtil::makeJString(relpath);
 
367
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
368
      jobject jchecksum = CreateJ::Checksum(checksum);
 
369
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
370
      jobject jprops = CreateJ::PropertyMap(props, scratch_pool);
 
371
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
372
 
 
373
      jobject jcontents = NULL;
 
374
      if (contents != NULL)
 
375
        jcontents = wrap_input_stream(contents);
 
376
 
 
377
      env.CallVoidMethod(ep->m_jeditor, mid,
 
378
                         jrelpath, jlong(revision),
 
379
                         jchecksum, jcontents, jprops);
 
380
    });
 
381
  return SVN_NO_ERROR;
 
382
}
 
383
 
 
384
svn_error_t*
 
385
EditorProxy::cb_alter_symlink(void *baton,
 
386
                              const char *relpath,
 
387
                              svn_revnum_t revision,
 
388
                              const char *target,
 
389
                              apr_hash_t *props,
 
390
                              apr_pool_t *scratch_pool)
 
391
{
 
392
  //DEBUG:fprintf(stderr, "  (n) EditorProxy::cb_alter_symlink('%s', r%lld)\n",
 
393
  //DEBUG:        relpath, static_cast<long long>(revision));
 
394
  const ::Java::Env env;
 
395
  SVN_JAVAHL_CATCH(env, SVN_ERR_RA_SVN_EDIT_ABORTED,
 
396
    {
 
397
      ::Java::LocalFrame frame(env);
 
398
 
 
399
      EditorProxy* const ep = static_cast<EditorProxy*>(baton);
 
400
      if (!ep || !ep->m_valid)
 
401
        return invalid_editor();
 
402
 
 
403
      static jmethodID mid = 0;
 
404
      SVN_ERR(get_editor_method(mid, "alterSymlink",
 
405
                                "(Ljava/lang/String;J"
 
406
                                "Ljava/lang/String;"
 
407
                                "Ljava/util/Map;)V"));
 
408
 
 
409
      jstring jrelpath = JNIUtil::makeJString(relpath);
 
410
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
411
      jstring jtarget = JNIUtil::makeJString(target);
 
412
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
413
      jobject jprops = CreateJ::PropertyMap(props, scratch_pool);
 
414
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
415
 
 
416
      env.CallVoidMethod(ep->m_jeditor, mid,
 
417
                         jrelpath, jlong(revision),
 
418
                         jtarget, jprops);
 
419
    });
 
420
  return SVN_NO_ERROR;
 
421
}
 
422
 
 
423
svn_error_t*
 
424
EditorProxy::cb_delete(void *baton,
 
425
                       const char *relpath,
 
426
                       svn_revnum_t revision,
 
427
                       apr_pool_t *scratch_pool)
 
428
{
 
429
  //DEBUG:fprintf(stderr, "  (n) EditorProxy::cb_delete('%s', r%lld)\n",
 
430
  //DEBUG:        relpath, static_cast<long long>(revision));
 
431
  const ::Java::Env env;
 
432
  SVN_JAVAHL_CATCH(env, SVN_ERR_RA_SVN_EDIT_ABORTED,
 
433
    {
 
434
      ::Java::LocalFrame frame(env);
 
435
 
 
436
      EditorProxy* const ep = static_cast<EditorProxy*>(baton);
 
437
      if (!ep || !ep->m_valid)
 
438
        return invalid_editor();
 
439
 
 
440
      static jmethodID mid = 0;
 
441
      SVN_ERR(get_editor_method(mid, "delete",
 
442
                                "(Ljava/lang/String;J)V"));
 
443
 
 
444
      jstring jrelpath = JNIUtil::makeJString(relpath);
 
445
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
446
 
 
447
      env.CallVoidMethod(ep->m_jeditor, mid, jrelpath);
 
448
    });
 
449
  return SVN_NO_ERROR;
 
450
}
 
451
 
 
452
svn_error_t*
 
453
EditorProxy::cb_copy(void *baton,
 
454
                     const char *src_relpath,
 
455
                     svn_revnum_t src_revision,
 
456
                     const char *dst_relpath,
 
457
                     svn_revnum_t replaces_rev,
 
458
                     apr_pool_t *scratch_pool)
 
459
{
 
460
  //DEBUG:fprintf(stderr, "  (n) EditorProxy::cb_copy('%s', r%lld, '%s')\n",
 
461
  //DEBUG:        src_relpath, static_cast<long long>(src_revision), dst_relpath);
 
462
  const ::Java::Env env;
 
463
  SVN_JAVAHL_CATCH(env, SVN_ERR_RA_SVN_EDIT_ABORTED,
 
464
    {
 
465
      ::Java::LocalFrame frame(env);
 
466
 
 
467
      EditorProxy* const ep = static_cast<EditorProxy*>(baton);
 
468
      if (!ep || !ep->m_valid)
 
469
        return invalid_editor();
 
470
 
 
471
      static jmethodID mid = 0;
 
472
      SVN_ERR(get_editor_method(mid, "copy",
 
473
                                "(Ljava/lang/String;J"
 
474
                                "Ljava/lang/String;J)V"));
 
475
 
 
476
      jstring jsrc_relpath = JNIUtil::makeJString(src_relpath);
 
477
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
478
      jstring jdst_relpath = JNIUtil::makeJString(dst_relpath);
 
479
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
480
 
 
481
      env.CallVoidMethod(ep->m_jeditor, mid,
 
482
                         jsrc_relpath, jlong(src_revision),
 
483
                         jdst_relpath, jlong(replaces_rev));
 
484
    });
 
485
  return SVN_NO_ERROR;
 
486
}
 
487
 
 
488
svn_error_t*
 
489
EditorProxy::cb_move(void *baton,
 
490
                     const char *src_relpath,
 
491
                     svn_revnum_t src_revision,
 
492
                     const char *dst_relpath,
 
493
                     svn_revnum_t replaces_rev,
 
494
                     apr_pool_t *scratch_pool)
 
495
{
 
496
  //DEBUG:fprintf(stderr, "  (n) EditorProxy::cb_move('%s', r%lld, '%s')\n",
 
497
  //DEBUG:        src_relpath, static_cast<long long>(src_revision), dst_relpath);
 
498
  const ::Java::Env env;
 
499
  SVN_JAVAHL_CATCH(env, SVN_ERR_RA_SVN_EDIT_ABORTED,
 
500
    {
 
501
      ::Java::LocalFrame frame(env);
 
502
 
 
503
      EditorProxy* const ep = static_cast<EditorProxy*>(baton);
 
504
      if (!ep || !ep->m_valid)
 
505
        return invalid_editor();
 
506
 
 
507
      static jmethodID mid = 0;
 
508
      SVN_ERR(get_editor_method(mid, "move",
 
509
                                "(Ljava/lang/String;J"
 
510
                                "Ljava/lang/String;J)V"));
 
511
 
 
512
      jstring jsrc_relpath = JNIUtil::makeJString(src_relpath);
 
513
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
514
      jstring jdst_relpath = JNIUtil::makeJString(dst_relpath);
 
515
      SVN_JAVAHL_OLDSTYLE_EXCEPTION_CHECK(env);
 
516
 
 
517
      env.CallVoidMethod(ep->m_jeditor, mid,
 
518
                         jsrc_relpath, jlong(src_revision),
 
519
                         jdst_relpath, jlong(replaces_rev));
 
520
    });
 
521
  return SVN_NO_ERROR;
 
522
}
 
523
 
 
524
svn_error_t*
 
525
EditorProxy::cb_complete(void *baton, apr_pool_t *scratch_pool)
 
526
{
 
527
  //DEBUG:fprintf(stderr, "  (n) EditorProxy::cb_complete()\n");
 
528
  const ::Java::Env env;
 
529
  SVN_JAVAHL_CATCH(env, SVN_ERR_RA_SVN_EDIT_ABORTED,
 
530
    {
 
531
      ::Java::LocalFrame frame(env);
 
532
 
 
533
      EditorProxy* const ep = static_cast<EditorProxy*>(baton);
 
534
      if (!ep || !ep->m_valid)
 
535
        return invalid_editor();
 
536
      ep->m_valid = false;
 
537
 
 
538
      static jmethodID mid = 0;
 
539
      SVN_ERR(get_editor_method(mid, "complete", "()V"));
 
540
 
 
541
      env.CallVoidMethod(ep->m_jeditor, mid);
 
542
    });
 
543
  return SVN_NO_ERROR;
 
544
}
 
545
 
 
546
svn_error_t*
 
547
EditorProxy::cb_abort(void *baton, apr_pool_t *scratch_pool)
 
548
{
 
549
  //DEBUG:fprintf(stderr, "  (n) EditorProxy::cb_abort()\n");
 
550
  const ::Java::Env env;
 
551
  SVN_JAVAHL_CATCH(env, SVN_ERR_RA_SVN_EDIT_ABORTED,
 
552
    {
 
553
      ::Java::LocalFrame frame(env);
 
554
 
 
555
      EditorProxy* const ep = static_cast<EditorProxy*>(baton);
 
556
      if (!ep || !ep->m_valid)
 
557
        return invalid_editor();
 
558
      ep->m_valid = false;
 
559
 
 
560
      static jmethodID mid = 0;
 
561
      SVN_ERR(get_editor_method(mid, "abort", "()V"));
 
562
 
 
563
      env.CallVoidMethod(ep->m_jeditor, mid);
 
564
    });
 
565
  return SVN_NO_ERROR;
 
566
}