private void processExecutableElement(String prefix, ExecutableElement element) { if (element.getModifiers().contains(Modifier.PUBLIC) && (TypeKind.VOID != element.getReturnType().getKind())) { Element returns = this.processingEnv.getTypeUtils() .asElement(element.getReturnType()); if (returns instanceof TypeElement) { ItemMetadata group = ItemMetadata.newGroup(prefix, this.typeUtils.getType(returns), this.typeUtils.getType(element.getEnclosingElement()), element.toString()); if (this.metadataCollector.hasSimilarGroup(group)) { this.processingEnv.getMessager().printMessage(Kind.ERROR, "Duplicate `@ConfigurationProperties` definition for prefix '" + prefix + "'", element); } else { this.metadataCollector.add(group); processTypeElement(prefix, (TypeElement) returns); } } } }
private void processNestedType(String prefix, TypeElement element, String name, ExecutableElement getter, VariableElement field, TypeMirror returnType) { Element returnElement = this.processingEnv.getTypeUtils().asElement(returnType); boolean isNested = isNested(returnElement, field, element); AnnotationMirror annotation = getAnnotation(getter, configurationPropertiesAnnotation()); if (returnElement != null && returnElement instanceof TypeElement && annotation == null && isNested) { String nestedPrefix = ConfigurationMetadata.nestedPrefix(prefix, name); this.metadataCollector.add(ItemMetadata.newGroup(nestedPrefix, this.typeUtils.getType(returnElement), this.typeUtils.getType(element), (getter == null ? null : getter.toString()))); processTypeElement(nestedPrefix, (TypeElement) returnElement); } }
private void processNestedTypes(String prefix, TypeElement element, TypeElementMembers members) { for (Map.Entry<String, ExecutableElement> entry : members.getPublicGetters() .entrySet()) { String name = entry.getKey(); ExecutableElement getter = entry.getValue(); VariableElement field = members.getFields().get(name); Element returnType = this.processingEnv.getTypeUtils() .asElement(getter.getReturnType()); AnnotationMirror annotation = getAnnotation(getter, configurationPropertiesAnnotation()); boolean isNested = isNested(returnType, field, element); if (returnType != null && returnType instanceof TypeElement && annotation == null && isNested) { String nestedPrefix = ConfigurationMetadata.nestedPrefix(prefix, name); this.metadataCollector.add(ItemMetadata.newGroup(nestedPrefix, this.typeUtils.getType(returnType), this.typeUtils.getType(element), getter.toString())); processTypeElement(nestedPrefix, (TypeElement) returnType); } } }
private void processSimpleTypes(String prefix, TypeElement element, TypeElementMembers members, Map<String, Object> fieldValues) { for (Map.Entry<String, ExecutableElement> entry : members.getPublicGetters() .entrySet()) { String name = entry.getKey(); ExecutableElement getter = entry.getValue(); TypeMirror returnType = getter.getReturnType(); ExecutableElement setter = members.getPublicSetter(name, returnType); VariableElement field = members.getFields().get(name); Element returnTypeElement = this.processingEnv.getTypeUtils() .asElement(returnType); boolean isExcluded = this.typeExcludeFilter.isExcluded(returnType); boolean isNested = isNested(returnTypeElement, field, element); boolean isCollection = this.typeUtils.isCollectionOrMap(returnType); if (!isExcluded && !isNested && (setter != null || isCollection)) { String dataType = this.typeUtils.getType(returnType); String sourceType = this.typeUtils.getType(element); String description = this.typeUtils.getJavaDoc(field); Object defaultValue = fieldValues.get(name); boolean deprecated = isDeprecated(getter) || isDeprecated(setter) || isDeprecated(element); this.metadataCollector.add(ItemMetadata.newProperty(prefix, name, dataType, sourceType, null, description, defaultValue, (deprecated ? getItemDeprecation(getter) : null))); } } }
private void processSimpleLombokTypes(String prefix, TypeElement element, TypeElementMembers members, Map<String, Object> fieldValues) { for (Map.Entry<String, VariableElement> entry : members.getFields().entrySet()) { String name = entry.getKey(); VariableElement field = entry.getValue(); if (!isLombokField(field, element)) { continue; } TypeMirror returnType = field.asType(); Element returnTypeElement = this.processingEnv.getTypeUtils() .asElement(returnType); boolean isExcluded = this.typeExcludeFilter.isExcluded(returnType); boolean isNested = isNested(returnTypeElement, field, element); boolean isCollection = this.typeUtils.isCollectionOrMap(returnType); boolean hasSetter = hasLombokSetter(field, element); if (!isExcluded && !isNested && (hasSetter || isCollection)) { String dataType = this.typeUtils.getType(returnType); String sourceType = this.typeUtils.getType(element); String description = this.typeUtils.getJavaDoc(field); Object defaultValue = fieldValues.get(name); boolean deprecated = isDeprecated(field) || isDeprecated(element); this.metadataCollector.add(ItemMetadata.newProperty(prefix, name, dataType, sourceType, null, description, defaultValue, (deprecated ? new ItemDeprecation() : null))); } } }
public boolean hasSimilarGroup(ItemMetadata metadata) { if (!metadata.isOfItemType(ItemMetadata.ItemType.GROUP)) { throw new IllegalStateException("item " + metadata + " must be a group"); } for (ItemMetadata existing : this.metadataItems) { if (existing.isOfItemType(ItemMetadata.ItemType.GROUP) && existing.getName().equals(metadata.getName()) && existing.getType().equals(metadata.getType())) { return true; } } return false; }
@Override public boolean matches(ConfigurationMetadata value) { ItemMetadata itemMetadata = getFirstItemWithName(value, this.name); if (itemMetadata == null) { return false; } if (this.type != null && !this.type.equals(itemMetadata.getType())) { return false; } if (this.sourceType != null && !this.sourceType.getName().equals(itemMetadata.getSourceType())) { return false; } if (this.defaultValue != null && !ObjectUtils .nullSafeEquals(this.defaultValue, itemMetadata.getDefaultValue())) { return false; } if (this.description != null && !this.description.equals(itemMetadata.getDescription())) { return false; } if (this.deprecation == null && itemMetadata.getDeprecation() != null) { return false; } if (this.deprecation != null && !this.deprecation.equals(itemMetadata.getDeprecation())) { return false; } return true; }
private ItemMetadata getFirstItemWithName(ConfigurationMetadata metadata, String name) { for (ItemMetadata item : metadata.getItems()) { if (item.isOfItemType(this.itemType) && name.equals(item.getName())) { return item; } } return null; }
@Test public void mergingOfAdditionalProperty() throws Exception { ItemMetadata property = ItemMetadata.newProperty(null, "foo", "java.lang.String", AdditionalMetadata.class.getName(), null, null, null, null); writeAdditionalMetadata(property); ConfigurationMetadata metadata = compile(SimpleProperties.class); assertThat(metadata).has(Metadata.withProperty("simple.comparator")); assertThat(metadata).has(Metadata.withProperty("foo", String.class) .fromSource(AdditionalMetadata.class)); }
@Test public void mergeExistingPropertyDefaultValue() throws Exception { ItemMetadata property = ItemMetadata.newProperty("simple", "flag", null, null, null, null, true, null); writeAdditionalMetadata(property); ConfigurationMetadata metadata = compile(SimpleProperties.class); assertThat(metadata).has(Metadata.withProperty("simple.flag", Boolean.class) .fromSource(SimpleProperties.class).withDescription("A simple flag.") .withDeprecation(null, null).withDefaultValue(true)); assertThat(metadata.getItems()).hasSize(4); }
@Test public void mergeExistingPropertyDescription() throws Exception { ItemMetadata property = ItemMetadata.newProperty("simple", "comparator", null, null, null, "A nice comparator.", null, null); writeAdditionalMetadata(property); ConfigurationMetadata metadata = compile(SimpleProperties.class); assertThat(metadata) .has(Metadata.withProperty("simple.comparator", "java.util.Comparator<?>") .fromSource(SimpleProperties.class) .withDescription("A nice comparator.")); assertThat(metadata.getItems()).hasSize(4); }
@Test public void mergeExistingPropertyDeprecation() throws Exception { ItemMetadata property = ItemMetadata.newProperty("simple", "comparator", null, null, null, null, null, new ItemDeprecation("Don't use this.", "simple.complex-comparator")); writeAdditionalMetadata(property); ConfigurationMetadata metadata = compile(SimpleProperties.class); assertThat(metadata) .has(Metadata.withProperty("simple.comparator", "java.util.Comparator<?>") .fromSource(SimpleProperties.class) .withDeprecation("Don't use this.", "simple.complex-comparator")); assertThat(metadata.getItems()).hasSize(4); }
@Test public void mergeExistingPropertyDeprecationOverride() throws Exception { ItemMetadata property = ItemMetadata.newProperty("singledeprecated", "name", null, null, null, null, null, new ItemDeprecation("Don't use this.", "single.name")); writeAdditionalMetadata(property); ConfigurationMetadata metadata = compile(DeprecatedSingleProperty.class); assertThat(metadata).has( Metadata.withProperty("singledeprecated.name", String.class.getName()) .fromSource(DeprecatedSingleProperty.class) .withDeprecation("Don't use this.", "single.name")); assertThat(metadata.getItems()).hasSize(3); }
@Test public void mergingOfAdditionalDeprecation() throws Exception { writePropertyDeprecation(ItemMetadata.newProperty("simple", "wrongName", "java.lang.String", null, null, null, null, new ItemDeprecation("Lame name.", "simple.the-name"))); ConfigurationMetadata metadata = compile(SimpleProperties.class); assertThat(metadata).has(Metadata.withProperty("simple.wrong-name", String.class) .withDeprecation("Lame name.", "simple.the-name")); }
private void writePropertyDeprecation(ItemMetadata... items) throws IOException { File additionalMetadataFile = createAdditionalMetadataFile(); JSONArray propertiesArray = new JSONArray(); for (ItemMetadata item : items) { JSONObject jsonObject = new JSONObject(); jsonObject.put("name", item.getName()); if (item.getType() != null) { jsonObject.put("type", item.getType()); } ItemDeprecation deprecation = item.getDeprecation(); if (deprecation != null) { JSONObject deprecationJson = new JSONObject(); if (deprecation.getReason() != null) { deprecationJson.put("reason", deprecation.getReason()); } if (deprecation.getReplacement() != null) { deprecationJson.put("replacement", deprecation.getReplacement()); } jsonObject.put("deprecation", deprecationJson); } propertiesArray.put(jsonObject); } JSONObject additionalMetadata = new JSONObject(); additionalMetadata.put("properties", propertiesArray); writeMetadata(additionalMetadataFile, additionalMetadata); }
private void processExecutableElement(String prefix, ExecutableElement element) { if (element.getModifiers().contains(Modifier.PUBLIC) && (TypeKind.VOID != element.getReturnType().getKind())) { Element returns = this.processingEnv.getTypeUtils() .asElement(element.getReturnType()); if (returns instanceof TypeElement) { this.metadataCollector.add( ItemMetadata.newGroup(prefix, this.typeUtils.getType(returns), this.typeUtils.getType(element.getEnclosingElement()), element.toString())); processTypeElement(prefix, (TypeElement) returns); } } }
@Override public String getText() { ItemMetadata configurationItem = item.getConfigurationItem(); String deprecatedText = configurationItem.isDeprecated() ? ("<br/><br/><b>Deprecated</b>") : ""; String defaultValueText = (null != configurationItem.getDefaultValue()) ? ("<br/><i>Default Value:</i> " + String.valueOf(configurationItem.getDefaultValue())) : ""; String descriptionText = (null != configurationItem.getDescription()) ? ("<br/><br/>" + configurationItem.getDescription()) : ""; String text = "<b>" + configurationItem.getName() + "</b>" + "<br/><a>" + configurationItem.getType() + "</a>" + defaultValueText + deprecatedText + descriptionText; return text; }
private void processSimpleTypes(String prefix, TypeElement element, TypeElementMembers members, Map<String, Object> fieldValues) { for (Map.Entry<String, ExecutableElement> entry : members.getPublicGetters() .entrySet()) { String name = entry.getKey(); ExecutableElement getter = entry.getValue(); ExecutableElement setter = members.getPublicSetters().get(name); VariableElement field = members.getFields().get(name); TypeMirror returnType = getter.getReturnType(); Element returnTypeElement = this.processingEnv.getTypeUtils() .asElement(returnType); boolean isExcluded = this.typeExcludeFilter.isExcluded(returnType); boolean isNested = isNested(returnTypeElement, field, element); boolean isCollection = this.typeUtils.isCollectionOrMap(returnType); if (!isExcluded && !isNested && (setter != null || isCollection)) { String dataType = this.typeUtils.getType(returnType); String sourceType = this.typeUtils.getType(element); String description = this.typeUtils.getJavaDoc(field); Object defaultValue = fieldValues.get(name); boolean deprecated = isDeprecated(getter) || isDeprecated(setter) || isDeprecated(element); this.metadataCollector.add(ItemMetadata.newProperty(prefix, name, dataType, sourceType, null, description, defaultValue, (deprecated ? getItemDeprecation(getter) : null))); } } }
private void processLombokTypes(String prefix, TypeElement element, TypeElementMembers members, Map<String, Object> fieldValues) { for (Map.Entry<String, VariableElement> entry : members.getFields().entrySet()) { String name = entry.getKey(); VariableElement field = entry.getValue(); if (!isLombokField(field, element)) { continue; } TypeMirror returnType = field.asType(); Element returnTypeElement = this.processingEnv.getTypeUtils() .asElement(returnType); boolean isExcluded = this.typeExcludeFilter.isExcluded(returnType); boolean isNested = isNested(returnTypeElement, field, element); boolean isCollection = this.typeUtils.isCollectionOrMap(returnType); boolean hasSetter = hasLombokSetter(field, element); if (!isExcluded && !isNested && (hasSetter || isCollection)) { String dataType = this.typeUtils.getType(returnType); String sourceType = this.typeUtils.getType(element); String description = this.typeUtils.getJavaDoc(field); Object defaultValue = fieldValues.get(name); boolean deprecated = isDeprecated(field) || isDeprecated(element); this.metadataCollector.add(ItemMetadata.newProperty(prefix, name, dataType, sourceType, null, description, defaultValue, (deprecated ? new ItemDeprecation() : null))); } } }
@Test public void mergingOfAdditionalProperty() throws Exception { ItemMetadata property = ItemMetadata.newProperty(null, "foo", "java.lang.String", AdditionalMetadata.class.getName(), null, null, null, null); writeAdditionalMetadata(property); ConfigurationMetadata metadata = compile(SimpleProperties.class); assertThat(metadata, containsProperty("simple.comparator")); assertThat(metadata, containsProperty("foo", String.class) .fromSource(AdditionalMetadata.class)); }
@Test public void mergeExistingPropertyDefaultValue() throws Exception { ItemMetadata property = ItemMetadata.newProperty("simple", "flag", null, null, null, null, true, null); writeAdditionalMetadata(property); ConfigurationMetadata metadata = compile(SimpleProperties.class); assertThat(metadata, containsProperty("simple.flag", Boolean.class) .fromSource(SimpleProperties.class) .withDescription("A simple flag.").withDefaultValue(is(true))); assertThat(metadata.getItems().size(), is(4)); }
@Test public void mergeExistingPropertyDescription() throws Exception { ItemMetadata property = ItemMetadata.newProperty("simple", "comparator", null, null, null, "A nice comparator.", null, null); writeAdditionalMetadata(property); ConfigurationMetadata metadata = compile(SimpleProperties.class); assertThat(metadata, containsProperty("simple.comparator", "java.util.Comparator<?>") .fromSource(SimpleProperties.class) .withDescription("A nice comparator.")); assertThat(metadata.getItems().size(), is(4)); }
@Test public void mergeExistingPropertyDeprecation() throws Exception { ItemMetadata property = ItemMetadata.newProperty("simple", "comparator", null, null, null, null, null, new ItemDeprecation("Don't use this.", "simple.complex-comparator")); writeAdditionalMetadata(property); ConfigurationMetadata metadata = compile(SimpleProperties.class); assertThat(metadata, containsProperty("simple.comparator", "java.util.Comparator<?>") .fromSource(SimpleProperties.class) .withDeprecation("Don't use this.", "simple.complex-comparator")); assertThat(metadata.getItems().size(), is(4)); }
@Test public void mergeExistingPropertyDeprecationOverride() throws Exception { ItemMetadata property = ItemMetadata.newProperty("singledeprecated", "name", null, null, null, null, null, new ItemDeprecation("Don't use this.", "single.name")); writeAdditionalMetadata(property); ConfigurationMetadata metadata = compile(DeprecatedSingleProperty.class); assertThat(metadata, containsProperty("singledeprecated.name", String.class.getName()) .fromSource(DeprecatedSingleProperty.class) .withDeprecation("Don't use this.", "single.name")); assertThat(metadata.getItems().size(), is(3)); }
@Test public void mergingOfAdditionalDeprecation() throws Exception { writePropertyDeprecation(ItemMetadata.newProperty("simple", "wrongName", "java.lang.String", null, null, null, null, new ItemDeprecation("Lame name.", "simple.the-name"))); ConfigurationMetadata metadata = compile(SimpleProperties.class); assertThat(metadata, containsProperty("simple.wrong-name", String.class) .withDeprecation("Lame name.", "simple.the-name")); }
@Override public boolean matches(Object item) { ConfigurationMetadata metadata = (ConfigurationMetadata) item; ItemMetadata itemMetadata = getFirstItemWithName(metadata, this.name); if (itemMetadata == null) { return false; } if (this.type != null && !this.type.equals(itemMetadata.getType())) { return false; } if (this.sourceType != null && !this.sourceType.getName().equals(itemMetadata.getSourceType())) { return false; } if (this.defaultValue != null && !this.defaultValue.matches(itemMetadata.getDefaultValue())) { return false; } if (this.description != null && !this.description.equals(itemMetadata.getDescription())) { return false; } if (this.deprecation != null && !this.deprecation.equals(itemMetadata.getDeprecation())) { return false; } return true; }