How to append values to a key using ini4j? - java

I want to append a value to following Key like this:
[Section]
Key=value1,value2
I tried Wini and Section getAll() and putAll() functions but it always replaces value1 with value2 instead of appending value2. And I did' t find any tutorial about this online. How can I do this using ini4j? Or another jni writinig and parsing library?

I finally treated it as a single Key-value pair and appended to the string after "Key=".

This topic is a little old, but I'm faced exact the same problem, so...
To read all:
//open the file
Ini ini = new Ini(new File(iniFileName));
//load all values at once
Ini.Section names = ini.get("mySectionX");
myStr[] = names.getAll("myKey1", String[].class);
To put all (with the same ini and names):
//if myStr[] have changes
names.putAll("myKey1", myStr);
At final you gonna have the ini file like this ("myKey1" is ALWAYS the same):
[mySectionX]
myKey1 = value1
myKey1 = value2
myKey1 = value3

Adding more information,
if you want o create a new file:
Ini ini = new Ini();
ini.setComment(" Main comment "); //comment about the file
//add a section comment, a section and a value
ini.putComment("mySectionX", " Comment about the section");
ini.put("mySectionX", "myKey1", "value1");
//adding many parameters at one in a section
String[] keyList = {value1, value2, value3};
ini.add("mySectionY");
Ini.Section names = ini.get("mySectionY");
names.putAll("myKey1", keyList); //put all new elements at once
...
ini.store(new File(iniFileName));

Related

apache PropertiesConfiguration doesn't resolve placeholders

Say that I have the following two configuration files:
File 1:
key1 = ${common.key1}
key2 = ${common.key2}
File 2:
common.key1 = value1
common.key2 = value2
And I have the following code:
import org.apache.commons.configuration.PropertiesConfiguration;
...
PropertiesConfiguration newConfig = new PropertiesConfiguration();
File configFile1 = new File("...paht to file 1");
File configFile2 = new File("...path to file 2");
newConfig.setDelimiterParsingDisabled(true);
newConfig.load(configFile2);
newConfig.load(configFile1);
Iterator<String> props = newConfig.getKeys();
while (props.hasNext()) {
String propName = props.next();
String propValue = newConfig.getProperty(propName).toString();
System.out.println(propName + " = " + propValue);
}
I have the following output:
common.key1 = value1
common.key2 = value2
key1 = ${common.key1}
key2 = ${common.key2}
Why the placeholders are not resolved ?
See this page in the documentation, which says:
Below is some more information related to variable interpolation users should be aware of:
...
Variable interpolation is done by all property access methods. One exception is the generic getProperty() method which returns the raw property value.
And that's exactly what you are using in your code.
The API docs of getProperty() mentions this as well:
Gets a property from the configuration. ... On this level variable substitution is not yet performed.
Use other methods available in PropertiesConfiguration to get the actual, interpolated value. For example, call getProperties() on the PropertiesConfiguration to convert it to a java.util.Properties object and iterate on that instead.
It is also possible to use it in generic way with placeholders substitution like below:
config.get(Object.class, propName);
Unlike getProperty method the get method with Object.class parameter will return value of original class with variables interpolated.

Processing large number of records from a file in Java

I have million records in CSV file which has 3 columns id,firstName,lastName. I have to process this file in java and validate that id should be unique, firstName should not be null. If there are scenarios where id is not unique and/or firstName is null then I have to write these records in an output file with a fourth column as the reason("id not unique"/"firstName is NULL"). Performance should be good. Please suggest the best effective way.
You can use a collection (ArrayList) to store all the ID's in it in a loop and check if it doesn't already exist. If it doest, write it in a file.
The code should be like this:
if(!idList.contains(id)){
idList.add(id);
}else{
writer.write(id);
}
The above code should work in a loop for all the records being read from the CSV file.
You can use OpenCsv jar for the purpose you have specified. It's under Apache 2.0 licence.
You can download the jar from
http://www.java2s.com/Code/Jar/o/Downloadopencsv22jar.htm
below is the code for the same
Reader reader = Files.newBufferedReader(Paths.get(INPUT_SAMPLE_CSV_FILE_PATH));
CSVReader csvReader = new CSVReader(reader);
Writer writer = Files.newBufferedReader(Paths.get(OUTPUT_SAMPLE_CSV_FILE_PATH));
CSVWriter csvWriter = new CSVWriter(writer);
List<String[]> list = csvReader.readAll();
for (String[] row : list) {
//assuming First column to be Id
String id = row[0];
//assuming name to be second column
String name = row[1];
//assuming lastName to be third column
String lastName = row[2];
//Put your pattern here
if(id==null || !id.matches("pattern") || name==null || !name.matches("pattern")){
String[] outPutData = new String[]{id, name , lastName, "Invalid Entry"};
csvWriter.writeNext(outPutData);
}
}
let me know if this works or you need further help or clarifications.
If you want a good performance algorithm, you should not use ArrayList.contains(element) as explained here, uses O(n) complexity. Instead I suggest you to use a HashSet as the HashSet.Contains(element) operation has an O(1) complexity. To make things short, with ArrayList you would make 1,000,000^2 operations, while with HashSet you would use 1,000,000 operations.
In pseudo-code (to not give away the full answer and make you find the answer on your own) I would do this:
File outputFile
String[] columns
HashSet<String> ids
for(line in file):
columns = line.split(',')
if(ids.contains(columns.id):
outputFile.append(columns.id + " is not unique")
continue
if(columns.name == null):
outputFile.append("first name is null!")
continue
ids.add(columns.id)

Parsing Properties file

I am trying to parse a Properties file that has the following format:
CarModel=Prius
CarMake=Toyota
Option1=Transmission
OptionValue1a=Manual
OptionValue1b=Automatic
Option2=Brakes
OptionValue2a=Regular
OptionValue2b=ABS
My question is, what if there are various forms of the Properties file? For instance, what if a Properties file has 3 options for Option 1, and another Properties file has 2 options for Option 1? Right now my code looks like this:
Properties props = new Properties();
FileInputStream x = new FileInputStream(filename);
props.load(x);
String carModel = props.getProperty("CarModel");
if(!carModel.equals(null)){
String carMake = props.getProperty("CarMake");
String option1 = props.getProperty("Option1");
String option1a = props.getProperty("OptionValue1a");
String option1b = props.getProperty("OptionValue1b");
etc. I'm thinking I need a lot of 'if' statements, but I'm unsure how to implement them. Any ideas?
Are you sure you want to use a properties file? I suggest using YAML.
I am trying to parse a Properties file that has the following format:
CarModel: Prius
CarMake: Toyota
Transmission:
- Manual
- Automatic
Brakes:
- Regular
- ABS
Using SnakeYAML you can do
Map<String, Object> car = (Map) new Yaml().load(new FileReader(filename));
Note the lines starting with - are turned into a list.
If you must stick with Properties, I suggest putting the list in a property.
CarModel=Prius
CarMake=Toyota
Options=Transmission Manual|Automatic,\
Brakes Regular|ABS
This way you can read the options like
String options = prop.getProperty("Options");
for(String option : options.split("\\s*,\\s*")) {
String[] parts = option.split("\\s+");
String optionType = parts[0];
String[] optionChoices = parts[1].split("[|]");
}
This way you can have any number of options with any number of choices.

How to get values of getParameterValues in the order they are sent?

I am sending registration form data through HttpPost method to Servlet and get this data by getParameterValues.
No problem with getting data, but I get the data in random order. I want that at servlet I get the data in order of how they are sent. I try to solve this by reading in internet but nothing can help. I am posting my servlet code here.
response.setContentType("text/html");
ObjectOutputStream out = new ObjectOutputStream(response.getOutputStream());
Enumeration paramNames = request.getParameterNames();
String params[] = new String[7];
int i=0;
while(paramNames.hasMoreElements())
{
String paramName = (String) paramNames.nextElement();
System.out.println(paramName);
String[] paramValues = request.getParameterValues(paramName);
params[i] = paramValues[0];
System.out.println(params[i]);
i++;
}
I get the output like this
5_Country
United States
4_Password
zxcbbnm
1_Lastname
xyz
0_Firstname
abc
3_Email
abc#xyz.com
6_Mobile
1471471471
2_Username
abcd
I want 0_Firstname first then 1_Lastname then 2_Username like that, because I want to insert this data in database. Here 0,1,2...I wrote just for indicate that I want value in this order.
Try this
Enumeration<String> enumParamNames = request.getParameterNames();
Convert Enumeration to List inorder to sort them.
List<String> listParamNames = Collections.list(enumParamNames);
The paramNames will look like this before sorting
[5_Country, 4_Password, 1_Lastname, 0_Firstname, 2_Username, 3_Email]
Sort the list by Collections.sort(listParamNames);
The sorted paramNames will look like this
[0_Firstname, 1_Lastname, 2_Username, 3_Email, 4_Password, 5_Country]
Now you can loop with listParamNames to get the associated param value
for(String paramName : listParamNames)
{
System.out.println(paramName);
System.out.print("\t");
/* Instead of using getParameterValues() which will get you String array, in your case no need for that. You need only one `Value`, so you go with `getParameter` */
System.out.print(request.getParameter(paramName));
}
Output:
0_Firstname - abc
1_Lastname - xyz
etc....
You won't get the parameter names in order by using request.getParameterNames(); .
You can either use
String [] parameterNames = new String[]{"param1","param2","param3"};
for(String param : parameterNames){
System.out.println(param);
}
where parameterNames conains sequence in which you want your parameters.
You can even configure it and read sequence from a config file.
OR
You can use
request.getQueryString() to get the QueryString, while using GET Method
OR
You can use
request.getInputStream() to get the QueryString, while using POST Method
and parse the raw data to get the Query string.
After getting query string , you can split and use the way you want.

Java ArrayList into Name value pair

In a java class, am using an arraylist say reports containing list of all the reports which have reportid, reportname, reporttype etc which i want to add into NameValuePair and send a Http postmethod call to a particular url.
I want to add the arraylists - reportname into name value pair(org.apache.commons.httpclient.NameValuePair) and then use the http client post method to submit the name value pair data to a particular url.
Here is my name value pair
if (validateRequest()) {
NameValuePair[] data = {
new NameValuePair("first_name", firstName),
new NameValuePair("last_name", lastName),
new NameValuePair("email", mvrUser.getEmail()),
new NameValuePair("organization", mvrUser.getOrganization()),
new NameValuePair("phone", mvrUser.getPhone()),
new NameValuePair("website", mvrUser.getWebsite()),
new NameValuePair("city", mvrUser.getCity()),
new NameValuePair("state", mvrUser.getState()),
new NameValuePair("country", mvrUser.getCountry()),
new NameValuePair(**"report(s)", reports**.)
};
please suggest me how to add the reports arraylist reportname into reports field of NameValuePair.
--
thanks
# adarsh
can I use with generics something like this?
reportname = "";
for (GSReport report : reports) {
reportname = reportname + report.getReportName();
reportname += ",";
}
and then add in namevalue pair as
new NameValuePair("report(s)", reportname)
for name value pair use map like things... eg. Hastable(it is synchronized) , u can use other
implementation of Map which are not synchronized.
I suggest to serialize your reports ArrayList into a JSON formatted String.
new NameValuePair("reports", reportsAsJson)
You can build your reportsAsJson variable using any of the JSON serialization libraries (like the one at http://json.org/java/). It will have approximatively this format :
reportsAsJson = "[{reportid:'1',reportname:'First Report',reporttype:'Type 1'}, {reportid:'2',reportname:'Seond Report',reporttype:'Type 2'}]";
Well, you cannot do that. NameValuePair takes in String arguments in the constructor. It makes sense as it is used for HTTP POST.
What you can do is come up with a way to serialize the Report object into String and send this string as a string parameter. One way of doing this maybe is to delimit the parameters of the Report class.
reports=reportName1|reportName2|reportName3
Assuming reports is your ArrayList,
String reportsStr = "";
for(int i = 0; i < reports.size(); i++) {
reportStr += reportName;
if(i != reports.size() - 1) {
reportsStr += "|";
}
}
NameValuePair nvPair = new NameValuePair("reports", reportsStr);

Categories