private void processType(TypeElement type, Templated templated, String inject) { String isElementTypeParameter = getIsElementTypeParameter(type.getInterfaces()); String subclass = TypeSimplifier.simpleNameOf(generatedClassName(type, "Templated_", "")); TemplateContext context = new TemplateContext(TypeSimplifier.packageNameOf(type), TypeSimplifier.classNameOf(type), subclass, isElementTypeParameter, inject); // root element and template TemplateSelector templateSelector = getTemplateSelector(type, templated); org.jsoup.nodes.Element root = parseTemplate(type, templateSelector); context.setRoot(createRootElementInfo(root, subclass)); // find and verify all @DataElement members List<DataElementInfo> dataElements = processDataElements(type, templateSelector, root); context.setDataElements(dataElements); // find and verify all @PostConstruct methods List<PostConstructInfo> postConstructs = processPostConstruct(type); context.setPostConstructs(postConstructs); // init parameters and abstract properties List<AbstractPropertyInfo> abstractProperties = processAbstractProperties(type); context.setAbstractProperties(abstractProperties); // generate code code(FREEMARKER_TEMPLATE, context.getPackage(), context.getSubclass(), () -> ImmutableMap.of("context", context)); info("Generated templated implementation [%s] for [%s]", context.getSubclass(), context.getBase()); }
private List<AbstractPropertyInfo> processAbstractProperties(TypeElement type) { List<AbstractPropertyInfo> abstractProperties = new ArrayList<>(); ElementFilter.methodsIn(type.getEnclosedElements()).stream() .filter(method -> method.getModifiers().contains(Modifier.ABSTRACT)) .forEach(method -> { // verify method if (method.getReturnType().getKind() == TypeKind.VOID) { abortWithError(method, "Abstract classes in a @%s class must not return void", Templated.class.getSimpleName()); } if (!method.getParameters().isEmpty()) { abortWithError(method, "Abstract classes in a @%s class must not have parameters", Templated.class.getSimpleName()); } String typeName = TypeSimplifier.simpleTypeName(method.getReturnType()); String methodName = method.getSimpleName().toString(); String fieldName = (isGetter(method)) ? nameWithoutPrefix(methodName) : methodName; String modifier = getModifier(method); abstractProperties.add(new AbstractPropertyInfo(typeName, fieldName, methodName, modifier)); }); return abstractProperties; }
private List<PostConstructInfo> processPostConstruct(TypeElement type) { List<PostConstructInfo> postConstructs = new ArrayList<>(); ElementFilter.methodsIn(type.getEnclosedElements()).stream() .filter(method -> MoreElements.isAnnotationPresent(method, PostConstruct.class)) .forEach(method -> { // verify method if (method.getModifiers().contains(Modifier.PRIVATE)) { abortWithError(method, "@%s method must not be private", PostConstruct.class.getSimpleName()); } if (method.getModifiers().contains(Modifier.STATIC)) { abortWithError(method, "@%s method must not be static", PostConstruct.class.getSimpleName()); } if (!method.getReturnType().equals(typeUtils.getNoType(TypeKind.VOID))) { abortWithError(method, "@%s method must return void", PostConstruct.class.getSimpleName()); } if (!method.getParameters().isEmpty()) { abortWithError(method, "@%s method must not have parameters", PostConstruct.class.getSimpleName()); } postConstructs.add(new PostConstructInfo(method.getSimpleName().toString())); }); if (postConstructs.size() > 1) { warning(type, "%d methods annotated with @%s found. Order is not guaranteed!", postConstructs.size(), PostConstruct.class.getSimpleName()); } return postConstructs; }
private RootElementInfo createRootElementInfo(org.jsoup.nodes.Element root, String subclass) { List<Attribute> attributes = root.attributes().asList().stream() .filter(attribute -> !attribute.getKey().equals("data-element")) .collect(Collectors.toList()); ExpressionParser expressionParser = new ExpressionParser(); String html = root.children().isEmpty() ? null : JAVA_STRING_ESCAPER.escape(root.html()); Map<String, String> expressions = expressionParser.parse(html); expressions.putAll(expressionParser.parse(root.outerHtml())); return new RootElementInfo(root.tagName(), subclass.toLowerCase() + "_root_element", attributes, html, expressions); }
dataElements.add(new DataElementInfo(typeName, field.getSimpleName().toString(), selector, kind, false)); }); dataElements.add(new DataElementInfo(typeName, method.getSimpleName().toString(), selector, kind, true)); });
private void processType(TypeElement type, Templated templated, String inject) { String isElementTypeParameter = getIsElementTypeParameter(type.getInterfaces()); String subclass = TypeSimplifier.simpleNameOf(generatedClassName(type, "Templated_", "")); TemplateContext context = new TemplateContext(TypeSimplifier.packageNameOf(type), TypeSimplifier.classNameOf(type), subclass, isElementTypeParameter, inject); // root element and template TemplateSelector templateSelector = getTemplateSelector(type, templated); org.jsoup.nodes.Element root = parseTemplate(type, templateSelector); context.setRoot(createRootElementInfo(root, subclass)); // find and verify all @DataElement members List<DataElementInfo> dataElements = processDataElements(type, templateSelector, root); context.setDataElements(dataElements); // find and verify all @PostConstruct methods List<PostConstructInfo> postConstructs = processPostConstruct(type); context.setPostConstructs(postConstructs); // init parameters and abstract properties List<AbstractPropertyInfo> abstractProperties = processAbstractProperties(type); context.setAbstractProperties(abstractProperties); // generate code code(FREEMARKER_TEMPLATE, context.getPackage(), context.getSubclass(), () -> ImmutableMap.of("context", context)); info("Generated templated implementation [%s] for [%s]", context.getSubclass(), context.getBase()); }
private RootElementInfo createRootElementInfo(org.jsoup.nodes.Element root, String subclass) { List<Attribute> attributes = root.attributes().asList().stream() .filter(attribute -> !attribute.getKey().equals("data-element")) .collect(Collectors.toList()); ExpressionParser expressionParser = new ExpressionParser(); String html = root.children().isEmpty() ? null : JAVA_STRING_ESCAPER.escape(root.html()); Map<String, String> expressions = expressionParser.parse(html); expressions.putAll(expressionParser.parse(root.outerHtml())); return new RootElementInfo(root.tagName(), subclass.toLowerCase() + "_root_element", attributes, html, expressions); }
private List<AbstractPropertyInfo> processAbstractProperties(TypeElement type) { List<AbstractPropertyInfo> abstractProperties = new ArrayList<>(); ElementFilter.methodsIn(type.getEnclosedElements()).stream() .filter(method -> method.getModifiers().contains(Modifier.ABSTRACT)) .forEach(method -> { // verify method if (method.getReturnType().getKind() == TypeKind.VOID) { abortWithError(method, "Abstract classes in a @%s class must not return void", Templated.class.getSimpleName()); } if (!method.getParameters().isEmpty()) { abortWithError(method, "Abstract classes in a @%s class must not have parameters", Templated.class.getSimpleName()); } String typeName = TypeSimplifier.simpleTypeName(method.getReturnType()); String methodName = method.getSimpleName().toString(); String fieldName = (isGetter(method)) ? nameWithoutPrefix(methodName) : methodName; String modifier = getModifier(method); abstractProperties.add(new AbstractPropertyInfo(typeName, fieldName, methodName, modifier)); }); return abstractProperties; }
private List<PostConstructInfo> processPostConstruct(TypeElement type) { List<PostConstructInfo> postConstructs = new ArrayList<>(); ElementFilter.methodsIn(type.getEnclosedElements()).stream() .filter(method -> MoreElements.isAnnotationPresent(method, PostConstruct.class)) .forEach(method -> { // verify method if (method.getModifiers().contains(Modifier.PRIVATE)) { abortWithError(method, "@%s method must not be private", PostConstruct.class.getSimpleName()); } if (method.getModifiers().contains(Modifier.STATIC)) { abortWithError(method, "@%s method must not be static", PostConstruct.class.getSimpleName()); } if (!method.getReturnType().equals(typeUtils.getNoType(TypeKind.VOID))) { abortWithError(method, "@%s method must return void", PostConstruct.class.getSimpleName()); } if (!method.getParameters().isEmpty()) { abortWithError(method, "@%s method must not have parameters", PostConstruct.class.getSimpleName()); } postConstructs.add(new PostConstructInfo(method.getSimpleName().toString())); }); if (postConstructs.size() > 1) { warning(type, "%d methods annotated with @%s found. Order is not guaranteed!", postConstructs.size(), PostConstruct.class.getSimpleName()); } return postConstructs; }
dataElements.add(new DataElementInfo(typeName, field.getSimpleName().toString(), selector, kind, false)); }); dataElements.add(new DataElementInfo(typeName, method.getSimpleName().toString(), selector, kind, true)); });
private void processType(TypeElement type, Templated templated, String inject) { String isElementTypeParameter = getIsElementTypeParameter(type.getInterfaces()); String subclass = TypeSimplifier.simpleNameOf(generatedClassName(type, "Templated_", "")); TemplateContext context = new TemplateContext(TypeSimplifier.packageNameOf(type), TypeSimplifier.classNameOf(type), subclass, isElementTypeParameter, inject); // root element and template TemplateSelector templateSelector = getTemplateSelector(type, templated); org.jsoup.nodes.Element root = parseTemplate(type, templateSelector); context.setRoot(createRootElementInfo(root, subclass)); // find and verify all @DataElement members List<DataElementInfo> dataElements = processDataElements(type, templateSelector, root); context.setDataElements(dataElements); // find and verify all @PostConstruct methods List<PostConstructInfo> postConstructs = processPostConstruct(type); context.setPostConstructs(postConstructs); // init parameters and abstract properties List<AbstractPropertyInfo> abstractProperties = processAbstractProperties(type); context.setAbstractProperties(abstractProperties); // generate code code(FREEMARKER_TEMPLATE, context.getPackage(), context.getSubclass(), () -> ImmutableMap.of("context", context)); info("Generated templated implementation [%s] for [%s]", context.getSubclass(), context.getBase()); }
private RootElementInfo createRootElementInfo(org.jsoup.nodes.Element root, String subclass) { List<Attribute> attributes = root.attributes().asList().stream() .filter(attribute -> !attribute.getKey().equals("data-element")) .collect(Collectors.toList()); ExpressionParser expressionParser = new ExpressionParser(); String html = root.children().isEmpty() ? null : JAVA_STRING_ESCAPER.escape(root.html()); Map<String, String> expressions = expressionParser.parse(html); expressions.putAll(expressionParser.parse(root.outerHtml())); return new RootElementInfo(root.tagName(), subclass.toLowerCase() + "_root_element", attributes, html, expressions); }
private List<AbstractPropertyInfo> processAbstractProperties(TypeElement type) { List<AbstractPropertyInfo> abstractProperties = new ArrayList<>(); ElementFilter.methodsIn(type.getEnclosedElements()).stream() .filter(method -> method.getModifiers().contains(Modifier.ABSTRACT)) .forEach(method -> { // verify method if (method.getReturnType().getKind() == TypeKind.VOID) { abortWithError(method, "Abstract classes in a @%s class must not return void", Templated.class.getSimpleName()); } if (!method.getParameters().isEmpty()) { abortWithError(method, "Abstract classes in a @%s class must not have parameters", Templated.class.getSimpleName()); } String typeName = TypeSimplifier.simpleTypeName(method.getReturnType()); String methodName = method.getSimpleName().toString(); String fieldName = (isGetter(method)) ? nameWithoutPrefix(methodName) : methodName; String modifier = getModifier(method); abstractProperties.add(new AbstractPropertyInfo(typeName, fieldName, methodName, modifier)); }); return abstractProperties; }
private List<PostConstructInfo> processPostConstruct(TypeElement type) { List<PostConstructInfo> postConstructs = new ArrayList<>(); ElementFilter.methodsIn(type.getEnclosedElements()).stream() .filter(method -> MoreElements.isAnnotationPresent(method, PostConstruct.class)) .forEach(method -> { // verify method if (method.getModifiers().contains(Modifier.PRIVATE)) { abortWithError(method, "@%s method must not be private", PostConstruct.class.getSimpleName()); } if (method.getModifiers().contains(Modifier.STATIC)) { abortWithError(method, "@%s method must not be static", PostConstruct.class.getSimpleName()); } if (!method.getReturnType().equals(typeUtils.getNoType(TypeKind.VOID))) { abortWithError(method, "@%s method must return void", PostConstruct.class.getSimpleName()); } if (!method.getParameters().isEmpty()) { abortWithError(method, "@%s method must not have parameters", PostConstruct.class.getSimpleName()); } postConstructs.add(new PostConstructInfo(method.getSimpleName().toString())); }); if (postConstructs.size() > 1) { warning(type, "%d methods annotated with @%s found. Order is not guaranteed!", postConstructs.size(), PostConstruct.class.getSimpleName()); } return postConstructs; }
dataElements.add(new DataElementInfo(typeName, field.getSimpleName().toString(), selector, kind, false)); }); dataElements.add(new DataElementInfo(typeName, method.getSimpleName().toString(), selector, kind, true)); });