mardi 18 septembre 2018

Using generic argument from a Type [duplicate]

This question already has an answer here:

So I'm playing around with Reflection and I want to show/print all properties of a class with their values. I have a class that looks like this :

class A
{
    public string a {get; set;}
    public List<string> nums {get;set;}
    public HashSet<int> hashl {get;set;}
    public DateTime dt {get; set;}
    public decimal v {get;set;}
    public A(string _a, decimal _v)
    {
        this.a = _a;
        this.nums = new List<string>();
        this.dt = DateTime.Today.AddDays(-2);
        this.v = _v;
        this.hashl = new HashSet<int>();
    }
}

And I'm getting the job done like this :

void Main()
{
    var val = new A("E", 34.000345345m);
    val.nums.Add("12312312312");
    val.nums.Add("0000054645");
    val.hashl.Add(34);
    val.hashl.Add(567567);
    Type t = typeof(A);
    PropertyInfo[] properties = t.GetProperties();
    foreach(var p in properties)
    {
        Type propertyType = p.PropertyType;
        if (propertyType.IsPrimitive || propertyType == typeof(decimal) || propertyType == typeof(string) || propertyType == typeof(DateTime) || propertyType == typeof(TimeSpan))
        {
            Console.WriteLine(String.Format("} = {1:f}", p.Name, p.GetValue(val)));
        }
        else if (propertyType.GetInterface("IEnumerable", true) != null)
        {
            Type genericArugment = propertyType.GetGenericArguments()[0];
            string values = string.Join(", ", (p.GetValue(val, null) as IEnumerable).Cast<object>().ToArray());
            Console.WriteLine("} of type {1} = {2}", p.Name, propertyType.GetGenericArguments()[0], values);
        }
    }
}

This code works fine but I want to use genericArugment as an argument in the Cast function, but the error is :

'genericArugment' is a variable but it is used like a Type

The error is quite clear, but how can I used it as a type since the variable 'genericArugment' contains a type ?





Annotate a function and detect when it is called at Runtime - Kotlin/Java

Hello let me try to make this clear: I want to do almost the same thing the Android annotations do. For example :

@RequiresApi(Build.VERSION_CODES.LOLLIPOP) public void someFunction() {}

I would like to make something similar but at Runtime. Annotate a function and when that function is called, i make a treatement (probably using reflection) and depending on the result i proceed to run or not the annotated function. Something like:

@IsLoggedIn() public void someFunction() {}

The someFunction() function will be executed only if the user is logged in.





Using Java reflection class to create an object and use it in arraylist

I started to use Java Reflection recently but currently stuck at this.

So I have something like this:

Class<?> dogClass = Class.forName("com.example.dog");
Object dogObject = dogClass.newInstance();

I would like to use the above object in this arraylist:

List<Dog> dogList = new ArrayList();

So in normal case:

for(Dog d : dogList) {
....
.... 
}

But when I tried to use the java reflection, it doesn't work..

for(dogObject d : dogList) {
....
.... 
}

Can anyone enlighten me please? Thank you.





lundi 17 septembre 2018

Get variable name instead of value

Using bash, I think this is possible, but not sure about JavaScript, say we have this:

    const {masterid} = req.query;

    if (!masterid) {
        return res.status(500).send(new Error('Missing query param "masterid".'));
    }

What I want to do is not hardcode "masterid" in the string, instead do something like this:

    const {masterid} = req.query;

    if (!masterid) {
        return res.status(500).send(new Error(`Missing query param "${Reflect(masterid).name()}.".`));
    }

is there a way to do this with the Reflect API?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect





Setting values of nested struct fields using reflection in Go

I'm trying to create a protobuf structure out of a

type FlatMessage map[string][]byte

and I'm struggling with setting values of nested fields.

I have an

func (fm *FlatMessage) Unflatten() (pb.Message, error)

method to transform flat message into structured protobuf.

I also have a helper function called analyze which takes a struct of type pb.Message and returns a map[int]*ProtoField where:

type ProtoField struct {
    Name  string
    Type  reflect.Type
}

i.e. analyze traverses pb.Message recursively and gathers all the information I need about it. So far so good.

Now when I go key by key through my FlatMessage, the key is an encoded field number of a respective protobuf field, and I can set it using reflection, like this:

r := reflect.ValueOf(&result).Elem().FieldByName(field.Name)
if r.IsValid() {
    r.Set(scalarValue)
}

but that works only when the field.Name in question does not refer to a nested field, i.e., setting OldV1Id works fine, but attempting to set Profile.Id or, say, Destination.Address.TypeOfNumber, results in:

panic: reflect: call of reflect.Value.Set on zero Value [recovered]
    panic: reflect: call of reflect.Value.Set on zero Value

I understand that this is due to the fact that my r becomes <invalid Value> when called on a field which is a nested one, but how can I work around it?

My r is of course not valid, not addressable, and not settable. I can make a reflect.New out of it, but I can't figure out how to set that new reflect.Value in such a way that the field of my original structures becomes modified. No matter what I do the my function doesn't modify fields with nested names with this approach.

Another solution I tried is adding a Value reflect.Value to my ProtoField structure, and modifying analyze so that it appends a reflect.ValueOf(s).Field(i) where s is the top-level struct interface{} and i is its ith field. Then whenever I encounter a field that is a nested one, I call r := reflect.ValueOf(field.Value), but then the problem is I'm unable to call r.Set(scalarValue) because of incompatible types.

Any help or insight is much appreciated.





Enforcer Description Attribute on C# Enums

Is there any way to enforce the usage of DescriptionAttribute on an Enum constants ?

I've tried creating a custom Attribute

    [DescriptionEnforcerAttribute("test")]
    public enum CachedKeys : int
    {
        Summer = 1,
        Winter = 2
    }

    [AttributeUsage(AttributeTargets.Enum)]
    public class DescriptionEnforcerAttribute : Attribute
    {
        public DescriptionEnforcerAttribute(string test)
        {
            CheckEnumConstantsForDescription();
        }

        private static IEnumerable<Type> GetMarkedTypes(Assembly assembly)
        {
            foreach (Type type in assembly.GetTypes())
            {
                if (type.GetCustomAttributes(typeof(DescriptionEnforcerAttribute), true).Length > 0)
                {
                    yield return type;
                }
            }
        }

        /// <summary>
        /// Checks if all constants from an enum have DescriptionAttribute
        /// </summary>
        private static void CheckEnumConstantsForDescription()
        {
            foreach (Type type in GetMarkedTypes(typeof(DescriptionEnforcerAttribute).Assembly))
            {
                MemberInfo[] members = type.GetType().GetMembers();

                foreach (MemberInfo member in members)
                {
                    if (member.GetCustomAttribute<DescriptionAttribute>() == null) throw new EnumDescriptionException();
                }
            }
        }

So the idea is that I want to create an Attribute that will check for all constants within an enum. It should throw an exception if it finds that there are constants that don't have the DescriptionAttribute marker.

Thanks





Creating dynamic security policies for Security Manager

I am currently developing a way of adding 'plugins' or 'apps' to my platform. The general concept is, the developer creates a .jar file, which returns a JPanel when instanced:

appLoader = URLClassLoader.newInstance(new URL[] { someDownloadUrl });
appBuilder = appLoader.loadClass("iezon.app." + someAppName);

I created a AppSecurityManager class to do the processing of the jar file before creating the instance to ensure that their are no socket connections, file reading etc being executed inside the jar file. This is what my default policy looks like:

grant {
    permission java.lang.RuntimePermission "setSecurityManager";
    permission java.lang.RuntimePermission "createSecurityManager";
    permission java.lang.RuntimePermission "usePoliciy";
}

Which works fine when I do this:

System.setProperty("java.security.policy", "file:/C:/Temp/default.policy");
System.setSecurityManager(new SecurityManager());
JPanel panel = (JPanel) appBuilder.newInstance();
System.setSecurityManager(null);
return panel;

However, I want to be able to run a method appBuilder.getMethod("getPermissions").invoke(this, null); which then returns an ArrayList of permissions that jar file needs for the security manager which then the user must agree to before the jar file can create an instance.

I have tried creating a new policy with the app name in the security manager which is called from the policy acceptance panel when the user accepts:

public static void createPolicy(ArrayList<String> policies, App app) {

    try {
        FileWriter fileWriter =
                new FileWriter("C:/Temp/" + app.getName() + ".policy");
        BufferedWriter bufferedWriter =
                new BufferedWriter(fileWriter);

        bufferedWriter.write("grant {");
        bufferedWriter.newLine();

        for(String policy : policies) {
            bufferedWriter.write("    permission java.lang.RuntimePermission \"" + policy + "\";");
            bufferedWriter.newLine();
        }

        bufferedWriter.write("}");
        bufferedWriter.close();

    } catch(IOException ex) {
        ex.printStackTrace();
    }
}

This works fine and all the default policy permissions got wrote into the dynamically made file, however, when I then launch the app:

System.setProperty("java.security.policy", "file:/C:/Temp/" + app.getName() + ".policy");
System.setSecurityManager(new SecurityManager());
JPanel panel = (JPanel) app.getObject().newInstance();
System.setSecurityManager(null);
return panel;

The SecurityManager throws a SecurityException for the setSecurityManager().

Any help would be extremely appreciated where I am going wrong with dynamically building the policy.