mercredi 31 août 2022

How to sort a list based on multiple fields of sublcass dynamically

I am creating a Android Application which show list of Stores. The main Recyclerview shows the list of Store and every store object has SortingData which holds multiple fields like minimumDistance,rating etc.

By user selection i get a list of selected tags which size varies on the base of user selection and want to sort the main list of stores by it.

Every selected tag holds a propery isAscending which shows that it should be sorted in Ascending or Descending order. Lets say Rating with be Descending and Minimum Distance will be ascending and so on.

I have written a custom comparator to do so, to avoid multiple if conditions inside a loop but this comparator has issues. Like, its sorting the intergers based on first digit only doubles are also not sorted well.

Below is my code

data class Store(
    val name: String,
    val sortingData: SortingData,
    val status: String
) {
}
data class SortingData(
    val averageProductPrice: Int,
    val bestMatch: Double,
    val deliveryCosts: Int,
    val distance: Int,
    val minCost: Int,
    val newest: Double,
    val popularity: Double,
    val ratingAverage: Float
)

data class SortTag(var text: String, var key:String,var isSelected: Boolean,var isAscending:Boolean) {
}

Function

fun sortListByAdditionalTags(
    list: MutableList<Store>>,    selectedTags: List<SortTag>
): MutableList<Store> {
    /*
 Best Match -> Descending highest value on top
 Newest -> Descending highest value on top
 Rating Average -> Descending highest value on top
 Distance -> Ascending lowest value on top
 Popularity -> Descending highest value on top
 Average Product Price ->  Ascending lowest value on top
 Delivery cost ->  Ascending lowest value on top
 Min cost->  Ascending lowest value on top
 */
    var sorted = list
    selectedTags.forEach {
        sorted = list.sortedWith(
            comparator = AdditionalSortComparator(
                it.key,
                it.isAscending
            )
        ) as MutableList< Store 
>

    }
    return sorted

}

Custom Sort Comparator

class AdditionalSortComparator(
    private val sortProperty: String? = null,
    private val isAscending: Boolean
) : Comparator<Store> {
    override fun compare(o1: Store?, o2: Store?): Int {
        val sortingData =
            Store::class.declaredMemberProperties.firstOrNull { it.name == "sortingData" }

        val s1: sortingData = o1?.let { sortingData?.get(it) } as sortingData
        val s2: sortingData = o2?.let { sortingData?.get(it) } as sortingData

        val calledVariable = SortingData::class.declaredMemberProperties.firstOrNull { it.name == sortProperty }
        return if (calledVariable != null) {
            if (calledVariable.get(s1) is Int) {
                val valueFirst = calledVariable.get(s1) as Int
                val valueSecond = calledVariable.get(s2) as Int
                if (isAscending) valueFirst - valueSecond else valueSecond - valueFirst
            } else if (calledVariable.get(s1) is Float) {
                val valueFirst = calledVariable.get(s1) as Float
                val valueSecond = calledVariable.get(s2) as Float
                if (isAscending) valueFirst - valueSecond else valueSecond - valueFirst
            } else if (calledVariable.get(s1) is Double) {
                val valueFirst = calledVariable.get(s1) as Double
                val valueSecond = calledVariable.get(s2) as Double
                if (isAscending) abs(valueFirst-valueSecond) else abs(valueSecond-valueFirst)
            }

            if (isAscending) calledVariable.get(s1).toString()
                .compareTo(calledVariable.get(s2).toString())
            else calledVariable.get(s2).toString()
                .compareTo(calledVariable.get(s1).toString())
        } else {
            val idProperty = Store::name
            val valueFirst = idProperty.get(o1)
            val valueSecond = idProperty.get(o2)
            if (isAscending) valueFirst.compareTo(valueSecond) else valueSecond.compareTo(valueFirst)
        }
    }
}

The dependency i used for Kotlin Reflection is

implementation("org.jetbrains.kotlin:kotlin-reflect:1.7.10")

Can somebody please help me out with this, how i can achieve this functionality in an efficient and correct manner?





Unable to get DeclaredField "usr_paths " via java reflection 17.0.3

Hello to everyone sitting on this forum, enter code hereI ran into a problem, I will be very glad if you can help me.

So I'm trying to get usr_paths, but the console gives an error that it can't find this field, what should I do?

public static void addDir(String s) throws IOException {
    try {
        Field field = ClassLoader.class.getDeclaredField("usr_paths"); // there's a error here !!
        field.setAccessible(true);
        String[] paths = (String[]) field.get(null);
        for (int i = 0; i < paths.length; i++) {
            if (s.equals(paths[i])) {
                return;
            }
        }
        String[] tmp = new String[paths.length + 1];
        System.arraycopy(paths, 0, tmp, 0, paths.length);
        tmp[paths.length] = s;
        field.set(null, tmp);
        System.setProperty("java.library.path", System.getProperty("java.library.path") + File.pathSeparator + s);
    } catch (IllegalAccessException e) {
        throw new IOException("Failed to get permissions to set library path");
    } catch (NoSuchFieldException e) {
        throw new IOException("Failed to get field handle to set library path");
    }
}




mardi 30 août 2022

c# Iterate over var with value obtained with GetValue()

In an MVC 5 c# application, I am attempting to extract values from objects at runtime using strings for property names. The process works fine until the value extracted is a collection. I am unable to write the code to iterate over the extracted value.

using System;
using System.Collections.Generic;               
public class Program
{
    public static void Main()
    {
        Student student = new Student { 
             Lectures = new List<Lecture>{ 
                new Lecture { Title="Science"},
                new Lecture {Title="Math"}
             }
        };
        
        var obj = student;
        string fld = "Lectures";

        // The following code knows nothing about Students or Lectures
        // It does know that the "fld" is a property name of "obj" that contains a collection

        var items = obj.GetType().GetProperty(fld).GetValue(obj);
        foreach (var item in items)
        {
            // Code to process item
        }
    }
}

public class Lecture
{
     public string Title {get;set;}
}

public class Student
{
   public List<Lecture> Lectures {get;set;}
}

The above "for" instruction is flagged as a syntax error with the red highlight on "items". The error indicates that it cannot operate on variables of type "object" because "object" does not contain a public definition for GetEnumerator.

Pasting the above code into https://dotnetfiddle.net illustrates the issue.

Is what I attempting possible? When debugging, "items" does show as a collection of Lecture.





lundi 29 août 2022

IllegalAccessException on calling constructor after loading class via URLClassLoader

I try to load a class from file system(which is not in the cp of my main) and then want a new instance of that loaded class like this:

try {
    File folder = new File("/tmp/");
    URLClassLoader loader = URLClassLoader.newInstance(new URL[] {folder.toURI().toURL()});
    Class clazz = loader.loadClass("testpkg.test");
    Constructor constructor = clazz.getConstructor();
    Object instance = constructor.newInstance();
} catch (Exception e) {
    e.printStackTrace();
}

the class file exists in the /tmp/testpkg directory and has the name test.class. The code for the uncompiled .java looks like this:

package testpkg;
class test{
    public test(){
            System.out.println("I am the constructor!");
    }
}

unfortunately I get a runtimeError at the following line:

Object instance = constructor.newInstance();

which says:

java.lang.IllegalAccessException: Class tmp.ClassLoadingFun can not access a member of class testpkg.test with modifiers "public"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
at java.lang.reflect.Constructor.newInstance(Constructor.java:413)
at tmp.ClassLoadingFun.<init>(ClassLoadingFun.java:16)
at tmp.ClassLoadingFun.main(ClassLoadingFun.java:23)

When i fuzz around with the package or class name, it will terminate earlier stating, there is no proper class found. So I guess the loading of the class works. Only calling the constructor does not. Why can't I access this public(!) constructor?





Is it safe to modify private variables using ReflectionUtils

Java ReflectionUtils gives us a way to make private variables accessible and modifiable. I just wrote some code which intercepts a process and modifies some private variables of an object.

How safe is this? My doubt is, What if in future, the person who owns this object decides to rename it to something else ? Since its a private var, he is completely entitled to.

If this is unsafe, then what is the point of ReflectionUtils allowing us to set private variables at all ?

Thanks in advance.





Use Spirv-Reflect with GLSL shader doesn't find any information

I'm working with vulkan 1.2 and i try to reflect the input, ouput of the shader here:

#version 450

layout(location = 0) in vec2 inPosition;
layout(location = 1) in vec3 inColor;

layout(location = 0) out vec3 fragColor;

void main() {
    gl_Position = vec4(inPosition, 0.0, 1.0);
    fragColor = inColor;
}

The goal is to automatically set correctly the layout(location) line in the pipeline Currently, i reflect my shader like this:

void Shader::reflectInput(const std::vector<char>& code)
    {
        SpvReflectShaderModule spvModule = {};
        SpvReflectResult result = spvReflectCreateShaderModule(sizeof(code), reinterpret_cast<const uint32_t*>(code.data()), &spvModule);
        assert(result == SPV_REFLECT_RESULT_SUCCESS);
        uint32_t count = 0;
        result = spvReflectEnumerateInputVariables(&spvModule, &count, NULL);
        assert(result == SPV_REFLECT_RESULT_SUCCESS);
        std::vector<SpvReflectInterfaceVariable*> input_vars(count);
        result = spvReflectEnumerateInputVariables(&spvModule, &count, input_vars.data());
        assert(result == SPV_REFLECT_RESULT_SUCCESS);
        count = 0;
        result = spvReflectEnumerateOutputVariables(&spvModule, &count, NULL);
        assert(result == SPV_REFLECT_RESULT_SUCCESS);

        std::vector<SpvReflectInterfaceVariable*> output_vars(count);
        result = spvReflectEnumerateOutputVariables(&spvModule, &count, output_vars.data());
        assert(result == SPV_REFLECT_RESULT_SUCCESS);

        if (spvModule.shader_stage == SPV_REFLECT_SHADER_STAGE_VERTEX_BIT)
        {
            binding_description.binding = 0;
            binding_description.stride = 0;
            binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;

            attribute_descriptions.reserve(input_vars.size());
            for (size_t i_var = 0; i_var < input_vars.size(); ++i_var)
            {
                const SpvReflectInterfaceVariable& refl_var = *(input_vars[i_var]);
                if (refl_var.decoration_flags & SPV_REFLECT_DECORATION_BUILT_IN)
                    continue;
                VkVertexInputAttributeDescription attr_desc{};
                attr_desc.location = refl_var.location;
                attr_desc.binding = binding_description.binding;
                attr_desc.format = static_cast<VkFormat>(refl_var.format);
                attr_desc.offset = 0;  // final offset computed below after sorting.
                attribute_descriptions.push_back(attr_desc);
            }
            std::sort(std::begin(attribute_descriptions), std::end(attribute_descriptions),
                [](const VkVertexInputAttributeDescription& a, const VkVertexInputAttributeDescription& b) {
                    return a.location < b.location; });
            // Compute final offsets of each attribute, and total vertex stride.
            for (auto& attribute : attribute_descriptions) {
                uint32_t format_size = FormatSize(attribute.format);
                attribute.offset = binding_description.stride;
                binding_description.stride += format_size;
            }
        }
    }

    uint32_t Shader::FormatSize(VkFormat format)
    {
        uint32_t result = 0;
        switch (format) {
        case VK_FORMAT_UNDEFINED: result = 0; break;
        case VK_FORMAT_R4G4_UNORM_PACK8: result = 1; break;
        case VK_FORMAT_R4G4B4A4_UNORM_PACK16: result = 2; break;
        case VK_FORMAT_B4G4R4A4_UNORM_PACK16: result = 2; break;
        case VK_FORMAT_R5G6B5_UNORM_PACK16: result = 2; break;
        case VK_FORMAT_B5G6R5_UNORM_PACK16: result = 2; break;
        case VK_FORMAT_R5G5B5A1_UNORM_PACK16: result = 2; break;
        case VK_FORMAT_B5G5R5A1_UNORM_PACK16: result = 2; break;
        case VK_FORMAT_A1R5G5B5_UNORM_PACK16: result = 2; break;
        case VK_FORMAT_R8_UNORM: result = 1; break;
        case VK_FORMAT_R8_SNORM: result = 1; break;
        case VK_FORMAT_R8_USCALED: result = 1; break;
        case VK_FORMAT_R8_SSCALED: result = 1; break;
        case VK_FORMAT_R8_UINT: result = 1; break;
        case VK_FORMAT_R8_SINT: result = 1; break;
        case VK_FORMAT_R8_SRGB: result = 1; break;
        case VK_FORMAT_R8G8_UNORM: result = 2; break;
        case VK_FORMAT_R8G8_SNORM: result = 2; break;
        case VK_FORMAT_R8G8_USCALED: result = 2; break;
        case VK_FORMAT_R8G8_SSCALED: result = 2; break;
        case VK_FORMAT_R8G8_UINT: result = 2; break;
        case VK_FORMAT_R8G8_SINT: result = 2; break;
        case VK_FORMAT_R8G8_SRGB: result = 2; break;
        case VK_FORMAT_R8G8B8_UNORM: result = 3; break;
        case VK_FORMAT_R8G8B8_SNORM: result = 3; break;
        case VK_FORMAT_R8G8B8_USCALED: result = 3; break;
        case VK_FORMAT_R8G8B8_SSCALED: result = 3; break;
        case VK_FORMAT_R8G8B8_UINT: result = 3; break;
        case VK_FORMAT_R8G8B8_SINT: result = 3; break;
        case VK_FORMAT_R8G8B8_SRGB: result = 3; break;
        case VK_FORMAT_B8G8R8_UNORM: result = 3; break;
        case VK_FORMAT_B8G8R8_SNORM: result = 3; break;
        case VK_FORMAT_B8G8R8_USCALED: result = 3; break;
        case VK_FORMAT_B8G8R8_SSCALED: result = 3; break;
        case VK_FORMAT_B8G8R8_UINT: result = 3; break;
        case VK_FORMAT_B8G8R8_SINT: result = 3; break;
        case VK_FORMAT_B8G8R8_SRGB: result = 3; break;
        case VK_FORMAT_R8G8B8A8_UNORM: result = 4; break;
        case VK_FORMAT_R8G8B8A8_SNORM: result = 4; break;
        case VK_FORMAT_R8G8B8A8_USCALED: result = 4; break;
        case VK_FORMAT_R8G8B8A8_SSCALED: result = 4; break;
        case VK_FORMAT_R8G8B8A8_UINT: result = 4; break;
        case VK_FORMAT_R8G8B8A8_SINT: result = 4; break;
        case VK_FORMAT_R8G8B8A8_SRGB: result = 4; break;
        case VK_FORMAT_B8G8R8A8_UNORM: result = 4; break;
        case VK_FORMAT_B8G8R8A8_SNORM: result = 4; break;
        case VK_FORMAT_B8G8R8A8_USCALED: result = 4; break;
        case VK_FORMAT_B8G8R8A8_SSCALED: result = 4; break;
        case VK_FORMAT_B8G8R8A8_UINT: result = 4; break;
        case VK_FORMAT_B8G8R8A8_SINT: result = 4; break;
        case VK_FORMAT_B8G8R8A8_SRGB: result = 4; break;
        case VK_FORMAT_A8B8G8R8_UNORM_PACK32: result = 4; break;
        case VK_FORMAT_A8B8G8R8_SNORM_PACK32: result = 4; break;
        case VK_FORMAT_A8B8G8R8_USCALED_PACK32: result = 4; break;
        case VK_FORMAT_A8B8G8R8_SSCALED_PACK32: result = 4; break;
        case VK_FORMAT_A8B8G8R8_UINT_PACK32: result = 4; break;
        case VK_FORMAT_A8B8G8R8_SINT_PACK32: result = 4; break;
        case VK_FORMAT_A8B8G8R8_SRGB_PACK32: result = 4; break;
        case VK_FORMAT_A2R10G10B10_UNORM_PACK32: result = 4; break;
        case VK_FORMAT_A2R10G10B10_SNORM_PACK32: result = 4; break;
        case VK_FORMAT_A2R10G10B10_USCALED_PACK32: result = 4; break;
        case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: result = 4; break;
        case VK_FORMAT_A2R10G10B10_UINT_PACK32: result = 4; break;
        case VK_FORMAT_A2R10G10B10_SINT_PACK32: result = 4; break;
        case VK_FORMAT_A2B10G10R10_UNORM_PACK32: result = 4; break;
        case VK_FORMAT_A2B10G10R10_SNORM_PACK32: result = 4; break;
        case VK_FORMAT_A2B10G10R10_USCALED_PACK32: result = 4; break;
        case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: result = 4; break;
        case VK_FORMAT_A2B10G10R10_UINT_PACK32: result = 4; break;
        case VK_FORMAT_A2B10G10R10_SINT_PACK32: result = 4; break;
        case VK_FORMAT_R16_UNORM: result = 2; break;
        case VK_FORMAT_R16_SNORM: result = 2; break;
        case VK_FORMAT_R16_USCALED: result = 2; break;
        case VK_FORMAT_R16_SSCALED: result = 2; break;
        case VK_FORMAT_R16_UINT: result = 2; break;
        case VK_FORMAT_R16_SINT: result = 2; break;
        case VK_FORMAT_R16_SFLOAT: result = 2; break;
        case VK_FORMAT_R16G16_UNORM: result = 4; break;
        case VK_FORMAT_R16G16_SNORM: result = 4; break;
        case VK_FORMAT_R16G16_USCALED: result = 4; break;
        case VK_FORMAT_R16G16_SSCALED: result = 4; break;
        case VK_FORMAT_R16G16_UINT: result = 4; break;
        case VK_FORMAT_R16G16_SINT: result = 4; break;
        case VK_FORMAT_R16G16_SFLOAT: result = 4; break;
        case VK_FORMAT_R16G16B16_UNORM: result = 6; break;
        case VK_FORMAT_R16G16B16_SNORM: result = 6; break;
        case VK_FORMAT_R16G16B16_USCALED: result = 6; break;
        case VK_FORMAT_R16G16B16_SSCALED: result = 6; break;
        case VK_FORMAT_R16G16B16_UINT: result = 6; break;
        case VK_FORMAT_R16G16B16_SINT: result = 6; break;
        case VK_FORMAT_R16G16B16_SFLOAT: result = 6; break;
        case VK_FORMAT_R16G16B16A16_UNORM: result = 8; break;
        case VK_FORMAT_R16G16B16A16_SNORM: result = 8; break;
        case VK_FORMAT_R16G16B16A16_USCALED: result = 8; break;
        case VK_FORMAT_R16G16B16A16_SSCALED: result = 8; break;
        case VK_FORMAT_R16G16B16A16_UINT: result = 8; break;
        case VK_FORMAT_R16G16B16A16_SINT: result = 8; break;
        case VK_FORMAT_R16G16B16A16_SFLOAT: result = 8; break;
        case VK_FORMAT_R32_UINT: result = 4; break;
        case VK_FORMAT_R32_SINT: result = 4; break;
        case VK_FORMAT_R32_SFLOAT: result = 4; break;
        case VK_FORMAT_R32G32_UINT: result = 8; break;
        case VK_FORMAT_R32G32_SINT: result = 8; break;
        case VK_FORMAT_R32G32_SFLOAT: result = 8; break;
        case VK_FORMAT_R32G32B32_UINT: result = 12; break;
        case VK_FORMAT_R32G32B32_SINT: result = 12; break;
        case VK_FORMAT_R32G32B32_SFLOAT: result = 12; break;
        case VK_FORMAT_R32G32B32A32_UINT: result = 16; break;
        case VK_FORMAT_R32G32B32A32_SINT: result = 16; break;
        case VK_FORMAT_R32G32B32A32_SFLOAT: result = 16; break;
        case VK_FORMAT_R64_UINT: result = 8; break;
        case VK_FORMAT_R64_SINT: result = 8; break;
        case VK_FORMAT_R64_SFLOAT: result = 8; break;
        case VK_FORMAT_R64G64_UINT: result = 16; break;
        case VK_FORMAT_R64G64_SINT: result = 16; break;
        case VK_FORMAT_R64G64_SFLOAT: result = 16; break;
        case VK_FORMAT_R64G64B64_UINT: result = 24; break;
        case VK_FORMAT_R64G64B64_SINT: result = 24; break;
        case VK_FORMAT_R64G64B64_SFLOAT: result = 24; break;
        case VK_FORMAT_R64G64B64A64_UINT: result = 32; break;
        case VK_FORMAT_R64G64B64A64_SINT: result = 32; break;
        case VK_FORMAT_R64G64B64A64_SFLOAT: result = 32; break;
        case VK_FORMAT_B10G11R11_UFLOAT_PACK32: result = 4; break;
        case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: result = 4; break;

        default:
            break;
        }
        return result;
    }

I'm just following the example Spirv-reflect give, nevertheless, it doesn't find any information. So maybe i'm using wrong (it's probably that^^). Even the simple information spvModule.shader_stage is equal to 0 when i try to do it.

I precise that i translate my shader to spirv code. And it's the spv file i give to my reflection code.

Do you have ideas of what i could do wrong? Bad shader wrting? Bad use of the library?





dimanche 28 août 2022

How to sort a collection based on java.lang.reflect.Field? [duplicate]

I'm stuck in a situation where I only got Fields (java.lang.reflect) of a given class.

To help you better imagine, let's say we have code:

List<Apple> sortApplesByFieldName(List<Apple> apples, String fieldName) {
    Field field = Apple.class.getDeclaredField(fieldName);

    // some stream logic for sorting using this var
    return apples;
}

Can someone actually solve this problem?

Also, using a switch statement is not an option, as fields can change.

Note, the class Apple is a regular POJO with private fields and public getters/setters.