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 DiffSummaryReceiver.cpp
24  * @brief Implementation of the class DiffSummaryReceiver
25  */
26 
27 #include "JNIUtil.h"
28 #include "EnumMapper.h"
29 #include "DiffSummaryReceiver.h"
30 
DiffSummaryReceiver(jobject jreceiver)31 DiffSummaryReceiver::DiffSummaryReceiver(jobject jreceiver)
32 {
33   m_receiver = jreceiver;
34 }
35 
~DiffSummaryReceiver()36 DiffSummaryReceiver::~DiffSummaryReceiver()
37 {
38   // m_receiver does not need to be destroyed, because it is a
39   // parameter to the Java SVNClient.diffSummarize() method, and
40   // thus not explicitly managed.
41 }
42 
43 svn_error_t *
summarize(const svn_client_diff_summarize_t * diff,void * baton,apr_pool_t * pool)44 DiffSummaryReceiver::summarize(const svn_client_diff_summarize_t *diff,
45                                void *baton,
46                                apr_pool_t *pool)
47 {
48   if (baton)
49     return static_cast<DiffSummaryReceiver *>(baton)->onSummary(diff, pool);
50 
51   return SVN_NO_ERROR;
52 }
53 
54 svn_error_t *
onSummary(const svn_client_diff_summarize_t * diff,apr_pool_t * pool)55 DiffSummaryReceiver::onSummary(const svn_client_diff_summarize_t *diff,
56                                apr_pool_t *pool)
57 {
58   JNIEnv *env = JNIUtil::getEnv();
59 
60   // Create a local frame for our references
61   env->PushLocalFrame(LOCAL_FRAME_SIZE);
62   if (JNIUtil::isJavaExceptionThrown())
63     return SVN_NO_ERROR;
64 
65   // As Java method IDs will not change during the time this library
66   // is loaded, they can be cached.
67   static jmethodID callback = 0;
68   jclass clazz;
69   if (callback == 0)
70     {
71       // Initialize the method ID.
72       clazz = env->FindClass(JAVAHL_CLASS("/callback/DiffSummaryCallback"));
73       if (JNIUtil::isJavaExceptionThrown())
74         POP_AND_RETURN(SVN_NO_ERROR);
75 
76       callback = env->GetMethodID(clazz, "onSummary",
77                                   "(" JAVAHL_ARG("/DiffSummary;") ")V");
78       if (JNIUtil::isJavaExceptionThrown() || callback == 0)
79         POP_AND_RETURN(SVN_NO_ERROR);
80     }
81 
82   // Do some prep work for tranforming the DIFF parameter into a
83   // Java equivalent.
84   static jmethodID ctor = 0;
85   clazz = env->FindClass(JAVAHL_CLASS("/DiffSummary"));
86   if (JNIUtil::isJavaExceptionThrown())
87     POP_AND_RETURN(SVN_NO_ERROR);
88 
89   if (ctor == 0)
90     {
91       ctor = env->GetMethodID(clazz, "<init>",
92                               "(Ljava/lang/String;"
93                               JAVAHL_ARG("/DiffSummary$DiffKind;") "Z"
94                               JAVAHL_ARG("/types/NodeKind;") ")V");
95       if (JNIUtil::isJavaExceptionThrown() || ctor == 0)
96         POP_AND_RETURN(SVN_NO_ERROR);
97     }
98   // Convert the arguments into their Java equivalent,
99   jstring jPath = JNIUtil::makeJString(diff->path);
100   if (JNIUtil::isJavaExceptionThrown())
101     POP_AND_RETURN(SVN_NO_ERROR);
102 
103   jobject jNodeKind = EnumMapper::mapNodeKind(diff->node_kind);
104   if (JNIUtil::isJavaExceptionThrown())
105     POP_AND_RETURN(SVN_NO_ERROR);
106 
107   jobject jSummarizeKind = EnumMapper::mapSummarizeKind(diff->summarize_kind);
108   if (JNIUtil::isJavaExceptionThrown())
109     POP_AND_RETURN(SVN_NO_ERROR);
110 
111   // Actually tranform the DIFF parameter into a Java equivalent.
112   jobject jDiffSummary = env->NewObject(clazz, ctor, jPath, jSummarizeKind,
113                                         (jboolean) diff->prop_changed,
114                                         jNodeKind);
115   if (JNIUtil::isJavaExceptionThrown() || jDiffSummary == NULL)
116     POP_AND_RETURN(SVN_NO_ERROR);
117 
118   // Invoke the Java DiffSummaryReceiver callback.
119   env->CallVoidMethod(m_receiver, callback, jDiffSummary);
120   POP_AND_RETURN_EXCEPTION_AS_SVNERROR();
121 }
122