Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
sourceFile :
new ChangePropertyValue(key, value, null, false, null)
.getVisitor().visitNonNull(sourceFile, ctx);
return new org.openrewrite.properties.AddProperty(key, value, null, null, null)
return new org.openrewrite.properties.AddProperty(key, value, null, null, null, null, null)
.getVisitor()
.visitNonNull(t, ctx);
}
Expand All @@ -133,7 +133,7 @@ public Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
sourceFile :
new ChangePropertyValue(key, value, null, false, null)
.getVisitor().visitNonNull(sourceFile, ctx);
return new org.openrewrite.properties.AddProperty(key, value, null, null, null)
return new org.openrewrite.properties.AddProperty(key, value, null, null, null, null, null)
.getVisitor()
.visitNonNull(t, ctx);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,26 @@ public class AddProperty extends Recipe {
@Nullable
Boolean orderedInsertion;

@Option(displayName = "Before property",
description = "Insert the new property before the property with this key. " +
"Takes precedence over `orderedInsertion`. " +
"If the referenced property does not exist, falls back to default behavior. " +
"Mutually exclusive with `afterProperty`.",
required = false,
example = "server.port")
@Nullable
String beforeProperty;

@Option(displayName = "After property",
description = "Insert the new property after the property with this key. " +
"Takes precedence over `orderedInsertion`. " +
"If the referenced property does not exist, falls back to default behavior. " +
"Mutually exclusive with `beforeProperty`.",
required = false,
example = "server.port")
@Nullable
String afterProperty;

String displayName = "Add a new property";

String description = "Adds a new property to a property file. " +
Expand All @@ -80,7 +100,11 @@ public class AddProperty extends Recipe {
public Validated<Object> validate() {
return Validated.none()
.and(Validated.required("property", property))
.and(Validated.required("value", value));
.and(Validated.required("value", value))
.and(Validated.test("beforeProperty",
"`beforeProperty` and `afterProperty` are mutually exclusive",
this,
r -> StringUtils.isBlank(r.beforeProperty) || StringUtils.isBlank(r.afterProperty)));
}

@Override
Expand Down Expand Up @@ -117,16 +141,39 @@ public Properties.File visitFile(Properties.File file, ExecutionContext ctx) {
entry);
}

List<Properties.Content> contentList = new ArrayList<>(p.getContent().size() + 1);
if (orderedInsertion == null || orderedInsertion) {
int insertionIndex = sortedInsertionIndex(entry, p.getContent());
contentList.addAll(p.getContent().subList(0, insertionIndex));
contentList.addAll(newContents);
contentList.addAll(p.getContent().subList(insertionIndex, p.getContent().size()));
List<Properties.Content> contentList = new ArrayList<>(p.getContent().size() + newContents.size());
boolean inserted = false;

if (!StringUtils.isBlank(beforeProperty)) {
int refIndex = findEntryIndex(p.getContent(), p, beforeProperty);
if (refIndex >= 0) {
int insertIndex = findCommentBlockStart(p.getContent(), refIndex);
contentList.addAll(p.getContent().subList(0, insertIndex));
contentList.addAll(newContents);
contentList.addAll(p.getContent().subList(insertIndex, p.getContent().size()));
inserted = true;
}
} else if (!StringUtils.isBlank(afterProperty)) {
int refIndex = findEntryIndex(p.getContent(), p, afterProperty);
if (refIndex >= 0) {
int insertIndex = refIndex + 1;
contentList.addAll(p.getContent().subList(0, insertIndex));
contentList.addAll(newContents);
contentList.addAll(p.getContent().subList(insertIndex, p.getContent().size()));
inserted = true;
}
}
else {
contentList.addAll(p.getContent());
contentList.addAll(newContents);

if (!inserted) {
if (orderedInsertion == null || orderedInsertion) {
int insertionIndex = sortedInsertionIndex(entry, p.getContent());
contentList.addAll(p.getContent().subList(0, insertionIndex));
contentList.addAll(newContents);
contentList.addAll(p.getContent().subList(insertionIndex, p.getContent().size()));
} else {
contentList.addAll(p.getContent());
contentList.addAll(newContents);
}
}


Expand All @@ -145,6 +192,23 @@ public Properties.File visitFile(Properties.File file, ExecutionContext ctx) {
};
}

private static int findEntryIndex(List<Properties.Content> contentList, Properties.File file, String referenceKey) {
Set<Properties.Entry> matches = FindProperties.find(file, referenceKey, false);
if (matches.isEmpty()) {
return -1;
}
Properties.Entry matched = matches.iterator().next();
return contentList.indexOf(matched);
}

private static int findCommentBlockStart(List<Properties.Content> contentList, int entryIndex) {
int start = entryIndex;
while (start > 0 && contentList.get(start - 1) instanceof Properties.Comment) {
start--;
}
return start;
}

private static int sortedInsertionIndex(Properties.Entry entry, List<Properties.Content> contentsList) {
if (contentsList.isEmpty()) {
return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ examples:
- 'null'
- 'null'
- 'null'
- 'null'
- 'null'
sources:
- before: |
management=true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ecosystem,packageName,name,displayName,description,recipeCount,category1,category2,options
maven,org.openrewrite:rewrite-properties,org.openrewrite.properties.AddProperty,Add a new property,Adds a new property to a property file. Attempts to place the new property in alphabetical order by the property keys. Whitespace before and after the `=` must be included in the property and value.,1,,Properties,"[{""name"":""property"",""type"":""String"",""displayName"":""Property key"",""description"":""The property key to add."",""example"":""management.metrics.enable.process.files"",""required"":true},{""name"":""value"",""type"":""String"",""displayName"":""Property value"",""description"":""The value of the new property key."",""example"":""newPropValue"",""required"":true},{""name"":""comment"",""type"":""String"",""displayName"":""Optional comment to be prepended to the property"",""description"":""A comment that will be added to the new property."",""example"":""This is a comment""},{""name"":""delimiter"",""type"":""String"",""displayName"":""Optional delimiter"",""description"":""Property entries support different delimiters (`=`, `:`, or whitespace). The default value is `=` unless provided the delimiter of the new property entry."",""example"":"":""},{""name"":""orderedInsertion"",""type"":""Boolean"",""displayName"":""Ordered property insertion"",""description"":""Whether to attempt adding the property in an order following alphabetic sorting. The default value is `true`."",""example"":""false""}]"
maven,org.openrewrite:rewrite-properties,org.openrewrite.properties.AddProperty,Add a new property,Adds a new property to a property file. Attempts to place the new property in alphabetical order by the property keys. Whitespace before and after the `=` must be included in the property and value.,1,,Properties,"[{""name"":""property"",""type"":""String"",""displayName"":""Property key"",""description"":""The property key to add."",""example"":""management.metrics.enable.process.files"",""required"":true},{""name"":""value"",""type"":""String"",""displayName"":""Property value"",""description"":""The value of the new property key."",""example"":""newPropValue"",""required"":true},{""name"":""comment"",""type"":""String"",""displayName"":""Optional comment to be prepended to the property"",""description"":""A comment that will be added to the new property."",""example"":""This is a comment""},{""name"":""delimiter"",""type"":""String"",""displayName"":""Optional delimiter"",""description"":""Property entries support different delimiters (`=`, `:`, or whitespace). The default value is `=` unless provided the delimiter of the new property entry."",""example"":"":""},{""name"":""orderedInsertion"",""type"":""Boolean"",""displayName"":""Ordered property insertion"",""description"":""Whether to attempt adding the property in an order following alphabetic sorting. The default value is `true`."",""example"":""false""},{""name"":""beforeProperty"",""type"":""String"",""displayName"":""Before property"",""description"":""Insert the new property before the property with this key. Takes precedence over `orderedInsertion`. If the referenced property does not exist, falls back to default behavior. Mutually exclusive with `afterProperty`."",""example"":""server.port""},{""name"":""afterProperty"",""type"":""String"",""displayName"":""After property"",""description"":""Insert the new property after the property with this key. Takes precedence over `orderedInsertion`. If the referenced property does not exist, falls back to default behavior. Mutually exclusive with `beforeProperty`."",""example"":""server.port""}]"
maven,org.openrewrite:rewrite-properties,org.openrewrite.properties.AddPropertyComment,Add comment before property key,"Add a new comment before a property key if not already present, optionally commenting out the property.",1,,Properties,"[{""name"":""propertyKey"",""type"":""String"",""displayName"":""Property key"",""description"":""The name of the property to add comment."",""example"":""management.metrics.binders"",""required"":true},{""name"":""comment"",""type"":""String"",""displayName"":""Comment"",""description"":""The comment to be added."",""example"":""comment"",""required"":true},{""name"":""commentOutProperty"",""type"":""Boolean"",""displayName"":""Comment out property"",""description"":""If true, property will be commented out."",""example"":""true""}]"
maven,org.openrewrite:rewrite-properties,org.openrewrite.properties.CopyValue,Copy property value,"Copies a property value from one key to another. The existing key/value pair remains unaffected by this change. If the destination key already exists, its value will be replaced. By default, creates the destination key if it does not exist.",1,,Properties,"[{""name"":""oldPropertyKey"",""type"":""String"",""displayName"":""Old property key"",""description"":""The property key to copy the value from. Supports glob patterns."",""example"":""app.source.property"",""required"":true},{""name"":""oldFilePath"",""type"":""String"",""displayName"":""Old file path"",""description"":""The file path to the properties file to copy the value from. If `null` then the value will be copied from any properties file it appears within."",""example"":""src/main/resources/application.properties""},{""name"":""newPropertyKey"",""type"":""String"",""displayName"":""New property key"",""description"":""The property key to copy the value to."",""example"":""app.destination.property"",""required"":true},{""name"":""newFilePath"",""type"":""String"",""displayName"":""New file path"",""description"":""The file path to the properties file to copy the value to. If `null` then the value will be copied only into the same file it was found in."",""example"":""src/main/resources/application.properties""},{""name"":""createNewKeys"",""type"":""Boolean"",""displayName"":""Create new keys"",""description"":""When the destination key does _not_ already exist, create it. Default is `true`.""},{""name"":""relaxedBinding"",""type"":""Boolean"",""displayName"":""Use relaxed binding"",""description"":""Whether to match the `oldPropertyKey` using [relaxed binding](https://docs.spring.io/spring-boot/docs/2.5.6/reference/html/features.html#features.external-config.typesafe-configuration-properties.relaxed-binding) rules. Default is `true`. Set to `false` to use exact matching.""}]"
maven,org.openrewrite:rewrite-properties,org.openrewrite.properties.ChangePropertyKey,Change property key,Change a property key leaving the value intact.,1,,Properties,"[{""name"":""oldPropertyKey"",""type"":""String"",""displayName"":""Old property key"",""description"":""The property key to rename."",""example"":""management.metrics.binders.files.enabled"",""required"":true},{""name"":""newPropertyKey"",""type"":""String"",""displayName"":""New property key"",""description"":""The new name for the key identified by `oldPropertyKey`."",""example"":""management.metrics.enable.process.files"",""required"":true},{""name"":""relaxedBinding"",""type"":""Boolean"",""displayName"":""Use relaxed binding"",""description"":""Whether to match the `oldPropertyKey` using [relaxed binding](https://docs.spring.io/spring-boot/docs/2.5.6/reference/html/features.html#features.external-config.typesafe-configuration-properties.relaxed-binding) rules. Default is `true`. Set to `false` to use exact matching.""},{""name"":""regex"",""type"":""Boolean"",""displayName"":""Regex"",""description"":""Default false. If enabled, `oldPropertyKey` will be interpreted as a Regular Expression, and capture group contents will be available in `newPropertyKey`""}]"
Expand Down
Loading