X

Geertjan's Blog

Setting NetBeans Properties Programatically

Geertjan Wielenga
Product Manager
In the Wicket plug-in module that I'm developing, I want to make sure that the user doesn't need to set the servlet's URL pattern. Normally, the user needs to go to the application's Project Properties dialog box, and then set the relative path for the servlet in the Run panel. This sets the client.urlPart property in the nbproject/project.properties file. Then, when the user deploys the application, the relative URL is appended to the context path. However, since the Wicket Frameworks panel lets the user specify the servlet URL, so that this can be set programatically in web.xml, it makes sense to use that same value in project.properties. However, getting it there is not so simple, because in the case of web.xml, there's a NetBeans API that deals with this, providing methods for writing and reading each of the parts of a web.xml file. When it comes to project.properties, things are a bit different (and I needed NetBeans developer Martin Krauskopf to help me out). In this case, the EditableProperties class is the key to everything. This is what I have in my WicketFrameworkProvider class (the highlighted line is the one that sets the property):
FileObject documentBase = wm.getDocumentBase();
project = FileOwnerQuery.getOwner(documentBase);
FileObject projectprop = project.getProjectDirectory().getFileObject(AntProjectHelper.PROJECT_PROPERTIES_PATH);
EditableProperties ep = loadProperties(projectprop);
ep.setProperty("client.urlPart", panel.getURLPattern());
storeProperties(projectprop,ep);

If you look at the code completion, there are also other files you can reach in this way:

So, two utility methods are called above, loadProperties and storeProperties. Here they are:

private static EditableProperties loadProperties(FileObject propsFO) throws IOException {
InputStream propsIS = propsFO.getInputStream();
EditableProperties props = new EditableProperties(true);
try {
props.load(propsIS);
} finally {
propsIS.close();
}
return props;
}
public static void storeProperties(FileObject propsFO, EditableProperties props) throws IOException {
FileLock lock = propsFO.lock();
try {
OutputStream os = propsFO.getOutputStream(lock);
try {
props.store(os);
} finally {
os.close();
}
} finally {
lock.releaseLock();
}
}

And that's it. Now the client.urlPart property is set as soon as the user clicks Finish in the Wicket Frameworks panel in the New Project wizard. When I told Martin that I think this is really cool, he sent me a quick warning that this isn't usable in all cases—your plug-in module needs to know the property it is changing, otherwise it cannot make the change. By depending on a project's implementation details, you are limited to changing only those properties of which you are aware.

Join the discussion

Comments ( 3 )
  • Martin Krauskopf Thursday, March 16, 2006
    Just to add that you should use ProjectManager.mutex().writeAccess(...) whenever you are writing into project's metadata to be sure that nobody other tries to do so at the same time (I forgot to write this before). EditableProperties are preferred (to java.util.Properties) mainly because they are "VCS-friendly" among others - more in Javadoc you pointed to.

    But anyway as you said it is similar to implementation dependency since you are more or less accessing non-public API. But if there is no other way... ;)
  • Patrick Wright Sunday, March 19, 2006
    Hey Geertjan: nice job. I have been waiting till I have free time to work on a scripting module for NetBeans, so that one could write macros to change NB properties at runtime without writing modules. Firefox does this, as does jEdit. Your investigation into how to access properties will make that much easier, thanks. Patrick
  • Geertjan Sunday, March 19, 2006
    Hi Martin, thanks for the additional insight.

    Hi Patrick, great to hear! That's exactly why I'm blogging about these things (in addition to having a place where I can store new learnings), so that developers out there can pick up bits of info to reuse in their own programming. By the way, it's been a while since you've received e-mails intended for Patrick Keegan, hasn't it? I must be doing something right. :-)

Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha