Преобразование исходного кода Java для перемещения аннотаций из геттеров в свойства - PullRequest
0 голосов
/ 13 июня 2019

У меня есть около 300 объектов JPA, где получатели снабжены аннотациями постоянства.Я хотел бы найти способ переместить все такие аннотации вместо свойств и удалить все методы получения и установки.Я сделал это вручную примерно для 100 из этих классов, но это очень трудоемкая и умопомрачительная работа.

Я смотрю на инструменты преобразования исходного кода, такие как Ложка , но все еще не уверен, что он может делать то, что мне нужно.

Более конкретно, как я могу преобразоватьэтот код:

@Entity
@Table(name = "crm_ticket")
public class CrmTicket implements Serializable {

    private static final long serialVersionUID = -902718555957517699L;

    private CrmAccount crmAccount;
    private ItsType subType;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "account")
    public CrmAccount getCrmAccount() {
        return crmAccount;
    }

    public void setCrmAccount(CrmAccount crmAccount) {
        this.crmAccount = crmAccount;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "sub_type")
    public ItsType getSubType() {
        return subType;
    }

    public void setSubType(ItsType type) {
        this.subType = type;
    }
}

К этому:

@Entity
@Table(name = "crm_ticket")
@Data
public class CrmTicket implements Serializable {

    private static final long serialVersionUID = -902718555957517699L;
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "account")
    private CrmAccount crmAccount;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "sub_type")
    private ItsType subType;
}

Ответы [ 2 ]

1 голос
/ 15 июня 2019

Ложка будет хорошо работать для этого, вы должны использовать aField. addAnnotation и aSetter. delete .

0 голосов
/ 15 июня 2019

Я использовал Ложку .Это было не так больно.Я настроил их плагин maven для запуска моего процессора, и он преобразовал код моих классов Entity.Затем я скопировал сгенерированный код обратно в мой проект и удалил конфигурацию плагина.

Вот мой код процессора:

public class JpaAnnotationMover extends AbstractProcessor<CtMethod> {

    Pattern p1 = Pattern.compile("return.*this\\.(.*?)$");
    Pattern p2 = Pattern.compile("return(.*?)$");

    @Override
    public boolean isToBeProcessed(CtMethod method) {
        return isInEntity(method) && isAGetter(method) && hasOneStatement(method) && !isTransient(method);
    }

    @Override
    public void process(CtMethod ctMethod) {
CtType parentClass = ctMethod.getParent(CtType.class);
        String fieldName = getFieldName(ctMethod);

        if (fieldName == null) {
            log.warn(String.format("expected field name for %s not found.", ctMethod.getSimpleName()));
            return;
        }

        CtField field = parentClass.getField(fieldName);
        if (field == null) {
            log.warn(String.format("Expected field %s not found.", fieldName));
            return;
        }

        for (CtAnnotation<? extends Annotation> annotation : ctMethod.getAnnotations()) {
            field.addAnnotation(annotation);
        }

        parentClass.removeMethod(ctMethod);
        log.info(String.format("Processed method %s:%s", parentClass.getSimpleName(), ctMethod.getSimpleName()));

        // find corresponding setter
        String setterName = "set" + WordUtils.capitalize(fieldName);

        @SuppressWarnings("unchecked") CtMethod setter = parentClass
                .getMethod(getFactory().Type().createReference("void"), setterName, ctMethod.getType());

        if (setter == null) {
            log.warn(String.format("Unable to find setter for %s", fieldName));
            return;
        }

        parentClass.removeMethod(setter);

        if (!parentClass.hasAnnotation(Data.class)) {
            parentClass.addAnnotation(getFactory().createAnnotation(getFactory().Type().createReference(Data.class)));
        }
}

private Boolean isInEntity(CtMethod method) {
        CtType parentClass = method.getParent(CtType.class);
        return parentClass.hasAnnotation(Entity.class);
    }

    private Boolean isAGetter(CtMethod method) {
        return method.getSimpleName().contains("get");
    }

    private Boolean hasOneStatement(CtMethod method) {
        return method.getBody().getStatements().size() == 1;
    }

    private Boolean isTransient(CtMethod method) {
        return method.hasAnnotation(Transient.class);
    }

    private String getFieldName(CtMethod method) {
        String statement = method.getBody().getLastStatement().toString();
        Matcher m = p1.matcher(statement);
        Matcher m2 = p2.matcher(statement);
        return m.matches() ? m.group(1).trim() : m2.matches() ? m2.group(1).trim() : null;
    }
}
...