您是否知道任何获取对象的库并返回表示如何使用其构建器类构建该对象的String?

时间:2015-08-26 13:42:39

标签: java json builder

我们说我有以下POJO:

public class Student {

    private String firstName;
    private String lastName;

    public Student(){};

    public Student(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

及其建造者:

public class StudentBuilder {

    private Student student;

    public StudentBuilder() {
        this.student = new Student();
    }

    public StudentBuilder withFirstName(String firstName) {
        this.student.setFirstName(firstName);
        return this;
    }

    public StudentBuilder withLastName(String lastName) {
        this.student.setLastName(lastName);
        return this;
    }

    public Student build() {
        return this.student;
    }
}

鉴于我有一个Student类的实例,是否有一个库可以将student对象作为参数并返回表示该句子的String,以使用其构建器实例化该特定对象?

用法应该是这样的:

    public static void main(String[] args) {
        Student student = new Student("John", "Smith");     
        String builderInstantiator = StringObjectInstantiator.generate(student);
        Assert.assertEquals("new StudentBuilder().withFirstName(\"John\").withLastName(\"Smith\").build();", builderInstantiator);
}

我想在开始实施它之前先问一下。

短篇小说: 我正在处理的应用程序的一个模块将为我提供一个包含序列化pojos的json文件。 基于该json,我必须生成一些使用其构建器实例化这些对象的java类。

输入样本:

[
   {
       "firstName": "John",
       "lastName": "Smith"
   },
   {
       "firstName": "David",
       "lastName": "Winter"
   },
   {
       "firstName": "Rebecca",
       "lastName": "Cross"
   }
]

输出样本:

public class StudentProvider {

    public List<Student> get() {
        return Arrays.asList(
                new StudentBuilder().withFirstName("John").withLastName("Smith").build(),
                new StudentBuilder().withFirstName("David").withLastName("Winter").build(),
                new StudentBuilder().withFirstName("Rebecca").withLastName("Cross").build()
                );
    }
}

1 个答案:

答案 0 :(得分:2)

我认为你可能正在寻找某种代码生成,但我认为不会有库完全符合你的要求。您可以尝试一些构建器生成器,如pojo builder并编辑源代码(或者像Fluent builders这样的eclipse插件。)

除了生成字符串之外,如果对象只包含String,char,int等简单类型,那么生成字符串将很容易。如果你有一个自定义对象,它应该生成什么代码。比方说,如果Student类有一个Object类型的字段,那么需要传递给withXXX()方法的值是什么?如果你能保证所讨论的对象只包含简单的字段,那么编写自己的方法会更好。就像

一样
public static String generate(Object obj){
    StringBuilder str = new StringBuilder("new " + obj.getClass().getSimpleName() + "()");
    Field[] allFields = obj.getClass().getDeclaredFields();
        for (Field field : allFields) {
            field.setAccessible(true);
            try {
            str.append(".with").append(capitalize(field.getName())).append("(").append(resolveField(field.get(obj))).append(")");
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } 
        }
    return str.append(".build();").toString();
}

注意:这是一个快速的解决方案,可能不是一个理想的解决方案。一个完整的例子

import java.lang.reflect.Field;

class CustomObject {
    String innerValue1;
    String innerValue2;

    public CustomObject(String innerValue1, String innerValue2) {
        this.innerValue1 = innerValue1;
        this.innerValue2 = innerValue2;
    }
    public String getInnerValue1() {
        return innerValue1;
    }
    public void setInnerValue1(String innerValue1) {
        this.innerValue1 = innerValue1;
    }
    public String getInnerValue2() {
        return innerValue2;
    }
    public void setInnerValue2(String innerValue2) {
        this.innerValue2 = innerValue2;
    }
}

class Student {

    private String firstName;
    private String lastName;
    private int sample;
    private char sampleChar;
    private CustomObject obj;

    public Student(){};

    public Student(String firstName, String lastName, int sample, char sampleChar, CustomObject obj) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.sample = sample;
    this.sampleChar = sampleChar;
    this.obj = obj;
    }

    public String getFirstName() {
    return firstName;
    }

    public void setFirstName(String firstName) {
    this.firstName = firstName;
    }

    public String getLastName() {
    return lastName;
    }

    public void setLastName(String lastName) {
    this.lastName = lastName;
    }

    public int getSample() {
        return sample;
    }

    public void setSample(int sample) {
        this.sample = sample;
    }

    public CustomObject getObj() {
        return obj;
    }

    public void setObj(CustomObject obj) {
        this.obj = obj;
    }

    public char getSampleChar() {
        return sampleChar;
    }

    public void setSampleChar(char sampleChar) {
        this.sampleChar = sampleChar;
    }
}

public class StringObjectInstantiator {

    public static String generate(Object obj, boolean appenColon){
        StringBuilder str = new StringBuilder("new " + obj.getClass().getSimpleName() + "()");
        Field[] allFields = obj.getClass().getDeclaredFields();
        for (Field field : allFields) {
        field.setAccessible(true);
        try {
                str.append(".with").append(capitalize(field.getName())).append("(").append(resolveField(field.get(obj))).append(")");
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } 
        }
        str.append(".build()");
        return appenColon ?  str.append(";").toString() : str.toString();
    }

    private static String resolveField(Object fieldValue) {
        String className = fieldValue.getClass().getSimpleName();
        if("String".equals(className)){
            return "\"" + fieldValue + "\"";
        } else if("Character".equals(className)){
            return "'" + fieldValue + "'";
        } else if("Number".equals(fieldValue.getClass().getSuperclass().getSimpleName())){
            return fieldValue.toString();
        } else {
            return generate(fieldValue, false);
        }
    }

    private static String capitalize(final String line) {
       return Character.toUpperCase(line.charAt(0)) + line.substring(1);
    }

    public static void main(String[] args) {
        System.out.println(generate(new Student("James", "Bond", 2, 'J', new CustomObject("A", "B")), true));
    }

}