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