Symbols and special characters in maps as keys THROUGH YML FILE - java

Is it possible to store characters such as : ; / , . in the keys in map in Java that's mapped through application.yml?
I'm trying to store URIs and a value associated with them through a mapping in application.yml file however since it's a key, it doesnt save any of the special characters
http://localhost:8080 becomes httplocalhost8080
Is there any way to preserve those lost characters?
~~EDIT~~
I've tried escape characters, double, and single quotes around the keys and still once they are in the hashmap, they are ignored.
The property in the yml file has this structure:
uri-example-config:
keyToValueMap:
http://localhost:8080 : String1
http://exmaple.com: String2
http://moreURIs.com: String2
And then my config is:
#Configuration
#ConfigurationProperties(prefix = "uri-example-config")
#EnableConfigurationProperties
#Getter
#Setter
public class URIProperties {
private Map<String, String> keyToValueMap = new HashMap<>();
}
~~~~EDIT 2~~~~
Yes, i can easily map.put("http://localhost:8080"...) and the strings is preserved as expected. Doing it through yml file with config and properties causes this issue.

Java HashMap accept any Object (String is an Object) as key !
Also, HashMap will not write/change your String.
I think your problem comes from the loading of your .yml
Yaml accept special characters as key if its in double quote.
- "http://localhost:8080"
Check your serializer / deserializer
Edit
There is an explanation on the github of the project
You should surround your string with brackets
- '[http://localhost:8080]'

Yes it is
For your example in java you just have to escape it right.
Map testmap=new HashMap<String,Object>();
Object testObject="a value Object";
testmap.put("http://localhost:8080",testObject);
for (Object s:testmap.keySet()) {
System.out.println(s);
}
Will print out:
http://localhost:8080

Maybe you can create an URI like this:
URI uri = new URI("http", null, "localhost", "8080", "/my/api");
String uriAsString = uri.toASCIIString();
And then set it into your map as a string.
I suggest you to look at this post, you might find a solution there:
HTTP URL Address Encoding in Java

Yes, it is possible to use characters like : ; / , . in a String key Map, if the key is of type String so the Map can accept any string with any character.
The key should be of type a class that implements equals and hashCode methods. If these methods aren't available so they will be inherited from the Object class.

Related

What is the best way to store a common part of Strings in Java?

I have some very similar string like this:
String first = "differentConfig1,config1,config2,config3,config4,config5,config6,config7,config8,config9";
String second = "differentConfig2,config1,config2,config3,config4,config5,config6,config7,config8,config9";
String third = "differentConfig3,config1,config2,config3,config4,config5,config6,config7,config8,config9";
where config1 ... config9 are the same in each string, but differentConfig1, differentConfig2 and differentConfig3 are different
what is the best way to avoid duplicating config1-9 in each string?
(Note that config1-9 are around 1 line long values)
What I have now is:
private String commonConfiguration() {
return "config1,config2,config3,config4,config5,config6,config7,config8,config9"
}
and then the strings are constructed like this:
String first = "differentConfig1," + commonConfiguration();
I was thinking about using variables instead of a function, but I am afraid that a very long variable at the beginning of the function would make it less readable.
Configuration strings are better when stored in files. This is how most systems work too. Ex: Most systems like Kafka or Cassandra have configurations of loging, log file location, addresses etc in such configuration files.
So with this approach you can change these configuration strings as per a different environment as needed without impacting code.
With the use of a properties file, your input would just be a collection of key-value pairs.
firstConfig="differentConfig1,config1,config2,config3,config4,config5,config6,config7,config8,config9"
secondConfig="differentConfig2,config1,config2,config3,config4,config5,config6,config7,config8,config9"
thirdConfig="differentConfig3,config1,config2,config3,config4,config5,config6,config7,config8,config9"
I dont really suggest breaking it further, but if you are sure that they will always have the same commonPrefix, one option is to do something like this:
In your properties file,
firstConfig="differentConfig1"
secondConfig="differentConfig2"
thirdConfig="differentConfig3"
commonPrefix="config1,config2,config3....config9"
And in your code, you read these configuration string and append them. Something like this:
String c1 = Registry.getString("firstConfig")+Registry.getString("commonPrefix")
String c2 = Registry.getString("secondConfig")+Registry.getString("commonPrefix")
String c3 = Registry.getString("thirdConfig")+Registry.getString("commonPrefix")
Note: Properties file just a file that is present in your java project that holds the information of the configurations as a key-value pair.

Library or algorithm to convert a HOCON string to a valid json string

I am limited to using hocon for our config files in our java app's.
My problem is I cannot change the format but I now need to store it in another backend that only accepts flat yaml files.
Example app.conf file:
play {
http {
port = 9000
port = ${?HTTP_PORT}
secret.key = "secretKey"
secret.key = ${?APPLICATION_SECRET}
errorHandler = Example.handler.ErrorHandler
}
}
Attempt 1: Read and parse hocon file with TypesafeConfig:
final ConfigRenderOptions renderOptions = ConfigRenderOptions.defaults()
.setOriginComments( false )
.setJson( true )
.setComments( false );
// Render mergedConfig: Config
String jsonFromHocon = mergedConfig.root().render( renderOptions );
final JsonNode jsonNodeTree = mapper.readTree( jsonFromHocon );
There are 2 problems when this happens:
The mapper.readTree will throw an error because the 2nd entry of play.http.port is not a number and it is not quoted, ${?HTTP_PORT} is the literal value; I want to preserve the features of hocon which include env replacements if the value is not quoted.
Even if the values were converted into legal values - when it is converted to json it is overwritten with the last value. This breaks feature parity with hocon.
Any ideas on how to take advantage of typeSafe configs ability to print out conf to semi-valid json.
I cannot use a packaged json parser unless I am able to manipulate the result of the values.
I googled a bit on how to custom read values but I do not believe it is possible at this time.
expected output:
Add quotes to all values and append the value __replace__ to all keys with duplicate keys and have the env vars
play {
http {
port = "9000"
port__replace__ = "${?HTTP_PORT}"
secret.key = "\"secretKey\""
secret.key__replace__ = "${?APPLICATION_SECRET}"
errorHandler = "Example.handler.ErrorHandler"
}
}
Please prove me wrong! Or suggest an idea!
Is there a hocon format to yaml format parser out there?

Prevent Gson from escaping Unicode symbols

I have Map<String, String> which later I want to serialize to JSON using Gson. Some of keys of this map contain Unicode characters like \uf177 etc. The problem appears when I try to serialize such a map to JSON, let's say I have Map<String, String> containing:
"TEST_KEY" -> "\uf177"
then, when serialized using Gson, I have:
{
"TEST_KEY": "\\uf177"
}
Which is not what I want, I want these Unicode symbols to be as they are when serialized. Is there a way to achieve this? Would appreciate any help,
UPDATE
Code which produces the issue:
projectI18nFileContent = commentsRemover.transform(projectI18nFileContent);
//find json map which represents translations
Matcher fullTranslationsMapMatcher = translationsMapSerializedToJsonPattern.matcher(projectI18nFileContent);
if (!fullTranslationsMapMatcher.find()) {
throw new IllegalArgumentException(format("%s \n does not contain valid translations json map", projectI18nFileContent));
}
String translationsMapSerializedToJson = fullTranslationsMapMatcher.group();
String newTranslationsMapSerializedToJson = gson.toJson(newTranslations);
//replace old json translations map with a new
return projectI18nFileContent.replace(translationsMapSerializedToJson, newTranslationsMapSerializedToJson);
This piece of code is dedicated to change content of i18n file for javascript project, this is the reason why unicode should not be escaped (otherwise it's just resolved not correctly)
Thanks,
Cheers
According to Json spec the backslashes must to be escaped.
So you shouldn't try to prevent this. It's correct behavior.

commons configuration: comma and multikey issue

My requirement was to update a key/value pair property file for which Commons Configuration is used.
But problem is when you save any text using this api it remove space after comma in a value.
If you disable parsing then it create multiple keys of safe name broken by comma :(
PropertiesConfiguration config = new PropertiesConfiguration("prop.properties");
//config.setDelimiterParsingDisabled(true);
config.save();
Expected value (with no truncation of spaces after before comma):
Name = some , Text , for testing
If setDelimiterParsingDisabled is false then below is outout all spaces gone
Name = some,Text,for testing
If that is True then below is output
Name = some
Name = Text
Name = for testing
I need first one with all space intact means key as is...how to do that
I believe both things cannot be achieved so what is id is I changed Delimeter to carrot ^ sign and not it behaving as I like.
So this is answered.

Why Properties.store delimiting with \ for values separating with :

I have a file which contains properties like :
MyKey=value1:value2
I am using Properties.load to load these into a property object and then outputting the values into another file (using Property.store ).
But the new file is delimiting it with \
MyKey=value1\:value2
Why is this happening ?
This happens, because : is like = a reserved char.
Truth = Beauty
Truth:Beauty
Truth :Beauty
All these lines will set the value for the Property with the Key Truth to Beauty
http://docs.oracle.com/javase/7/docs/api/java/util/Properties.html#load(java.io.Reader)
The write method will escape the : sign to \:. After loading this chars will be removed.

Categories

Resources