private void handleMessage()

in dbus-java/src/main/java/org/freedesktop/dbus/connections/AbstractConnection.java [719:846]


    private void handleMessage(final MethodCall m) throws DBusException {
        logger.debug("Handling incoming method call: {}", m);

        ExportedObject eo = null;
        Method meth = null;
        Object o = null;

        if (null == m.getInterface() || m.getInterface().equals("org.freedesktop.DBus.Peer")
                || m.getInterface().equals("org.freedesktop.DBus.Introspectable")) {
            eo = getExportedObjects().get(null);
            if (null != eo && null == eo.getObject().get()) {
                unExportObject(null);
                eo = null;
            }
            if (null != eo) {
                meth = eo.getMethods().get(new MethodTuple(m.getName(), m.getSig()));
            }
            if (null != meth) {
                o = new GlobalHandler(this, m.getPath());
            } else {
                eo = null;
            }
        }
        if (null == o) {
            // now check for specific exported functions

            eo = getExportedObjects().get(m.getPath());
            if (null != eo && null == eo.getObject().get()) {
                logger.info("Unexporting {} implicitly", m.getPath());
                unExportObject(m.getPath());
                eo = null;
            }

            if (null == eo) {
                eo = fallbackContainer.get(m.getPath());
            }

            if (null == eo) {
                sendMessage(new Error(m,
                        new UnknownObject(m.getPath() + " is not an object provided by this process.")));
                return;
            }
            if (logger.isTraceEnabled()) {
                logger.trace("Searching for method {}  with signature {}", m.getName(), m.getSig());
                logger.trace("List of methods on {}: ", eo);
                for (MethodTuple mt : eo.getMethods().keySet()) {
                    logger.trace("   {} => {}", mt, eo.getMethods().get(mt));
                }
            }
            meth = eo.getMethods().get(new MethodTuple(m.getName(), m.getSig()));
            if (null == meth) {
                sendMessage(new Error(m, new UnknownMethod(String.format(
                        "The method `%s.%s' does not exist on this object.", m.getInterface(), m.getName()))));
                return;
            }
            o = eo.getObject().get();
        }

        // now execute it
        final Method me = meth;
        final Object ob = o;
        final boolean noreply = (1 == (m.getFlags() & Message.Flags.NO_REPLY_EXPECTED));
        final DBusCallInfo info = new DBusCallInfo(m);
        final AbstractConnection conn = this;

        logger.trace("Adding Runnable for method {}", meth);
        Runnable r = new Runnable() {

            @Override
            public void run() {
                logger.debug("Running method {} for remote call", me);
                if (me == null) {
                	logger.debug("Cannot run method - method variable was null");
                	return;
                }
                try {
                    Type[] ts = me.getGenericParameterTypes();
                    m.setArgs(Marshalling.deSerializeParameters(m.getParameters(), ts, conn));
                    logger.trace("Deserialised {} to types {}", Arrays.deepToString(m.getParameters()), Arrays.deepToString(ts));
                } catch (Exception e) {
                    logger.debug("", e);
                    handleException(conn, m, new UnknownMethod("Failure in de-serializing message: " + e));
                    return;
                }

                try {
                    INFOMAP.put(Thread.currentThread(), info);
                    Object result;
                    try {
                        logger.trace("Invoking Method: {} on {} with parameters {}", me, ob, Arrays.deepToString(m.getParameters()));
                        result = me.invoke(ob, m.getParameters());
                    } catch (InvocationTargetException ite) {
                        logger.debug(ite.getMessage(), ite);
                        throw ite.getCause();
                    }
                    INFOMAP.remove(Thread.currentThread());
                    if (!noreply) {
                        MethodReturn reply;
                        if (Void.TYPE.equals(me.getReturnType())) {
                            reply = new MethodReturn(m, null);
                        } else {
                            StringBuffer sb = new StringBuffer();
                            for (String s : Marshalling.getDBusType(me.getGenericReturnType())) {
                                sb.append(s);
                            }
                            Object[] nr = Marshalling.convertParameters(new Object[] {
                                    result
                            }, new Type[] {
                                    me.getGenericReturnType()
                            }, conn);

                            reply = new MethodReturn(m, sb.toString(), nr);
                        }
                        conn.sendMessage(reply);
                    }
                } catch (DBusExecutionException exDee) {
                    logger.debug("", exDee);
                    handleException(conn, m, exDee);
                } catch (Throwable e) {
                    logger.debug("", e);
                    handleException(conn, m,
                            new DBusExecutionException(String.format("Error Executing Method %s.%s: %s",
                                    m.getInterface(), m.getName(), e.getMessage())));
                }
            }
        };
        executeInWorkerThreadPool(r);
    }