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 package com.sun.star.lib.uno.environments.remote;
25 
26 
27 import java.io.PrintWriter;
28 import java.io.StringWriter;
29 
30 
31 import java.lang.reflect.InvocationTargetException;
32 
33 import com.sun.star.lib.uno.typedesc.MethodDescription;
34 import com.sun.star.uno.Any;
35 import com.sun.star.uno.IMethodDescription;
36 import com.sun.star.uno.Type;
37 import com.sun.star.uno.UnoRuntime;
38 import com.sun.star.uno.XCurrentContext;
39 
40 /**
41  * The Job is an abstraction for tasks which have to be done
42  * remotely because of a method invocation.
43  * <p>
44  * @version 	$Revision: 1.17 $ $ $Date: 2008-04-11 11:21:00 $
45  * @author 	    Kay Ramme
46  * @see         com.sun.star.lib.uno.environments.remote.ThreadID
47  * @see         com.sun.star.lib.uno.environments.remote.IReceiver
48  * @since       UDK1.0
49  */
50 public class Job {
51 	protected Job _next;
52 
53 	protected IReceiver _iReceiver;
54 	protected Message  _iMessage;
55 	          Object    _disposeId;
56 
57 	protected Object    _object;
58 
Job(Object object, IReceiver iReceiver, Message iMessage)59 	public Job(Object object, IReceiver iReceiver, Message iMessage) {
60 		_object       = object;
61 		_iReceiver    = iReceiver;
62 		_iMessage     = iMessage;
63 	}
64 
65 	/**
66 	 * Dispatches a <code>queryInterface</code> call
67 	 * <p>
68 	 * @return  the result of the call (should be an <code>Any</code>)
69 	 * @param message       the parameter for the call
70 	 * @param resultClass   the result type as an out parameter
71 	 * @param status        the status as an out parameter
72 	 * @param o_outs        the out parameters of the call as out parameters
73 	 * @param o_out_sig     the out signature as an out parameter
74 	 */
dispatch_queryInterface(Type type)75 	protected Object dispatch_queryInterface(Type type) {
76 		Class zInterface = type.getTypeDescription().getZClass();
77 
78 		Object result = null;
79 
80 		Object face = UnoRuntime.queryInterface(zInterface, _object);
81 		// the hell knows why, but empty interfaces a given back as void anys
82 		if(face != null)
83 			result = new Any(type, face);
84 		return result;
85 	}
86 
87     /**
88      * Execute the job.
89      *
90      * @return the result of the message.
91      */
execute()92     public Object execute() throws Throwable {
93         Object msgResult = _iMessage.getResult();
94         if (_iMessage.isRequest()) {
95             Object result = null;
96             Throwable exception = null;
97             IMethodDescription md = _iMessage.getMethod();
98             Object[] args = _iMessage.getArguments();
99             XCurrentContext oldCC = UnoRuntime.getCurrentContext();
100             UnoRuntime.setCurrentContext(_iMessage.getCurrentContext());
101             try {
102                 result = md.getIndex() == MethodDescription.ID_QUERY_INTERFACE
103                     ? dispatch_queryInterface((Type) args[0])
104                     : md.getMethod().invoke(_object, args);
105             } catch (InvocationTargetException e) {
106                 exception = e.getTargetException();
107                 if (exception == null) {
108                     exception = e;
109                 }
110             } catch (Exception e) {
111                 exception = e;
112             } finally {
113                 UnoRuntime.setCurrentContext(oldCC);
114             }
115             if (_iMessage.isSynchronous()) {
116                 if (exception == null) {
117                     _iReceiver.sendReply(
118                         false, _iMessage.getThreadId(), result);
119                 } else {
120                     // Here we have to be aware of non-UNO exceptions, because
121                     // they may kill a remote side which does not know anything
122                     // about their types:
123                     if (exception != null
124                         && !(exception instanceof com.sun.star.uno.Exception)
125                         && !(exception instanceof
126                              com.sun.star.uno.RuntimeException))
127                     {
128                         StringWriter writer = new StringWriter();
129                         exception.printStackTrace(new PrintWriter(writer));
130                         exception = new com.sun.star.uno.RuntimeException(
131                             "Java exception: <" + writer + ">", null);
132                     }
133                     _iReceiver.sendReply(
134                         true, _iMessage.getThreadId(), exception);
135                 }
136             }
137             return null;
138         } else if (_iMessage.isAbnormalTermination()) {
139             throw remoteUnoRequestRaisedException(_iMessage.getResult());
140         } else {
141             return _iMessage.getResult();
142         }
143     }
144 
getThreadId()145     public ThreadId getThreadId() {
146         return _iMessage.getThreadId();
147     }
148 
isRequest()149     public boolean isRequest() {
150         return _iMessage.isRequest();
151     }
152 
isSynchronous()153     public boolean isSynchronous() {
154         return _iMessage.isSynchronous();
155     }
156 
dispose()157 	public void dispose() {
158 //  		_oId        = null;
159 //  		_iReceiver  = null;
160 //  		_threadId   = null;
161 //  		_object     = null;
162 //  		_operation  = null;
163 //  		_param      = null;
164 //  		_exception  = null;
165 //  		_zInterface = null;
166 //  		_disposeId  = null;
167 	}
168 
169     // The name of this method is chosen to generate a somewhat self-explanatory
170     // stack trace:
remoteUnoRequestRaisedException(Object exception)171     private Exception remoteUnoRequestRaisedException(Object exception) {
172         Exception e = (Exception) exception;
173         e.fillInStackTrace();
174         return e;
175     }
176 }
177