How to use custom services method in liferay themes in velocity files like init_custom.vm, portal_normal.vm etc.
I see liferay provides a lot of variables of helper utility classes like $portalUtil for PortalUtil, $getterUtil for GetterUtil and so on, inside the init.vm file.
So is it possible to get instance of my custom services like an instance of com.my.custom.service.MyCustomLocalServiceImpl or services of liferay from UserLocalServiceImpl?
Here is some psuedo code, to give an idea of what I need:
// this code calls method from MyCustomLocalServiceImpl class to fetch items
#set ($listOfItems = $myCustomLocalServiceUtil.getAllItems())
// this code calls method from UserLocalServiceImpl class to fetch users
#set ($listOfUsers = $userLocalServiceUtil.getUsers(0, 99))
Environment: Liferay 6.1 CE GA1
It is possible.
The following code shows how to get the services:
// Fetching instance of my custom services
#set ($myCustomLocalService = $serviceLocator.findService('myCustomServices-portlet', 'com.my.custom.service.MyCustomLocalService'))
// Fetching instance of UserLocalServiceImpl
#set ($userLocalService = $serviceLocator.findService('com.liferay.portal.service.UserLocalService'))
Then simply call the service methods:
#set ($listOfItems = $myCustomLocalService.getAllItems())
#set ($listOfUsers = $userLocalService.getUsers(0, 99))
For Liferay 6.1 CE GA1: I found this class VelocityVariablesImpl (see methods like insertHelperUtilities, insertVariables) which actually makes all the variables and helper utilities available to the velocity templates.
You can extend velocity context used in theme with custom variables and services using following hook plugin. Let's say you need to use your custom local service.
create a hook plugin with following liferay-hook.xml definition
<hook>
<portal-properties>portal.properties</portal-properties>
</hook>
create portal.properties in main/resources (when you use maven) or in docroot/WEB-INF/src (when you use plugins sdk), place following configuration there
servlet.service.events.pre=com.my.custom.action.MyCustomPreAction
create com.my.custom.action.MyCustomPreAction class in your hook that will extend com.liferay.portal.kernel.events.Action
implement run method
#Override
public void run(final HttpServletRequest request, final HttpServletResponse response)
throws ActionException {
Map<String, Object> vmVariables = (Map<String, Object>) request.getAttribute(WebKeys.VM_VARIABLES);
if (vmVariables == null) {
vmVariables = new HashMap<String, Object>(1);
}
vmVariables.put("myCustomServiceUtil", com.my.custom.service.MyCustomLocalServiceUtil.class);
request.setAttribute(WebKeys.VM_VARIABLES, map);
}
after your hook is deployed you can use your custom service in velocity template of your theme
// this code calls method from MyCustomLocalServiceImpl class to fetch items
#set ($listOfItems = $myCustomServiceUtil.getAllItems())
Related
I'm developing a wizard that implements the org.eclipse.pde.ui.IPluginContentWizard interface. Thus it gets added as plug-in project template in the end of the plug-in project wizard. All files will be created just fine, but there is one error in the project. The plug-in is not declared to be a singleton which it must be when extending extension points.
How do I do that within the wizard? I figured it needs to be done in performFinish(IProject project, IPluginModelBase model, IProgressMonitor monitor) but neither the project nor the model gives me a possibility to do so.
Edit: For future readers: My mistake was, that I didn't add the extension via the API but rather via generating the plugin.xml "by hand". This caused no mechanism in the background to do their job and thus the singleton directive wasn't set.
This way will be too long, let's use more PDE API:
First, define the template section
import org.eclipse.pde.ui.templates.OptionTemplateSection;
public class YourTemplateSection extends OptionTemplateSection {
//implement abstract methods according your needs
#Override
protected void updateModel(IProgressMonitor monitor) throws CoreException {
IPluginBase plugin = model.getPluginBase();
//do what is needed
plugin.add(extension);//here the "singleton" directive will be set
}
}
then use the section with wizard
import org.eclipse.pde.ui.templates.ITemplateSection;
import org.eclipse.pde.ui.templates.NewPluginTemplateWizard;
public class YourContentWizard extends NewPluginTemplateWizard {
#Override
public ITemplateSection[] createTemplateSections() {
return new ITemplateSection[] { new YourTemplateSection() };
}
}
In case one does the same rookie mistake then me, I wanted to post my solution I came up after revisiting the project later:
Don't create the plugin.xml manually, use the PDE API of the plugin model to add extensions.
In the org.eclipse.pde.ui.IPluginContentWizard implementions's performFinish(...) method do this:
try {
IPluginExtension extension = model.getExtensions().getModel().getFactory().createExtension();
extension.setPoint("org.eclipse.elk.core.layoutProviders");
IPluginElement provider = model.getPluginFactory().createElement(extension);
provider.setName("provider");
provider.setAttribute("class", id + "." + algorithmName + "MetadataProvider");
extension.add(provider);
model.getExtensions().add(extension);
} catch (CoreException e) {
e.printStackTrace();
}
I have to implement a custom action to search the windows registry for the installed version of the dotnet framework. Therefore I thought to extend the ReadRegistryValueAction to integrate my individual search algorithm. But the custom action will not be found at the IDE. So I extends the action from the AbstractInstallAction and included the RegistryRoot class to configure the action inside the IDE the same way as with provided registry actions of install4j framework.
public class CheckDotNetInstallationAction extends AbstractInstallAction {
private RegistryRoot registryRoot;
public RegistryRoot getRegistryRoot() {
return registryRoot;
}
public void setRegistryRoot(RegistryRoot registryRoot) {
this.registryRoot = registryRoot;
}
#Override
public boolean install(InstallerContext paramInstallerContext)
throws UserCanceledException {
// do custom search
return false;
}
}
But instead to get a dropdown list, there is only a blank field. I expected also a dropdown list the same way as in the present registry action. Now there are two questions:
Is it possible to extends existing actions/screens/forms and to use and configure it in the IDE or is it necessary to extends from the AbstractInstallAction?
How can I use classes like RegistryRoot for my custom components the same way as they are used in the actions provided by the install4j framework? Specifically the way to configure these components inside the IDE.
You have to add add a BeanInfo class and set an enumeration mapper. See the source file
samples/customCode/SampleActionBeanInfo.java
in your install4j install4j Installation and and look for the the call to setEnumerationMappers.
I'm currently writing a jenkins plug-in that has multiple builders. I wanted to share the fields in the descriptor/global.jelly across all builders. How can I share this information? Can I use inheritance or encapsulation?
A good place to start is to search the Jenkins github repository
The code you want is
Jenkins.getInstance().getDescriptor( MyPluginWithGlobalConfig.class )
Which will give you the descriptor back you want (as there is only one instance of the descriptor)
Here is one I used in a plugin (in groovy) which fetches a descriptor then calls a method on it source file
#Override
public List<String> rebuild(List<String> list){
SeleniumDynamicCapability.DescriptorImpl sdcd = Jenkins.getInstance().getDescriptor(SeleniumDynamicCapability.class)
List<SeleniumCapabilityRO> sc = sdcd.loadDefaultItems()
if (sc.size() == 0)
throw(new SeleniumException("No selenium capabilities detected"))
setSeleniumCapabilities(sc)
sc.each{list.add(it.toString())}
return list;
}
I'm trying to extract parts of a GWT application into many separate dialogs that can be invoked from php.
Existing state:
We have a GWT appplication that is deployed to JBoss as a WAR.
The app has a single module with a signle entry point.
The main JSP sets up the environment and then has some JS that loads the .nocache.js using document.write();
The entry point's onModuleLoad() creates a panel to fill the browser and adds it to the root using RootPanel.get("root").add();
When some event happens (e.g., user presses button) we pop up a DialogBox by instatiating a subclass and calling center() or setVisible()
Desired state:
We want a php app with multiple pages, to be able to invoke various DialogBox subclasses.
I think that the php side should use JS function calls that use document.write();
As for the GWT side, the options I see are:
One module with multiple entry points.
Multiple modules.
Does anyone have any experience or understanding of what would be the best practice here?
If I've understood right, you need to call GWT methods from Javascript.
You can use JSNI.
But I think you should try gwt-exporter on the GWT side. Overview. Tutorial.
It's simple GWT module to create JS_API for your GWT modules.
Not pretending to be the best practices, just quick example.
On the server-side you include an existing GWT module with DialogBoxes on every page.
You need to modify this GWT module or create new like this.
public class GwtModule implements EntryPoint {
#Override
public void onModuleLoad() {
// exportable class
DialogBoxManager dbm = new DialogBoxManager();
// export all Exportable classes of module
ExporterUtil.exportAll();
// needed cause JS_API will be available only after the GWT is loaded
onLoad();
}
// call when GWT module loaded
private native void onLoad() /*-{
$wnd.loaded();
}-*/;
DialogBoxManager looks like this
#Export
#ExportPackage("pkg")
public class DialogBoxManager implements ClickHandler, Exportable {
private DialogBox db;
public DialogBoxManager() {
this.db = new DialogBox();
}
#Export("showDB")
public void showDialog() {
db.setVisible(true);
db.center();
db.show();
}
#Override
public void onClick(ClickEvent event) {
showDialog();
}
}
String values in #Export("show"), #ExportPackage("pkg"), etc. annotations will be used in our JS_API calls for annotated GWT methods (you can export also fields).
You can use just #Export (as I did for DialogBoxManager).
When GWT module is loaded in your JS library you can realize initialization of JS_API member or what you need
var dbManager = null;
...
function loaded() {
dbManager = new pkg.DialogBoxManager();
}
and then just call JS_API like this
function showDB() {
if (dbManager != null) {
dbManager.showDB();
}
}
I want to use the default XML editor (org.eclipse.wst.xml.ui) of Eclipse in an RCP application. I need to read the DOM of the xml file currently open. The plugin doesn't offer any extension point, so I'm trying to access the internal classes. I am aware that the I should not access the internal classes, but I don't have another option.
My approach is to create a fragment and an extension point to be able to read data from the plugin. I'm trying not to recompile the plugin, that's why I thought that a fragment was necessary. I just want to load it and extract the data at runtime.
So, my question is: is there another way to access the classes of a plugin? if yes, how?
Any tutorial, doc page or useful link for any of the methods is welcome.
Since nobody answered my question and I found the answer after long searches, I will post the answer for others to use if they bump into this problem.
To access a plugin at runtime you must create and extension point and an extension attached to it into the plugin that you are trying to access.
Adding classes to a plugin using a fragment is not recommended if you want to access those classes from outside of the plugin.
So, the best solution for this is to get the plugin source from the CVS Repository and make the modifications directly into the source of the plugin. Add extension points, extensions and the code for functionality.
Tutorials:
Getting the plugin from the CVS Repository:
http://www.eclipse.org/webtools/community/tutorials/DevelopingWTP/DevelopingWTP.html
Creating extensions and extension points and accessing them:
http://www.vogella.de/articles/EclipseExtensionPoint/article.html
http://www.eclipsezone.com/eclipse/forums/t97608.rhtml
I ended up extending XMLMultiPageEditorPart like this:
public class MultiPageEditor extends XMLMultiPageEditorPart implements
IResourceChangeListener {
#Override
public void resourceChanged(IResourceChangeEvent event) {
// TODO Auto-generated method stub
setActivePage(3);
}
public Document getDOM() {
int activePageIndex = getActivePage();
setActivePage(1);
StructuredTextEditor fTextEditor = (StructuredTextEditor) getSelectedPage();
IDocument document = fTextEditor.getDocumentProvider().getDocument(
fTextEditor.getEditorInput());
IStructuredModel model = StructuredModelManager.getModelManager()
.getExistingModelForRead(document);
Document modelDocument = null;
try {
if (model instanceof IDOMModel) {
// cast the structured model to a DOM Model
modelDocument = (Document) (((IDOMModel) model).getDocument());
}
} finally {
if (model != null) {
model.releaseFromRead();
}
}
setActivePage(activePageIndex);
return modelDocument;
}
}
This is not a clean implementation, but it gets the job done.