Apache commons configuration reading properties in the format a.<no>.b - java

I have a properties file that says
window.1.height=100
window.1.width=80
window.2.height=50
window.2.width=30
window.3.height=150
window.3.width=100
I am using the PropertiesConfiguration class and reading the properties.
How can I know the count of windows in the properties. Is therea pattern search

I usually use something like
int i = 0;
String val;
for(;;) {
val = props.get("foo" + i);
if (null == val) {
break;
}
//process val
}
This places the constraint that the counter values must be contiguous.

There are a couple of things you can do if you have any control over the properties file itself. If you are locked into that format, I don't believe there is anything you can do.
However, if you are not locked into that format, here are a couple of solutions:
XML Configuration
Change from a properties file to an XML file format. Something like this:
<windows>
<window>
<width>80</width>
<height>100</height>
</window>
<window>
<width>30</width>
<height>50</height>
</window>
<window>
<width>100</width>
<height>150</height>
</window>
</windows>
Then use XMLConfiguration instead of PropertiesConfiguration. You could then call
config.getList("windows").size()
to get the count of windows.
Properties Configuration
Your other option, which still involves a properties file, is a little bit more contrived. Your properties file would change to look like this:
window.height=100
window.width=80
window.height=50
window.width=30
window.height=150
window.width=100
Then to get the number of windows you would call
config.getList("window.height").size();
However, using this method, you would have to change how you retrieve the values. For example, in order to get the width and height of the second window, you would use this:
config.getInteger("window.width(1)");
config.getInteger("window.height(1)");
Using parens, you can access an individual element of a list, using zero-based indicies. It is a little more difficult to understand, but it would work.

The api has it already onboard. See Configuration#subset

Related

YamlBeans: Turning an object into a hashmap

I have a Yaml file that's something like below:
rules:
- p_table:
["p_event/Name",
"p_fault/Name"]
- s_table:
["s_event/Name",
"s_fault/Name"]
- r_table:
["r_event/Name",
"r_fault/Name"]
So, I can already take the .yml file above and parse through it with YamlBeans and print it out with code like below:
System.out.println(map.get("rules"));
This gives this kind of result:
[{p_table=[p_event/Name, p_fault/Name]},
{s_table=[s_event/Name, s_fault/Name]},
{r_table=[r_event/Name, r_fault/Name]}]
What I would like to do is more on this sort of level, where I can store it in a HashMap and actually use the specifics within the map, with something like this:
HashMap<String, ArrayList<Strings>> Policies = (HashMap)(map.get("rules"));
But when I do that I either have an exception thrown or it just returns null, is there a solution for this should I not be using HashMaps... or can I just not translate objects in such a way? I plan on replacing the String with another type from a different library that uses Strings but wanted to start at the bottom and then go up from there.
The obvious solution would be to remove the sequence from the YAML file:
rules:
p_table:
["p_event/Name",
"p_fault/Name"]
s_table:
["s_event/Name",
"s_fault/Name"]
r_table:
["r_event/Name",
"r_fault/Name"]
If you can't change the YAML file, you need to transform the data after loading it.

Build DB connection string from environment variables

I'm using the Play Framework (Java) and am not able to figure out how to use environment variables in my configuration file for building the database connection string. While I'm able to use environment variables like this (for user name and password):
default.username = ${?FU_MAIN_DB_USERNAME}
default.password = ${?FU_MAIN_DB_PASSWORD}
I'm not able to make it work in the url string. Perhaps this is a simple case of string processing in Scala that I'm missing, but since I'm working in Java, I could use some help.
So far, I have tried the url string in the following formats and failed:
Tried to add a $ to variable name to perform interpolation:
default.url = "jdbc:postgresql://$${?FU_MAIN_DB_HOST}:$${?FU_MAIN_DB_PORT}/$${?FU_MAIN_DB_NAME}";
But this doesn't substitute. Rather, it picks the string as such.
default.url = "jdbc:postgresql://${?FU_MAIN_DB_HOST}:${?FU_MAIN_DB_PORT}/${?FU_MAIN_DB_NAME}";
This too inserts the '$' and all verbatim. Then I thought maybe something like PHP-style will work
default.url = "jdbc:postgresql://${${?FU_MAIN_DB_HOST}}:${${?FU_MAIN_DB_PORT}}/${${?FU_MAIN_DB_NAME}}";
But no.
I also tried doing stuff like "jdbc:postgresql://".concat(${?FU_MAIN_DB_HOST}) ... but this also inserts '.concat' verbatim.
Finally, I tried concatenation using the '+' operator, but I'm told (by my IDE) that symbols like +: etc. are not allowed in the application.conf file.
How then, in God's name, am I supposed to do that?!
The double quotes turn off interpolation. But you need to do that for the : and the //.
Try
default.url = "jdbc:postgresql://"${?FU_MAIN_DB_HOST}":"${?FU_MAIN_DB_PORT}/${?FU_MAIN_DB_NAME}
Maybe you are better off to set the whole thing in one big environment variable instead.

How to iterate and load property file values in UI using ZK?

I have a property file named "ABC.properties" having values such as
A="APPLE"
B="BALL"
C="CAT"
Now i need to get these values and load in my UI. Have iterate and then need to load because like wise there may be more than 50 values in that property file.
Can anyone please help me with this?
In your zk.xml file, give the path of properties file you wanted to read.
<zk>
<system-config>
<label-location>/path/to/ABC.properties</label-location>
</system-config>
</zk>
If you want to read them in zul file, for example you want to show label having value as A then
< label value="${labels.A}" />
If you want to read properties file's value in listener class then do
Labels.getLabel("A");
First of all, I don't know if there are more items in the property file then you need to fetch.
Note : Multiple properties files all readed in this way and are accessible in the same map.
If yes :
Convert the key's with subsections :
FRUIT.APPLE = apple
FRUIT.ORANGE = orange
TOYS.BALL = ball
TOYS.DOLL = doll
and so on.
The next thing is as #BhushanPatil already mentioned :
In your zk.xml file, give the path of properties file you wanted to read.
<zk>
<system-config>
<label-location>/path/to/ABC.properties</label-location>
</system-config>
</zk>
Then you have the following method getSegmentedLabels under Labels.
This is the method we will use.
So if you want to declare it only in the zul, the next step is what you have to do :
<?xel-method
prefix="prop" name="all" class="org.zkoss.util.resource.Labels"
signature="java.util.Map getSegmentedLabels()"?>
<vlayout forEach="${prop:all().get('FRUIT')}">
<label value="${each.key} : ${each.value}"/>
</vlayout>
The Xel-method is for declaring the static method (only way to acces a static method before ZK 8).
Now we want to get all our FRUIT labels, so we call the getSegmentedLabels with the Xel-method name all().
This return a Map<String,Object> where all the labels are in.
We are interested only in the subsection FRUIT so we get the value behind the key FRUIT.
This object is again a Map<String,Object> wich contains every key under the FRUIT.
In this example it contains <'APPLE','apple'>,<'ORANGE','orange'>.
The next thing we need to do is iterating over the Map and showing all the values of the Map.
This we do with the forEach attribute.
So the each object's value is now an Object of class Entry<String,Object>.
The only thing to show it now is showing the value, with is Entry.getValue().

Retrieve Data Properties of An Individual using OWL API in eclipse

I want to retrieve all data properties set for an individual of any class using owl api. The code i have used is
OWLNamedIndividual inputNoun = df.getOWLNamedIndividual(IRI.create(prefix + "Cow"));
for (OWLDataProperty prop: inputNoun.getDataPropertiesInSignature())
{
System.out.println("the properties for Cow are " + prop); //line 1
}
This code compiles with success but line 1 print nothing at all. What should be the correct syntax. Have thoroughly googled and couldnt find any thing worth it.
OWLNamedIndividual::getDataPropertiesInSignature() does not return the properties for which the individual has a filler, it returns the properties that appear in the object itself. For an individual this is usually empty. The method is on the OWLObject interface, which covers things like class and property expressions and ontologies, for which it has a more useful output.
If you want the data properties with an actual filler for an individual, use OWLOntology::getDataPropertyAssertionAxioms(OWLIndividual), like this:
OWLNamedIndividual input = ...
Set<OWLDataPropertyAssertionAxiom> properties=ontology.getDataPropertyAssertionAxioms(input);
for (OWLDataPropertyAssertionAxiom ax: properties) {
System.out.println(ax.getProperty());
}

Apache Commons Configuration get property based on parent with attribute equal to value

I'm using Apache Commons Configuration with XML for the configuration of my application, and I'm having trouble getting a property that I want.
I have the following XML structure (minimal structure just to get point across):
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<planets>
<planet name="mars">
<terrain>terrain/mars.terrain</terrain>
</planet>
<planet name="earth">
<terrain>terrain/earth.terrain</terrain>
</planet>
</planets>
</settings>
As I understand it, the best I can do here to get the mars terrain setting is:
config.getProperty("planets.planet(0).terrain");
Unfortunately, my app doesn't/shouldn't have any concept of the indexes of these planets. At least, the indexes aren't going to be consistent. They could change at any time, so it's unreliable to refer to them by index as is done above.
So, what I want to be able to do is something like this:
config.getProperty("planets.planet[#name=mars].terrain");
That doesn't work, as you might have guessed. The only other way I've found to do it is obtuse and unacceptable:
List<Object> planets = config.getList("planets.planet[#name]");
String terrain = "";
for (int i = 0; i < planets.size(); i++) {
if (planets[i].toString().equals("mars")) {
terrain = config.getString("planets.planet(" + i + ").terrain");
break;
}
}
I'm sure you can see why that's undesirable. Now, I'm to the point where I'm considering just wrapping/extending the Apache Commons Configuration library in order to add this type of functionality, but I'm just unwilling to accept that there isn't an easier way to do this.
Question Revisited
What am I overlooking, and how can this be accomplished in a simpler manner? Does this functionality simply not exist?
I found out that I could replace the DefaultExpressionEngine with an XPathExpressionEngine.
XMLConfiguration.setDefaultExpressionEngine(new XPathExpressionEngine());
This allowed me to use XPath to get my properties, and I could now do:
String terrainFile = config.getString("planets/planet[#name='mars']/terrain");
One thing to note is that you need the Apache Commons JXPath lib to use the XPathExpressionEngine, or you will get an error when you try to create it.

Categories

Resources