Can we get a property from properties file using some expression. e.g
If I have properties in file like this
user/a/b=active
user/a/c=active
user/a/d=active
Now How can I get all properties which are active. Also Can I get all active using user/a/* or something like that
The java.util.Properties class has stringPropertyNames() method
you can use the method to iterate all the names and check name and value
Properties prop = new Properties();
// add some properties
prop.put("user/a/b", "active");
prop.put("user/a/c", "active");
prop.put("user/a/d", "active");
// save the Property names in the set
Set<String> set = prop.stringPropertyNames();
for (String name: set) {
if (name.startsWIth("user/a/")) {
//check value and do something
}
}
Related
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.
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.
Printscreen additional fields useradmin
How can I add some new User Properties to the CQ Users?
I found an solution but it don't work --> http://experience-aem.blogspot.ch/2014/01/aem-cq-56-extend-useradmin-add-new-user.html
I tried to manipulate in CRX the UserProperties.js with new Properties, I see them in useradmin but if I try to add the new propertie in Java Code (not via useradmin) I can save it without error, but the value is empty in useradmin.
And if I try to add some value via useradmin for the new propertie, all user gets the same value.
How can I add new User Properties, that I can set the Value via Java code like the standard properties.
user = userManager.createUser(username, password);
ValueFactory valueFactory = session.getValueFactory();
emailValue = valueFactory.createValue(email);
givennameValue = valueFactory.createValue(givenname);
nameValue = valueFactory.createValue(name);
//User class just accepts Value Object
user.setProperty("profile/" + UserProperties.EMAIL, emailValue);
user.setProperty("profile/" + UserProperties.FAMILY_NAME, nameValue);
user.setProperty("profile/" + UserProperties.GIVEN_NAME, givennameValue);
I found an solution.
Go to crx /libs/cq/security/widgets/source/widgets/security/UserProperties.js
add the fields you need in the items array of the user (Caution - there are items for user and items for groups in the same place)
in the loadRecord method of your JS, you have to add each new field to the "record" object
"items":[{
"xtype":"textfield",
"fieldLabel":CQ.I18n.getMessage("Mail"),
"anchor":"100%",
"vtype":"email",
"msgTarget":"under",
"name":"email"
},{
"xtype":"textfield",
"fieldLabel":CQ.I18n.getMessage("My Field"),
"anchor":"100%",
"msgTarget":"under",
"name":"myfield"
},{
"xtype":"textarea",
"fieldLabel":CQ.I18n.getMessage("About"),
"anchor":"100% -155",
"name":"aboutMe"
}],
loadRecord: function(rec) {
this.enableUserSaveButton(false);
this.enableGroupSaveButton(false);
var type = rec.get("type");
if (type=="user") {
this.activeForm = this.userForm;
this.hiddenForm = this.groupForm;
if (rec.id==CQ.security.UserProperties.ADMIN_ID) {
this.pwdButtons.each(function(bt) {bt.hide(); return true;} )
} else {
this.pwdButtons.each(function(bt) {bt.show(); return true;} )
}
} else {
this.activeForm = this.groupForm;
this.hiddenForm = this.userForm;
}
//is loading additional property from json and show it in formular
rec.data["myfield"] = rec.json["myfield"];
this.activeForm.getForm().loadRecord(rec);
In the java code you can then add the new properties via the "user" object to the new properties. Note that the properties are put into the subfolder "profile".
user.setProperty("profile/" + "myfield", myFieldValue);
Did you try the second approach, posted by "pedro" in the link you've posted?
It probably has to do with pushing the new field to the record:
http://experience-aem.blogspot.com/2014/01/aem-cq-56-extend-useradmin-add-new-user.html?showComment=1390804750445#c2823498719990547675
i hope this may helps you the file exist on http://[host name]:[port]/crx/de/index.jsp#/libs/cq/security/widgets/source/widgets/security/UserProperties.js
and you will have two major properties the first one is for the user this.userForm the other one is this.groupForm for groups.
I want to read a usual properties file and put the attribute and his value into a Map object.
Technically, a properties file like
attr1=hello
attr2=java
attr3=world
would dynamically become a map object like this
+-------+-------+
+ K | V +
+-------+-------+
+ attr1 | hello +
+-------+-------+
+ attr2 | java +
+-------+-------+
+ attr3 | world +
+-------+-------+
In the end, it shouldn't matter what's in the properties file, the whole file will just be saved as a Map.
Is it possible to do that with java.Properties or is a FileReader or an InputStream with special parsing necessary?
java.util.Properties also implements of Map.
To load the properties from file, use Properties' load() method with Reader or InputStream.
For instance,
Properties config = new Properties();
try {
config.load(<this.class>.getResourceAsStream(<property-file-name>)); //example input stream
//now can access it as a Map instance
config.get(<Key>);
config.entrySet();
//additionally, you can access Properties methods
config.getProperty(<property-name>);
} catch(...) {
...
}
If you want only Map instance, let's say kind of Map<String, String>, need to convert the properties to required map instance by iterating the property names.
Properties config = new Properties();
try {
config.load(<this.class>.getResourceAsStream(<property-file-name>)); //exampl input stream
Map<String, String> map = new HashMap<String, String>();
for (final String name: config.stringPropertyNames())
map.put(name, config.getProperty(name));
} catch(...) {
...
}
I'm storing my app settings in properties file that I use in Ant and in the Java app. Maybe it's not good pratice, but I find it very handy to avoid duplications. The file contains variables such as:
usefulstuff.dir = ${user.home}/usefulstuff
So that other people can run the program on *nix systems, provided that they have the usefulstuff folder in their home directory.
Now, the fascinating thing is that this properties file works fine in Ant (the variable gets resolved to /home/username), while when I load the same file directly in the Java app, I get a string containing ${user.home}/usefulstuff, which is not very useful indeed.
I load the props with this code in Ant:
<loadproperties srcFile="myProps.properties"/>
And in the Java app:
FileInputStream ins = new FileInputStream(propFilePath);
myProps.load(ins);
ins.close();
Am I missing anything? Maybe is there a better way to load properties in a Java app than load()?
I don't think it's particularly "fascinating" that this works in Ant - Ant is deliberately written to do so:
Properties are key-value-pairs where Apache Ant tries to expand ${key} to value at runtime.
and
Ant provides access to all system properties as if they had been defined using a <property> task. For example, ${os.name} expands to the name of the operating system.
If you want the same behaviour, you'll need to implement the same sort of logic. It's possible that you could use the classes from Ant directly, if they do what you want - and if you're happy to ship the relevant binaries (and abide by the licence).
Otherwise, you might want to use a regular expression to find all the matches - or (probably simpler) iterate over all of the system properties and do a simple replacement on them.
As Jon said, it should be straighforward to write the property handling yourself. For eg:
import java.util.*;
public class PropertiesTest
{
public static void main(String[] args)
{
Properties props = new Properties();
props.setProperty("foo", "foo/${os.name}/baz/${os.version}");
props.setProperty("bar", "bar/${user.country}/baz/${user.country}");
System.out.println("BEFORE:");
printProperties(props);
resolveSystemProperties(props);
System.out.println("\n\nAFTER:");
printProperties(props);
}
static void resolveSystemProperties(Properties props)
{
Map<String, String> sysProps = readSystemProperties();
Set<String> sysPropRefs = sysProps.keySet();
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
String value = props.getProperty(name);
for (String ref : sysPropRefs)
{
if (value.contains(ref))
{
value = value.replace(ref, sysProps.get(ref));
}
}
props.setProperty(name, value);
}
}
static Map<String, String> readSystemProperties()
{
Properties props = System.getProperties();
Map<String, String> propsMap =
new HashMap<String, String>(props.size());
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
propsMap.put("${" + name + "}", props.getProperty(name));
}
return propsMap;
}
static void printProperties(Properties props)
{
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
String value = props.getProperty(name);
System.out.println(name + " => " + value);
}
}
}