Can I use both arrays and non-arrays with Apache Commons Config? - java

With the following properties file:
foo=hello, world!
bar=first,second
I would like to retrieve the first item as a string and the second as an array. I would have thought that getString vs getStringArray would deal with this, but it doesn't - getString("foo") just gets everything before the comma, i.e. "hello".
If I disable delimiter parsing using setDelimiterParsingDisabled, foo is fine, but this also changes the behaviour of getStringArray("bar") to return a single-element array!
I can't find how I can explicitly tell it how I want it to interpret an individual config item, either as a string or as an array. I don't want to put the config items into separate config files with different delimiter rules, and I'd prefer to use a comma as the delimiter for the getStringArray case.
To elaborate, this snippet prints either hello - 2 or hello, world! - 1 - I want it to print hello, world! - 2 !
AbstractFileConfiguration config = new PropertiesConfiguration();
config.setFileName("C:\\temp\\temp.properties");
//config.setDelimiterParsingDisabled(true);
config.load();
System.out.println(config.getString("foo") + " - " + config.getStringArray("bar").length);

As you found out, Commons Config lacks something like a getPlainString() method. Here are some suggestions for workarounds.
I think using a different list delimiter is the easiest to implement. If you need something more complex, consider the other two:
Use a different list delimiter with setListDelimiter()
Works as long as you don't need to interpret the same value as a String and as an array.
properties file:
foo=hello, world!
bar=first;second
Code:
AbstractFileConfiguration config = new PropertiesConfiguration();
config.setFileName("C:\\temp\\temp.properties");
config.setListDelimiter(';');
config.load();
System.out.println(config.getString("foo") + " - " + config.getStringArray("bar").length);
Disable delimiter parsing and do your own splitting
Easily done with String.split(). A simple static method will do:
public static String[] gerStringArray(Configuration config, String key)
Or create a subclass of PropertiesConfiguration and override the getStringArray() and getList() methods.
Use two different configurations
One for settings data where you know what format the data will have. Here you can activate delimiter parsing.
And one for text data where you might have arbitrary data. Here you should deactivate delimiter parsing.
This has the additional advantage of separating settings and text data.
Not mixing settings and text data keeps both configurations cleaner. Especially if there's a lot of both.
Often settings data changes depending on the deployment environment (live/test) while text data changes depending on the locale (en_GB/de_DE).

In the properties file you can do something like that:
urls=localhost
urls=127.0.0.1
In Java you can get the list:
String[] urls = Configure.settings().getStringArray("urls");
for(String url : urls)
System.out.println(url);

Related

Map invalid character to valid character while creating a file and back to original name when read filename

I need to map invalid characters to some other characters like "/" to "_" (forward slash to underscore) while creating a file because file name do not allowed to put slashes, question, double quotes etc.
Suppose I have
String name = "Message Test - 22/10/2016";
Now I want to write a file by using above string but it gives error because of slashes.
So I want to map slash like all the invalid characters to any other characters while writing a file. After writing, I need to read all the names of the files & show on the page.
SOMEHOW I MAP THE CHARACTERS, SO FILE NAME WOULD BE
Message_Test_-_22-10-2016
When I show it on web I need to return file name as the original name like
Message Test - 22/10/2016
I am using java. Can anyone help me out of this how can I start writing this approach or Is there any api for it or Is there any other approach.
I don't want to use database to co-related alias file name with original file name
I need to map invalid characters to some other characters like "/" to "_"
It is not enough robust since it supposes that you never use the _ character in the filename.
If you use it, how to know if a file stored as my_file should be displayed as my_file or my/file in your application.
I think that a more reliable way would be to have a file (JSON or XML for example) that stores the two properties for each file :
the stored filename
the visual name representing it in your application
It demands an additional file but it makes things really clearer.
You can use a map to store the mappings:
E.g.
Map<Character,Character> map = new HashMap<Character,Character>();
map.put('/','_');
And then replace the characters in 1 traversal:
for(int i=0;i<str.length();i++){
char c = str.charAt(i);
if( map.containsKey(c) )
str.replace(c,map.get(c));
}

How to print the symbols and < and > to a file as space < and > respectively

How do you print symbols in Java to a file when you have only the symbol description?
I received a string from DB2 which contains symbols.
Two samples:
1) <0800>
2) 51V 3801Z
Such a string goes to two different places. One is a JSP rendering it as HTML. That is perfect; I get <0800> and 51V 3801Z, respectively. The other place is a CSV file created with java.io.FileWriter, and it does not convert to "<", ">", and " ". Instead, it is printed exactly as it came from DB2:
<0800>
and 51V 3801Z.
Is there anything the "new" nio library could help me? I have tried apache.commons.lang3.StringScapeUtils.escapeHTML4 without success.
I suggest looking into Apache's StringEscapeUtils, namely the unescapeHtml4() method.
Example:
String input = "<0800>";
String output = StringEscapeUtils.unescapeHtml4(input);
Ensure you are using the unescapeHtml4 method, and not the regular escapeHtml4 method!

Apache Commons Configuration : read a .properties file and rewrite it with no change

Since I do not know of a better solution, I am currently writing small Java classes to process .properties file to merge them, remove duplicate properties, override properties, etc. (I need to process many files and a huge number of properties).
org.apache.commons.configuration.PropertiesConfiguration works great for reading a properties file (using org.apache.commons.configuration.AbstractFileConfiguration.load(InputStream, String), however if I rewrite the file using org.apache.commons.configuration.AbstractFileConfiguration.save(File), I have two problems:
the original layout and comments are lost. I am going to try the PropertiesConfigurationLayout, which is supposed to help here (see How to overwrite one property in .properties without overwriting the whole file?) and post the results
the properties are slightly modified. Accents é and è are rewritten as unicode characters (\u00E9), which I do not want. Afaik .properties files are generally ISO-8859-1 (and I think mine are), so escaping shouldn't be necessary.
Specifying the encoding when calling org.apache.commons.configuration.AbstractFileConfiguration.load(InputStream, String) does not make a difference, because when it is not specified, the same encoding is used by default anyway (private static final String DEFAULT_ENCODING = "ISO-8859-1";). What could I do about that ?
Doing some tests I think you can do what you want, using CombinedConfiguration plus a OverrideCombiner. Basically the properties will be merged automatically and the trick for the layout is to get the layout from one of the loaded files:
CombinedConfiguration props = new CombinedConfiguration();
final PropertiesConfiguration defaultsProps = new PropertiesConfiguration(new File("/tmp/default.properties"));
final PropertiesConfiguration customProps = new PropertiesConfiguration(new File("/tmp/custom.properties"));
props.setNodeCombiner(new OverrideCombiner());
props.addConfiguration(customProps); //first should be loaded the override values
props.addConfiguration(defaultsProps); // last your 'default' values
PropertiesConfiguration finalFile = new PropertiesConfiguration();
finalFile.append(props);
PropertiesConfigurationLayout layout = new PropertiesConfigurationLayout(finalFile, defaultsProps.getLayout()); //here we copy the layout from the 'base file'
layout.save(new FileWriter(new File("/tmp/app.properties")));
The issue with the encoding I don't know if its possible to find a solution.

Merging two relative file URLs

Let' say I have two paths, first can look like folder/ and second like /anotherFolder/image.png. I would like to merge those two paths in some automated fashion and with option for user to omit the last slash in first string and first slash in second string. So all of these
folder/ + /anotherFolder/image.png
folder + anotherFolder/image.png
folder + /anotherFolder/image.png
should give me folder/anotherFolder/image.png
I need to merge two properties in one of my projects and I want it as dummy as possible:)So is there some trick with URL class or do I have to play around with Strings?
You can do this with java.io.File, by using the constructor which takes a File and a String as arguments, will interpret the String as a relative path to the File.
Or with java.net.URL, you can send an URL and a String to the constructur, which will interpret the URL as a context for the String parameter.
I actually used FileUtils.getFile() from Apache Commons IO but Rolf's solution was working too.

How to retrieve particular part of string

I have got a directory listing as a String and I want to retrieve a particular part of the string, the only thing is that as this is a directory it can change in length
I want to retrieve the file name from the string
"C:\projects\Compiler\Compiler\src\JUnit\ExampleTest.java"
"C:\projects\ExampleTest.java"
So in these two cases I want to retrieve just ExampleTest (the filename can also change so i need something like get the text before the first . and after the last \). Is there a way to do this using something like regex or something similar?
Why not use Apache Commons FileNameUtils rather than coding your own regular expressions ? From the doc:
This class defines six components within a filename (example
C:\dev\project\file.txt):
the prefix - C:\
the path - dev\project\
the full path - C:\dev\project\
the name - file.txt
the base name - file
the extension - txt
You're a lot better off using this. It's geared directly towards filenames, dirs etc. and given that it's a commonly used, well-defined component, it'll have been tested extensively and edge cases ironed out etc.
new File(thePath).getName()
or
int pos = thePath.lastIndexOf("\\");
return pos >= 0? thePath.substring(pos+1): thePath;
File file = new File("C:\\projects\\ExampleTest.java");
System.out.println(file.getAbsoluteFile().getName());
Java code
String test = "C:\\projects\\Compiler\\Compiler\\src\\JUnit\\ExampleTest.java";
String arr[] = test.split("\\Q"+"\\");
System.out.println(arr[arr.length-1].split("\\.")[0]);
This is the regex in c# and it works in java :P too.Thanks to Perl.It matches in Group[1]
^.*\\(.*?)\..*?$

Categories