Blogs
Introduction
So once you've been doing some Liferay OSGi development, you'll recognize your component properties stanza, most commonly applied to a typical portlet class:
@Component(
immediate = true,
property = {
"com.liferay.portlet.add-default-resource=true",
"com.liferay.portlet.display-category=category.hidden",
"com.liferay.portlet.layout-cacheable=true",
"com.liferay.portlet.private-request-attributes=false",
"com.liferay.portlet.private-session-attributes=false",
"com.liferay.portlet.render-weight=50",
"com.liferay.portlet.use-default-template=true",
"javax.portlet.display-name=my-controlpanel Portlet",
"javax.portlet.expiration-cache=0",
"javax.portlet.init-param.template-path=/",
"javax.portlet.init-param.view-template=/view.jsp",
"javax.portlet.name=" + MyControlPanelPortletKeys.MyControlPanel,
"javax.portlet.resource-bundle=content.Language",
"javax.portlet.security-role-ref=power-user,user",
"javax.portlet.supports.mime-type=text/html"
},
service = Portlet.class
)
public class MyControlPanelPortlet extends MVCPortlet {
}
This is the typical thing you get when you use the Blade tools' "panel-app" template.
This is well and good, you're in development and you can edit these as you need to add, remove or change values.
But what can you do with the OOTB Liferay components, the ones that are compiled into classes packaged into a jar which is packaged into an LPKG file in the osgi/marketplace folder?
Overriding Component Properties
So actually this is quite easy to do. Before I show you how, though, I want to show what is actually going on...
So the "property" stanza or the lesser-used "properties" one (this one is used to identify a file to use for component properties), these are actually managed by the OSGi Configuration Admin service. Because it is managed by CA, we actually get a slew of functionality without even knowing about it.
The @Activate and @Modified annotations that allow you to pass in the properties map? CA is participating in that.
The @Reference annotation target filters referring to property values? CA is participating in that.
Just like CA is at the core of all of the configuration interfaces and Liferay's ConfigurationProviderUtil to fetch a particular instance, these properties can be accessed in code in a similar way.
The other thing that CA brings us, the thing we're going to take advantage of here, is that CA can use override files w/ custom property adds/updates (sorry, no deletes).
Lets say my sample class is actually com.dnebinger.control.panel.test.internal.portlet.MyControlPanelPortlet. To override the properties, I just have to create an osgi/configs/com.dnebinger.control.panel.test.internal.portlet.MyControlPanelPortlet.cfg file. Note the importance of a) the location where the file goes, b) the file name is the full package/class name and c) the file has either the .cfg or .config extension and conforms to the appropriate CA formatting for the type.
The .cfg format is the simplest of the two, it actually follows a standard property file format. So if I wanted to override the category, to expose this portlet so it can be dropped on a page, I could put the following in my osgi/configs/com.dnebinger.control.panel.test.internal.portlet.MyControlPanelPortlet.cfg file:
com.liferay.portlet.display-category=category.sample
That's all there is to it. CA will use this override when collecting the component properties and, when Liferay is processing it, will treat this portlet as though it is in the Sample category and allow you to drop it on a page.
In a similar way you can add new properties, but the caveat is that the code must support them. For example, the MyControlPanelPortlet is not instanceable; I could put the following into my .cfg file:
com.liferay.portlet.instanceable=true
I'm adding a new property, one that is not in the original set of properties, but I know the code supports it and will make the portlet instanceable.
Conclusion
Using this same technique, you can override the properties for any OOTB Liferay component, including portlets, action classes, etc.
Just be sure to put the file into the osgi/configs folder, name the file correctly using full path/class, and use the .cfg or .config extensions with the correct format.
You can find out more about the .config format here: https://dev.liferay.com/discover/portal/-/knowledge_base/7-0/understanding-system-configuration-files

