Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: add yml properties manager #134

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@
<artifactId>maven-plugin-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>2.3</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package org.codehaus.mojo.properties.managers;

import javax.inject.Named;
import javax.inject.Singleton;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.yaml.snakeyaml.Yaml;

/**
* Properties manager using YAML as backand.
*/
@Named
@Singleton
public class YmlPropertiesManager implements PropertiesManager {

private static final String SUPPORTED_EXTENSION_YML = "yml";
private static final String SUPPORTED_EXTENSION_YAML = "yaml";

@Override
public boolean isExtensionSupport(final String extension) {
return SUPPORTED_EXTENSION_YML.equals(extension) || SUPPORTED_EXTENSION_YAML.equals(extension);
}

@Override
public Properties load(final InputStream in) throws IOException {
final Properties properties = new Properties();
final Map<String, Object> map = flattenYamlToMap("", new Yaml().load(in));
properties.putAll(map);
return properties;
}

public Map<String, Object> flattenYamlToMap(String parentKey, final Map<String, Object> yamlMap) {
if (parentKey != null && !parentKey.trim().isEmpty()) {
parentKey = parentKey.trim() + ".";
}
final Map<String, Object> result = new HashMap<>();

for (final Map.Entry<String, Object> entry : yamlMap.entrySet()) {
final String key = String.format("%s%s", parentKey, entry.getKey().trim());
final Object value = entry.getValue();
if (value instanceof Map) {
final Map<String, Object> stringObjectMap = flattenYamlToMap(key, (Map<String, Object>) value);
result.putAll(stringObjectMap);
} else if (value instanceof Collection) {
final Object[] values = ((Collection<?>) value).toArray();
for (int i = 0; i < values.length; i++) {
if (values[i] instanceof Map) {
result.putAll(flattenYamlToMap(
String.format("%s%s[%d]", parentKey, entry.getKey(), i), (Map) values[i]));
} else {
result.put(String.format("%s%s[%d]", parentKey, entry.getKey(), i), String.valueOf(values[i]));
}
}
} else {
result.put(key, value);
}
}
return result;
}

@Override
public void save(final Properties properties, final OutputStream out, String comments) throws IOException {

final OutputStreamWriter outputStreamWriter = new OutputStreamWriter(out, StandardCharsets.ISO_8859_1);

try (PrintWriter pw = new PrintWriter(outputStreamWriter);
StringWriter sw = new StringWriter()) {
properties.store(sw, comments);
comments = '#' + comments;

final List<String> lines = new ArrayList<>();
try (BufferedReader r = new BufferedReader(new StringReader(sw.toString()))) {
String line;
while ((line = r.readLine()) != null) {
if (!line.startsWith("#") || line.equals(comments)) {
lines.add(line);
}
}
}

Collections.sort(lines);
for (final String l : lines) {
pw.println(l);
}
}
}

@Override
public String toString() {
return String.format("%s [extension=%s]", getClass().getSimpleName(), SUPPORTED_EXTENSION_YML);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.codehaus.mojo.properties.managers;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Properties;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class YmlPropertiesManagerTest {

private static final String NL = System.lineSeparator();

private final YmlPropertiesManager manager = new YmlPropertiesManager();

@Test
public void testLoad() throws IOException {

// given
final String props = "# comments" + NL + NL + "key1:" + NL + " key2: value1" + NL + "key3: value2" + NL
+ "key4: " + NL + " - A" + NL + " - B" + NL + " - C" + NL;

final ByteArrayInputStream inputStream = new ByteArrayInputStream(props.getBytes());

// when
final Properties properties = manager.load(inputStream);

// then
assertEquals(5, properties.size());
assertEquals("value1", properties.getProperty("key1.key2"));
assertEquals("value2", properties.getProperty("key3"));
assertEquals("A", properties.getProperty("key4[0]"));
}

@Test
public void testSave() throws IOException {

// given
final Properties properties = new Properties();
properties.setProperty("key1", "value1");
properties.setProperty("key2", "value2");

final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

// when
manager.save(properties, outputStream, "Test comments");

// then
final String expected = "#Test comments" + NL + "key1=value1" + NL + "key2=value2" + NL;

assertEquals(expected, outputStream.toString());
}
}