views:

106

answers:

8

In my properties file I have one property, which contains a comma separated list of values

In my code, I would like to load that property in, split it from the commas, and add each value into an array. I also want to make sure I don't have values in the array due to whitespace etc

example property :

prop_allowed_extensions = .jpeg,tiff, .txt 

I have come up with this so far, but it feels dirty, is there a more elegant solution?

String test = classProperties.getProperty("prop_allowed_extensions", "txt, jpeg");
String[] splitString = StringUtils.split(test, ',');
String[] newString = new String[splitString.length];             
for (int i = 0; i < splitString.length; i++)
{
   newString[i] = StringUtils.trim(splitString[i]);                
}

I just want the text of the file extension, would it be appropriate to use a regular expression to remove whitespace/non-letters?

A: 

Given your use case, it seems like a more elegant solution would be to not use the properties file format at all, and instead go with something that supports arrays such as YAML or JSON.

You will find links to Java libraries on each of those pages; the transition should be painless.

danben
+1  A: 

Following your pattern, you can do it like this:

String test = classProperties.getProperty("prop_allowed_extensions", "txt, jpeg");
List<String> extensions = new ArrayList<String>();         
for (String part:test.split(",")) {
   extensions.add(part.trim());               
}

The difference is that the result is in a list now. test.split(",") will be called only once, so there is no performance issue.

Andreas_D
Trying to keep it as a String[] so I can use it in FileUtils.listAllFiles http://commons.apache.org/io/api-1.4/org/apache/commons/io/FileUtils.html#listFiles%28java.io.File,%20java.lang.String[],%20boolean%29
James.Elsey
You can do extensions.toArray(new String[extensions.size()]) to get a String[] to pass to FileUtils.listAllFiles.
Chry Cheng
Uh, then what's the point in going to the list? Gits and shiggles?
Mark Peters
The list is there so you can have some place to put the extensions without having to worry about allocating enough space beforehand or managing it as you go along.
Chry Cheng
yes, but string.split() takes care of this already. I also don't see the point in using a list here.
seanizer
A: 
String test = classProperties.getProperty("prop_allowed_extensions", "txt, jpeg");
String[] splitString = StringUtils.split(test, ',');
for(String s : splitString) {
    s = StringUtils.trim(s);
}

would be slightly more elegant, but Java does not support LINQ like .net where you would be able to avoid the explicit loop altogether.

Frank
-1 this does not work. you are re-assigning local variables, not changing array values
seanizer
You are right, so I even would need the for loop with an integer index.
Frank
yes, the enhanced for loop only allows reading, not changing or removing.
seanizer
+1  A: 
String[] allowedFormats = classProperties
                           .getProperty("prop_allowed_extensions", "txt, jpeg")
                           .replaceAll("[ \\.]","")
                           .split(",");

With Java 1.5 or superior, in Array format.

BenoitParis
Would not get rid of the space before "jpeg".
Mark Peters
My bad, correcting this.
BenoitParis
would not get rid of the periods, either
seanizer
@seanizer It would, actually, that's what split(",") is for.
BenoitParis
nope, I am not talking about the commas, but the periods. Read the question. Example data is ".jpeg,tiff, .txt " and he says he wants to lose all non-letters
seanizer
@seanizer Indeed. I assumed the code was correct...
BenoitParis
+2  A: 

You can do it in two steps:

String[] allowedExtensions = str.replaceAll("[^\\w,_]", "").split(",")

(First kill anything that is not either a comma, an underscore or a word character (letter or digit), then split the resulting string

seanizer
Probably unnecessarily restrictive. File extensions often have underscores, etc.
Mark Peters
never heard of underscores in file extensions, but I'll add them anyway.
seanizer
+4  A: 

I'd personally just reduce it to the following (keeping in mind that String.split() takes a regular expression), but I don't know whether or not you'd consider it more elegant:

String test = classProperties.getProperty("prop_allowed_extensions",
        "txt, jpeg");
String[] extensions = test.trim().split("\\s*,\\s*");

Edit: You can remove the leading dot on each extension too, if it is present (this, or one of several other ways):

String[] test = classProperties.getProperty("prop_allowed_extensions",
        "txt, jpeg").trim().split("^\\.", 2);
String[] extensions = test[test.length - 1].split("\\s*,\\s*.?");
Tim Stone
Not complete, as there may be periods that need to be stripped. The pattern needs to be this: "\\s*,\\s*\\.?", but an initial period breaks it anyway.
seanizer
is trim() executed before split()? If so, then how would it remove whitespace inside the string, ie not on either end ? " properties, PROPERTIES"
James.Elsey
@James: you're splitting on not just a comma but instead a comma plus preceding/trailing whitespace. Since the delimiter is ignored in the resultant array, the whitespace will be excluded. The trim gets rid of the boundary cases.
Mark Peters
@seanizer: I think the OP was unclear. We were led to believe his example in the post was a functionally valid way of doing what he wanted to do, which leaves in the dot. His description seems to imply he doesn't want the dot. This answer is functionally equivalent to his code.
Mark Peters
@James - Mark's right, the trim call handles space at the end and beginning of the properties string. Originally I had tried to split on "^\\s*|\\s*,\\s*|\\s$" to avoid that call altogether, but split will return leading empty strings, so you'd get an undesired empty first element in the array in that case. This makes sure that you don't.
Tim Stone
@Mark yup, I've got the habit of actually reading questions and not only the existing code.
seanizer
It's actually wasteful to remove the periods in the sense that [`FileUtils.listFiles()`](http://commons.apache.org/io/api-1.4/org/apache/commons/io/FileUtils.html#listFiles%28java.io.File,%20java.lang.String[],%20boolean%29) just re-adds them, but the method will not properly accept extensions with leading dots, so doing so is necessary to answer the OP's question. I do think that "text of the file extension" is a bit vague though (even with "non-letters"), given the code example, but oh well.
Tim Stone
A: 

It's much more simple:

String test = classProperties.getProperty("prop_allowed_extensions", "txt, jpeg");
String[] splitString = test.trim().split("\\s*,\\s*");

(needs Java 5)

Aaron Digulla
+7  A: 

Apache Jakarta Commons Configuration handles properties file in a clean way, allowing you to specify lists in different formats:

colors.pie = #FF0000, #00FF00, #0000FF

OR

colors.pie = #FF0000;
colors.pie = #00FF00;
colors.pie = #0000FF;

And get the list like this:

String[] colors = config.getStringArray("colors.pie");
List colorList = config.getList("colors.pie");

See the How-to

streetpc
And if you don't want to use it, you may be interested to look how they did it in the code :)
streetpc
I voted for this and for Tim's answer. If you don't mind adding another library to your dependency, this is my preferred approach. Besides, if there's a library out there that can already do it, why do it yourself right?
Chry Cheng