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 org_apache_subversion_javahl_SVNRepos.cpp
24  * @brief Implementation of the native methods in the Java class SVNRepos
25  */
26 
27 #include "../include/org_apache_subversion_javahl_SVNRepos.h"
28 #include "JNIUtil.h"
29 #include "JNIStackElement.h"
30 #include "JNIStringHolder.h"
31 #include "JNIByteArray.h"
32 #include "SVNRepos.h"
33 #include "EnumMapper.h"
34 #include "Revision.h"
35 #include "InputStream.h"
36 #include "OutputStream.h"
37 #include "MessageReceiver.h"
38 #include "File.h"
39 #include "ReposNotifyCallback.h"
40 #include "svn_props.h"
41 #include "svn_private_config.h"
42 
43 JNIEXPORT jlong JNICALL
Java_org_apache_subversion_javahl_SVNRepos_ctNative(JNIEnv * env,jobject jthis)44 Java_org_apache_subversion_javahl_SVNRepos_ctNative
45 (JNIEnv *env, jobject jthis)
46 {
47   JNIEntry(SVNRepos, ctNative);
48   SVNRepos *obj = new SVNRepos;
49   return obj->getCppAddr();
50 }
51 
52 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_dispose(JNIEnv * env,jobject jthis)53 Java_org_apache_subversion_javahl_SVNRepos_dispose
54 (JNIEnv *env, jobject jthis)
55 {
56   JNIEntry(SVNRepos, dispose);
57   SVNRepos *cl = SVNRepos::getCppObject(jthis);
58   if (cl == NULL)
59     {
60       JNIUtil::throwError(_("bad C++ this"));
61       return;
62     }
63   cl->dispose(jthis);
64 }
65 
66 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_finalize(JNIEnv * env,jobject jthis)67 Java_org_apache_subversion_javahl_SVNRepos_finalize
68 (JNIEnv *env, jobject jthis)
69 {
70   JNIEntry(SVNRepos, finalize);
71   SVNRepos *cl = SVNRepos::getCppObject(jthis);
72   if (cl != NULL)
73     cl->finalize();
74 }
75 
76 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_create(JNIEnv * env,jobject jthis,jobject jpath,jboolean jdisableFsyncCommit,jboolean jkeepLog,jobject jconfigpath,jstring jfstype)77 Java_org_apache_subversion_javahl_SVNRepos_create
78 (JNIEnv *env, jobject jthis, jobject jpath, jboolean jdisableFsyncCommit,
79  jboolean jkeepLog, jobject jconfigpath, jstring jfstype)
80 {
81   JNIEntry(SVNRepos, create);
82   SVNRepos *cl = SVNRepos::getCppObject(jthis);
83   if (cl == NULL)
84     {
85       JNIUtil::throwError(_("bad C++ this"));
86       return;
87     }
88 
89   File path(jpath);
90   if (JNIUtil::isExceptionThrown())
91     return;
92 
93   File configpath(jconfigpath);
94   if (JNIUtil::isExceptionThrown())
95     return;
96 
97   JNIStringHolder fstype(jfstype);
98   if (JNIUtil::isExceptionThrown())
99     return;
100 
101   cl->create(path, jdisableFsyncCommit? true : false, jkeepLog? true : false,
102              configpath, fstype);
103 }
104 
105 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_deltify(JNIEnv * env,jobject jthis,jobject jpath,jobject jrevisionStart,jobject jrevisionStop)106 Java_org_apache_subversion_javahl_SVNRepos_deltify
107 (JNIEnv *env, jobject jthis, jobject jpath, jobject jrevisionStart,
108  jobject jrevisionStop)
109 {
110   JNIEntry(SVNRepos, deltify);
111   SVNRepos *cl = SVNRepos::getCppObject(jthis);
112   if (cl == NULL)
113     {
114       JNIUtil::throwError(_("bad C++ this"));
115       return;
116     }
117 
118   File path(jpath);
119   if (JNIUtil::isExceptionThrown())
120     return;
121 
122   Revision revisionStart(jrevisionStart);
123   if (JNIUtil::isExceptionThrown())
124     return;
125 
126   Revision revisionEnd(jrevisionStop);
127   if (JNIUtil::isExceptionThrown())
128     return;
129 
130   cl->deltify(path, revisionStart, revisionEnd);
131 }
132 
133 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_dump(JNIEnv * env,jobject jthis,jobject jpath,jobject jdataout,jobject jrevisionStart,jobject jrevisionEnd,jboolean jincremental,jboolean juseDeltas,jobject jnotifyCallback)134 Java_org_apache_subversion_javahl_SVNRepos_dump
135 (JNIEnv *env, jobject jthis, jobject jpath, jobject jdataout,
136  jobject jrevisionStart, jobject jrevisionEnd, jboolean jincremental,
137  jboolean juseDeltas, jobject jnotifyCallback)
138 {
139   JNIEntry(SVNRepos, dump);
140   SVNRepos *cl = SVNRepos::getCppObject(jthis);
141   if (cl == NULL)
142     {
143       JNIUtil::throwError(_("bad C++ this"));
144       return;
145     }
146 
147   File path(jpath);
148   if (JNIUtil::isExceptionThrown())
149     return;
150 
151   OutputStream dataOut(jdataout);
152   if (JNIUtil::isExceptionThrown())
153     return;
154 
155   Revision revisionStart(jrevisionStart);
156   if (JNIUtil::isExceptionThrown())
157     return;
158 
159   Revision revisionEnd(jrevisionEnd);
160   if (JNIUtil::isExceptionThrown())
161     return;
162 
163   ReposNotifyCallback notifyCallback(jnotifyCallback);
164 
165   cl->dump(path, dataOut, revisionStart, revisionEnd,
166            jincremental ? true : false, juseDeltas ? true : false,
167            jnotifyCallback != NULL ? &notifyCallback : NULL);
168 }
169 
170 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_hotcopy(JNIEnv * env,jobject jthis,jobject jpath,jobject jtargetPath,jboolean jcleanLogs,jboolean jincremental,jobject jnotifyCallback)171 Java_org_apache_subversion_javahl_SVNRepos_hotcopy
172 (JNIEnv *env, jobject jthis, jobject jpath, jobject jtargetPath,
173  jboolean jcleanLogs, jboolean jincremental, jobject jnotifyCallback)
174 {
175   JNIEntry(SVNRepos, hotcopy);
176   SVNRepos *cl = SVNRepos::getCppObject(jthis);
177   if (cl == NULL)
178     {
179       JNIUtil::throwError(_("bad C++ this"));
180       return;
181     }
182 
183   File path(jpath);
184   if (JNIUtil::isExceptionThrown())
185     return;
186 
187   File targetPath(jtargetPath);
188   if (JNIUtil::isExceptionThrown())
189     return;
190 
191   ReposNotifyCallback notifyCallback(jnotifyCallback);
192 
193   cl->hotcopy(path, targetPath, jcleanLogs ? true : false,
194               jincremental ? true : false,
195               jnotifyCallback != NULL ? &notifyCallback : NULL);
196 }
197 
198 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_listDBLogs(JNIEnv * env,jobject jthis,jobject jpath,jobject jreceiver)199 Java_org_apache_subversion_javahl_SVNRepos_listDBLogs
200 (JNIEnv *env, jobject jthis, jobject jpath, jobject jreceiver)
201 {
202   JNIEntry(SVNRepos, listDBLogs);
203   SVNRepos *cl = SVNRepos::getCppObject(jthis);
204   if (cl == NULL)
205     {
206       JNIUtil::throwError(_("bad C++ this"));
207       return;
208     }
209 
210   File path(jpath);
211   if (JNIUtil::isExceptionThrown())
212     return;
213 
214   MessageReceiver mr(jreceiver);
215   if (JNIUtil::isExceptionThrown())
216     return;
217 
218   cl->listDBLogs(path, mr);
219 }
220 
221 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_listUnusedDBLogs(JNIEnv * env,jobject jthis,jobject jpath,jobject jreceiver)222 Java_org_apache_subversion_javahl_SVNRepos_listUnusedDBLogs
223 (JNIEnv *env, jobject jthis, jobject jpath, jobject jreceiver)
224 {
225   JNIEntry(SVNRepos, listUnusedDBLogs);
226   SVNRepos *cl = SVNRepos::getCppObject(jthis);
227   if (cl == NULL)
228     {
229       JNIUtil::throwError(_("bad C++ this"));
230       return;
231     }
232 
233   File path(jpath);
234   if (JNIUtil::isExceptionThrown())
235     return;
236 
237   MessageReceiver mr(jreceiver);
238   if (JNIUtil::isExceptionThrown())
239     return;
240 
241   cl->listUnusedDBLogs(path, mr);
242 }
243 
244 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_load(JNIEnv * env,jobject jthis,jobject jpath,jobject jinputData,jobject jrevisionStart,jobject jrevisionEnd,jboolean jignoreUUID,jboolean jforceUUID,jboolean jusePreCommitHook,jboolean jusePostCommitHook,jboolean jvalidateProps,jboolean jignoreDates,jboolean jnormalizeProps,jstring jrelativePath,jobject jnotifyCallback)245 Java_org_apache_subversion_javahl_SVNRepos_load(
246     JNIEnv *env, jobject jthis, jobject jpath, jobject jinputData,
247     jobject jrevisionStart, jobject jrevisionEnd,
248     jboolean jignoreUUID, jboolean jforceUUID,
249     jboolean jusePreCommitHook, jboolean jusePostCommitHook,
250     jboolean jvalidateProps, jboolean jignoreDates, jboolean jnormalizeProps,
251     jstring jrelativePath, jobject jnotifyCallback)
252 {
253   JNIEntry(SVNRepos, load);
254   SVNRepos *cl = SVNRepos::getCppObject(jthis);
255   if (cl == NULL)
256     {
257       JNIUtil::throwError(_("bad C++ this"));
258       return;
259     }
260 
261   File path(jpath);
262   if (JNIUtil::isExceptionThrown())
263     return;
264 
265   InputStream inputData(jinputData);
266   if (JNIUtil::isExceptionThrown())
267     return;
268 
269   JNIStringHolder relativePath(jrelativePath);
270   if (JNIUtil::isExceptionThrown())
271     return;
272 
273   Revision revisionStart(jrevisionStart);
274   if (JNIUtil::isExceptionThrown())
275     return;
276 
277   Revision revisionEnd(jrevisionEnd, true);
278   if (JNIUtil::isExceptionThrown())
279     return;
280 
281   ReposNotifyCallback notifyCallback(jnotifyCallback);
282 
283   cl->load(path, inputData, revisionStart, revisionEnd,
284            jignoreUUID ? true : false,
285            jforceUUID ? true : false,
286            jusePreCommitHook ? true : false,
287            jusePostCommitHook ? true : false,
288            jvalidateProps ? true : false,
289            jignoreDates ? true : false,
290            jnormalizeProps ? true : false,
291            relativePath,
292            (jnotifyCallback != NULL ? &notifyCallback : NULL));
293 }
294 
295 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_lstxns(JNIEnv * env,jobject jthis,jobject jpath,jobject jmessageReceiver)296 Java_org_apache_subversion_javahl_SVNRepos_lstxns
297 (JNIEnv *env, jobject jthis, jobject jpath, jobject jmessageReceiver)
298 {
299   JNIEntry(SVNRepos, lstxns);
300   SVNRepos *cl = SVNRepos::getCppObject(jthis);
301   if (cl == NULL)
302     {
303       JNIUtil::throwError(_("bad C++ this"));
304       return;
305     }
306 
307   File path(jpath);
308   if (JNIUtil::isExceptionThrown())
309     return;
310 
311   MessageReceiver mr(jmessageReceiver);
312   if (JNIUtil::isExceptionThrown())
313     return;
314 
315   cl->lstxns(path, mr);
316 }
317 
318 JNIEXPORT jlong JNICALL
Java_org_apache_subversion_javahl_SVNRepos_recover(JNIEnv * env,jobject jthis,jobject jpath,jobject jnotifyCallback)319 Java_org_apache_subversion_javahl_SVNRepos_recover
320 (JNIEnv *env, jobject jthis, jobject jpath, jobject jnotifyCallback)
321 {
322   JNIEntry(SVNRepos, recover);
323   SVNRepos *cl = SVNRepos::getCppObject(jthis);
324   if (cl == NULL)
325     {
326       JNIUtil::throwError(_("bad C++ this"));
327       return -1;
328     }
329 
330   File path(jpath);
331   if (JNIUtil::isExceptionThrown())
332     return -1;
333 
334   ReposNotifyCallback callback(jnotifyCallback);
335 
336   return cl->recover(path, jnotifyCallback != NULL ? &callback : NULL);
337 }
338 
339 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_freeze(JNIEnv * env,jobject jthis,jobject jaction,jobjectArray jpaths)340 Java_org_apache_subversion_javahl_SVNRepos_freeze
341 (JNIEnv *env, jobject jthis, jobject jaction, jobjectArray jpaths)
342 {
343   JNIEntry(SVNRepos, freeze);
344   SVNRepos *cl = SVNRepos::getCppObject(jthis);
345   if (cl == NULL)
346     {
347       JNIUtil::throwError(_("bad C++ this"));
348       return;
349     }
350 
351   if (!jpaths || !env->GetArrayLength(jpaths))
352     {
353       JNIUtil::throwError(_("list of repository paths must not be empty"));
354       return;
355     }
356 
357   ReposFreezeAction action(jaction);
358   cl->freeze(jpaths, &action);
359 }
360 
361 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_rmtxns(JNIEnv * env,jobject jthis,jobject jpath,jobjectArray jtransactions)362 Java_org_apache_subversion_javahl_SVNRepos_rmtxns
363 (JNIEnv *env, jobject jthis, jobject jpath, jobjectArray jtransactions)
364 {
365   JNIEntry(SVNRepos, rmtxns);
366   SVNRepos *cl = SVNRepos::getCppObject(jthis);
367   if (cl == NULL)
368     {
369       JNIUtil::throwError(_("bad C++ this"));
370       return;
371     }
372 
373   File path(jpath);
374   if (JNIUtil::isExceptionThrown())
375     return;
376 
377   StringArray transactions(jtransactions);
378   if (JNIUtil::isExceptionThrown())
379     return;
380 
381   cl->rmtxns(path, transactions);
382 }
383 
384 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_setRevProp(JNIEnv * env,jobject jthis,jobject jpath,jobject jrevision,jstring jpropName,jstring jpropValue,jboolean jusePreRevPropChangeHook,jboolean jusePostRevPropChangeHook)385 Java_org_apache_subversion_javahl_SVNRepos_setRevProp
386 (JNIEnv *env, jobject jthis, jobject jpath, jobject jrevision,
387  jstring jpropName, jstring jpropValue, jboolean jusePreRevPropChangeHook,
388  jboolean jusePostRevPropChangeHook)
389 {
390   JNIEntry(SVNRepos, setRevProp);
391   SVNRepos *cl = SVNRepos::getCppObject(jthis);
392   if (cl == NULL)
393     {
394       JNIUtil::throwError(_("bad C++ this"));
395       return;
396     }
397 
398   File path(jpath);
399   if (JNIUtil::isExceptionThrown())
400     return;
401 
402   Revision revision(jrevision);
403   if (JNIUtil::isExceptionThrown())
404     return;
405 
406   JNIStringHolder propName(jpropName);
407   if (JNIUtil::isExceptionThrown())
408     return;
409 
410   JNIStringHolder propValue(jpropValue);
411   if (JNIUtil::isExceptionThrown())
412     return;
413 
414   cl->setRevProp(path, revision, propName, propValue,
415                  jusePreRevPropChangeHook ? true : false,
416                  jusePostRevPropChangeHook ? true : false);
417 }
418 
419 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_verify(JNIEnv * env,jobject jthis,jobject jpath,jobject jrevisionStart,jobject jrevisionEnd,jboolean jcheckNormalization,jboolean jmetadataOnly,jobject jnotifyCallback,jobject jverifyCallback)420 Java_org_apache_subversion_javahl_SVNRepos_verify(
421     JNIEnv *env, jobject jthis, jobject jpath,
422     jobject jrevisionStart, jobject jrevisionEnd,
423     jboolean jcheckNormalization, jboolean jmetadataOnly,
424     jobject jnotifyCallback, jobject jverifyCallback)
425 {
426   JNIEntry(SVNRepos, verify);
427   SVNRepos *cl = SVNRepos::getCppObject(jthis);
428   if (cl == NULL)
429     {
430       JNIUtil::throwError(_("bad C++ this"));
431       return;
432     }
433 
434   File path(jpath);
435   if (JNIUtil::isExceptionThrown())
436     return;
437 
438   Revision revisionStart(jrevisionStart);
439   if (JNIUtil::isExceptionThrown())
440     return;
441 
442   Revision revisionEnd(jrevisionEnd);
443   if (JNIUtil::isExceptionThrown())
444     return;
445 
446   ReposNotifyCallback notify_cb(jnotifyCallback);
447   if (JNIUtil::isExceptionThrown())
448     return;
449 
450   ReposVerifyCallback verify_cb(jverifyCallback);
451   if (JNIUtil::isExceptionThrown())
452     return;
453 
454   cl->verify(path, revisionStart, revisionEnd,
455              jcheckNormalization, jmetadataOnly,
456              jnotifyCallback != NULL ? &notify_cb : NULL,
457              jverifyCallback != NULL ? &verify_cb : NULL);
458 }
459 
460 JNIEXPORT jobject JNICALL
Java_org_apache_subversion_javahl_SVNRepos_lslocks(JNIEnv * env,jobject jthis,jobject jpath,jobject jdepth)461 Java_org_apache_subversion_javahl_SVNRepos_lslocks
462 (JNIEnv *env, jobject jthis, jobject jpath, jobject jdepth)
463 {
464   JNIEntry(SVNRepos, lslocks);
465   SVNRepos *cl = SVNRepos::getCppObject(jthis);
466   if (cl == NULL)
467     {
468       JNIUtil::throwError(_("bad C++ this"));
469       return NULL;
470     }
471 
472   File path(jpath);
473   if (JNIUtil::isExceptionThrown())
474     return NULL;
475 
476   return cl->lslocks(path, EnumMapper::toDepth(jdepth));
477 }
478 
479 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_rmlocks(JNIEnv * env,jobject jthis,jobject jpath,jobjectArray jlocks)480 Java_org_apache_subversion_javahl_SVNRepos_rmlocks
481 (JNIEnv *env, jobject jthis, jobject jpath, jobjectArray jlocks)
482 {
483   JNIEntry(SVNRepos, rmlocks);
484   SVNRepos *cl = SVNRepos::getCppObject(jthis);
485   if (cl == NULL)
486     {
487       JNIUtil::throwError(_("bad C++ this"));
488       return;
489     }
490 
491   File path(jpath);
492   if (JNIUtil::isExceptionThrown())
493     return;
494 
495   StringArray locks(jlocks);
496   if (JNIUtil::isExceptionThrown())
497     return;
498 
499   cl->rmlocks(path, locks);
500 }
501 
502 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_upgrade(JNIEnv * env,jobject jthis,jobject jpath,jobject jnotifyCallback)503 Java_org_apache_subversion_javahl_SVNRepos_upgrade
504 (JNIEnv *env, jobject jthis, jobject jpath, jobject jnotifyCallback)
505 {
506   JNIEntry(SVNRepos, upgrade);
507   SVNRepos *cl = SVNRepos::getCppObject(jthis);
508   if (cl == NULL)
509     {
510       JNIUtil::throwError(_("bad C++ this"));
511       return;
512     }
513 
514   File path(jpath);
515   if (JNIUtil::isExceptionThrown())
516     return;
517 
518   ReposNotifyCallback callback(jnotifyCallback);
519 
520   cl->upgrade(path, jnotifyCallback != NULL ? &callback : NULL);
521 }
522 
523 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_pack(JNIEnv * env,jobject jthis,jobject jpath,jobject jnotifyCallback)524 Java_org_apache_subversion_javahl_SVNRepos_pack
525 (JNIEnv *env, jobject jthis, jobject jpath, jobject jnotifyCallback)
526 {
527   JNIEntry(SVNRepos, pack);
528   SVNRepos *cl = SVNRepos::getCppObject(jthis);
529   if (cl == NULL)
530     {
531       JNIUtil::throwError(_("bad C++ this"));
532       return;
533     }
534 
535   File path(jpath);
536   if (JNIUtil::isExceptionThrown())
537     return;
538 
539   ReposNotifyCallback callback(jnotifyCallback);
540 
541   cl->pack(path, jnotifyCallback != NULL ? &callback : NULL);
542 }
543 
544 JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNRepos_cancelOperation(JNIEnv * env,jobject jthis)545 Java_org_apache_subversion_javahl_SVNRepos_cancelOperation
546 (JNIEnv *env, jobject jthis)
547 {
548   JNIEntry(SVNRepos, cancelOperation);
549   SVNRepos *cl = SVNRepos::getCppObject(jthis);
550   if (cl == NULL)
551     {
552       JNIUtil::throwError("bad C++ this");
553       return;
554     }
555   cl->cancelOperation();
556 }
557