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_connectivity.hxx"
26 
27 #include "java/ContextClassLoader.hxx"
28 #include "java/lang/Object.hxx"
29 
30 /** === begin UNO includes === **/
31 /** === end UNO includes === **/
32 
33 //........................................................................
34 namespace connectivity { namespace jdbc
35 {
36 //........................................................................
37 
38 	/** === begin UNO using === **/
39     using ::com::sun::star::uno::Reference;
40     using ::com::sun::star::uno::XInterface;
41 	/** === end UNO using === **/
42 
43     using ::connectivity::java_lang_Object;
44 
45 	//====================================================================
46 	//= ContextClassLoaderScope
47 	//====================================================================
48 	//--------------------------------------------------------------------
ContextClassLoaderScope(JNIEnv & environment,const GlobalRef<jobject> & newClassLoader,const::comphelper::ResourceBasedEventLogger & _rLoggerForErrors,const Reference<XInterface> & _rxErrorContext)49     ContextClassLoaderScope::ContextClassLoaderScope( JNIEnv& environment, const GlobalRef< jobject >& newClassLoader,
50         const ::comphelper::ResourceBasedEventLogger& _rLoggerForErrors, const Reference< XInterface >& _rxErrorContext )
51         :m_environment( environment )
52         ,m_currentThread( environment )
53         ,m_oldContextClassLoader( environment )
54     {
55         if ( !newClassLoader.is() )
56             return;
57 
58         do  // artificial loop for easier flow control
59         {
60 
61         LocalRef< jclass > threadClass( m_environment );
62         threadClass.set( m_environment.FindClass( "java/lang/Thread" ) );
63         if ( !threadClass.is() )
64             break;
65 
66         jmethodID currentThreadMethod( m_environment.GetStaticMethodID(
67             threadClass.get(), "currentThread", "()Ljava/lang/Thread;" ) );
68         if ( currentThreadMethod == NULL )
69             break;
70 
71         m_currentThread.set( m_environment.CallStaticObjectMethod( threadClass.get(), currentThreadMethod ) );
72         if ( !m_currentThread.is() )
73             break;
74 
75         jmethodID getContextClassLoaderMethod( m_environment.GetMethodID(
76             threadClass.get(), "getContextClassLoader", "()Ljava/lang/ClassLoader;" ) );
77         if ( getContextClassLoaderMethod == NULL )
78             break;
79         m_oldContextClassLoader.set( m_environment.CallObjectMethod( m_currentThread.get(), getContextClassLoaderMethod ) );
80         LocalRef< jthrowable > throwable( m_environment, m_environment.ExceptionOccurred() );
81         if ( throwable.is() )
82             break;
83 
84         m_setContextClassLoaderMethod = m_environment.GetMethodID(
85             threadClass.get(), "setContextClassLoader", "(Ljava/lang/ClassLoader;)V" );
86         if ( m_setContextClassLoaderMethod == NULL )
87             break;
88 
89         }
90         while ( false );
91 
92         if ( !isActive() )
93         {
94             java_lang_Object::ThrowLoggedSQLException( _rLoggerForErrors, &environment, _rxErrorContext );
95             return;
96         }
97 
98         // set the new class loader
99         m_environment.CallObjectMethod( m_currentThread.get(), m_setContextClassLoaderMethod, newClassLoader.get() );
100         LocalRef< jthrowable > throwable( m_environment, m_environment.ExceptionOccurred() );
101         if ( throwable.is() )
102         {
103             m_currentThread.reset();
104             m_setContextClassLoaderMethod = NULL;
105             java_lang_Object::ThrowLoggedSQLException( _rLoggerForErrors, &environment, _rxErrorContext );
106         }
107     }
108 
109 	//--------------------------------------------------------------------
pop(bool clearExceptions)110     void ContextClassLoaderScope::pop( bool clearExceptions )
111     {
112         if ( isActive() )
113         {
114             LocalRef< jobject > currentThread( m_currentThread.env(), m_currentThread.release() );
115             jmethodID setContextClassLoaderMethod( m_setContextClassLoaderMethod );
116             m_setContextClassLoaderMethod = NULL;
117 
118             m_environment.CallObjectMethod( currentThread.get(), setContextClassLoaderMethod, m_oldContextClassLoader.get() );
119             if ( clearExceptions )
120             {
121                 m_environment.ExceptionClear();
122             }
123         }
124     }
125 //........................................................................
126 } } // namespace connectivity::jdbc
127 //........................................................................
128