Skip to content

Commit 8f49cd5

Browse files
committed
refactor: extract logic for custom field name syntax
1 parent 02882be commit 8f49cd5

File tree

4 files changed

+68
-26
lines changed

4 files changed

+68
-26
lines changed

docs/changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ category: Administration
1616
* refactor: improve structure of subtask creation service
1717
* feat: ensure compatibility with Jira 10.4.0
1818
* refactor: use Java 16 syntax for lists
19+
* refactor: extract logic for custom field name syntax
1920

2021
### [24.11.0] - 2024-11-11
2122

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package de.codescape.jira.plugins.multiplesubtasks.model;
2+
3+
import java.util.regex.Matcher;
4+
import java.util.regex.Pattern;
5+
6+
/**
7+
* Utility class to deal with custom fields.
8+
*/
9+
public class CustomFields {
10+
11+
// custom fields can be referenced by id: customfield_12345
12+
public static final Pattern CUSTOM_FIELD_ID_PATTERN = Pattern.compile("customfield_\\d{5}");
13+
14+
// custom fields can be reference by name: customfield(fieldname)
15+
public static final Pattern CUSTOM_FIELD_NAME_PATTERN = Pattern.compile("customfield\\((?<name>(?:\\\\\\\\|\\\\\\)|[^)])++)\\)");
16+
17+
/**
18+
* Retrieve the name of the customfield from an expression like <code>customfield(fieldName)</code>.
19+
*/
20+
public static String extractCustomFieldName(String customFieldString) {
21+
Matcher matcher = CUSTOM_FIELD_NAME_PATTERN.matcher(customFieldString);
22+
if (matcher.matches()) {
23+
return matcher.group("name")
24+
.replaceAll("\\\\\\)", ")")
25+
.replaceAll("\\\\\\(", "(")
26+
.replaceAll("\\\\:", ":")
27+
.trim();
28+
} else {
29+
throw new SyntaxFormatException("Illegal custom field name: " + customFieldString);
30+
}
31+
}
32+
33+
}

src/main/java/de/codescape/jira/plugins/multiplesubtasks/model/Subtask.java

+5-26
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66

77
import java.util.*;
88
import java.util.regex.Matcher;
9-
import java.util.regex.Pattern;
10-
import java.util.stream.Collectors;
119

1210
/**
1311
* This class represents the request to create a new subtask with the given attributes.
@@ -40,12 +38,6 @@ public static class Attributes {
4038

4139
}
4240

43-
// custom fields can be referenced by id: customfield_12345:
44-
private static final Pattern CUSTOM_FIELD_ID_PATTERN = Pattern.compile("customfield_\\d{5}");
45-
46-
// custom fields can be reference by name: customfield(fieldname):
47-
private static final Pattern CUSTOM_FIELD_NAME_PATTERN = Pattern.compile("customfield\\((?<name>(?:\\\\\\\\|\\\\\\)|[^)])++)\\)");
48-
4941
private final String summary;
5042
private final String description;
5143
private final String assignee;
@@ -226,8 +218,8 @@ private String ensureValidEstimate(ArrayListMultimap<String, String> attributes)
226218

227219
private void verifyOnlyKnownAttributes(ArrayListMultimap<String, String> attributes) {
228220
attributes.forEach((key, value) -> {
229-
if (!Attributes.ALL.contains(key) && !CUSTOM_FIELD_ID_PATTERN.matcher(key).matches()
230-
&& !CUSTOM_FIELD_NAME_PATTERN.matcher(key).matches())
221+
if (!Attributes.ALL.contains(key) && !CustomFields.CUSTOM_FIELD_ID_PATTERN.matcher(key).matches()
222+
&& !CustomFields.CUSTOM_FIELD_NAME_PATTERN.matcher(key).matches())
231223
throw new SyntaxFormatException("Unknown attribute " + key + " found.");
232224
});
233225
}
@@ -261,7 +253,7 @@ private String ensureValidDueDate(ArrayListMultimap<String, String> attributes)
261253
private Map<String, List<String>> extractCustomFieldsById(ArrayListMultimap<String, String> attributes) {
262254
// get all custom field keys
263255
List<String> customFieldKeys = attributes.keySet().stream()
264-
.filter(s -> CUSTOM_FIELD_ID_PATTERN.matcher(s).matches())
256+
.filter(s -> CustomFields.CUSTOM_FIELD_ID_PATTERN.matcher(s).matches())
265257
.toList();
266258
// collect all keys and values into a map
267259
Map<String, List<String>> customFields = new HashMap<>();
@@ -272,25 +264,12 @@ private Map<String, List<String>> extractCustomFieldsById(ArrayListMultimap<Stri
272264
private Map<String, List<String>> extractCustomFieldsByName(ArrayListMultimap<String, String> attributes) {
273265
// get all custom field keys
274266
List<String> customFieldKeys = attributes.keySet().stream()
275-
.filter(s -> CUSTOM_FIELD_NAME_PATTERN.matcher(s).matches())
267+
.filter(s -> CustomFields.CUSTOM_FIELD_NAME_PATTERN.matcher(s).matches())
276268
.toList();
277269
// collect all keys and values into a map
278270
Map<String, List<String>> customFields = new HashMap<>();
279-
customFieldKeys.forEach(key -> customFields.put(extractCustomFieldName(key), new ArrayList<>(attributes.get(key))));
271+
customFieldKeys.forEach(key -> customFields.put(CustomFields.extractCustomFieldName(key), new ArrayList<>(attributes.get(key))));
280272
return customFields;
281273
}
282274

283-
private String extractCustomFieldName(String customFieldString) {
284-
Matcher matcher = CUSTOM_FIELD_NAME_PATTERN.matcher(customFieldString);
285-
if (matcher.matches()) {
286-
return matcher.group("name")
287-
.replaceAll("\\\\\\)", ")")
288-
.replaceAll("\\\\\\(", "(")
289-
.replaceAll("\\\\:", ":")
290-
.trim();
291-
} else {
292-
throw new SyntaxFormatException("Illegal custom field name: " + customFieldString);
293-
}
294-
}
295-
296275
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package de.codescape.jira.plugins.multiplesubtasks.model;
2+
3+
import org.junit.Test;
4+
5+
import static org.hamcrest.MatcherAssert.assertThat;
6+
import static org.hamcrest.Matchers.equalTo;
7+
import static org.hamcrest.Matchers.is;
8+
9+
public class CustomFieldsTest {
10+
11+
@Test
12+
public void extractCustomFieldNameForSimpleStringValue() {
13+
String result = CustomFields.extractCustomFieldName("customfield(Simple)");
14+
assertThat(result, is(equalTo("Simple")));
15+
}
16+
17+
@Test
18+
public void extractCustomFieldNameForAlphanumericValue() {
19+
String result = CustomFields.extractCustomFieldName("customfield(Test123)");
20+
assertThat(result, is(equalTo("Test123")));
21+
}
22+
23+
@Test
24+
public void extractCustomFieldNameForStringWithEscapedBracketsValue() {
25+
String result = CustomFields.extractCustomFieldName("customfield(Field(123\\))");
26+
assertThat(result, is(equalTo("Field(123)")));
27+
}
28+
29+
}

0 commit comments

Comments
 (0)