I want to read data from a .epf file, and the data is like:
/instance/org.eclipse.wb.core/design.palette.flyout.width=192
I think I can use Map<String, String> to store it, but the problem is how to get rid of the =, and then put the left part and right part into the Map?
As jarnbjo mentioned, if it conforms to the property file format, you can read the file using the Properties class.
If you want to store the data in a map, you can use a string function to get the 2 parts of the data:
// Assuming data contains "/instance/org.eclipse.wb.core/design.palette.flyout.width=192"
String[] parts = data.split("=");
// Get the parts
String key = parts[0]; // /instance/org.eclipse.wb.core/design.palette.flyout.width
String value = parts[1]; // 192
// Or just directly use the map
map.put(parts[0], parts[1]);
To test beforehand if the string contains an, just use String#contains().
if (string.contains("=")) {
// Split it.
} else {
throw new IllegalArgumentException("String " + string + " does not contain =");
}
If the files conform to the property file format, you can read them using the Properties class.
Related
I have a HashMap with String as the key type and String[] as value type.
I want to be able to change part of the value (a String array).
I am storing files' contents using this HashMap by saving the file name as the key and its contents as the value (String[]).
I've succeeded in collecting all the data for this HashMap. I want the value
to be displayed in this way:
Key: alert
Value:
0-=Rule_Name,Configuration_Set_ID,Alert_UID,Headline,Create_DateTime
1-f5_high_compression_profile,,211,61b6cc42-0b32-4bd9-a3be-a98d7144ca85,Compression profile gzip level too high,1565003688537
2-f5_automap_enabled,407,0b380e7d-22f9-40c2-8277-3a5ed2ea7116,Automap enabled,1565003696956
I want to replace value of epochtime in the string to Date with this convention yyyy/MM/dd HHmmss for each record (epoch time may be different in the file).
public void createHashMapWithAlertCSVContent() throws Exception {
for(String item: lstServer) {
String[] contentCSVStr=
CmdHelper.Remote.File.cat(SERVER,INDENI_INSIGHT_PATH +
"/"+item).split("\n");
mapServer.put(FileUtil.removeExtension(item), contentCSVStr);
}
if(mapServer.containsKey("job")) {
mapServer.remove("job");
Assert.assertEquals(mapServer.size()-1, lstServer.size());
} else {
Assert.assertEquals(mapServer.size(), lstServer.size());
}
mapServer.entrySet().forEach(entry-> {
System.out.println(entry.getKey() + " " +
entry.getValue());
});
}
What I expected to happen was any entry of epoch time in the array of string would be replaced to yyyy/MM/dd HHmmss convention.
I have this string f5_high_compression_profile,,211,61b6cc42-0b32-4bd9-a3be-a98d7144ca85,Compression profile gzip level too high,1565003688537.
I want to change 1565003688537 to look like the yyyy/MM/dd HHmmss convention.
1565003688537 may not be the same value when I read the content of the CSV, so it has to be able to handle that.
I want to change each entry of ecpoh time into date format value.
You can just read the value by map.get(key) then edit it and the put it again with map.put(key, value).
If the value is of a muatable type, eg. String[] then you can just make modifications directly on this object, because the map is referencig to this object and not holding a copy.
eg.
String[] value = map.get(key);
value[0] = "new String";
If you want to change the size of the String[] then you need to create new list and put it under same key to replace the previous value, or you can change the type to use List instaed of String[] so it will be easier to modify it.
I have list of words which I need to load to ArrayList< String >
prefix.properties
vocab\: = http://myweb.in/myvocab#
hydra\: = http://www.w3.org/ns/hydra/core#
schema\: = http://schema.org/
"vocab:" is actually "vocab:" .Slash(\) is used to read colon(:) character because it is special character.
Dictionary.java
public class Dictionary {
public static ArrayList<String> prefix = new ArrayList<>();
static {
Properties properties = new Properties();
InputStream input = null;
input = ClassLoader.getSystemResourceAsStream("prefix.properties");
System.out.println(input!=null);
try {
properties.load(input);
} catch (IOException e) {
e.printStackTrace();
}
Set<Map.Entry<Object, Object>> entries = properties.entrySet();
for(Map.Entry<Object, Object> E : entries)
{
prefix.add(E.getKey().toString());
prefix.add(E.getValue().toString());
}
}
}
In Dictionary.java , ArrayList prefix will have
prefix = [
"vocab:",
"http://myweb.in/myvocab#",
"hydra:",
"http://www.w3.org/ns/hydra/core#",
"schema:",
"http://schema.org/"
]
I am querying some data in another class.
For eg:
public class QueryClass
{
public ArrayList<String> queryResult(String findKey)
{
ArrayList<String> result = new ArrayList<String>();
ArrayList<String> prefix = Dictionary.prefix;
Iterator<String> iterator = prefix.iterator();
while (iterator.hasNext())
{
String currentKey = iterator.next()+findKey;
/**
Here my logic to search data with this currentKey
*/
}
return result;
}
}
Problem :
I want to avoid this method to load from .properties file because there is possibility of odd number of elements can be present while .properties file provide (key,value) pair way to store data.
Reason why I have to load from separate file ? Because In future I will have to add more keywords/String thats why I put it in prefix.properties file.
Is there any alternative way to do this?
Do not re-invent the wheel.
If you can define the file format, then just go for java properties.
You see, the Properties class has a method getProperty(String, String) where the second argument can be used to pass a default value for example. That method could be used in order to fetch keys that don't come with values.
I would be really careful about inventing your own format; instead I would look into ways of re-using what is already there. Writing code is similar to building roads: people forget that each new road that is built translates to maintenance efforts in the future.
Besides: you add string values to a list of strings by calling list.add(strValue). That is all that is to that.
Edit on your comment: when "java properties" are not what you are looking for; then consider using other formats. For example you could be persisting your data in some JSON based format. And then just go for some existing JSON parser. Actually, your data almost looks like JSON already.
I'm not sure why you need to use ArrayList but if you want to pass these property keys/values, there are 2 better ways:
Use Properties itself.
Convert to HashMap.
My scenario here Is to check strings are localized or not using Selenium automation with java, I have Properties file A with “Key and Value (xpaths)” and Properties_en file B (ResourceBundle), here is where I have the translated strings with “Key and Value(Strings)”.
I have used Properties file A and read the list of strings in web UI into an ArrayList function.
List of strings
First Name
Last Name
Phone
Now I want to compare that list of strings with specific Key "eg:LIST_" and its Value (strings) on Properties_en file B.
Properties_en file B (ResourceBundle)
LIST_FIRST_NAME= First Name
LIST_LAST_NAME= Last Name
LIST_PHONE= Phone
Here i need to compare the list of strings with all Properties_en.properties key that contains "LIST_" and verify that the list of string are all present on the Properties_en file too.
Is there an way to achieve this ?
You can use substring to take only the desired string from the ArrayList.
You know that from List A the first element is First Name. Now, from List you know that the first element is LIST_First_Name. In order to compare them you need to make a substring for the first element in List B
List[0].substring(5)
and it will return the remaining string after eliminating the first 6 characters, which is First Name.
I hope this is what you wanted to know.
You need to read your resource bundle file and store its keys in a set. When reading file you need to split each string on '=' and store only the first part: set.add(line.split('=')[0]). This set will contain then {LIST_FIRST_NAME, LIST_LAST_NAME, ...}.
Then you should read your first file, and for each field you need to test if it exists in a set. But first, you need convert this string to format LIST_FIELD_NAME_UPPERCASE_WITH_DASHES (note, this matches format of keys in ResourceBundle file)
If it the set contains this field, then this field was localized.
Outline is like this:
private Set<String> constructSet(Reader r) {
String line;
Set<String> result = new HashSet<>()
while(null != (line = reader.readLine())
{
String[] keyValue = line.split('=');
if (null != keyValue[1])
result.add(keyValue[0]);
}
return result;
}
public boolean test(Reader fileWithStringsReader, Reader resourceBundleReader)
{
String line;
Set<String> localizedKeys = constructSet(resourceBundleReader);
while (null != (line = fileWithStringsReader.readLine())
{
if (!localizedKeys.contains(transformLine(line))
return false;
}
return true;
}
private String transformLine(String line)
{
if (null == line)
return line;
String[] splitLine = line.split(' ');
return "LIST_" + StringUtils.join(splitLine, "_").toUpperCase();
}
String CompanyData = "{ChargeCompany1Cnt:0,ChargeCompany2Cnt:73,ChargeCompany3Cnt:44,BalanceCompany3Cnt:0,ChargeCompany4Flag:green,BalanceCompany2Flag:green,BalanceCompany1Cnt:0,ChargeCompany3Flag:red,ChargeCompany1Flag:green,BalanceCompany4Flag:green,BalanceCompany1Flag:green,BalanceCompany2Cnt:0,BalanceCompany4Cnt:0,BalanceCompany3Flag:green,ChargeCompany2Flag:red,ChargeCompany4Cnt:6}";
CompanyData is my string I am splitting the data like below. There is no issue with this code, but if the order is changed in the string splitting is breaking.
how to split this string and assign to another string by its name(like splitting based on ChargeCompany1Cnt, ChargeCompany2Cnt). i have used cut and sed commands in UNIX to do this, right now converting my Shell script into JAVA. So sorry if it's a basic question
String ChargeCompany1Cnt=CompanyData.split(,)[0].replace("{","");
String ChargeCompany2Cnt=CompanyData.split(,)[1];
String ChargeCompany3Cnt=CompanyData.split(,)[2];
String BalanceCompany3Cnt=CompanyData.split(,)[3];
String ChargeCompany1Flag=CompanyData.split(,)[8];
Basically I need to find String like ChargeCompany2Cnt,ChargeCompany1Flag in CompanyData and print ChargeCompany2Cnt:73 ChargeCompany1Flag:green
Please note if this is JSON object you can parse it easily with ObjectMapper
of Jacson. you can use the below code for manual parsing
String CompanyData = "{ChargeCompany1Cnt:0,ChargeCompany2Cnt:73,ChargeCompany3Cnt:44,BalanceCompany3Cnt:0,ChargeCompany4Flag:green,BalanceCompany2Flag:green,BalanceCompany1Cnt:0,ChargeCompany3Flag:red,ChargeCompany1Flag:green,BalanceCompany4Flag:green,BalanceCompany1Flag:green,BalanceCompany2Cnt:0,BalanceCompany4Cnt:0,BalanceCompany3Flag:green,ChargeCompany2Flag:red,ChargeCompany4Cnt:6}";
HashMap<String,String> mymap = new HashMap<String,String>();
for ( String s: CompanyData.split("[?,{}]")) {
if (!s.equals(""))
mymap.put(s.split(":")[0],s.split(":")[1]); }
for (HashMap.Entry<String, String> entry : mymap.entrySet()) {
String key = entry.getKey().toString();;
String value = entry.getValue();
System.out.println( key + " = " + value );
Your question isn't too clear, but perhaps this snippet will point you in the right direction:
List<String> companyCount = new ArrayList<>();
String[] companies = CompanyData.substring(1, -1).split(",");
for (String companyCnt : companies) {
companyCount.add(companyCnt);
}
Incidentally, you can probably perform this whole operation without use of cut(1) as well.
Depending on how you intend to use the variables you could alternatively create a set of key-value pairs instead of explicitly declaring each variable.
Then you could split the names out (i.e. split each element further on :) and use them as keys without needing to know which is which.
I am trying to use ResourceBundle#getStringArray to retrieve a String[] from a properties file. The description of this method in the documentation reads:
Gets a string array for the given key from this resource bundle or one of its parents.
However, I have attempted to store the values in the properties file as multiple individual key/value pairs:
key=value1
key=value2
key=value3
and as a comma-delimited list:
key=value1,value2,value3
but neither of these is retrievable using ResourceBundle#getStringArray.
How do you represent a set of key/value pairs in a properties file such that they can be retrieved using ResourceBundle#getStringArray?
A Properties object can hold Objects, not just Strings. That tends to be forgotten because they're overwhelmingly used to load .properties files, and so often will only contain Strings. The documentation indicates that calling bundle.getStringArray(key) is equivalent to calling (String[]) bundle.getObject(key). That's the problem: the value isn't a String[], it's a String.
I'd suggest storing it in comma-delimited format and calling split() on the value.
You can use Commons Configuration, which has methods getList and getStringArray that allow you to retrieve a list of comma separated strings.
Umm, looks like this is a common problem, from threads here and here.
It seems either you don't use the method and parse the value for an array yourself or you write your own ResourceBundle implementation and do it yourself :(. Maybe there is an apache commons project for this...
From the JDK source code, it seems the PropertyResourceBundle does not support it.
I don't believe this is possible with ResourceBundles loaded from a properties file. The PropertyResourceBundle leverages the Properties class to load the properties file. The Properties class loads a properties file as a set of String->String map entries and doesn't support pulling out String[] values.
Calling ResourceBundle.getStringArray just calls ResourceBundle.getObject, casting the result to a String[]. Since the PropertyResourceBundle just hands this off to the Properties instance it loaded from the file, you'll never be able to get this to work with the current, stock PropertyResourceBundle.
example:
mail.ccEmailAddresses=he#anyserver.at, she#anotherserver.at
..
myBundle=PropertyResourceBundle.getBundle("mailTemplates/bundle-name", _locale);
..
public List<String> getCcEmailAddresses()
{
List<String> ccEmailAddresses=new ArrayList<String>();
if(this.myBundle.containsKey("mail.ccEmailAddresses"))
{
ccEmailAddresses.addAll(Arrays.asList(this.template.getString("mail.ccEmailAddresses").split("\\s*(,|\\s)\\s*")));// 1)Zero or more whitespaces (\\s*) 2) comma, or whitespace (,|\\s) 3) Zero or more whitespaces (\\s*)
}
return ccEmailAddresses;
}
I have tried this and could find a way.
One way is to define a subclass of ListresourceBundle, then define instance variable of type String[]
and assign the value to the key.. here is the code
#Override
protected Object[][] getContents() {
// TODO Auto-generated method stub
String[] str1 = {"L1","L2"};
return new Object[][]{
{"name",str1},
{"country","UK"}
};
}
just use spring - Spring .properties file: get element as an Array
relevant code:
base.module.elementToSearch=1,2,3,4,5,6
#Value("${base.module.elementToSearch}")
private String[] elementToSearch;
public String[] getPropertyStringArray(PropertyResourceBundle bundle, String keyPrefix) {
String[] result;
Enumeration<String> keys = bundle.getKeys();
ArrayList<String> temp = new ArrayList<String>();
for (Enumeration<String> e = keys; keys.hasMoreElements();) {
String key = e.nextElement();
if (key.startsWith(keyPrefix)) {
temp.add(key);
}
}
result = new String[temp.size()];
for (int i = 0; i < temp.size(); i++) {
result[i] = bundle.getString(temp.get(i));
}
return result;
}
key=value1;value2;value3
String[] toArray = rs.getString("key").split(";");