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_util_SubstLib.cpp
24 * @brief Implementation of the native methods in the Java class SubstLib
25 */
26
27 #include <memory>
28
29 #include "../include/org_apache_subversion_javahl_util_SubstLib.h"
30
31 #include "jniwrapper/jni_stack.hpp"
32 #include "jniwrapper/jni_array.hpp"
33 #include "jniwrapper/jni_string.hpp"
34 #include "jniwrapper/jni_string_map.hpp"
35 #include "jniwrapper/jni_io_stream.hpp"
36
37 #include "JNIUtil.h"
38 #include "NativeStream.hpp"
39 #include "Utility.hpp"
40 #include "CxxCompat.hpp"
41
42 #include <apr_hash.h>
43
44 #include "svn_subst.h"
45
46 #include "svn_private_config.h"
47
48
49 namespace {
50 apr_hash_t*
build_keywords_common(Java::Env env,const SVN::Pool & pool,jbyteArray jkeywords_value,jlong jrevision,jstring jurl,jstring jrepos_root_url,jobject jdate,jstring jauthor)51 build_keywords_common(Java::Env env, const SVN::Pool& pool,
52 jbyteArray jkeywords_value, jlong jrevision,
53 jstring jurl, jstring jrepos_root_url,
54 jobject jdate, jstring jauthor)
55 {
56 const Java::ByteArray keywords_value(env, jkeywords_value);
57 const Java::String url(env, jurl);
58 const Java::String repos_root_url(env, jrepos_root_url);
59 const Java::String author(env, jauthor);
60
61 const Java::ByteArray::Contents keywords_contents(keywords_value);
62 svn_string_t* keywords_string = keywords_contents.get_string(pool);
63 const char* revision = (jrevision < 0 ? NULL
64 : apr_psprintf(pool.getPool(),
65 "%" APR_UINT64_T_FMT,
66 apr_uint64_t(jrevision)));
67 const Java::String::Contents url_contents(url);
68 const Java::String::Contents root_url_contents(repos_root_url);
69 const Java::String::Contents author_contents(author);
70
71 apr_hash_t* kw = NULL;
72 SVN_JAVAHL_CHECK(env,
73 svn_subst_build_keywords3(
74 &kw,
75 keywords_string->data,
76 revision,
77 url_contents.c_str(),
78 root_url_contents.c_str(),
79 (jdate ? JNIUtil::getDate(jdate) : 0),
80 author_contents.c_str(),
81 pool.getPool()));
82 return kw;
83 }
84
85 svn_stream_t*
translate_stream_common(Java::Env env,const SVN::Pool & pool,svn_stream_t * stream,jbyteArray jeol_marker,jboolean jrepair_eol,jobject jkeywords,jboolean juse_keywords,jboolean jexpand_keywords,jbyteArray jkeywords_value,jlong jrevision,jstring jurl,jstring jrepos_root_url,jobject jdate,jstring jauthor)86 translate_stream_common(Java::Env env, const SVN::Pool& pool,
87 svn_stream_t* stream,
88 jbyteArray jeol_marker, jboolean jrepair_eol,
89 jobject jkeywords, jboolean juse_keywords,
90 jboolean jexpand_keywords,
91 jbyteArray jkeywords_value, jlong jrevision,
92 jstring jurl, jstring jrepos_root_url,
93 jobject jdate, jstring jauthor)
94 {
95 apr_hash_t* const keywords =
96 (juse_keywords
97 ? JavaHL::Util::make_keyword_hash(env, jkeywords, pool)
98 : build_keywords_common(
99 env, pool, jkeywords_value, jrevision,
100 jurl, jrepos_root_url, jdate, jauthor));
101
102 const Java::ByteArray eol_marker(env, jeol_marker);
103 svn_string_t* const eol_str =
104 Java::ByteArray::Contents(eol_marker).get_string(pool);
105 return svn_subst_stream_translated(stream,
106 eol_str->data,
107 svn_boolean_t(jrepair_eol),
108 keywords,
109 svn_boolean_t(jexpand_keywords),
110 pool.getPool());
111 }
112 } // anoymous namespace
113
114
115 JNIEXPORT jobject JNICALL
Java_org_apache_subversion_javahl_util_SubstLib_buildKeywords(JNIEnv * jenv,jobject jthis,jbyteArray jkeywords_value,jlong jrevision,jstring jurl,jstring jrepos_root_url,jobject jdate,jstring jauthor)116 Java_org_apache_subversion_javahl_util_SubstLib_buildKeywords(
117 JNIEnv* jenv, jobject jthis,
118 jbyteArray jkeywords_value, jlong jrevision,
119 jstring jurl, jstring jrepos_root_url,
120 jobject jdate, jstring jauthor)
121 {
122 typedef Java::Map<Java::ByteArray, jbyteArray> ByteArrayMap;
123
124 SVN_JAVAHL_JNI_TRY(SubstLib, buildKeywords)
125 {
126 const Java::Env env(jenv);
127
128 // Using a "global" request pool since we don't keep a context with
129 // its own pool around for these functions.
130 SVN::Pool pool;
131
132 apr_hash_t* const kw = build_keywords_common(
133 env, pool, jkeywords_value, jrevision,
134 jurl, jrepos_root_url, jdate, jauthor);
135
136 ByteArrayMap keywords(env, jint(apr_hash_count(kw)));
137 for (apr_hash_index_t* hi = apr_hash_first(pool.getPool(), kw);
138 hi; hi = apr_hash_next(hi))
139 {
140 const void* rkey;
141 void* rval;
142 apr_hash_this(hi, &rkey, NULL, &rval);
143
144 svn_string_t* const val = static_cast<svn_string_t*>(rval);
145 keywords.put(static_cast<const char*>(rkey),
146 Java::ByteArray(env, val->data, jsize(val->len)));
147 }
148 return keywords.get();
149 }
150 SVN_JAVAHL_JNI_CATCH;
151 return NULL;
152 }
153
154
155 JNIEXPORT jobject JNICALL
Java_org_apache_subversion_javahl_util_SubstLib_translateInputStream(JNIEnv * jenv,jobject jthis,jobject jsource,jbyteArray jeol_marker,jboolean jrepair_eol,jobject jkeywords,jboolean juse_keywords,jboolean jexpand_keywords,jbyteArray jkeywords_value,jlong jrevision,jstring jurl,jstring jrepos_root_url,jobject jdate,jstring jauthor)156 Java_org_apache_subversion_javahl_util_SubstLib_translateInputStream(
157 JNIEnv* jenv, jobject jthis,
158 jobject jsource, jbyteArray jeol_marker, jboolean jrepair_eol,
159 jobject jkeywords, jboolean juse_keywords, jboolean jexpand_keywords,
160 jbyteArray jkeywords_value, jlong jrevision,
161 jstring jurl, jstring jrepos_root_url,
162 jobject jdate, jstring jauthor)
163 {
164 SVN_JAVAHL_JNI_TRY(SubstLib, translateInputStream)
165 {
166 const Java::Env env(jenv);
167
168 // We'll allocate the stream in the bound object's pool.
169 JavaHL::cxx::owned_ptr<JavaHL::NativeInputStream>
170 translated(new JavaHL::NativeInputStream());
171 svn_stream_t* source = Java::InputStream::get_global_stream(
172 env, jsource, translated->get_pool());
173
174 translated->set_stream(translate_stream_common(
175 env, translated->get_pool(), source,
176 jeol_marker, jrepair_eol,
177 jkeywords, juse_keywords, jexpand_keywords,
178 jkeywords_value, jrevision,
179 jurl, jrepos_root_url, jdate, jauthor));
180 const jobject jtranslated = translated->create_java_wrapper();
181 translated.release();
182 return jtranslated;
183 }
184 SVN_JAVAHL_JNI_CATCH;
185 return NULL;
186 }
187
188
189 JNIEXPORT jobject JNICALL
Java_org_apache_subversion_javahl_util_SubstLib_translateOutputStream(JNIEnv * jenv,jobject jthis,jobject jdestination,jbyteArray jeol_marker,jboolean jrepair_eol,jobject jkeywords,jboolean juse_keywords,jboolean jexpand_keywords,jbyteArray jkeywords_value,jlong jrevision,jstring jurl,jstring jrepos_root_url,jobject jdate,jstring jauthor)190 Java_org_apache_subversion_javahl_util_SubstLib_translateOutputStream(
191 JNIEnv* jenv, jobject jthis,
192 jobject jdestination, jbyteArray jeol_marker, jboolean jrepair_eol,
193 jobject jkeywords, jboolean juse_keywords, jboolean jexpand_keywords,
194 jbyteArray jkeywords_value, jlong jrevision,
195 jstring jurl, jstring jrepos_root_url,
196 jobject jdate, jstring jauthor)
197 {
198 SVN_JAVAHL_JNI_TRY(SubstLib, translateInputStream)
199 {
200 const Java::Env env(jenv);
201
202 // We'll allocate the stream in the bound object's pool.
203 JavaHL::cxx::owned_ptr<JavaHL::NativeOutputStream>
204 translated(new JavaHL::NativeOutputStream());
205 svn_stream_t* destination = Java::OutputStream::get_global_stream(
206 env, jdestination, translated->get_pool());
207
208 translated->set_stream(translate_stream_common(
209 env, translated->get_pool(), destination,
210 jeol_marker, jrepair_eol,
211 jkeywords, juse_keywords, jexpand_keywords,
212 jkeywords_value, jrevision,
213 jurl, jrepos_root_url, jdate, jauthor));
214 const jobject jtranslated = translated->create_java_wrapper();
215 translated.release();
216 return jtranslated;
217 }
218 SVN_JAVAHL_JNI_CATCH;
219 return NULL;
220 }
221