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 
24 
25 #ifndef SVN_JAVAHL_JNIWRAPPER_EXCEPTION_HPP
26 #define SVN_JAVAHL_JNIWRAPPER_EXCEPTION_HPP
27 
28 #include "jni_env.hpp"
29 #include "jni_object.hpp"
30 
31 namespace Java {
32 
33 /**
34  * Base class for all exception generators, and generator class for
35  * exceptions of type @c java.lang.Throwable.
36  *
37  * The associated JNI class reference is stored for the lifetime of
38  * the JVM in the global class cache.
39  *
40  * @since New in 1.9.
41  */
42 class Exception
43 {
44 public:
45   /**
46    * Constructs a wrapper for the @c jthrowable object @a exc.
47    */
Exception(Env env,jthrowable exc)48   explicit Exception(Env env, jthrowable exc)
49     : m_env(env),
50       m_jthis(exc),
51       m_class(env.GetObjectClass(exc))
52     {}
53 
54   /**
55    * Raises a Java exception of the concrete class, and throws a
56    * native exception at the same time.
57    *
58    * It is an error to call this method if an existing @c jthrowable
59    * object was wrapped.
60    */
raise() const61   void raise() const
62     {
63       throw_java_exception();
64       throw SignalExceptionThrown();
65     }
66 
67   /**
68    * Raises a Java exception of the concrete class with the givem
69    * @a message, and throws a native exception at the same time.
70    *
71    * It is an error to call this method if an existing @c jthrowable
72    * object was wrapped.
73    */
raise(const char * message) const74   void raise(const char* message) const
75     {
76       throw_java_exception(message);
77       throw SignalExceptionThrown();
78     }
79 
80   /**
81    * Raises a Java exception of the concrete class, but does not throw
82    * a native exception.
83    *
84    * It is an error to call this method if an existing @c jthrowable
85    * object was wrapped.
86    */
87   void throw_java_exception() const;
88 
89   /**
90    * Raises a Java exception of the concrete class with the given
91    * @a message, but does not throw a native exception.
92    *
93    * It is an error to call this method if an existing @c jthrowable
94    * object was wrapped.
95    */
96   void throw_java_exception(const char* message) const;
97 
98   /**
99    * Checks if an existing @c jthrowable object was wrapped.
100    */
instantiated() const101   bool instantiated() const
102     {
103       return (m_jthis != NULL);
104     }
105 
106   /**
107    * Returns the wrapped @c jthrowable object.
108    */
throwable() const109   jthrowable throwable() const
110     {
111       return m_jthis;
112     }
113 
114   /**
115    * Wrapper for the Java method @c getMessage().
116    * Only valid if an existing @c jthrowable object was wrapped.
117    */
118   jstring get_message() const;
119 
120 
121   /**
122    * Returns the wrapped exception instance.
123    */
get() const124   jobject get() const
125     {
126       return m_jthis;
127     }
128 
129   /**
130    * Returns the wrapped exception class.
131    */
get_class() const132   jclass get_class() const
133     {
134       return m_class;
135     }
136 
137   /**
138    * Returns the wrapped enviromnment reference.
139    */
get_env() const140   Env get_env() const
141     {
142       return m_env;
143     }
144 
145 protected:
146   /**
147    * Constructs an exception generator with the concrete class
148    * @a class_name.
149    */
Exception(Env env,const char * class_name)150   explicit Exception(Env env, const char* class_name)
151     : m_env(env),
152       m_jthis(NULL),
153       m_class(env.FindClass(class_name))
154     {}
155 
156   /**
157    * Constructs an exception generator with the concrete class @a cls.
158    */
Exception(Env env,const Object::ClassImpl * impl)159   explicit Exception(Env env, const Object::ClassImpl* impl)
160     : m_env(env),
161       m_jthis(NULL),
162       m_class(impl->get_class())
163     {}
164 
165 private:
166   /**
167    * This object's implementation details.
168    */
169   class ClassImpl : public Object::ClassImpl
170   {
171     friend class ClassCacheImpl;
172 
173   protected:
ClassImpl(Env env,jclass cls)174     explicit ClassImpl(Env env, jclass cls)
175       : Object::ClassImpl(env, cls)
176       {}
177 
178   public:
179     virtual ~ClassImpl();
180   };
181 
182   const Env m_env;
183   jthrowable m_jthis;
184   jclass m_class;
185 
186   friend class ClassCacheImpl;
187   static void static_init(Env env, jclass cls);
188   static const char* const m_class_name;
189   static MethodID m_mid_get_message;
190 };
191 
192 /**
193  * Generator class for exceptions of type @c java.lang.RuntimeException.
194  *
195  * @since New in 1.9.
196  */
197 class RuntimeException : public Exception
198 {
199 public:
200   /**
201    * Constructs an exception generator object.
202    */
RuntimeException(Env env)203   explicit RuntimeException(Env env)
204     : Exception(env, m_class_name)
205     {}
206 
207 private:
208   static const char* const m_class_name;
209 };
210 
211 
212 /**
213  * Generator class for exceptions of type @c java.lang.NullPointerException.
214  *
215  * @since New in 1.9.
216  */
217 class NullPointerException : public Exception
218 {
219 public:
220   /**
221    * Constructs an exception generator object.
222    */
NullPointerException(Env env)223   explicit NullPointerException(Env env)
224     : Exception(env, m_class_name)
225     {}
226 
227 private:
228   static const char* const m_class_name;
229 };
230 
231 /**
232  * Generator class for exceptions of type @c java.lang.OutOfMemoryError.
233  *
234  * @since New in 1.9.
235  */
236 class OutOfMemoryError : public Exception
237 {
238 public:
239   /**
240    * Constructs an exception generator object.
241    */
OutOfMemoryError(Env env)242   explicit OutOfMemoryError(Env env)
243     : Exception(env, m_class_name)
244     {}
245 
246 private:
247   static const char* const m_class_name;
248 };
249 
250 /**
251  * Generator class for exceptions of type
252  * @c java.lang.IndexOutOfBoundsException.
253  *
254  * @since New in 1.9.
255  */
256 class IndexOutOfBoundsException : public Exception
257 {
258 public:
259   /**
260    * Constructs an exception generator object.
261    */
IndexOutOfBoundsException(Env env)262   explicit IndexOutOfBoundsException(Env env)
263     : Exception(env, m_class_name)
264     {}
265 
266 private:
267   /**
268    * This object's implementation details.
269    */
270   class ClassImpl : public Object::ClassImpl
271   {
272     friend class ClassCacheImpl;
273 
274   protected:
ClassImpl(Env env,jclass cls)275     explicit ClassImpl(Env env, jclass cls)
276       : Object::ClassImpl(env, cls)
277       {}
278 
279   public:
280     virtual ~ClassImpl();
281   };
282 
283   friend class ClassCacheImpl;
284   static const char* const m_class_name;
285 };
286 
287 /**
288  * Generator class for exceptions of type @c java.io.IOException.
289  *
290  * @since New in 1.9.
291  */
292 class IOException : public Exception
293 {
294 public:
295   /**
296    * Constructs an exception generator object.
297    */
IOException(Env env)298   explicit IOException(Env env)
299     : Exception(env, m_class_name)
300     {}
301 
302 private:
303   static const char* const m_class_name;
304 };
305 
306 /**
307  * Generator class for exceptions of type @c java.lang.IllegalArgumentException.
308  *
309  * @since New in 1.9.
310  */
311 class IllegalArgumentException : public Exception
312 {
313 public:
314   /**
315    * Constructs an exception generator object.
316    */
IllegalArgumentException(Env env)317   explicit IllegalArgumentException(Env env)
318     : Exception(env, m_class_name)
319     {}
320 
321 private:
322   static const char* const m_class_name;
323 };
324 
325 /**
326  * Generator class for exceptions of type
327  * @c java.util.NoSuchElementException.
328  *
329  * @since New in 1.9.
330  */
331 class NoSuchElementException : public Exception
332 {
333 public:
334   /**
335    * Constructs an exception generator object.
336    */
NoSuchElementException(Env env)337   explicit NoSuchElementException(Env env)
338     : Exception(env, m_class_name)
339     {}
340 
341 private:
342   /**
343    * This object's implementation details.
344    */
345   class ClassImpl : public Object::ClassImpl
346   {
347     friend class ClassCacheImpl;
348 
349   protected:
ClassImpl(Env env,jclass cls)350     explicit ClassImpl(Env env, jclass cls)
351       : Object::ClassImpl(env, cls)
352       {}
353 
354   public:
355     virtual ~ClassImpl();
356   };
357 
358   friend class ClassCacheImpl;
359   static const char* const m_class_name;
360 };
361 
362 } // namespace Java
363 
364 #endif // SVN_JAVAHL_JNIWRAPPER_EXCEPTION_HPP
365