Skip to content

Commit ad13b8b

Browse files
committed
feat: support property editing
Signed-off-by: Pawel Veselov <[email protected]>
1 parent 14fd758 commit ad13b8b

File tree

23 files changed

+1243
-123
lines changed

23 files changed

+1243
-123
lines changed

README.adoc

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,37 @@ mvn pom-editor:add-dep -Dgav='org.junit.jupiter:junit-jupiter:5.9.2' -Dscope=tes
8282

8383
|===
8484

85+
=== Add/Change/Remove a property
86+
87+
Let's suppose that you need to add a property to your pom file.
88+
89+
[source, sh]
90+
----
91+
mvn pom-editor:change-prop -Dproperty='custom-property' -Dvalue='Caesar'
92+
----
93+
94+
.change-prop supported parameters
95+
[cols="change-prop params"]
96+
|===
97+
|Parameter | Description | Required | Default
98+
99+
| pom
100+
| Target POM file.
101+
| No
102+
| pom.xml
103+
104+
| property
105+
| The name of the property
106+
| Yes
107+
|
108+
109+
| value
110+
| The value of the property, if not specified, the request is to delete the property if it exists.
111+
| No
112+
|
113+
114+
|===
115+
85116
=== Confirm the changes
86117

87118
When you perform the goal add-dep with the command below:
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
package br.org.soujava.pomeditor.api;
19+
20+
import org.apache.maven.plugin.logging.Log;
21+
import org.l2x6.pom.tuner.PomTransformer;
22+
23+
import java.nio.charset.StandardCharsets;
24+
import java.nio.file.Path;
25+
import java.util.Optional;
26+
27+
/**
28+
* Command responsible for changing a property within a given pom
29+
*/
30+
public interface ChangeProperty {
31+
32+
/**
33+
* Change a property based on the {@link Property} instance into the target POM xml
34+
*
35+
* @param pom it's the target POM xml
36+
* @param property it's a {@link Property} instance
37+
*/
38+
static void execute(Log log, Path pom, Property property) {
39+
new PomTransformer(
40+
pom,
41+
StandardCharsets.UTF_8,
42+
PomTransformer.SimpleElementWhitespace.AUTODETECT_PREFER_SPACE)
43+
.transform(changePropertyIfNeeded(log, property));
44+
}
45+
46+
private static PomTransformer.Transformation changePropertyIfNeeded(Log log, Property propertyToChange) {
47+
return (document, context) -> {
48+
49+
String name = propertyToChange.getName();
50+
String value = propertyToChange.getValue();
51+
boolean removing = value == null;
52+
53+
log.debug("name: "+name);
54+
log.debug("value: "+value);
55+
log.debug("removing: "+removing);
56+
57+
// the container API is a bit weird, we can't set a text value on a node, only on a sub-node.
58+
59+
Optional<PomTransformer.ContainerElement> propsWrap = context.getContainerElement("project", "properties");
60+
PomTransformer.ContainerElement props;
61+
if (propsWrap.isEmpty()) {
62+
log.debug("properties node not found");
63+
if (removing) {
64+
log.debug("nothing to do, exiting");
65+
return;
66+
}
67+
props = context.getOrAddContainerElement("properties");
68+
log.debug("added properties:"+props);
69+
} else {
70+
props = propsWrap.get();
71+
log.debug("existing properties:"+props);
72+
}
73+
74+
Optional<PomTransformer.ContainerElement> propWrap = props.getChildContainerElement(name);
75+
if (propWrap.isEmpty()) {
76+
log.debug("No property "+name+" found");
77+
if (removing) {
78+
return;
79+
}
80+
}
81+
82+
if (removing) {
83+
PomTransformer.ContainerElement prop = propWrap.get();
84+
log.debug("Removing prop "+prop);
85+
prop.remove(false, false);
86+
return;
87+
}
88+
89+
log.debug("Adding to properties");
90+
props.addOrSetChildTextElement(name, value);
91+
92+
};
93+
}
94+
95+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
package br.org.soujava.pomeditor.api;
19+
20+
import java.util.Objects;
21+
22+
/**
23+
* Represents a property to be changed
24+
*/
25+
public final class Property {
26+
27+
/**
28+
* Returns a {@link PropertyBuilder} instance
29+
* @return a {@link PropertyBuilder}
30+
*/
31+
public static PropertyBuilder builder() {
32+
return new PropertyBuilder();
33+
}
34+
35+
/**
36+
* Returns a {@link PropertyBuilder} based on the specified property name and value.
37+
* @param name property name
38+
* @param value property value, or {@code null} to request removal
39+
* @return a {@link PropertyBuilder}
40+
*/
41+
public static PropertyBuilder of(String name, String value) {
42+
43+
return builder().withName(name).withValue(value);
44+
45+
}
46+
47+
/**
48+
* Dependency builder
49+
*/
50+
public static class PropertyBuilder {
51+
52+
private String name;
53+
private String value;
54+
55+
/**
56+
* @param name property name
57+
* @return {@code this} {@link PropertyBuilder} instance
58+
*/
59+
public PropertyBuilder withName(String name) {
60+
this.name = name;
61+
return this;
62+
}
63+
64+
/**
65+
* @param value property value
66+
* @return {@code this} {@link PropertyBuilder} instance
67+
*/
68+
public PropertyBuilder withValue(String value) {
69+
this.value = value;
70+
return this;
71+
}
72+
73+
/**
74+
* @return a new {@link Property} instance
75+
*/
76+
public Property build() {
77+
return new Property(name, value);
78+
}
79+
}
80+
81+
private final String name;
82+
private final String value;
83+
84+
private Property(String name, String value) {
85+
86+
if (name == null || name.isBlank()) {
87+
throw new IllegalArgumentException("name must be provided");
88+
}
89+
90+
this.name = name;
91+
this.value = value;
92+
93+
}
94+
95+
public String getName() {
96+
return name;
97+
}
98+
99+
public String getValue() {
100+
return value;
101+
}
102+
103+
@Override
104+
public boolean equals(Object o) {
105+
if (this == o) return true;
106+
if (o == null || getClass() != o.getClass()) return false;
107+
Property that = (Property) o;
108+
return Objects.equals(name, that.name)
109+
&& Objects.equals(value, that.value);
110+
}
111+
112+
@Override
113+
public String toString() {
114+
StringBuilder sb = new StringBuilder();
115+
sb.append("{");
116+
sb.append("name='").append(name).append('\'');
117+
sb.append(", value='").append(value).append('\'');
118+
sb.append("}");
119+
return sb.toString();
120+
}
121+
122+
@Override
123+
public int hashCode() {
124+
return Objects.hash(name, value);
125+
}
126+
}

src/main/java/br/org/soujava/pomeditor/mojo/AddDependencyMojo.java

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919

2020
import br.org.soujava.pomeditor.api.AddDependency;
2121
import br.org.soujava.pomeditor.api.Dependency;
22-
import br.org.soujava.pomeditor.api.PomChange;
23-
import org.apache.maven.plugin.AbstractMojo;
2422
import org.apache.maven.plugin.MojoExecutionException;
2523
import org.apache.maven.plugin.MojoFailureException;
2624
import org.apache.maven.plugins.annotations.Mojo;
@@ -30,16 +28,14 @@
3028
import java.nio.file.Paths;
3129
import java.util.Optional;
3230
import java.util.function.BiConsumer;
33-
import java.util.function.Consumer;
34-
import java.util.function.Function;
3531

3632
/**
3733
* Mojo responsible to add a given dependency to a target POM
3834
* if such dependency is not declared
3935
* or the given dependency's version is greater than the existent at target POM
4036
*/
4137
@Mojo(name = "add-dep")
42-
public class AddDependencyMojo extends AbstractMojo {
38+
public class AddDependencyMojo extends EditingMojo {
4339

4440
@Parameter(property = "gav")
4541
String gav;
@@ -49,16 +45,9 @@ public class AddDependencyMojo extends AbstractMojo {
4945
String classifier;
5046
@Parameter(property = "scope")
5147
String scope;
52-
@Parameter(property = "pom", defaultValue = "pom.xml")
53-
String pom = "pom.xml";
5448

5549
BiConsumer<Path, Dependency> addDependencyCommand;
5650

57-
Function<Path, Boolean> backupFunction;
58-
59-
Consumer<Path> rollbackFunction;
60-
61-
6251
@Override
6352
public void execute() throws MojoExecutionException, MojoFailureException {
6453

@@ -84,16 +73,6 @@ private BiConsumer<Path, Dependency> dependencyCommand() {
8473
.orElse(AddDependency::execute);
8574
}
8675

87-
private PomChange change(Path pomFile) {
88-
return PomChange
89-
.builder()
90-
.withLogger(getLog()::info)
91-
.withPom(pomFile)
92-
.withBackupFunction(backupFunction)
93-
.withRollbackFunction(rollbackFunction)
94-
.build();
95-
}
96-
9776
private Dependency buildDependency() throws MojoExecutionException {
9877
try {
9978
return Dependency

0 commit comments

Comments
 (0)