1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 package com.sun.star.lib.uno.environments.remote; 21 22 23 import java.io.PrintWriter; 24 import java.io.StringWriter; 25 26 import java.lang.reflect.InvocationTargetException; 27 28 import com.sun.star.lib.uno.typedesc.MethodDescription; 29 import com.sun.star.uno.Any; 30 import com.sun.star.uno.Type; 31 import com.sun.star.uno.UnoRuntime; 32 import com.sun.star.uno.XCurrentContext; 33 34 /** 35 * The Job is an abstraction for tasks which have to be done 36 * remotely because of a method invocation. 37 * 38 * @see com.sun.star.lib.uno.environments.remote.ThreadId 39 * @see com.sun.star.lib.uno.environments.remote.IReceiver 40 * @since UDK1.0 41 */ 42 public class Job { 43 protected IReceiver _iReceiver; 44 protected Message _iMessage; 45 Object _disposeId; 46 47 protected Object _object; 48 Job(Object object, IReceiver iReceiver, Message iMessage)49 public Job(Object object, IReceiver iReceiver, Message iMessage) { 50 _object = object; 51 _iReceiver = iReceiver; 52 _iMessage = iMessage; 53 } 54 55 /** 56 * Dispatches a <code>queryInterface</code> call. 57 * 58 * @return the result of the call (should be an <code>Any</code>). 59 */ dispatch_queryInterface(Type type)60 protected Object dispatch_queryInterface(Type type) { 61 Class<?> zInterface = type.getTypeDescription().getZClass(); 62 63 Object result = null; 64 65 Object face = UnoRuntime.queryInterface(zInterface, _object); 66 // the hell knows why, but empty interfaces a given back as void anys 67 if(face != null) 68 result = new Any(type, face); 69 return result; 70 } 71 72 /** 73 * Execute the job. 74 * 75 * @return the result of the message. 76 */ execute()77 public Object execute() throws Throwable { 78 if (_iMessage.isRequest()) { 79 Object result = null; 80 Throwable exception = null; 81 MethodDescription md = _iMessage.getMethod(); 82 Object[] args = _iMessage.getArguments(); 83 XCurrentContext oldCC = UnoRuntime.getCurrentContext(); 84 UnoRuntime.setCurrentContext(_iMessage.getCurrentContext()); 85 try { 86 result = md.getIndex() == MethodDescription.ID_QUERY_INTERFACE 87 ? dispatch_queryInterface((Type) args[0]) 88 : md.getMethod().invoke(_object, args); 89 } catch (InvocationTargetException e) { 90 exception = e.getCause(); 91 if (exception == null) { 92 exception = e; 93 } 94 } catch (Exception e) { 95 exception = e; 96 } finally { 97 UnoRuntime.setCurrentContext(oldCC); 98 } 99 if (_iMessage.isSynchronous()) { 100 if (exception == null) { 101 _iReceiver.sendReply( 102 false, _iMessage.getThreadId(), result); 103 } else { 104 // Here we have to be aware of non-UNO exceptions, because 105 // they may kill a remote side which does not know anything 106 // about their types: 107 if (!(exception instanceof com.sun.star.uno.Exception) 108 && !(exception instanceof 109 com.sun.star.uno.RuntimeException)) 110 { 111 StringWriter writer = new StringWriter(); 112 exception.printStackTrace(new PrintWriter(writer)); 113 exception = new com.sun.star.uno.RuntimeException( 114 "Java exception: <" + writer + ">", null); 115 } 116 _iReceiver.sendReply( 117 true, _iMessage.getThreadId(), exception); 118 } 119 } 120 return null; 121 } else if (_iMessage.isAbnormalTermination()) { 122 throw remoteUnoRequestRaisedException(_iMessage.getResult()); 123 } else { 124 return _iMessage.getResult(); 125 } 126 } 127 getThreadId()128 public ThreadId getThreadId() { 129 return _iMessage.getThreadId(); 130 } 131 isRequest()132 public boolean isRequest() { 133 return _iMessage.isRequest(); 134 } 135 isSynchronous()136 public boolean isSynchronous() { 137 return _iMessage.isSynchronous(); 138 } 139 dispose()140 public void dispose() { 141 // _oId = null; 142 // _iReceiver = null; 143 // _threadId = null; 144 // _object = null; 145 // _operation = null; 146 // _param = null; 147 // _exception = null; 148 // _zInterface = null; 149 // _disposeId = null; 150 } 151 152 /** 153 * The name of this method is chosen to generate a somewhat self-explanatory 154 * stack trace. 155 */ remoteUnoRequestRaisedException(Object exception)156 private Exception remoteUnoRequestRaisedException(Object exception) { 157 Exception e = (Exception) exception; 158 e.fillInStackTrace(); 159 return e; 160 } 161 } 162 163 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 164