All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.freedesktop.dbus.StructHelper Maven / Gradle / Ivy

Go to download

Improved version of the DBus-Java library provided by freedesktop.org (https://dbus.freedesktop.org/doc/dbus-java/).

There is a newer version: 5.1.0
Show newest version
package org.freedesktop.dbus;

import org.freedesktop.dbus.annotations.Position;
import org.freedesktop.dbus.types.DBusStructType;
import org.freedesktop.dbus.types.Variant;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 * Helper util to create {@link Struct} subclasses when receiving it from DBus.
 *
 * @author David M.
 * @since v3.2.1 - 2019-10-25
 */
public final class StructHelper {

    private StructHelper() {

    }

    /**
     * Creates a {@link ArrayList} of struct of the given type using the list of object arrays.
     *
     * @param _obj list of object arrays to process
     * @param _structType struct class to create
     *
     * @param  struct type
     *
     * @return List of given struct type
     *
     * @throws NoSuchMethodException when no constructor can be found for the arguments of the struct
     * @throws SecurityException when constructor cannot be accesses
     * @throws InstantiationException when reflection fails
     * @throws IllegalAccessException  if this Constructor object is enforcing Java language access control and the underlying constructor is inaccessible.
     * @throws IllegalArgumentException when data types are incompatible or incompatible argument length
     * @throws InvocationTargetException if the underlying constructor throws an exception
     *
     * @since 4.3.1 - 2023-08-16
     */
    public static  List convertToStructList(List _obj, Class _structType) throws NoSuchMethodException, SecurityException, InstantiationException,
        IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        List result = new ArrayList<>();
        convertToStructCollection(_obj, _structType, result);
        return result;
    }

    /**
     * Creates a {@link LinkedHashSet} of struct of the given type using the list of object arrays.
     *
     * @param _obj list of object arrays to process
     * @param _structType struct class to create
     *
     * @param  struct type
     *
     * @return List of given struct type
     *
     * @throws NoSuchMethodException when no constructor can be found for the arguments of the struct
     * @throws SecurityException when constructor cannot be accesses
     * @throws InstantiationException when reflection fails
     * @throws IllegalAccessException  if this Constructor object is enforcing Java language access control and the underlying constructor is inaccessible.
     * @throws IllegalArgumentException when data types are incompatible or incompatible argument length
     * @throws InvocationTargetException if the underlying constructor throws an exception
     *
     * @since 4.3.1 - 2023-08-16
     */
    public static  Set convertToStructSet(Set _obj, Class _structType) throws NoSuchMethodException, SecurityException, InstantiationException,
        IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        Set result = new LinkedHashSet<>();
        convertToStructCollection(_obj, _structType, result);
        return result;
    }

    /**
     * Creates a collection of struct of the given type using the list of object arrays.
     *
     * @param _input list of object arrays to process
     * @param _structType struct class to create
     * @param _result collection to store results
     *
     * @param  struct type
     *
     * @return List of given struct type
     *
     * @throws NoSuchMethodException when no constructor can be found for the arguments of the struct
     * @throws SecurityException when constructor cannot be accesses
     * @throws InstantiationException when reflection fails
     * @throws IllegalAccessException  if this Constructor object is enforcing Java language access control and the underlying constructor is inaccessible.
     * @throws IllegalArgumentException when data types are incompatible or incompatible argument length
     * @throws InvocationTargetException if the underlying constructor throws an exception
     *
     * @since 4.3.1 - 2023-08-16
     */
    public static  void convertToStructCollection(Collection _input, Class _structType, Collection _result)
        throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

        Objects.requireNonNull(_structType, "Struct class required");
        Objects.requireNonNull(_result, "Collection for result storage required");
        Objects.requireNonNull(_input, "Input data required");

        Class[] constructorArgClasses = Arrays.stream(_structType.getDeclaredFields())
            .filter(f -> f.isAnnotationPresent(Position.class))
            .sorted((f1, f2) -> Integer.compare(f1.getAnnotation(Position.class).value(), f2.getAnnotation(Position.class).value()))
            .map(f -> f.getType())
            .toArray(Class[]::new);

        for (Object[] object : _input) {
            if (constructorArgClasses.length != object.length) {
                throw new IllegalArgumentException("Struct length does not match argument length");
            }
            T x = StructHelper.createStruct(constructorArgClasses, (Object) object, _structType);
            _result.add(x);
        }

    }

    /**
     * Creates a instance of the given {@link Struct} subclass if the given variant is some sort of Struct.
     * @param _variant variant to convert
     * @param _structClass {@link Struct} subclass to create
     *
     * @param  type of struct
     *
     * @return instance of _structClass or null if _variant is not Struct compatible or any input parameter is null
     *
     * @throws NoSuchMethodException when no constructor can be found for the arguments of the struct
     * @throws SecurityException when constructor cannot be accesses
     * @throws InstantiationException when reflection fails
     * @throws IllegalAccessException  if this Constructor object is enforcing Java language access control and the underlying constructor is inaccessible.
     * @throws IllegalArgumentException when data types are incompatible
     * @throws InvocationTargetException if the underlying constructor throws an exception
     */
    public static  T createStructFromVariant(Variant _variant, Class _structClass)
            throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        if (_variant == null || _structClass == null) {
            return null;
        }

        if (_variant.getType() instanceof DBusStructType && _variant.getValue() instanceof Object[]) {
            Class[] argTypes = Arrays.stream((Object[]) _variant.getValue()).map(a -> a.getClass()).toArray(size -> new Class[size]);
            return createStruct(argTypes, _variant.getValue(), _structClass);
        }

        return null;
    }

    /**
     * Will create a new {@link Struct} subclass instance if possible.
     * May replace Wrapper-classes with primitive classes in _constructorArgs if constructor does not match.
     *
     * @param _constructorArgs argument-classes expected by constructor
     * @param _values values passed to the constructor
     * @param _classToConstruct {@link Struct} subclass to instantiate
     *
     * @param  type of struct
     *
     * @return instance of _classToConstruct or null if any input argument is null
     *
     * @throws NoSuchMethodException when no constructor can be found for the arguments of the struct
     * @throws SecurityException when constructor cannot be accesses
     * @throws InstantiationException when reflection fails
     * @throws IllegalAccessException  if this Constructor object is enforcing Java language access control and the underlying constructor is inaccessible.
     * @throws IllegalArgumentException when data types are incompatible
     * @throws InvocationTargetException if the underlying constructor throws an exception
     */
    public static  T createStruct(Class[] _constructorArgs, Object _values,  Class _classToConstruct)
            throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        if (_constructorArgs == null || _classToConstruct == null || _values == null) {
            return null;
        }

        try {
            Constructor declaredConstructor = _classToConstruct.getDeclaredConstructor(_constructorArgs);
            declaredConstructor.setAccessible(true);
            if (_values instanceof Object[]) {
                return declaredConstructor.newInstance((Object[]) _values);
            } else {
                return declaredConstructor.newInstance(_values);
            }
        } catch (NoSuchMethodException | SecurityException _ex) {
            for (int i = 0; i < _constructorArgs.length; i++) {
                Class class1 = _constructorArgs[i];
                if (ArrayFrob.getWrapperToPrimitiveTypes().containsKey(class1)) {
                    _constructorArgs[i] = ArrayFrob.getWrapperToPrimitiveTypes().get(class1);
                    return createStruct(_constructorArgs, _values, _classToConstruct);
                }
            }
        }
        throw new NoSuchMethodException("Cannot find suitable constructor for arguments " + Arrays.toString(_constructorArgs) + " in class " + _classToConstruct + ".");
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy