Reputation: 21
I have a localized properties file with a list of key-value pairs. I want to write property values in japanese,chinese,german etc. to the file and also want to save the already existing file layout with comments and spaces. Need to write these languages in its own native form.
I tried to add a new property ("key = アカウント ナビゲーション コンポーネント") to the existing property file using PropertiesConfigurationLayout. It is possible to add new property in its native form and PropertiesConfigurationLayout helped to save the layout of the file. But the existing keys format will get changed to unicode format. Useful link : (http://marjavamitjava.com/modifying-property-file-maintaining-order-well-comments/)
This is the code I tried.
Code:
File file = new File("base_ch.properties");
PropertiesConfiguration config = new PropertiesConfiguration();
config.setEncoding("UTF-8");
PropertiesConfigurationLayout layout = new PropertiesConfigurationLayout(config);
Properties props = new Properties();
try(InputStreamReader in = new InputStreamReader(new FileInputStream(file), "UTF-8"))
{
layout.load(in);
OutputStreamWriter out =new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
props.put("key","アカウント ナビゲーション コンポーネント");
layout.save(out);
props.store(out, null);
}
catch (ConfigurationException | IOException e) {
e.printStackTrace();
}
base_ch.properties file content before code runs:
# -----------------------------------------------------------------------
# All rights reserved.
# Comments included here
# -----------------------------------------------------------------------
#Tue May 22 13:41:37
account.quote.expiration.time.label = Gültig bis
address.zipcode = 邮政编码:
base_ch.properties file content after code runs:
# -----------------------------------------------------------------------
# All rights reserved.
# Comments included here
# -----------------------------------------------------------------------
#Tue May 22 13:41:37
account.quote.expiration.time.label = G\u00FCltig bis
address.zipcode = \u90AE\u653F\u7F16\u7801
#Wed Dec 06 17:40:04 IST 2017
key=アカウント ナビゲーション コンポーネント
I want to save the file layout without any change and should retain the existing properties in its native form. It is able to write various languages to the properties file using various classes, but the file layout will get change in that cases. PropertiesConfigurationLayout is the only way I found to save the layout.
Can anyone help me?
Upvotes: 1
Views: 904
Reputation: 41
Just set JupIOFactory instance with unicode option as false to disable unicode escaping.
PropertiesConfiguration config = new PropertiesConfiguration()
config.setIOFactory(new PropertiesConfiguration.JupIOFactory(false))
Upvotes: 0
Reputation: 21
Got a solution for the question.
Customize PropertiesConfiguration and PropertiesConfigurationLayout classes for to meet the requirement.
Rewrite the escapeValue() method in PropertiesConfiguration in such a way to return the property value itself without escape characters.
Override the save method in PropertiesConfigurationLayout.
The below given is the class which extends PropertiesConfiguration :
public class PropertiesConfigurationExtended extends PropertiesConfiguration{
private static final char[] SEPARATORS = new char[] {'=', ':'};
private static final char[] WHITE_SPACE = new char[]{' ', '\t', '\f'};
private static final String ESCAPE = "\\";
public static class PropertiesWriter extends PropertiesConfiguration.PropertiesWriter{
private char delimiter;
/**
* Constructor.
*/
public PropertiesWriter(Writer writer, char delimiter)
{
super(writer,delimiter);
this.delimiter = delimiter;
}
public void writeProperty(String key, Object value,
boolean forceSingleLine) throws IOException
{
String v;
if (value instanceof List)
{
List values = (List) value;
if (forceSingleLine)
{
v = makeSingleLineValue(values);
}
else
{
writeProperty(key, values);
return;
}
}
else
{
v = escapeValue(value);
}
write(escapeKey(key));
write(" = ");
write(v);
writeln(null);
}
/**
* Rewrite the escapeValue method to avoid escaping of the given property value.
*
* @param value the property value
* @return the same property value
*/
private String escapeValue(Object value)
{
return String.valueOf(value);
}
}
}
The below given is the class which extends PropertiesConfigurationLayout :
public class PropertiesConfigurationLayoutExtended extends PropertiesConfigurationLayout{
public PropertiesConfigurationLayoutExtended(PropertiesConfigurationExtended config) {
super(config);
}
public void save(Writer out) throws ConfigurationException
{
try
{
char delimiter = getConfiguration().isDelimiterParsingDisabled() ? 0
: getConfiguration().getListDelimiter();
PropertiesConfigurationExtended.PropertiesWriter writer = new PropertiesConfigurationExtended.PropertiesWriter(
out, delimiter);
if (getHeaderComment() != null)
{
writer.writeln(getCanonicalHeaderComment(true));
writer.writeln(null);
}
for (Iterator it = getKeys().iterator(); it.hasNext();)
{
String key = (String) it.next();
if (getConfiguration().containsKey(key))
{
// Output blank lines before property
for (int i = 0; i < getBlancLinesBefore(key); i++)
{
writer.writeln(null);
}
// Output the comment
if (getComment(key) != null)
{
writer.writeln(getCanonicalComment(key, true));
}
// Output the property and its value
boolean singleLine = (isForceSingleLine() || isSingleLine(key))
&& !getConfiguration().isDelimiterParsingDisabled();
writer.writeProperty(key, getConfiguration().getProperty(
key), singleLine);
}
}
writer.flush();
}
catch (IOException ioex)
{
throw new ConfigurationException(ioex);
}
}
}
The class for writing properties to the file :
File file = new File("base_ch.properties");
PropertiesConfigurationExtended config = new PropertiesConfigurationExtended();
PropertiesConfigurationLayoutExtended layout = new PropertiesConfigurationLayoutExtended(config);
try(InputStreamReader in = new InputStreamReader(new FileInputStream(file), "UTF-8"))
{
layout.load(in);
OutputStreamWriter out =new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
config.setProperty("key","アカウント ナビゲーション コンポーネント");
layout.save(out, false));
}
catch (ConfigurationException | IOException e) {
e.printStackTrace();
}
Upvotes: 1
Reputation: 136022
If its only about adding properties to existing file then you can just add it:
Properties props = new Properties();
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("file", true), "UTF-8");
props.put("key", "アカウント ナビゲーション コンポーネント");
props.store(out, null);
Upvotes: 0