Parsing Properties file - java

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.

Related

Get all mailMerge fields from docx using docx4J

I have .docx file, containing mailMerge fields.
I want to extract all field names to List.
I saw some examples of dox4J, how to replace these fields with mapped value, but I DO NOT want to replace them, I need to read them only.
Is there a semy easy way to do that using docx4J?
Have a look at https://github.com/plutext/docx4j/blob/master/src/samples/docx4j/org/docx4j/samples/FieldsDiagnostics.java
You can also look at the code in MailMerger:
// find fields
ComplexFieldLocator fl = new ComplexFieldLocator();
new TraversalUtil(shellClone, fl);
// canonicalise and setup fieldRefs
List<FieldRef> fieldRefs = new ArrayList<FieldRef>();
canonicaliseStarts(fl, fieldRefs);
// Populate
for (FieldRef fr : fieldRefs) {
if ( fr.getFldName().equals("MERGEFIELD") ) {
String instr = extractInstr(fr.getInstructions() );
String datafieldName = getDatafieldNameFromInstr(instr);

About inserting dynamic data into the static content at run time

I have a template like this in properties file: Dear xxxxxx, you are payment is succesfull.
After loading this template from properties file, I want to replace that "xxxxxx" with dynamic data in Java class.
Please help me on this.
I used Message.format("template",object array which is having dynamic data);
Try this way
placeholderReplacementMap is map that contain your static value and dynamic value key pair
Map<String, Object> placeholderReplacementMap = new HashMap<>();
StrSubstitutor substitutor = new StrSubstitutor(placeholderReplacementMap);
placeholderReplacementMap.put("xxxxxx", dynamicValue);
String newString = substitutor.replace("Dear xxxxxx","you are payment is succesful");

How to append values to a key using ini4j?

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));

How do I normalize a CSV file with Encog?

I need to normalize a CSV file. I followed this article written by Jeff Heaton. This is (some) of my code:
File sourceFile = new File("Book1.csv");
File targetFile = new File("Book1_norm.csv");
EncogAnalyst analyst = new EncogAnalyst();
AnalystWizard wizard = new AnalystWizard(analyst);
wizard.wizard(sourceFile, true, AnalystFileFormat.DECPNT_COMMA);
final AnalystNormalizeCSV norm = new AnalystNormalizeCSV();
norm.analyze(sourceFile, false, CSVFormat.ENGLISH, analyst);
norm.setProduceOutputHeaders(false);
norm.normalize(targetFile);
The only difference between my code and the one of the article is this line:
norm.setOutputFormat(CSVFormat.ENGLISH);
I tried to use it but it seems that in Encog 3.1.0, that method doesn't exist. The error I get is this one (it looks like the problem is with the line norm.normalize(targetFile):
Exception in thread "main" org.encog.app.analyst.AnalystError: Can't find column: 11700
at org.encog.app.analyst.util.CSVHeaders.find(CSVHeaders.java:187)
at org.encog.app.analyst.csv.normalize.AnalystNormalizeCSV.extractFields(AnalystNormalizeCSV.java:77)
at org.encog.app.analyst.csv.normalize.AnalystNormalizeCSV.normalize(AnalystNormalizeCSV.java:192)
at IEinSoftware.main(IEinSoftware.java:55)
I added a FAQ that shows how to normalize a CSV file. http://www.heatonresearch.com/faq/4/2
Here's a function to do it... of course you need to create an analyst
private EncogAnalyst _analyst;
public void NormalizeFile(FileInfo SourceDataFile, FileInfo NormalizedDataFile)
{
var wizard = new AnalystWizard(_analyst);
wizard.Wizard(SourceDataFile, _useHeaders, AnalystFileFormat.DecpntComma);
var norm = new AnalystNormalizeCSV();
norm.Analyze(SourceDataFile, _useHeaders, CSVFormat.English, _analyst);
norm.ProduceOutputHeaders = _useHeaders;
norm.Normalize(NormalizedDataFile);
}

dynamically read/add value to the parameter of conf file with Properties

I have a message like below in my conf file.
text.message = Richard has to go to School in 01/06/2012 / 1days.
All highlighted field will be variable.
I want to read this text.me string and insert the value from my java using Properties.
I know how to read the whole string using Prop, but don't know how to read like above String which will be like.
text.message = #name# has to go to #place# in #date# / #days#.
how can I read the above string from the conf using Properties and insert data dynamically?
It can be either date or days in the string. How I can turn on and off between those parameters?
Thanks ahead.
You can use the MessageFormat API for this.
Kickoff example:
text.message = {0} has to go to {1} in {2,date,dd/MM/yyyy} / {3}
with
String message = properties.getProperty("text.message");
String formattedMessage = MessageFormat.format(message, "Richard", "School", new Date(), "1days");
System.out.println(formattedMessage); // Richard has to go to School in 31/05/2012 / 1days
You can use the MessageFormat class, which replaces dynamic placeholders in a string with the desired values.
For example, the following code...
String pattern = "{0} has to go to {1} in {2,date} / {3,number,integer} days.";
String result = MessageFormat.format(pattern, "Richard", "school", new Date(), 5);
System.out.println(result);
...will produce the following output:
Richard has to go to school in 31-May-2012 / 5 days.
You can simply get the pattern from your Properties object, then apply the MessageFormat translation.

Categories