Skip to content

Commit

Permalink
Merge pull request #819 from scottsteen/properties-transformer-charset
Browse files Browse the repository at this point in the history
Encode transformed properties files with specified Charset
  • Loading branch information
johnrengelman authored Mar 20, 2023
2 parents feae750 + ff38469 commit 5aecf84
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ class PropertiesFileTransformer implements Transformer {
@Input
String mergeSeparator = ','

@Input
String charset = 'ISO_8859_1'

@Internal
Closure<String> keyTransformer = IDENTITY

Expand Down Expand Up @@ -181,15 +184,17 @@ class PropertiesFileTransformer implements Transformer {

private Properties loadAndTransformKeys(InputStream is) {
Properties props = new CleanProperties()
// InputStream closed by caller, so we don't do it here.
if (is != null) {
props.load(is)
props.load(new InputStreamReader(is, charset))
}
return transformKeys(props)
}

private Properties transformKeys(Properties properties) {
if (keyTransformer == IDENTITY)
if (keyTransformer == IDENTITY) {
return properties
}
def result = new CleanProperties()
properties.each { key, value ->
result.put(keyTransformer.call(key), value)
Expand Down Expand Up @@ -230,18 +235,23 @@ class PropertiesFileTransformer implements Transformer {

@Override
void modifyOutputStream(ZipOutputStream os, boolean preserveFileTimestamps) {
// cannot close the writer as the OutputStream needs to remain open
def zipWriter = new OutputStreamWriter(os, charset)
propertiesEntries.each { String path, Properties props ->
ZipEntry entry = new ZipEntry(path)
entry.time = TransformerContext.getEntryTimestamp(preserveFileTimestamps, entry.time)
os.putNextEntry(entry)
IOUtil.copy(toInputStream(props), os)
IOUtil.copy(readerFor(props, charset), zipWriter)
zipWriter.flush()
os.closeEntry()
}
}

private static InputStream toInputStream(Properties props) {
private static InputStreamReader readerFor(Properties props, String charset) {
ByteArrayOutputStream baos = new ByteArrayOutputStream()
props.store(baos, '')
new ByteArrayInputStream(baos.toByteArray())
baos.withWriter(charset) { w ->
props.store(w, '')
}
new InputStreamReader(new ByteArrayInputStream(baos.toByteArray()), charset)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,23 @@ class PropertiesFileTransformerSpec extends TransformerSpecSupport {
'foo.properties' | { key -> 'bar.' + key.toLowerCase() } | ['foo': 'bar'] | ['FOO': 'baz'] || ['bar.foo': 'bar,baz']
'foo.properties' | { key -> key.replaceAll('^(foo)', 'bar.$1') } | ['foo': 'bar'] | ['FOO': 'baz'] || ['bar.foo': 'bar', 'FOO': 'baz']
}

void appliesCharset() {
given:
def element = getFileElement(path)
def transformer = new PropertiesFileTransformer()
transformer.charset = charset

when:
if (transformer.canTransformResource(element)) {
transformer.transform(context(path, input, charset))
}

then:
output == toMap(transformer.propertiesEntries[path])

where:
path | charset | input || output
'utf8.properties' | 'utf-8' | ['foo': '传傳磨宿说説'] || ['foo': '传傳磨宿说説']
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ class TransformerSpecSupport extends Specification {
return new ByteArrayInputStream(str.bytes)
}

protected static InputStream toInputStream(Properties props) {
protected static InputStream toInputStream(Properties props, String charset) {
ByteArrayOutputStream baos = new ByteArrayOutputStream()
props.store(baos, '')
baos.withWriter(charset) { w ->
props.store(w, '')
}
new ByteArrayInputStream(baos.toByteArray())
}

Expand All @@ -44,8 +46,8 @@ class TransformerSpecSupport extends Specification {
}
}

protected TransformerContext context(String path, Map input) {
TransformerContext.builder().path(path).is(toInputStream(toProperties(input))).relocators([]).stats(stats).build()
protected TransformerContext context(String path, Map input, String charset = 'ISO_8859_1') {
TransformerContext.builder().path(path).is(toInputStream(toProperties(input), charset)).relocators([]).stats(stats).build()
}

protected TransformerContext context(String path, String input) {
Expand Down

0 comments on commit 5aecf84

Please sign in to comment.