Skip to content

Commit a701633

Browse files
committed
Backport #100 into 2.10
1 parent 1160390 commit a701633

File tree

6 files changed

+106
-5
lines changed

6 files changed

+106
-5
lines changed

properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/JavaPropsGenerator.java

+5
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ public void setSchema(FormatSchema schema) {
137137
_basePath.append(indent);
138138
_jpropContext = JPropWriteContext.createRootContext(_indentLength);
139139
}
140+
// [dataformats-text#100]: Allow use of optional prefix
141+
final String prefix = _schema.prefix();
142+
if (prefix != null) {
143+
_basePath.append(prefix);
144+
}
140145
}
141146
return;
142147
}

properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/JavaPropsSchema.java

+32
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,14 @@ public class JavaPropsSchema
139139
*/
140140
protected String _header = "";
141141

142+
/**
143+
* Optional prefix to strip and append to key names.
144+
* Useful when subset of properties need to be processed.
145+
*
146+
* @since 2.10
147+
*/
148+
protected String _prefix;
149+
142150
/*
143151
/**********************************************************************
144152
/* Construction, factories, mutant factories
@@ -157,6 +165,7 @@ public JavaPropsSchema(JavaPropsSchema base) {
157165
_keyValueSeparator = base._keyValueSeparator;
158166
_lineEnding = base._lineEnding;
159167
_header = base._header;
168+
_prefix = base._prefix;
160169
}
161170

162171
/**
@@ -287,6 +296,22 @@ public JavaPropsSchema withLineEnding(String v) {
287296
return s;
288297
}
289298

299+
/**
300+
* Mutant factory for constructing schema instance where specified
301+
* prefix is prepended before logical path when generator writes output
302+
* and removed by parser before binding back as properties.
303+
*
304+
* @since 2.10
305+
*/
306+
public JavaPropsSchema withPrefix(String v) {
307+
if (_equals(v, _prefix)) {
308+
return this;
309+
}
310+
JavaPropsSchema s = new JavaPropsSchema(this);
311+
s._prefix = v;
312+
return s;
313+
}
314+
290315
/**
291316
* Mutant factory for constructing schema instance where specified
292317
* header section (piece of text written out right before actual
@@ -371,6 +396,13 @@ public String pathSeparator() {
371396
return _pathSeparator;
372397
}
373398

399+
/**
400+
* @since 2.10
401+
*/
402+
public String prefix() {
403+
return _prefix;
404+
}
405+
374406
public boolean writeIndexUsingMarkers() {
375407
return _writeIndexUsingMarkers && (_indexMarker != null);
376408
}

properties/src/main/java/com/fasterxml/jackson/dataformat/javaprop/util/JPropPathSplitter.java

+22-3
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ public static JPropPathSplitter create(JavaPropsSchema schema)
3535
}
3636
return new FullSplitter(sep, schema.parseSimpleIndexes(),
3737
indexMarker,
38-
pathOnlySplitter(schema));
38+
pathOnlySplitter(schema),
39+
schema.prefix());
3940
}
4041

4142
private static JPropPathSplitter pathOnlySplitter(JavaPropsSchema schema)
@@ -262,14 +263,25 @@ public static class FullSplitter extends JPropPathSplitter
262263
// small but important optimization for cases where index markers are absent
263264
protected final int _indexFirstChar;
264265
protected final JPropPathSplitter _simpleSplitter;
265-
266+
267+
/**
268+
* @since 2.10
269+
*/
270+
protected final String _prefix;
271+
266272
public FullSplitter(String pathSeparator, boolean useSimpleIndex,
267-
Markers indexMarker, JPropPathSplitter fallbackSplitter)
273+
Markers indexMarker, JPropPathSplitter fallbackSplitter,
274+
String prefix)
268275
{
269276
super(useSimpleIndex);
270277
String startMarker = indexMarker.getStart();
271278
_indexFirstChar = startMarker.charAt(0);
272279
_simpleSplitter = fallbackSplitter;
280+
if (prefix == null || prefix.isEmpty()) {
281+
_prefix = null;
282+
} else {
283+
_prefix = prefix + pathSeparator;
284+
}
273285
_indexMatch = Pattern.compile(String.format
274286
("(%s)|(%s(\\d{1,9})%s)",
275287
Pattern.quote(pathSeparator),
@@ -281,6 +293,13 @@ public FullSplitter(String pathSeparator, boolean useSimpleIndex,
281293
public JPropNode splitAndAdd(JPropNode parent,
282294
String key, String value)
283295
{
296+
// [dataformats-text#100]: handle possible prefix
297+
if (_prefix != null) {
298+
if (!key.startsWith(_prefix)) {
299+
return null;
300+
}
301+
key = key.substring(_prefix.length());
302+
}
284303
if (key.indexOf(_indexFirstChar) < 0) { // no index start marker
285304
return _simpleSplitter.splitAndAdd(parent, key, value);
286305
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.fasterxml.jackson.dataformat.javaprop;
2+
3+
import java.util.Map;
4+
import java.util.Properties;
5+
6+
import com.fasterxml.jackson.databind.ObjectMapper;
7+
8+
public class PrefixTest extends ModuleTestBase
9+
{
10+
private final JavaPropsMapper MAPPER = mapperForProps();
11+
12+
public void testPrefixParsing() throws Exception {
13+
final String INPUT = "org.o1.firstName=Bob\n"
14+
+"org.o1.lastName=Palmer\n"
15+
+"org.o2.firstName=Alice\n"
16+
+"org.o2.lastName=Black\n"
17+
+"junk=AQIDBA==\n";
18+
FiveMinuteUser result1 = _mapFrom(MAPPER.reader(JavaPropsSchema.emptySchema().withPrefix("org.o1")), INPUT, FiveMinuteUser.class, false);
19+
assertEquals("Bob", result1.firstName);
20+
assertEquals("Palmer", result1.lastName);
21+
FiveMinuteUser result2 = _mapFrom(MAPPER.reader(JavaPropsSchema.emptySchema().withPrefix("org.o2")), INPUT, FiveMinuteUser.class, false);
22+
assertEquals("Alice", result2.firstName);
23+
assertEquals("Black", result2.lastName);
24+
}
25+
26+
public void testPrefixGeneration() throws Exception
27+
{
28+
FiveMinuteUser input = new FiveMinuteUser("Bob", "Palmer", true, Gender.MALE,
29+
new byte[] { 1, 2, 3, 4 });
30+
String output = MAPPER.writer(JavaPropsSchema.emptySchema().withPrefix("org.o1")).writeValueAsString(input);
31+
assertEquals("org.o1.firstName=Bob\n"
32+
+"org.o1.lastName=Palmer\n"
33+
+"org.o1.gender=MALE\n"
34+
+"org.o1.verified=true\n"
35+
+"org.o1.userImage=AQIDBA==\n"
36+
,output);
37+
Properties props = MAPPER.writeValueAsProperties(input, JavaPropsSchema.emptySchema().withPrefix("org.o1"));
38+
assertEquals(5, props.size());
39+
assertEquals("true", props.get("org.o1.verified"));
40+
assertEquals("MALE", props.get("org.o1.gender"));
41+
}
42+
}

release-notes/CREDITS-2.x

+3-2
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,13 @@ Henning Schmiedehausen (hgschmie@github)
4949
(2.9.9)
5050

5151
Tanguy Leroux (tlrx@github)
52-
5352
* Reported #90: Exception when decoding Jackson-encoded `Base64` binary value in YAML
5453
(2.10.0)
5554

5655
Andrey Somov (asomov@github)
57-
5856
* Contributed #101: Use latest SnakeYAML version 1.23 and get rid of deprecated methods
5957
(2.10.0)
6058

59+
Alon Bar-Lev (alonbl@github)
60+
* Contributed #100: (properties) Add an option to specify properties prefix
61+
(2.10.0)

release-notes/VERSION-2.x

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Modules:
1010

1111
2.10.0 (not yet released)
1212

13+
#100: (properties) Add an option to specify properties prefix
14+
(contributed by Alon B-L)
1315
#101: (yaml) Use latest SnakeYAML version 1.24 and get rid of deprecated methods
1416
(contributed by Andrey S)
1517
#108: (yaml) Add new `CsvParser.Feature.ALLOW_COMMENTS` to replace deprecated

0 commit comments

Comments
 (0)