PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label reflection. Show all posts
Showing posts with label reflection. Show all posts

Thursday, November 24, 2022

[FIXED] Why does getClass().getName() work on a module class that is not open?

 November 24, 2022     java, java-9, module, reflection     No comments   

Issue

I have two Java 9 modules, a server, and a handler. The server loads HTTP handlers with the ServiceLoader (code below).

Why does the o.getClass().getName() in this snippet work? Is it because provides opens the handler class up to reflection? Does getClass().getName() not use reflection? Does Java somehow always map an interface to the underlying class instance (and thus to the class) without needing reflection?

server module code:

    ServiceLoader
      .load(HTTPHandlerWithContext.class)
      .stream()
      .map(ServiceLoader.Provider::get)
      .forEach(o -> {
        System.out.printf(
          "registering route %s to %s%n",
          o.getContext(),
          o.getClass().getName()
        );
        server.createContext(o.getContext(), o);
      });

handler module-info:

module com.example.helloworld {
  requires com.example.tinyjhttpd;
  requires jdk.httpserver;
  provides com.example.tinyjhttpd.HTTPHandlerWithContext
    with com.example.helloworld.HelloWorld;
}

What I think is the relevant snippet from Class.java was not enough to make it clear to me:

    // Cache the name to reduce the number of calls into the VM.
    // This field would be set by VM itself during initClassName call.
    private transient String name;
    private native String initClassName();

Solution

The Java Language Specification does not define Reflection (and hence, the impact of opens or the lack thereof) in detail but rather refers to the API specification:

[...] This specification constrains the behavior of such classes and interfaces, but does not provide a complete specification for them. The reader is referred to the Java SE Platform API documentation.

Consequently, this specification does not describe reflection in any detail. Many linguistic constructs have analogs in the Core Reflection API (java.lang.reflect) and the Language Model API (javax.lang.model), but these are generally not discussed here.

The Java SE Platform API documentation specifies when an IllegalAccessException can be thrown, e.g. on invocations of Field.get or Method.invoke.

Neither Object.getClass() nor Class.getName() have been specified to potentially throw an IllegalAccessException.

This is consistent with the runtime behavior of Java before the module system introduction. Just the rules regarding when an access is granted or not became more complex.

The impact of being able to query the name of a class is rather low compared to accessing the internal data or invoking non-API methods.



Answered By - Holger
Answer Checked By - Senaida (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, October 28, 2022

[FIXED] How to check an empty object?

 October 28, 2022     c#, is-empty, object, reflection     No comments   

Issue

I have a number of objects. Some of them have string properties and some of them have bool properties. I'm using them in multi-step form. so each step is bound to each object.

Now, if the user fills the first two sections and saves the data as a user wants to fill rest of the data later. At this point, I need to identify how much data is filled and how much is left. So that next time when the form gets loaded, based on the previously filled data I can identify from where to start filling the form.

I'm trying to identify at the time of saving that how many objects have values. In other words, if I find an object with all the values e.g. empty strings, I can skip that object to be saved into the database. I referred this https://stackoverflow.com/a/22683141/10037521 which shows how to check empty object which has all the string properties.

How to include boolean properties as well in this check? e.g. If the object has 10 bool properties and if all of them are false, I need to identify that object as empty.

So to summarize above question, how to identify if the object is blank which have bool or string properties?


Solution

Technically, you can combine Reflection and Linq into something like this:

  Object obj = ...

  // All Empty (false or null) public properties of either string or bool type
  PropertyInfo[] emptyProps = obj
    .GetType()
    .GetProperties(BindingFlags.Instance | BindingFlags.Public)
    .Where(prop => prop.CanRead) // you may want to check prop.CanWrite as well
    .Where(prop => prop.PropertyType == typeof(bool) || 
                   prop.PropertyType == typeof(string))
    .Where(prop => object.Equals(prop.GetValue(obj), 
                                 prop.PropertyType.IsValueType 
                                   ? Activator.CreateInstance(prop.PropertyType) 
                                   : null))
    .ToArray();

However, I doubt if you should do this: some properties should not be saved:

   // Should be saved
   public string FirstName {...} 
   // Should be saved
   public string SecondName {...} 
   // Should NOT be saved
   public string Name {get {return $"{FirstName} {SecondName}";}}

You can have elaborated criteria which data should be saved, e.g. in case of FirstName you may want to check (at least!)

   // FirstName must be not null, not empty and not blank
   bool shouldSave = !string.IsNullOrWhiteSpace(FirstName);

That's why I suggest implementing a custom property / method within the class:

   public class MyClass {
     ...
     // virtual: you may want to add some properties in a derived class 
     public virtual bool IsEmpty {
       get {
         return string.IsNullOrWhiteSpace(FirstName) &&
                string.IsNullOrWhiteSpace(SecondName) &&
                ...
       }
     } 
   }


Answered By - Dmitry Bychenko
Answer Checked By - Cary Denson (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, October 25, 2022

[FIXED] How to programmatically find public properties of a class from inside one of it's methods

 October 25, 2022     oop, php, reflection     No comments   

Issue

I've got a class Foo with public and protected properties. Foo needs to have a non-static method, getPublicVars() that returns a list of all the public properties of Foo (this is just an example, I know from outside the Foo object calling get_object_vars() will accomplish this and there is no need for my getPublicVars() method).

Note: This must also return dynamically declared properties assigned at runtime to the class instance (object) that aren't defined in the class's definition.

Here's the example:

class Foo{
    private $bar = '123';
    protect $boo = '456';
    public   $beer = 'yum';

   //will return an array or comma seperated list
   public function getPublicVars(){
      // thar' be magic here...
   } 
}

 $foo = new Foo();
 $foo->tricky = 'dynamically added var';

 $result = $foo->getPublicVars();  
 var_dump($result); // array or comma list with 'tricky' and 'beer'   

What is the most concise way to get the only the public properties of an object from inside a class's own methods where both public and protected are visible?

I've looked at:

  • What is the best way to look inside a PHP class instance (object) to see all of its available public properties and methods?

But this doesn't seem to address my question as it points to using get_object_vars() from outside the object.


Solution

As you already realized, PHP's build in get_object_vars is scope-sensitive. You want the public object properties only.

So from that function to the public variant is not a large step:

function get_object_public_vars($object) {
    return get_object_vars($object);
}

Calling this get_object_public_vars will give you only the public properties then because it is place out of scope of the current object.

If you need more fine-grained control, you can also make use of the ReflectionObject:

(new ReflectionObject($this))->getProperties(ReflectionProperty::IS_PUBLIC);

Which has the benefit that you don't need to introduce another function in the global namespace.



Answered By - hakre
Answer Checked By - Mary Flores (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, September 20, 2022

[FIXED] How to use consumer and supplier instead Reflection in java 8

 September 20, 2022     consumer, java, reflection     No comments   

Issue

I have a two simple class and use reflection pattern for invoke method. I want to write module programming. Suppose we have a table in database that keep modules name:

Id  moduleName methodName   ClassName              active
1     sample     a           com.examle.sample        true  
2     SMS        sendSMS     com.example.SMS          false
3     Email      sendEmail   com.example.Email        false 
... ...          ...                       ...

When active is true the module must be activated.So when i write a program and compile that, i do not like again compile whole MyApp. So i use reflection pattern to invoke module. please see the codes.

public class Sample {
    public void a() {
        System.out.println("Call Method a");
    }
}
public class SMS {
    public void sendSMS(String str) {
        System.out.println("send SMS ok");
    }
}
public class Email {
    public void sendEmail(String str) {
        System.out.println("send Email ok");
    }
}
public class SampleMainClass {
    public static void main(String[] args) {

            //coonect to database and fetch all record in tables 
       while(record.next){
          if (record.getActive()){        
            Object o = Class.forName(record.getClssName()).newInstance() ;
            Method method = o.getClass().getDeclaredMethod(record.getMethodName());
            method.invoke(o);
          }                            
       }
    }

output

   Call Method a

So i heard in the java 8, reflection pattern is deprecate and instead that we can use consumer and supplier.

How to use consumer and supplier instead Reflection in java 8?

Thanks.


Solution

public class Q42339586 {

    static class Sample {
        void a() { System.out.println("a() called"); }
        void b() { System.out.println("b() called"); }
    }

    static <T> void createInstanceAndCallMethod(
            Supplier<T> instanceSupplier, Consumer<T> methodCaller) {
        T o = instanceSupplier.get();
        methodCaller.accept(o);
    }

    public static void main(String[] args) {
        createInstanceAndCallMethodJava8(Sample::new, Sample::a);
    }

}

Here, createInstanceAndCallMethod does what is done in your main() Method but it accepts parameters instead.

A Supplier is used to create a new instance and a Consumer is used to call a particular method on that instance. In the example both method references are passed as both parameters. Instead, you could also use lambda expressions and write () -> new Sample() and o -> o.a() instead. Please refer to this official tutorial part for more information.

The advantages over reflection are obvious:

  1. You cannot ask createInstanceAndCallMethod to create an instance of a class that doesn't exist.
  2. You cannot ask createInstanceAndCallMethod to call a method that doesn't exist in a particular class.
  3. As a result of both you don't have to deal with any checked Exception.

Of course this does only work when at some place in the code the actual class and method are known, e.g. it's not possible to read class and method name from a properties file and then use Java 8 mechanisms to safely create an instance and call a particular method.



Answered By - Markus Benko
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, September 19, 2022

[FIXED] How to retrieve arguments of a lambda expression?

 September 19, 2022     consumer, java, java-8, lambda, reflection     No comments   

Issue

How can I reparse java.util.function.Consumer instance and retrieve arguments and values of its lambda expression (forexample "student.person.surname"). Shortly I want to retrieve lambda expression (Consumer) as a text at runtime.

import lombok.Data;

import java.util.function.Consumer;

public class ConsumerTest {

    @Data
    public static class Person{
        private Integer id;
        private String name;
        private String surName;
    }

    @Data
    public static class Student{
        private Integer id;
        private Person person;
    }

    public static void main(String args[])
    {
        Student student = new Student();
        student.setId(1);
        Person person = new Person();
        person.setName("Ali");
        person.setSurName("Veli");
        person.setId(2);
        student.setPerson(person);

        Consumer<Student> displayLambda = s -> s.getPerson().setSurName("Gulsoy");

        displayLambda.accept(student);

    //I want to reparse displaylambda instance and print arguments. 
    //As here I must be able to retrieve "student.person.surname" and "Gulsoy"
    }

}

Solution

Thanks a lot for the answers. I have found a way to my problem by using de.danielbechler.diff.ObjectDifferBuilder even though I haven't read lambda expression exactly.

Before running consumer accept method, student object is cloned and after executing displayLambda.accept(student) we can get the difference between changed student object and previous student object. And so we can catch changed parameter and value as seen below.

import de.danielbechler.diff.ObjectDifferBuilder;
import de.danielbechler.diff.node.DiffNode;
import de.danielbechler.diff.node.Visit;
import lombok.Data;

import java.util.function.Consumer;

public class ConsumerTest {

    @Data
    public static class Person implements Cloneable{
        private Integer id;
        private String name;
        private String surName;

        public Person clone() throws CloneNotSupportedException {
            Person clonedObj = (Person) super.clone();
            clonedObj.name = new String(this.name);
            clonedObj.surName = new String(this.surName);
            clonedObj.id = new Integer(id);
            return clonedObj;
        }
    }

    @Data
    public static class Student implements Cloneable{
        private Integer id;
        private Person person;

        public Student clone() throws CloneNotSupportedException {
            Student clonedObj = (Student) super.clone();
            clonedObj.id = new Integer(id);
            clonedObj.person = this.person.clone();
            return clonedObj;
        }
    }

    public static void main(String args[])
    {
        Consumer<Student> displayLambda = s -> s.getPerson().setSurName("Gülsoy");

        Student student = new Student();
        student.setId(1);
        Person person = new Person();
        person.setName("Ali");
        person.setSurName("Veli");
        person.setId(2);
        student.setPerson(person);

        Student preStudent=null;

        // Before running consumer accept method, clone unchanged student object
        try {
            preStudent = student.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        // executing consumer lambda expression with accept method
        displayLambda.accept(student);

        // Checking difference with new Student instance and previous Student instance
        DiffNode diff = ObjectDifferBuilder.buildDefault().compare(preStudent, student);

        if (diff.hasChanges()) {
            Student finalPreStudent = preStudent;
            diff.visit((node, visit) -> {
                if (!node.hasChildren()) { // Only print if the property has no child
                    final Object oldValue = node.canonicalGet(finalPreStudent);
                    final Object newValue = node.canonicalGet(student);

                    // By doing this way we can catch parameter name and changing value
                    final String message = node.getPropertyName() + " changed from " +
                            oldValue + " to " + newValue;
                    System.out.println(message);
                }
            });
        } else {
            System.out.println("No differences");
        }
    }
}



Answered By - zekai
Answer Checked By - Terry (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, August 25, 2022

[FIXED] How to list the clauses inside a module in SWI-Prolog?

 August 25, 2022     module, prolog, reflection, swi-prolog     No comments   

Issue

SWI-Prolog has for example the library(dcgbasics) for use with DCGs.

While referencing the module is easy with use_module/1, e.g.

:- use_module(library(dcg/basics)).

trying to use listing/1 with it is not so easy.

?- listing(dcg:_).
true.

?- listing(dcgbasics:_).
true.

?- basics:listing.
true.

What is the correct way to get a listing of the clauses in library(dcg/basics)?


Follow up after answer given.

To list a specific clause, e.g. blanks//0 the query is

?- listing(dcg_basics:blanks).
blanks(A, B) :-
    blank(A, C),
    !,
    D=C,
    blanks(D, B).
blanks(A, A).

true.

Solution

Use either:

?- dcg_basics:listing.

Or:

?- listing(dcg_basics:_).

The first argument of use_module/1-2 is a file specification, not a module name. But listing the module contents requires the actual module name, which may be different (as it is the case here) from the module file basename. But how to find the module name from the file specification? In the particular case of SWI-Prolog:

?- absolute_file_name(library(dcg/basics), Path, [extensions([pl])]),
   module_property(Module, file(Path)).
Path = '/Users/pmoura/lib/swipl/library/dcg/basics.pl',
Module = dcg_basics.


Answered By - Paulo Moura
Answer Checked By - Willingham (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, August 24, 2022

[FIXED] How to list all functions in a module?

 August 24, 2022     inspect, module, python, reflection     No comments   

Issue

I have a Python module installed on my system and I'd like to be able to see what functions/classes/methods are available in it.

I want to call the help function on each one. In Ruby I can do something like ClassName.methods to get a list of all the methods available on that class. Is there something similar in Python?

e.g. something like:

from somemodule import foo
print(foo.methods)  # or whatever is the correct method to call

Solution

Use the inspect module:

from inspect import getmembers, isfunction

from somemodule import foo
print(getmembers(foo, isfunction))

Also see the pydoc module, the help() function in the interactive interpreter and the pydoc command-line tool which generates the documentation you are after. You can just give them the class you wish to see the documentation of. They can also generate, for instance, HTML output and write it to disk.



Answered By - Thomas Wouters
Answer Checked By - Terry (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, August 4, 2022

[FIXED] What could cause java.lang.reflect.InvocationTargetException?

 August 04, 2022     exception, invoke, java, reflection     No comments   

Issue

Well, I've tried to understand and read what could cause it but I just can't get it:

I have this somewhere in my code:

 try{
 ..
 m.invoke(testObject);
 ..
 } catch(AssertionError e){
 ...
 } catch(Exception e){
 ..
 }

Thing is that, when it tries to invoke some method it throws InvocationTargetException instead of some other expected exception (specifically ArrayIndexOutOfBoundsException). As I actually know what method is invoked I went straight to this method code and added a try-catch block for the line that suppose to throw ArrayIndexOutOfBoundsException and it really threw ArrayIndexOutOfBoundsException as expected. Yet when going up it somehow changes to InvocationTargetException and in the code above catch(Exception e) e is InvocationTargetException and not ArrayIndexOutOfBoundsException as expected.

What could cause such a behavior or how can I check such a thing?


Solution

You've added an extra level of abstraction by calling the method with reflection. The reflection layer wraps any exception in an InvocationTargetException, which lets you tell the difference between an exception actually caused by a failure in the reflection call (maybe your argument list wasn't valid, for example) and a failure within the method called.

Just unwrap the cause within the InvocationTargetException and you'll get to the original one.



Answered By - Jon Skeet
Answer Checked By - Senaida (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, July 30, 2022

[FIXED] How to search for null values inside a java object?

 July 30, 2022     java, junit, reflection, validation     No comments   

Issue

I'm writing a JUnit test to assert that my algorithm's output object does not present any null value or empty strings.

For simplicity imagine 3 classes : Parent, Child, Car, where Parent is the object that I have to validate.

@Data
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder
public class Child {
    String name;
    int age;
}

@Data
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder
public class Car {
    String brand;
    String model;
}

@Data
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder
public class Parent {
    String name;
    int age;
    List<Child> children;
    Car car;
}

what is the best and easy way to search for null values or empty strings?

I'm currently using the following method as a validator, checking field by field for null values and empty strings.

private boolean isValid(Parent parent) {
    if(parent == null) return false;

    boolean isObjectNull = Stream.of(parent.getName(), parent.getChildren(), parent.getCar()).anyMatch(Objects::isNull);

    if(isObjectNull) return false;

    isObjectNull = Stream.of(parent.getCar().getBrand(), parent.getCar().getModel()).anyMatch(Objects::isNull);

    if(isObjectNull) return false;
    
    for(Child child : parent.getChildren()){
        isObjectNull = Stream.of(child.getName()).anyMatch(Objects::isNull);
        
        if(isObjectNull) return false;

        if(!isValidString(child.getName())) return false;
    }
    
    return isValidString(parent.getName(), parent.getCar().getBrand(), parent.getCar().getModel());
}

private boolean isValidString(String... values){
    for(String s : values){
        if(s.isEmpty())
    }
}

But I would love something I can also use for other objects I will create in the future.


Solution

You can use reflection to obtain all the getters from your objects that do return a reference (instead of a primitive). Then iterate over that list (or array, your choice) and execute them; when the return value for any of these is null, return false or throw an appropriate exception.

A little bit like this:

public final void validateNonNull( final Object candidate ) throws ValidationException
{
  if( isNull( candidate ) throw new ValidationException( "candidate is null" );

  final var candidateClass = candidate.getClass();
  final List<Method> getters = Arrays.stream( candidateClass.getMethods() ) // getters are always public!
    .filter( m -> !m.getName().equals( "getClass" ) )
    .filter( m -> m.getName().startsWith( "get" ) )
    .filter( m -> m.getParameterCount() == 0 )
    .filter( m -> !m.getReturnType().isPrimitive() )
    .collect( Collectors.toList() );

  for( var method : methods )
  {
    if( isNull( method.invoke( candidate ) ) throw new ValidationException( "candidate.%s() returned null".formatted( method.getName() ) );
  }
}

ValidationException is a custom exception, and you need to declare the checked exceptions that are declared for Method::invoke.

To check for empty Strings, too, change the for loop like this:

…
for( var method : methods )
{
  var retValue = method.invoke( candidate );
  if( retValue instanceof String aString && aString.isEmpty() ) throw new ValidationException( "candidate.%s() returned the empty String".formatted( method.getName() ) ); 
  if( isNull( retValue ) throw new ValidationException( "candidate.%s() returned null".formatted( method.getName() ) );
}


Answered By - tquadrat
Answer Checked By - David Goodson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, July 25, 2022

[FIXED] How to unmarshall JSON into a value created with reflection?

 July 25, 2022     go, json, reflection     No comments   

Issue

package controllers

import (
    "encoding/json"
    "errors"
    "io"
    "io/ioutil"
    "reflect"
)

func GetTypeFromReq(c *App, ty interface{}) (interface{}, error) {
    //get the type we are going to marshall into
    item := reflect.ValueOf(ty)

    //define and set the error that we will be returning to null
    var retErr error
    retErr = nil

    //extract the body from the request and defer closing of the body
    body, err := ioutil.ReadAll(io.LimitReader(c.Request.Body, 1048576))
    defer c.Request.Body.Close()

    //handle errors and unmarshal our data
    if err != nil {
        retErr = errors.New("Failed to Read body: " + err.Error())
    } else if err = json.Unmarshal(body, &item); err != nil {
        retErr = errors.New("Unmarshal Failed: " + err.Error())
    }

    return item, retErr
}

I am trying to pass a type and a request into a function, then inside that function unMarshall the request into a variable and return it.

I assume my approach is wrong because when i try to do this:

inter, err := GetTypeFromReq(&c, models.User{})
if err != nil {
    revel.ERROR.Println(err.Error())
}
user := inter.(models.User)

I get the error "interface conversion: interface {} is reflect.Value, not models.User"

any tips on how to approach this?


Solution

Here's how to modify the the function to make it work as expected:

func GetTypeFromReq(c *App, ty interface{}) (interface{}, error) {
  // Allocate new value with same type as ty
  v := reflect.New(reflect.TypeOf(ty))

  //define and set the error that we will be returning to null
  var retErr error
  retErr = nil

  //extract the body from the request and defer closing of the body
  body, err := ioutil.ReadAll(io.LimitReader(c.Request.Body, 1048576))
  defer c.Request.Body.Close()

  //handle errors and unmarshal our data
  if err != nil {
    retErr = errors.New("Failed to Read body: " + err.Error())
  } else if err = json.Unmarshal(body, v.Interface()); err != nil {
    retErr = errors.New("Unmarshal Failed: " + err.Error())
  }

  // v holds a pointer, call Elem() to get the value.
  return v.Elem().Interface(), retErr
}

Note the calls to Interface() to get a reflect.Value's current value.

Here's an approach that avoids reflection and type assertions:

func GetFromReq(c *App, item interface{}) error {
  //extract the body from the request and defer closing of the body
  body, err := ioutil.ReadAll(io.LimitReader(c.Request.Body, 1048576))
  defer c.Request.Body.Close()

  //handle errors and unmarshal our data
  if err != nil {
    retErr = errors.New("Failed to Read body: " + err.Error())
  } else if err = json.Unmarshal(body, item); err != nil {
    retErr = errors.New("Unmarshal Failed: " + err.Error())
  }
  return retErr
}

Use it like this:

var user models.User
err := GetFromReq(&c, &user)
if err != nil {
   revel.ERROR.Println(err.Error())
}

Use a JSON decoder to simplify the code:

func GetFromReq(c *App, item interface{}) error {
  defer c.Request.Body.Close()
  return json.NewDecoder(io.LimitReader(c.Request.Body, 1048576)).Deocode(item)
}

If c.Request is a *http.Request and c.Response is an http.ResponseWriter, then write the function as:

func GetFromReq(c *App, item interface{}) error {
  return json.NewDecoder(http.MaxBytesReaer(c.Response, c.Request.Body, 1048576)).Deocode(item)
}

There's no need to close the request body in the net/http server. Use MaxBytesReader instead of io.LimitReader to prevents clients from accidentally or maliciously sending a large request and wasting server resources.



Answered By - Cerise Limón
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, July 24, 2022

[FIXED] How to output a formatted string from a JSON model class

 July 24, 2022     c#, json, reflection, system.text.json     No comments   

Issue

I want something like the following:

using System;
using System.Text;
using System.Text.Json;
                    
public class Program
{
   public static void Main()
   {
      var myArgs = new ArgClass();
        
      // myArgs is populated via System.Text.Json deserialization
        
      Console.WriteLine(myArgs.ToArguments());
   }
}

public interface IArguments {}

public class ArgClass : IArguments
{
   [JsonPropertyName("propertyA")]
   public string PropA {get; set;}
    
   [JsonPropertyName("propertyA")]
   public int PropB {get; set;}
}

public static class IArgumentsExt
{
   public static string ToArguments(this IArguments ArgObj)
   {
      var argString = new StringBuilder();

      //Code to build argument string

      return argString.ToString();
    } 
}

So that the Console.Writeline() would output the following string:

-argument propertyA="some text" -argument propertyB=123

I feel like this is something that has to be done with reflection, but I know nothing about reflection. I have tried really hard to avoid situations that require it because everything I read (or watch) says it's slow.

The reason I want to do it like this is that the JSON string that I am deserializing has more properties that I am interested in at to moment, but I might want to use more of them in the future; like if I add more features to my app later. As it stands I can add PropC to ArgClass to pick up another JSON property. In which case I would want the new output of ToArguments() to be:

-argument propertyA="text a" -argument propertyB=123 -argument propertyC="text c"

without having to modify ToArguments().

Or maybe make another class:

public class OtherArgClass : IArguments
{
   [JsonPropertyName("propertyD")]
   public string PropD {get; set;}
    
   [JsonPropertyName("propertyE")]
   public int PropE {get; set;}
}

and have an output of myOtherArgs.ToArguments():

-argument propertyD="some other text" -argument propertyE=45.678

again, without modifying ToArguments().

I am using .Net 7 Preview and System.Text.Json (not Newtonsoft/Json.net)


Solution

Yes, System.Reflection is needed to achieve your required value.

  1. Get the properties of the instance which applies the JsonPropertyName attribute.

  2. Iterate the properties.

    2.1. Get the property name from the JsonPropertyName attribute.

    2.2. Get the property value and serialize.

    2.3. Add both values into StringBuilder.

using System.Reflection;
using System.Linq;

public static class IArgumentsExt
{
   public static string ToArguments(this IArguments ArgObj)
   {
      var argString = new StringBuilder();
       
       PropertyInfo[] props = ArgObj.GetType().GetProperties()
           .Where(x => x.CustomAttributes.Any(y => y.AttributeType.Name == nameof(JsonPropertyNameAttribute)))
           .ToArray();

       foreach (PropertyInfo prop in props)
       {       
           string propertyName = ((JsonPropertyNameAttribute)prop.GetCustomAttribute(typeof(JsonPropertyNameAttribute))).Name;

           // Or
           // string propertyName = prop.GetCustomAttribute<JsonPropertyNameAttribute>().Name;

           string propertyValue = JsonSerializer.Serialize(prop.GetValue(ArgObj));
           argString.Append($"-argument {propertyName}={propertyValue} ");
       }

      return argString.ToString()
          .Trim();
    } 
}

Sample .NET Fiddle



Answered By - Yong Shun
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, July 22, 2022

[FIXED] How to get parameter type in reflected class method (PHP 5.x)?

 July 22, 2022     parameters, php, php-5.4, reflection     No comments   

Issue

I'm trying to get type $bar variable.

<?php
class Foo
{
    public function test(stdClass $bar, array $foo)
    {

    }
}

$reflect = new ReflectionClass('Foo');
foreach ($reflect->getMethods() as $method) {
    foreach ($method->getParameters() as $num => $parameter) {
        var_dump($parameter->getType());
    }
}

I expect stdClass but I get

Call to undefined method ReflectionParameter::getType()

What can be wrong? Or there is some another way?..

$ php -v
PHP 5.4.41 (cli) (built: May 14 2015 02:34:29)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2014 Zend Technologies

UPD1 It should work for the array type as well.


Solution

It looks like similar question already added in PHP Reflection - Get Method Parameter Type As String

I wrote my solution it works for all cases:

/**
 * @param ReflectionParameter $parameter
 * @return string|null
 */
function getParameterType(ReflectionParameter $parameter)
{
    $export = ReflectionParameter::export(
        array(
            $parameter->getDeclaringClass()->name,
            $parameter->getDeclaringFunction()->name
        ),
        $parameter->name,
        true
    );
    return preg_match('/[>] ([A-z]+) /', $export, $matches)
        ? $matches[1] : null;
}


Answered By - Kirby
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, July 12, 2022

[FIXED] How to use reflection in Android for sending sms from second sim slot?

 July 12, 2022     android, dual-sim, message, reflection, sms     No comments   

Issue

I need to send sms via second slot of an android device. I searched many times to find a solution for sending sms with second sim slot. But there is not any regular solution for this problem. Some people use reflection for each series of mobile devices for sending sms from second slot. Now, how can I use reflection for this problem?


Solution

You don't mention which cookie you're targeting, but in Lollipop MR1 you can send with the second SIM card by fetching the SmsManager based on subscription:

http://developer.android.com/reference/android/telephony/SmsManager.html#getSmsManagerForSubscriptionId(int)

Every SIM card gets assigned a subscription ID when they are inserted. These IDs and information about the SIM are stored in the siminfo table in the TelephonyProvider. The IDs start from 1. To get information about what subscription IDs you currently have active, you use the SubscriptionManager: http://developer.android.com/reference/android/telephony/SubscriptionManager.html

The method getActiveSubscriptionInfoForSimSlotIndex takes a SIM slot index (normally either 0 or 1) and returns subscription info about that SIM, including the subscription ID which you can use to fetch the right SmsManager.

If you're targeting platforms prior to Lollipop then the DS support is not officially supported by Google and it's most likely added by the platform vendor (Qualcomm, Mediatek etc.) so the API is undocumented. You can query the SmsManager for its methods by calling SmsManager.class.getDeclaredMethods(), but the DS API might be in a completely different and undocumented class.



Answered By - fejd
Answer Checked By - Clifford M. (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home
View mobile version

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing