6

I have a form which is accepting only String variables but I want to generate a Class instance such that each string property is converted to its corresponding type identified by property name in the class.

For e.g. If I have three fields in a form with the name of NAME, ANNUAL SALARY and isLocalResident. I want to convert this form to an instance of Class1 where these properties are of String, BigInteger and Boolean type.

How do I do that?

Currently I am using BeanUtil Property of java, but it doesn't fulfill my requirement because it just doesn't covert to its required types; rather it asks me a setter and getter of the desired type. Please help me out of this. Any suggestion would be appreciated?

P note that this form is dynamic, i.e. number and name of fields shall depend on another input. The following code represents generating instance emp1 for Employee1 class.

public Empolyee1 setContent(List<String> nameList, List<String> valueList) {
    Empolyee1 emp1 = new Empolyee1();

    for(String attr : nameList) {
        if(attr.equalsIgnoreCase("name")) { 
            if(valueList.get(nameList.indexOf("name")) != null && !valueList.get(nameList.indexOf("name")).trim().equals("")) {
                emp1.setName(valueList.get(nameList.indexOf("name")));
            }
    } else {
        if(attr.equalsIgnoreCase("ANNUAL SALARY")) {
            if(valueList.get(nameList.indexOf("ANNUAL SALARY")) != null && !valueList.get(nameList.indexOf("ANNUAL SALARY")).trim().equals("")) {
                  emp1.setAnnualSalary(valueList.get(nameList.indexOf("ANNUAL SALARY")));
            }
        } else {
            if(attr.equalsIgnoreCase("isLocalResident")) {
                if(valueList.get(nameList.indexOf("isLocalResident")) != null && !valueList.get(nameList.indexOf("isLocalResident")).trim().equals("")) {
                    emp1.setIsLocalResident(valueList.get(nameList.indexOf("isLocalResident")));    
                }
            } 
        }
    }
    return empl1;
}
RamenChef
  • 5,557
  • 11
  • 31
  • 43
  • It's not clear: you want to instance a class with a dynamic number of attributes (of a dynamic type) automatically converted ? You don't know the number and type of the attributes, but do you know the overall number and type of attributes ? Do you know the (for example) 50 possible attributes, that in the form could combine in every permutation ? – Andrea Ligios Sep 21 '16 at 08:19
  • Refer this. http://stackoverflow.com/questions/13868986/dynamically-create-an-object-in-java-from-a-class-name-and-set-class-fields-by-u – Vel Sep 22 '16 at 02:07
  • @AndreaLigios , Yes I know the overall number and type of attributes. For example, I have 10 different classes with total number of 100 attributes. And each class may have different number of attributes. And i have xsd for each of the 10 classes containing getter and setter. Now, i have to set a class selected from UI. – jaswant meena Sep 23 '16 at 04:48
  • Note that using a for each loop and `indexOf` isn't a good way of doing this: use a regular for loop with an int index (e.g. `i`), and use this to get corresponding elements of `nameList` and `valueList` (e.g. `String attr = nameList.get(i); String value = valueList.get(i).trim();`). Of course, using a `Map` would be better again... – Andy Turner Nov 18 '16 at 20:26
  • Why not struts or spring? – Tony Jan 14 '17 at 10:56

1 Answers1

0

The key point is converting field name to Java Bean property name. toPropertyName method is a simple implementation based on the example of your question. (Bewared! if you need to support nested bean property, make sure your code prevent the potential class loader vulnerability of CVE-2014-0114...)

public static String toPropertyName(String s) {
    int len = s.length();
    StringBuilder sb = new StringBuilder(len);
    boolean toUpper = false;
    boolean isLower = false;
    for (int i = 0; i < len; i++) {
        char ch = s.charAt(i);
        if (Character.isLetterOrDigit(ch)) {
            if (Character.isUpperCase(ch)) {
                sb.append((toUpper || isLower)?ch:Character.toLowerCase(ch));
                isLower = false;
            } else {
                isLower = true;
                sb.append(toUpper?Character.toUpperCase(ch):ch);
            }
            toUpper = false;
        } else {
            isLower = false;
            toUpper = true;
        }
    }
    return sb.toString();
}

public Empolyee1 setContent(List<String> nameList, List<String> valueList) throws Exception {
    HashMap<String, String> map = new HashMap<String, String>();
    Iterator<String> nameIter = nameList.iterator();
    Iterator<String> valueIter = valueList.iterator();
    while (nameIter.hasNext()) {
        String name = (String) nameIter.next();
        map.put(toPropertyName(name), valueIter.hasNext()?valueIter.next():null);
    }
    Empolyee1 emp1= new Empolyee1();
    BeanUtils.populate(emp1, map);
    return emp1;
}

BeanUtils.populate(emp1, map) API is used to take other job. It convert inputed values and call setter of each Java Bean property.

Beck Yang
  • 3,004
  • 2
  • 21
  • 26