/* D-Bus Java Implementation Copyright (c) 2005-2006 Matthew Johnson This program is free software; you can redistribute it and/or modify it under the terms of either the GNU Lesser General Public License Version 2 or the Academic Free Licence Version 2.1. Full licence texts are included in the COPYING file with this program. */ package org.freedesktop.dbus; import cx.ath.matthew.debug.Debug; import cx.ath.matthew.utils.Hexdump; import org.freedesktop.dbus.exceptions.DBusException; import org.freedesktop.dbus.exceptions.MessageFormatException; import java.util.Vector; import static org.freedesktop.dbus.Gettext.getString; public class MethodCall extends Message { MethodCall() { } public MethodCall(String dest, String path, String iface, String member, byte flags, String sig, Object... args) throws DBusException { this(null, dest, path, iface, member, flags, sig, args); } public MethodCall(String source, String dest, String path, String iface, String member, byte flags, String sig, Object... args) throws DBusException { super(Message.Endian.BIG, Message.MessageType.METHOD_CALL, flags); if (null == member || null == path) throw new MessageFormatException(getString("missingDestinationPathFunction")); headers.put(Message.HeaderField.PATH, path); headers.put(Message.HeaderField.MEMBER, member); Vector<Object> hargs = new Vector<Object>(); hargs.add(new Object[]{Message.HeaderField.PATH, new Object[]{ArgumentType.OBJECT_PATH_STRING, path}}); if (null != source) { headers.put(Message.HeaderField.SENDER, source); hargs.add(new Object[]{Message.HeaderField.SENDER, new Object[]{ArgumentType.STRING_STRING, source}}); } if (null != dest) { headers.put(Message.HeaderField.DESTINATION, dest); hargs.add(new Object[]{Message.HeaderField.DESTINATION, new Object[]{ArgumentType.STRING_STRING, dest}}); } if (null != iface) { hargs.add(new Object[]{Message.HeaderField.INTERFACE, new Object[]{ArgumentType.STRING_STRING, iface}}); headers.put(Message.HeaderField.INTERFACE, iface); } hargs.add(new Object[]{Message.HeaderField.MEMBER, new Object[]{ArgumentType.STRING_STRING, member}}); if (null != sig) { if (Debug.debug) Debug.print(Debug.DEBUG, "Appending arguments with signature: " + sig); hargs.add(new Object[]{Message.HeaderField.SIGNATURE, new Object[]{ArgumentType.SIGNATURE_STRING, sig}}); headers.put(Message.HeaderField.SIGNATURE, sig); setArgs(args); } byte[] blen = new byte[4]; appendBytes(blen); append("ua(yv)", serial, hargs.toArray()); pad((byte) 8); long c = bytecounter; if (null != sig) append(sig, args); if (Debug.debug) Debug.print(Debug.DEBUG, "Appended body, type: " + sig + " start: " + c + " end: " + bytecounter + " size: " + (bytecounter - c)); marshallint(bytecounter - c, blen, 0, 4); if (Debug.debug) Debug.print("marshalled size (" + blen + "): " + Hexdump.format(blen)); } private static long REPLY_WAIT_TIMEOUT = 20000; /** * Set the default timeout for method calls. * Default is 20s. * * @param timeout New timeout in ms. */ public static void setDefaultTimeout(long timeout) { REPLY_WAIT_TIMEOUT = timeout; } Message reply = null; public synchronized boolean hasReply() { return null != reply; } /** * Block (if neccessary) for a reply. * * @param timeout The length of time to block before timing out (ms). * @return The reply to this MethodCall, or null if a timeout happens. */ public synchronized Message getReply(long timeout) { if (Debug.debug) Debug.print(Debug.VERBOSE, "Blocking on " + this); if (null != reply) return reply; try { wait(timeout); return reply; } catch (InterruptedException Ie) { return reply; } } /** * Block (if neccessary) for a reply. * Default timeout is 20s, or can be configured with setDefaultTimeout() * * @return The reply to this MethodCall, or null if a timeout happens. */ public synchronized Message getReply() { if (Debug.debug) Debug.print(Debug.VERBOSE, "Blocking on " + this); if (null != reply) return reply; try { wait(REPLY_WAIT_TIMEOUT); return reply; } catch (InterruptedException Ie) { return reply; } } protected synchronized void setReply(Message reply) { if (Debug.debug) Debug.print(Debug.VERBOSE, "Setting reply to " + this + " to " + reply); this.reply = reply; notifyAll(); } }