1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 package com.sun.star.lib.uno.environments.remote; 29 30 31 import java.io.PrintWriter; 32 import java.io.StringWriter; 33 34 35 import java.lang.reflect.InvocationTargetException; 36 37 import com.sun.star.lib.uno.typedesc.MethodDescription; 38 import com.sun.star.uno.Any; 39 import com.sun.star.uno.IMethodDescription; 40 import com.sun.star.uno.Type; 41 import com.sun.star.uno.UnoRuntime; 42 import com.sun.star.uno.XCurrentContext; 43 44 /** 45 * The Job is an abstraction for tasks which have to be done 46 * remotely because of a method invocation. 47 * <p> 48 * @version $Revision: 1.17 $ $ $Date: 2008-04-11 11:21:00 $ 49 * @author Kay Ramme 50 * @see com.sun.star.lib.uno.environments.remote.ThreadID 51 * @see com.sun.star.lib.uno.environments.remote.IReceiver 52 * @since UDK1.0 53 */ 54 public class Job { 55 protected Job _next; 56 57 protected IReceiver _iReceiver; 58 protected Message _iMessage; 59 Object _disposeId; 60 61 protected Object _object; 62 63 public Job(Object object, IReceiver iReceiver, Message iMessage) { 64 _object = object; 65 _iReceiver = iReceiver; 66 _iMessage = iMessage; 67 } 68 69 /** 70 * Dispatches a <code>queryInterface</code> call 71 * <p> 72 * @return the result of the call (should be an <code>Any</code>) 73 * @param message the parameter for the call 74 * @param resultClass the result type as an out parameter 75 * @param status the status as an out parameter 76 * @param o_outs the out parameters of the call as out parameters 77 * @param o_out_sig the out signature as an out parameter 78 */ 79 protected Object dispatch_queryInterface(Type type) { 80 Class zInterface = type.getTypeDescription().getZClass(); 81 82 Object result = null; 83 84 Object face = UnoRuntime.queryInterface(zInterface, _object); 85 // the hell knows why, but empty interfaces a given back as void anys 86 if(face != null) 87 result = new Any(type, face); 88 return result; 89 } 90 91 /** 92 * Execute the job. 93 * 94 * @return the result of the message. 95 */ 96 public Object execute() throws Throwable { 97 Object msgResult = _iMessage.getResult(); 98 if (_iMessage.isRequest()) { 99 Object result = null; 100 Throwable exception = null; 101 IMethodDescription md = _iMessage.getMethod(); 102 Object[] args = _iMessage.getArguments(); 103 XCurrentContext oldCC = UnoRuntime.getCurrentContext(); 104 UnoRuntime.setCurrentContext(_iMessage.getCurrentContext()); 105 try { 106 result = md.getIndex() == MethodDescription.ID_QUERY_INTERFACE 107 ? dispatch_queryInterface((Type) args[0]) 108 : md.getMethod().invoke(_object, args); 109 } catch (InvocationTargetException e) { 110 exception = e.getTargetException(); 111 if (exception == null) { 112 exception = e; 113 } 114 } catch (Exception e) { 115 exception = e; 116 } finally { 117 UnoRuntime.setCurrentContext(oldCC); 118 } 119 if (_iMessage.isSynchronous()) { 120 if (exception == null) { 121 _iReceiver.sendReply( 122 false, _iMessage.getThreadId(), result); 123 } else { 124 // Here we have to be aware of non-UNO exceptions, because 125 // they may kill a remote side which does not know anything 126 // about their types: 127 if (exception != null 128 && !(exception instanceof com.sun.star.uno.Exception) 129 && !(exception instanceof 130 com.sun.star.uno.RuntimeException)) 131 { 132 StringWriter writer = new StringWriter(); 133 exception.printStackTrace(new PrintWriter(writer)); 134 exception = new com.sun.star.uno.RuntimeException( 135 "Java exception: <" + writer + ">", null); 136 } 137 _iReceiver.sendReply( 138 true, _iMessage.getThreadId(), exception); 139 } 140 } 141 return null; 142 } else if (_iMessage.isAbnormalTermination()) { 143 throw remoteUnoRequestRaisedException(_iMessage.getResult()); 144 } else { 145 return _iMessage.getResult(); 146 } 147 } 148 149 public ThreadId getThreadId() { 150 return _iMessage.getThreadId(); 151 } 152 153 public boolean isRequest() { 154 return _iMessage.isRequest(); 155 } 156 157 public boolean isSynchronous() { 158 return _iMessage.isSynchronous(); 159 } 160 161 public void dispose() { 162 // _oId = null; 163 // _iReceiver = null; 164 // _threadId = null; 165 // _object = null; 166 // _operation = null; 167 // _param = null; 168 // _exception = null; 169 // _zInterface = null; 170 // _disposeId = null; 171 } 172 173 // The name of this method is chosen to generate a somewhat self-explanatory 174 // stack trace: 175 private Exception remoteUnoRequestRaisedException(Object exception) { 176 Exception e = (Exception) exception; 177 e.fillInStackTrace(); 178 return e; 179 } 180 } 181