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 RevisionRange.cpp
24 * @brief Implementation of the class RevisionRange.
25 */
26
27 #include <apr_pools.h>
28 #include "svn_client.h"
29 #include "svn_types.h"
30
31 #include "JNIUtil.h"
32 #include "RevisionRange.h"
33 #include "Revision.h"
34 #include "Pool.h"
35
RevisionRange(jobject jrevisionRange)36 RevisionRange::RevisionRange(jobject jrevisionRange)
37 {
38 m_range = jrevisionRange;
39 }
40
~RevisionRange()41 RevisionRange::~RevisionRange()
42 {
43 // m_range is assume to be managed externally, and thus is not
44 // explicitly destroyed.
45 }
46
47 namespace {
get_range_info(jobject jrange,svn_opt_revision_t * range_start,svn_opt_revision_t * range_end,svn_boolean_t * range_inheritable)48 void get_range_info(jobject jrange,
49 svn_opt_revision_t* range_start,
50 svn_opt_revision_t* range_end,
51 svn_boolean_t* range_inheritable)
52 {
53 JNIEnv *env = JNIUtil::getEnv();
54
55 jclass clazz = env->FindClass(JAVAHL_CLASS("/types/RevisionRange"));
56 if (JNIUtil::isExceptionThrown())
57 return;
58
59 if (range_start)
60 {
61
62 static jmethodID fmid = 0;
63 if (fmid == 0)
64 {
65 fmid = env->GetMethodID(clazz, "getFromRevision",
66 "()" JAVAHL_ARG("/types/Revision;"));
67 if (JNIUtil::isJavaExceptionThrown())
68 return;
69 }
70
71 jobject jstartRevision = env->CallObjectMethod(jrange, fmid);
72 if (JNIUtil::isExceptionThrown())
73 return;
74
75 Revision startRevision(jstartRevision);
76 if (JNIUtil::isExceptionThrown())
77 return;
78
79 *range_start = *startRevision.revision();
80 if (JNIUtil::isExceptionThrown())
81 return;
82 }
83
84 if (range_end)
85 {
86 static jmethodID tmid = 0;
87 if (tmid == 0)
88 {
89 tmid = env->GetMethodID(clazz, "getToRevision",
90 "()" JAVAHL_ARG("/types/Revision;"));
91 if (JNIUtil::isJavaExceptionThrown())
92 return;
93 }
94
95 jobject jendRevision = env->CallObjectMethod(jrange, tmid);
96 if (JNIUtil::isExceptionThrown())
97 return;
98
99 Revision endRevision(jendRevision);
100 if (JNIUtil::isExceptionThrown())
101 return;
102
103 *range_end = *endRevision.revision();
104 if (JNIUtil::isExceptionThrown())
105 return;
106 }
107
108 if (range_inheritable)
109 {
110 static jmethodID imid = 0;
111 if (imid == 0 && range_inheritable)
112 {
113 imid = env->GetMethodID(clazz, "isInheritable", "()Z");
114 if (JNIUtil::isJavaExceptionThrown())
115 return;
116 }
117
118 jboolean inheritable = env->CallBooleanMethod(jrange, imid);
119 if (JNIUtil::isExceptionThrown())
120 return;
121 *range_inheritable = inheritable;
122 }
123 }
124 } // anonymous namespace
125
toMergeRange(SVN::Pool & pool) const126 svn_merge_range_t* RevisionRange::toMergeRange(SVN::Pool &pool) const
127 {
128 svn_opt_revision_t range_start, range_end;
129 svn_boolean_t range_inheritable;
130 get_range_info(m_range, &range_start, &range_end, &range_inheritable);
131 if (JNIUtil::isExceptionThrown())
132 return NULL;
133
134 if (range_start.kind != svn_opt_revision_number
135 || range_end.kind != svn_opt_revision_number)
136 JNIUtil::raiseThrowable("java.lang.InvalidStateException",
137 "Revsision ranges must contain revision numbers");
138
139 svn_merge_range_t* range =
140 static_cast<svn_merge_range_t*>
141 (apr_palloc(pool.getPool(), sizeof(*range)));
142
143 range->start = range_start.value.number;
144 range->end = range_end.value.number;
145 range->inheritable = range_inheritable;
146 return range;
147 }
148
toRange(SVN::Pool & pool) const149 svn_opt_revision_range_t *RevisionRange::toRange(SVN::Pool &pool) const
150 {
151 svn_opt_revision_range_t *range =
152 static_cast<svn_opt_revision_range_t *>
153 (apr_palloc(pool.getPool(), sizeof(*range)));
154
155 get_range_info(m_range, &range->start, &range->end, NULL);
156 if (JNIUtil::isExceptionThrown())
157 range = NULL;
158 return range;
159 }
160
161 jobject
makeJRevisionRange(svn_merge_range_t * range)162 RevisionRange::makeJRevisionRange(svn_merge_range_t *range)
163 {
164 JNIEnv *env = JNIUtil::getEnv();
165
166 jclass rangeClazz = env->FindClass(JAVAHL_CLASS("/types/RevisionRange"));
167 if (JNIUtil::isJavaExceptionThrown())
168 return NULL;
169 static jmethodID rangeCtor = 0;
170 if (rangeCtor == 0)
171 {
172 rangeCtor = env->GetMethodID(rangeClazz, "<init>", "(JJZ)V");
173 if (JNIUtil::isJavaExceptionThrown())
174 return NULL;
175 }
176 jobject jrange = env->NewObject(rangeClazz, rangeCtor,
177 jlong(range->start),
178 jlong(range->end),
179 jboolean(range->inheritable));
180 if (JNIUtil::isJavaExceptionThrown())
181 return NULL;
182
183 return jrange;
184 }
185