1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_javaunohelper.hxx"
26 
27 #include "osl/diagnose.h"
28 
29 #include "rtl/alloc.h"
30 #include "rtl/bootstrap.hxx"
31 #include "rtl/string.hxx"
32 
33 #include "uno/mapping.hxx"
34 #include "uno/environment.hxx"
35 
36 #include "cppuhelper/bootstrap.hxx"
37 
38 #include "com/sun/star/lang/XComponent.hpp"
39 #include "com/sun/star/lang/XSingleComponentFactory.hpp"
40 
41 #include "jni.h"
42 #include "jvmaccess/virtualmachine.hxx"
43 #include "jvmaccess/unovirtualmachine.hxx"
44 
45 #include "vm.hxx"
46 
47 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
48 
49 
50 using namespace ::com::sun::star;
51 using namespace ::com::sun::star::uno;
52 using ::rtl::OString;
53 using ::rtl::OUString;
54 
55 namespace javaunohelper
56 {
57 
jstring_to_oustring(jstring jstr,JNIEnv * jni_env)58 inline ::rtl::OUString jstring_to_oustring( jstring jstr, JNIEnv * jni_env )
59 {
60     OSL_ASSERT( sizeof (sal_Unicode) == sizeof (jchar) );
61     jsize len = jni_env->GetStringLength( jstr );
62     rtl_uString * ustr =
63         (rtl_uString *)rtl_allocateMemory( sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) );
64     jni_env->GetStringRegion( jstr, 0, len, ustr->buffer );
65     OSL_ASSERT( JNI_FALSE == jni_env->ExceptionCheck() );
66     ustr->refCount = 1;
67     ustr->length = len;
68     ustr->buffer[ len ] = '\0';
69     return ::rtl::OUString( ustr, SAL_NO_ACQUIRE );
70 }
71 
72 }
73 
74 //==================================================================================================
Java_com_sun_star_comp_helper_Bootstrap_cppuhelper_1bootstrap(JNIEnv * jni_env,jclass,jstring juno_rc,jobjectArray jpairs,jobject loader)75 extern "C" JNIEXPORT jobject JNICALL Java_com_sun_star_comp_helper_Bootstrap_cppuhelper_1bootstrap(
76     JNIEnv * jni_env, jclass, jstring juno_rc, jobjectArray jpairs,
77     jobject loader )
78 {
79     try
80     {
81         if (0 != jpairs)
82         {
83             jsize nPos = 0, len = jni_env->GetArrayLength( jpairs );
84             while (nPos < len)
85             {
86                 // name
87                 jstring jstr = (jstring)jni_env->GetObjectArrayElement( jpairs, nPos );
88                 if (JNI_FALSE != jni_env->ExceptionCheck())
89                 {
90                     jni_env->ExceptionClear();
91                     throw RuntimeException(
92                         OUSTR("index out of bounds?!"), Reference< XInterface >() );
93                 }
94                 if (0 != jstr)
95                 {
96                     OUString name( ::javaunohelper::jstring_to_oustring( jstr, jni_env ) );
97                     // value
98                     jstr = (jstring)jni_env->GetObjectArrayElement( jpairs, nPos +1 );
99                     if (JNI_FALSE != jni_env->ExceptionCheck())
100                     {
101                         jni_env->ExceptionClear();
102                         throw RuntimeException(
103                             OUSTR("index out of bounds?!"), Reference< XInterface >() );
104                     }
105                     if (0 != jstr)
106                     {
107                         OUString value( ::javaunohelper::jstring_to_oustring( jstr, jni_env ) );
108 
109                         // set bootstrap parameter
110                         ::rtl::Bootstrap::set( name, value );
111                     }
112                 }
113                 nPos += 2;
114             }
115         }
116 
117         // bootstrap uno
118         Reference< XComponentContext > xContext;
119         if (0 == juno_rc)
120         {
121             xContext = ::cppu::defaultBootstrap_InitialComponentContext();
122         }
123         else
124         {
125             OUString uno_rc( ::javaunohelper::jstring_to_oustring( juno_rc, jni_env ) );
126             xContext = ::cppu::defaultBootstrap_InitialComponentContext( uno_rc );
127         }
128 
129         // create vm access
130         ::rtl::Reference< ::jvmaccess::UnoVirtualMachine > vm_access(
131             ::javaunohelper::create_vm_access( jni_env, loader ) );
132         // wrap vm singleton entry
133         xContext = ::javaunohelper::install_vm_singleton( xContext, vm_access );
134 
135         // get uno envs
136 	    OUString cpp_env_name = OUSTR(CPPU_CURRENT_LANGUAGE_BINDING_NAME);
137         OUString java_env_name = OUSTR(UNO_LB_JAVA);
138         Environment java_env, cpp_env;
139 	    uno_getEnvironment((uno_Environment **)&cpp_env, cpp_env_name.pData, NULL);
140         uno_getEnvironment( (uno_Environment **)&java_env, java_env_name.pData, vm_access.get() );
141 
142         // map to java
143         Mapping mapping( cpp_env.get(), java_env.get() );
144         if (! mapping.is())
145         {
146             Reference< lang::XComponent > xComp( xContext, UNO_QUERY );
147             if (xComp.is())
148                 xComp->dispose();
149             throw RuntimeException(
150                 OUSTR("cannot get mapping C++ <-> Java!"),
151                 Reference< XInterface >() );
152         }
153 
154         jobject jret = (jobject)mapping.mapInterface( xContext.get(), ::getCppuType( &xContext ) );
155         jobject jlocal = jni_env->NewLocalRef( jret );
156         jni_env->DeleteGlobalRef( jret );
157 
158         return jlocal;
159     }
160     catch (RuntimeException & exc)
161     {
162         jclass c = jni_env->FindClass( "com/sun/star/uno/RuntimeException" );
163         if (0 != c)
164         {
165             OString cstr( ::rtl::OUStringToOString(
166                               exc.Message, RTL_TEXTENCODING_JAVA_UTF8 ) );
167             OSL_TRACE( __FILE__": forwarding RuntimeException: %s", cstr.getStr() );
168             jni_env->ThrowNew( c, cstr.getStr() );
169         }
170     }
171     catch (Exception & exc)
172     {
173         jclass c = jni_env->FindClass( "com/sun/star/uno/Exception" );
174         if (0 != c)
175         {
176             OString cstr( ::rtl::OUStringToOString(
177                               exc.Message, RTL_TEXTENCODING_JAVA_UTF8 ) );
178             OSL_TRACE( __FILE__": forwarding Exception: %s", cstr.getStr() );
179             jni_env->ThrowNew( c, cstr.getStr() );
180         }
181     }
182 
183     return 0;
184 }
185 
186