dimanche 19 avril 2020

Java Spring MVC - Dynamic property name of class in model

exist easy solution how this (C# . NET):

    private void sortData(string param, string type)
    {
        var propertyInfo = typeof(MusicCatalogueRowClass).GetProperty(param);
        if (type == "asc")
        {
            _Data.rows = _Data.rows.OrderBy(o => propertyInfo.GetValue(o, null)).ToList();
        }
        else {
            _Data.rows = _Data.rows.OrderByDescending(o => propertyInfo.GetValue(o, null)).ToList();
        }
        saveDataToFile();
    }

make in Java Spring (without .NET)? I wanna sort list of object by dynamic name property...

Thank you very much for any advice...





Get list of type(s) of specific interface implemented by concrete class

Given a class, how can i find the types for the INotificationHandler<>:

public class OtherClass : INotificationHandler<Aggregate>, INotificationHandler<Quote>
{
  /* */
}

var typesList = [] { typeof(OtherClass) };

var result = MagicFunctionToGetTemplateTypesForNotificationHandlerInterface(typesList)

// where result = [] { typeof(Aggregate), typeof(Quote) };

I am considering going down the road of GetType().GenericTypeArguments[0] however want to check if there is a safer way first.

I have tried searching and appreciate this could very well be a duplicate, if so please let me know and I will delete.





how to insert data into H2 database using reflection API

I have a Person class anootated with @PrimaryKey and @Column

    public class Person {

    @PrimaryKey(name = "p_id")
    private Integer id;

    @Column(name = "c_name")
    private String name;

    @Column(name = "c_age")
    private Integer age;
    }

Following is the persist method:

   public void persist(T t) throws IllegalArgumentException, IllegalAccessException, SQLException {
    // TODO Auto-generated method stub
    MetaModel metaModel = MetaModel.of(t.getClass());
    String sql = metaModel.buildInsertRequest();

    try(PreparedStatement statement = prepareStatementWith(sql).andParameters(t)){
        statement.executeUpdate();  
    }

}

    private PreparedStatementWrapper prepareStatementWith(String sql) throws SQLException {
    // TODO Auto-generated method stub

    Connection con = buildConnection();
    PreparedStatement statement = con.prepareStatement(sql);

    return new PreparedStatementWrapper(statement);
}

    private class PreparedStatementWrapper{

    private PreparedStatement statement;
    public PreparedStatementWrapper(PreparedStatement statement) {
        // TODO Auto-generated constructor stub
         this.statement = statement;
    }

Here. returning the sql query

   public String buildInsertRequest() {
    // insert into Person(id, name, age) values(?, ?, ?)
    String pkColumnName = getPrimaryKey().getName();
    List<String> columNames = getColumn().stream().map(c -> c.getName()).collect(Collectors.toList());
    columNames.add(0, pkColumnName);
    String columnElement = String.join(", ", columNames);

    int numberOfColumns = getColumn().size() + 1;
    String questionMarkElement = IntStream.range(0, numberOfColumns)
                                            .mapToObj(index -> "?")
                                            .collect(Collectors.joining(", "));
    return "INSERT into " + this.clss.getSimpleName() + "(" + columnElement + ") values (" + questionMarkElement + ")";
}

   Here adding the parameter

   public PreparedStatement andParameters(T t) throws SQLException, IllegalArgumentException, IllegalAccessException {
        // TODO Auto-generated method stub

        MetaModel metaModel = MetaModel.of(t.getClass());
        Class<?> pkType = metaModel.getPrimaryKey().getType();
        if(pkType == Integer.class) {
            Integer id = idGenerator.incrementAndGet();
            statement.setInt(1, id);    
            Field field = metaModel.getPrimaryKey().getField();
            field.setAccessible(true);
            field.set(t, id);
        }
        for(int columnIndex = 0; columnIndex < metaModel.getColumn().size(); columnIndex++) {
            ColumnField columnField = (ColumnField) metaModel.getColumn().get(columnIndex);
            Class<?> fieldType = columnField.getType();
            Field field = columnField.getField();
            field.setAccessible(true);
            Object value = field.get(t);
            if(fieldType == Integer.class) {
                statement.setInt(columnIndex + 2,(Integer) value);
            } else if(fieldType == String.class) {
                statement.setString(columnIndex + 1, (String)value);
            }
        }
        return statement;
    }

I am getting error in prepareStatementWith(sql) method, it's not reurning the new PreparedStatementWrapper instead it's throwing exception Exception in thread "main" org.h2.jdbc.JdbcSQLException: Table "PERSON" not found; SQL statement: INSERT into Person(p_id, c_name, c_age) values (?, ?, ?)

Following is the connection details:

    public Connection buildConnection() throws SQLException {
    Connection con = 
            DriverManager.getConnection("jdbc:h2:C:\\Users\\biplab.musib\\eclipse-workspace\\ReflectionProject\\db-files\\db-files", "sa", "");
    return con;

JDBC url in H2 promp : jdbc:h2:C:\Users\biplab.musib\eclipse-workspace\ReflectionProject\db-files\db-reflection

can someone help me here





Set parameter of any Func<>

I have an object of any of the func types func<>, Func<,>, func<,,> ... And I'd like to replace one of the input parameters with a constant value.

eg:

object SetParameter<T>(object function, int index, T value){
    //I don't know how to code this.
}

Func<int, String, String> function = (a, b) => a.ToString() + b;
object objectFunction = function;
object newFunction = SetParameter<int>(objectFunction, 0, 5);
// Here the new function should be a Func<String, String> which value "(b) => function(5, b)"

I already now how to get the type of the resulting function, but that does not really help me in implementing the desired behavior:

private Type GetNewFunctionType<T>(object originalFunction, int index, T value)
{
    Type genericType = originalFunction.GetType();

    if (genericType.IsGenericType)
    {
        var types = genericType.GetGenericArguments().ToList();
        types.RemoveAt(index);
        Type genericTypeDefinition = genericType.GetGenericTypeDefinition();
        return genericTypeDefinition.MakeGenericType(types.ToArray());
    }

    throw new InvalidOperationException($"{nameof(originalFunction)} must be a generic type");
}




samedi 18 avril 2020

how can I set the value of multiple List in class using reflection?

I want to set the value of some properties using reflection.

  public class ResultContent
    {
        public List<Cars> AllCars { get; set; }
        public List<Colors> AllColors { get; set; }
    }
    public class Colors
    {
        public string Name { get; set; }
        public string Color { get; set; }
    }
    public class Cars
    {
        public string CarName { get; set; }
        public int Speed { get; set; }
    }

    foreach (var prop in typeof(ResultContent).GetProperties())
    {

    }

how can I set the properties inside the List for example inside the List<Cars>





Java reflection without invoking static initializer

In java when you look up a class with Class.forName, set a field using Field.set or call a method using Method.invoke, the static initializer (<clinit> method) is invoked first. Is there a way to avoid or disable this behavior, without changing the bytecode?





How to generate monaco completion proposals from C# assembly?

I have a DLL with a set of classes I want to get code completion in Monaco code editor UI. They require them to be in format like this:

{
            label: '"lodash"',
            kind: monaco.languages.CompletionItemKind.Function,
            documentation: "The Lodash library exported as Node.js modules.",
            insertText: '"lodash": "*"',
            range: range
}

So how to generate Monaco completion proposals from C# assembly?

Notes:

  1. this may be related "Using Roslyn C# Completion Service programmatically" yet how to make them work together?
  2. If one could generate something like this using reflection:
    'namespace test{',
        'declare interface custom {',
        'id :string;',
        '};',
        '',
        'declare function MyCustomFunction(i :custom) :void;',
        '}'

It would solve the problem as shown here