static Object deSerializeParameter()

in dbus-java/src/main/java/org/freedesktop/dbus/Marshalling.java [485:612]


    static Object deSerializeParameter(Object _parameter, Type _type, AbstractConnection _conn) throws Exception {
        LOGGER.trace("Deserializing from {} to {}", _parameter.getClass(), _type.getClass());

        // its a wrapped variant, unwrap it
        if (_type instanceof TypeVariable && _parameter instanceof Variant) {
            _parameter = ((Variant<?>) _parameter).getValue();
        }

        // Turn a signature into a Type[]
        if (_type instanceof Class && ((Class<?>) _type).isArray() && ((Class<?>) _type).getComponentType().equals(Type.class) && _parameter instanceof String) {
            List<Type> rv = new ArrayList<>();
            getJavaType((String) _parameter, rv, -1);
            _parameter = rv.toArray(new Type[0]);
        }

        // its an object path, get/create the proxy
        if (_parameter instanceof ObjectPath) {
            if (_type instanceof Class && DBusInterface.class.isAssignableFrom((Class<?>) _type)) {
                _parameter = _conn.getExportedObject(((ObjectPath) _parameter).getSource(), ((ObjectPath) _parameter).getPath());
            } else {
                _parameter = new DBusPath(((ObjectPath) _parameter).getPath());
            }
        }

        // it should be a struct. create it
        if (_parameter instanceof Object[] && _type instanceof Class && Struct.class.isAssignableFrom((Class<?>) _type)) {
            LOGGER.trace("Creating Struct {} from {}", _type, _parameter);
            Type[] ts = Container.getTypeCache(_type);
            if (null == ts) {
                Field[] fs = ((Class<?>) _type).getDeclaredFields();
                ts = new Type[fs.length];
                for (Field f : fs) {
                    Position p = f.getAnnotation(Position.class);
                    if (null == p) {
                        continue;
                    }
                    ts[p.value()] = f.getGenericType();
                }
                Container.putTypeCache(_type, ts);
            }

            // recurse over struct contents
            _parameter = deSerializeParameters((Object[]) _parameter, ts, _conn);
            for (Constructor<?> con : ((Class<?>) _type).getDeclaredConstructors()) {
                try {
                    _parameter = con.newInstance((Object[]) _parameter);
                    break;
                } catch (IllegalArgumentException exIa) {
                }
            }
        }

        // recurse over arrays
        if (_parameter instanceof Object[]) {
            Type[] ts = new Type[((Object[]) _parameter).length];
            Arrays.fill(ts, _parameter.getClass().getComponentType());
            _parameter = deSerializeParameters((Object[]) _parameter, ts, _conn);
        }
        if (_parameter instanceof List) {
            Type type2;
            if (_type instanceof ParameterizedType) {
                type2 = ((ParameterizedType) _type).getActualTypeArguments()[0];
            } else if (_type instanceof GenericArrayType) {
                type2 = ((GenericArrayType) _type).getGenericComponentType();
            } else if (_type instanceof Class && ((Class<?>) _type).isArray()) {
                type2 = ((Class<?>) _type).getComponentType();
            } else {
                type2 = null;
            }
            if (null != type2) {
                _parameter = deSerializeParameters((List<Object>) _parameter, type2, _conn);
            }
        }

        // correct floats if appropriate
        if (_type.equals(Float.class) || _type.equals(Float.TYPE)) {
            if (!(_parameter instanceof Float)) {
                _parameter = ((Number) _parameter).floatValue();
            }
        }

        // make sure arrays are in the correct format
        if (_parameter instanceof Object[] || _parameter instanceof List || _parameter.getClass().isArray()) {
            if (_type instanceof ParameterizedType) {
                _parameter = ArrayFrob.convert(_parameter, (Class<? extends Object>) ((ParameterizedType) _type).getRawType());
            } else if (_type instanceof GenericArrayType) {
                Type ct = ((GenericArrayType) _type).getGenericComponentType();
                Class<?> cc = null;
                if (ct instanceof Class) {
                    cc = (Class<?>) ct;
                }
                if (ct instanceof ParameterizedType) {
                    cc = (Class<?>) ((ParameterizedType) ct).getRawType();
                }
                Object o = Array.newInstance(cc, 0);
                _parameter = ArrayFrob.convert(_parameter, o.getClass());
            } else if (_type instanceof Class && ((Class<?>) _type).isArray()) {
                Class<?> cc = ((Class<?>) _type).getComponentType();
                if ((cc.equals(Float.class) || cc.equals(Float.TYPE)) && (_parameter instanceof double[])) {
                    double[] tmp1 = (double[]) _parameter;
                    float[] tmp2 = new float[tmp1.length];
                    for (int i = 0; i < tmp1.length; i++) {
                        tmp2[i] = (float) tmp1[i];
                    }
                    _parameter = tmp2;
                }
                Object o = Array.newInstance(cc, 0);
                _parameter = ArrayFrob.convert(_parameter, o.getClass());
            }
        }
        if (_parameter instanceof DBusMap) {
            LOGGER.trace("Deserializing a Map");
            DBusMap<?,?> dmap = (DBusMap<?,?>) _parameter;

            Type[] maptypes;
            if (_type instanceof ParameterizedType) {
                maptypes = ((ParameterizedType) _type).getActualTypeArguments();
            } else {
                maptypes = _parameter.getClass().getTypeParameters();
            }

            for (int i = 0; i < dmap.entries.length; i++) {
                dmap.entries[i][0] = deSerializeParameter(dmap.entries[i][0], maptypes[0], _conn);
                dmap.entries[i][1] = deSerializeParameter(dmap.entries[i][1], maptypes[1], _conn);
            }
        }
        return _parameter;
    }