Jai’s Weblog – Tech, Security & Fun…

Tech, Security & Fun…

  • Jaibeer Malik

    Jaibeer Malik
  • View Jaibeer Malik's profile on LinkedIn
  • Subscribe

  • Feedburner

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 30 other followers

  • Archives

  • Categories

  • Stats

    • 394,900
  • Live Traffic

Archive for the ‘Wicket’ Category

Demo Application: JSR 286 Wicket Portlet Development on WebSphere Portal 6.1

Posted by Jai on June 5, 2009


This post share the demo application (source code, deployable war file and patched wicket jar) covering JSR 286 (The Eventing feature) Wicket Portlet development on WebSphere Portal 6.1.

Based on my previous posts JSR 286 Wicket Portlet Development on WebSphere Portal 6.1Wicket Portlet Development on WebSphere Portal – Lessons Learnt and few queries/comments, I have uploaded the working code.

The sample project: maven 2 based, RAD 7.5 project on WS Portal 6.1 and Wicket 1.4-rc2, Spring integration etc.

Download Location: http://www.mediafire.com/jaibeermalik

The portal-wicket folder contains three files.

JSR286WicketWSP61-src-full.zip : source code including patched wicket jar files
JSR286WicketWSP61-src-no-jars.zip : source code with out jar files
JSR286WicketWSP61.war : war file, try to directly deploy it. Configure portal server to work for filters and after deploying wire the portlets.

Read the rest of this entry »

Posted in Java, Spring, WebSphere Portal, Wicket | Tagged: , , , , , | Leave a Comment »

Wicket Portlet Development on WebSphere Portal – Lessons Learnt

Posted by Jai on May 4, 2009


This post will share some of the lessons learnt during JSR 286 Wicket (1.4-rc2) Portlet Development on WebSphere Portal 6.1. Some of the issues were only specific to a particular environment like it was working fine on local dev environment but it failed on testing environment. For some of the issues, I have not debugged the cause of the problem but would like to share what worked in my case.

Portlet xsd event-definition Element Declaration:

The first time when I added event-definition in the portlet deployment descriptor (portlet.xml), I got the following error:

Read the rest of this entry »

Posted in Java, WebSphere Portal, Wicket | Tagged: , , , , | Leave a Comment »

JSR 286 Wicket Portlet Development on WebSphere Portal 6.1

Posted by Jai on April 14, 2009


We will discussion here to get started with the JSR 286 Wicket portlet development on WebSpere Portal 6.1. Wicket release 1-4-rc2 has been updated to support the JSR 286: Upgrade Wicket Portlet Support to only use native Portlet API 2.0 . And have a look at later releases Upgrade wicket to fully support portlet 2.0 for more information. It seems to work fine in case of other portal containers like Liferay as mentioned steps Portal How To.

Lets have a look how to make it work for WS Portal. We will start with setting the environment first and will try to resolve the compatibility issues. Follow the below steps:

  • Update wicket release 1.4-rc2 with patch.
  • Configure WebSphere Portal to work with wicket filter
  • Develop JSR 286 eventing system based wicket portlet
  • Configure the portlet wiring in WS Portal

Update Wicket 1-4-rc2:

Have to look at wicket latest release 1-4-rc2 does not support IBM Websphere Portal Server 6.1 to understand the problem in case of WS Portal.

To fix it, update the jar with the patch:

Configuring WebSphere Portal Server:

It seems like WebSphere doesn’t handle the servlet filters porperly and you may get this error while deploying the wicket portlets on WebSphere 6.1:  Error 404: SRVE0190E: File not found:

Setting the com.ibm.ws.webcontainer.invokefilterscompatibility” property to true in Servers > Server > Web Container Settings > Web Container > Custom Properties, may help solve the issue.

Developing JSR 286 Wicket Portlets:

We will take JSR 86 eventing system as an example to work for wicket portlets.

Lets develop two portlets say TestPortlet and TestDetailsPortlet to publish and process events and spring integration for bean management.

Update deployment descriptor web.xml:


<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>

<context-param>
<param-name>org.apache.wicket.detectPortletContext</param-name>
<param-value>true</param-value>
</context-param>

<filter>
	<filter-name>wicket.testPortlet</filter-name>
	<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
	<init-param>
<param-name>applicationClassName</param-name>
<param-value>com.test.portlet.testproject.TestPortletApplication</param-value>
	</init-param>
</filter>

<filter-mapping>
        <filter-name>wicket.testPortlet </filter-name>
	<url-pattern>/testPortlet/*</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>INCLUDE</dispatcher>
</filter-mapping>

<filter>
	<filter-name>wicket.testPortletDetails</filter-name>
	<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
	<init-param>
<param-name>applicationClassName</param-name>
<param-value>com.test.portlet.testproject.TestPortletDetailsApplication</param-value>
	</init-param>
</filter>

<filter-mapping>
	<filter-name>wicket.testPortletDetails </filter-name>
	<url-pattern>/testDetailsPortlet/*</url-pattern>
	<dispatcher>REQUEST</dispatcher>
	<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
	<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Now configure the portlet.xml :

<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" xmlns:test="http://www.test.com/portlets/testing" ...

<portlet>
	<description>Test Portlet</description>
<portlet-name>TestPortlet</portlet-name>
	<display-name>TestPortlet</display-name>
<portlet-class>com.test.portlet.test.TestPortlet</portlet-class>
	<init-param>
		<name>wicketFilterPath</name>
		<value>/testPortlet</value>
	</init-param>
	<supports>
		<mime-type>*/*</mime-type>
<portlet-mode>VIEW</portlet-mode>
	</supports>
<portlet-info>
		<title>Test Portlet</title>
	</portlet-info>
	<supported-publishing-event>
		<qname>test:test_selected</qname>
	</supported-publishing-event>
</portlet>
<portlet>
	<description>Test Details Portlet</description>
<portlet-name>TestDetailsPortlet</portlet-name>
	<display-name>TestDetailsPortlet</display-name>
<portlet-class>com.test.portlet.testdetails.TestDetailsPortlet</portlet-class>
	<init-param>
		<name>wicketFilterPath</name>
		<value>/testDetailsPortlet</value>
	</init-param>
	<supports>
		<mime-type>*/*</mime-type>
<portlet-mode>VIEW</portlet-mode>
	</supports>
<portlet-info>
		<title>Test Details Portlet</title>
	</portlet-info>
	<supported-processing-event>
	        <qname>test:test_selected</qname>
	</supported-processing-event>
</portlet>
<event-definition>
	<qname>test:test_selected</qname>
	<value-type>java.lang.String</value-type>
</event-definition>

Note: Put the event-definition entries in the end after all the portlet entries, cross check with portlet 2 xsd for validation.

For each portlet, we will be specifying separate application class (eg. TestPortletApplication and TestDetailsPortletApplication) where each one will have different home page (eg. TestPage and TestDetailsPage).

TestPortletApplication:

    public class TestPortletApplication extends WebApplication {

        @Override
	protected void init() {
		super.init();
		addComponentInstantiationListener(new SpringComponentInjector(this));
	}

	@Override
	public Class<? extends Page> getHomePage() {
		return TestPage.class;
	}
    }

TestDetailsPortletApplication:

    public class TestDetailsPortletApplication extends WebApplication {    

        @Override
	protected void init() {
		super.init();
		addComponentInstantiationListener(new SpringComponentInjector(this));
	}

	@Override
	public Class<? extends Page> getHomePage() {
		return TestDetailsPage.class;
	}
    }

TestPage:

Lets say this wicket WebPage submits some value on selection/click. Here lets say
it submits some parameter “test_value” which we are using to set the event value.

TestDetailsPage:


public class TestDetailsPage extends WebPage {

 @SpringBean(name = "testService")
 private TestService testService;
 ...
 public TestDetailsPage() {
     //Get parameter value set by the process event and use in the wicket page
     String testSelectedValue = getRequest().getParameter("test_selected_value");
     ....
     //Do whatever you need to do, find or store.
     testService.findTestDetails(testSelectedValue);
  }

 ...

}

Update TestPortlet to publish the event:


public class TestPortlet extends WicketPortlet {

 @Override
 public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException {
        super.processAction(request, response);
        //set the event and value, here we are getting value from request and setting as event value.
        QName name = new QName("http://www.test.com/portlets/testing","test_selected");
        response.setEvent(name, request.getParameter(“test_value”));
 }
}

Qname is same which you mentioned in the portlet definition file for the test-selected event. And “test_value” is the parameter value which you want to pass to this event. Here in this example we will use only string values to pass otherwise it can be any serialized object.

Update TestDetailsPortlet to procees the event:

public class TestPortlet extends WicketPortlet {

 @ProcessEvent(qname = "{http://www.test.com/portlets/testing}test_selected")
 public void processTestSelectedEvent(EventRequest request, EventResponse response) throws PortletException, IOException {
       //Do whatever you want to do with the event handling part.
       response.setRenderParameter("test_selected_value", request.getEvent().getValue().toString());
 }
}

Configuring Portlet Wiring:

Once you are done with the deployment, you need to wire the two portlet otherwise you will get the error:

“EJPKB0991E: The propertybroker encountered a problem finding a communication source with name…”.

Have a look at Using portlet wires for WS Portal 6.1.

To access the wiring Tool portlet, proceed as follows:
1.Access the Manage Pages portlet.
2.Locate the page for which you want to add wires.
3.Click the Edit Page Layout icon for that page. This takes you to the Edit Layout panel.
4.Click the Wires tab. You can now start working with wires.

The same example of Developing Inter Portlet communication (IPC) portlets can be achieved using the JSR 268 Public Render Parameters also but this example demonstrates how it works using the JSR 268 eventing support.

Hope this will help you to get things started on WebSphere Portal. Feel free to share your experiences and lets hope it gets fixed either by Wicket or IBM in future.

Posted in Java, Spring, WebSphere Portal, Wicket | Tagged: , , , | 8 Comments »

Localization of Wicket Applications

Posted by Jai on November 12, 2008


In this article we will try to understand how to handle the Localization issues in Wicket Applications.

In Markup, localized labels can be shown using <wicket:message> tags

<wicket:message key=”test.key.here”></wicket:message>

In Java code, Localization can be achieved using following different ways:

  • Localizer
  • ResourceModel
  • StringResourceModel

The following article explains very well that “How does Wicket Resolve Resource Bundles and Spring as a message provider”.

Localizer:

getLocalizer().getString(….);

It returns you the localized string. But the problem here is that “If the component is not an instance of Page then it must be a component that has already been added to a page.” otherwise it will throw the following warning message.

—-

12:07:11,726 WARN [Localizer] Tried to retrieve a localized string for a component that has not yet been added to the page. This can sometimes lead to an invalid or no localized resource returned. Make sure you are not calling Component#getString() inside your Component’s constructor. Offending component: [MarkupContainer [Component id = testPanel, page = <No Page>, path = testPanel.TestPanel]]

—–

So, either we change the design not to call this in component constructor or extract out the method and call it explicitly after adding component to the page or we use other method.

ResourceModel/StringResourceModel:

ResourceModel is a lightweight version of the StringResourceModel. It lacks parameter substitutions, but is generally easier to use.

Here we get rid of the above warning message, it internally calls the localizer but gets it from Application settings. It look for the IStringResourceLoader implementation which can be BundleStringResourceLoader, ComponentStringResourceLoader or ClassStringResourceLoader.

To use BundleStringResourceLoader:

tester.getApplication().getResourceSettings().addStringResourceLoader(new BundleStringResourceLoader(“test.application”));

For wicket versions 1.3.2 and earlier (fixed in 1.3.3 onwards) there is a bug https://issues.apache.org/jira/browse/WICKET-1415 and you will get following exception:

——-

Caused by: java.lang.NullPointerException 
 	at org.apache.wicket.resource.loader.BundleStringResourceLoader.loadStringResource(BundleStringResourceLoader.java:94)
 	at org.apache.wicket.Localizer.getString(Localizer.java:221)
 	at org.apache.wicket.Localizer.getString(Localizer.java:131)
 	at org.apache.wicket.model.ResourceModel.getObject(ResourceModel.java:73)

——–

To use ClassStringResourceLoader:

tester.getApplication().getResourceSettings().addStringResourceLoader(new ClassStringResourceLoader(MaintenanceApplication.class));

And you can escape the above NPE using this. An instance of this loader is registered with the Application by default.

Posted in Wicket | Tagged: , | Leave a Comment »

Dynamically add panels and validators to a wicket form

Posted by Jai on June 7, 2008


For those who are not very clear about wicket basics I would suggest to go through this nice article Introducing Apache Wicket by Nick Heudecker.

Wicket developers usually find this requirement to add different Panels and Validators to Form dynamically, means the actual implementation of the Panel and Validator is not know while creating the wicket page. I will walk you through an example that shows how we can do this.

Lets say we have a wicket page containing two panels, one top panel which displays some list and bottom panel which shows the details of the selected item from the list. The details of the each item may be different like one item showing TextField component and another showing DropDownChoice component and both have some Label as common component.

Top List Panel – TestListPanel:

—————–
public class TestListPanel extends Panel {
public TestListPanel(String id, TestDetailsPanel testDetailsPanel) {
super(id);
this.testDetailsPanel = testDetailsPanel;
addComponents();
}

private void addComponents() {
Form form = new Form(“testListForm”) {
@Override
protected void onSubmit() {
selectedTestListId = selectedTestListIdField.getModelObjectAsString();
if (StringUtils.isNotBlank(selectedTestListId)) {
testDetailsPanel.showDetails(Long.parseLong(selectedTestListId));
}
}
};

…..

…..

}
———–

The list panel contains the details panel and the testListForm submits the selectedTestListId which calls the showDetails method on details panel which will show the details of the panel.

Test model – TestModel:

—————

public class TestModel implements Serializable, IModel {

private String name;
private String description;
private List<String> choices;

….

}

———–

This is the view model for the page which keeps data to be shown on the page.

Details Panel – TestDetailsPanel :

———————

public class TestDetailsPanel extends Panel {

private TestModel testModel;
private DetailsPanel detailsPanel = null;
private TestValidator testValidator = null;

private Form detailsForm;

…..

….


public void showDetails(long id) {
testModel = testService.getModel(id));
detailsForm.setModel(new CompoundPropertyModel(testModel));

if (“textField”.equals(testModel.getType())) {
detailsPanel = new TextFieldDetailsPanel(“detailsPanel”, testModel);
} else if (“dropDownChoice”.equals(testModel.getType())) {
detailsPanel = new DropDownChoiceDetailsPanel(
“detailsPanel”, testModel);
}

if (testValidator != null) {
detailsForm.remove(testValidator);
}

testValidator = detailsPanel.getValidator(testValidator);
detailsForm.add(testValidator);
detailsForm.addOrReplace(detailsPanel);

}


..

}

——————————

The details panel loads the model testModel to get the Model data from testService. Depending on the type of the testType.getType() (some criteria) the implementation of details panel assigned. Using addOrReplace method the form is added or replaced to the Form.

Lets have a look at the implementation of these different panels.

Common details panel – DetailsPanel:

——————

public abstract class DetailsPanel extends Panel {

private Label nameLabel;

public DetailsPanel(String id, TestModel testModel) {
super(id);
nameLabel = new Label(“name”,testModel.getName());
addOrReplace(nameLabel);
}

abstract testValidator getValidator(TestValidator testValidator);


}

——————–

The common details panel contains the common information between all panels.

TextField details panel – TextFieldDetailsPanel:

———–

public class TextFieldDetailsPanel extends DetailsPanel {

public TextFieldDetailsPanel(String id, TestModel testModel) {
super(id, testModel);

add(new TextField(“description”, new PropertyModel(testModel, “description”)));
}

public TestValidator getValidator(TestValidator testValidator) {
testValidator = new TestValidator(<text field related validation>);
return testValidator;
}


}

——————-

TextFieldDetailsPanel extends DetailsPanel and so getting nameLabel information and new component TextField is added for this implementation of the DetailsPanel. The getValidator will give this panel data dependent implementation of the validator and will do the validation of the description textField.

Drop down choice details panel – DropDownChoiceDetailsPanel:

——–
public class DropDownChoiceDetailsPanel extends DetailsPanel {

public DropDownChoiceDetailsPanel(String id, TestModel testModel) {
super(id, testModel);

add(new DropDownChoice(“dropDownChoices”, new PropertyModel(testModel, “choices”)));
}

public TestValidator getValidator(TestValidator testValidator) {
testValidator = new TestValidator(<drop down choice related validation>);
return testValidator;
}


}

—————

The same way DropDownChoiceDetailsPanel is implemented. But here instead of TextField, DropDownChoice component is added. And the different drop down choice based validation is done for this panel.

Even the validator could have been added the same way but here it is kept as single instance of testValidator which is kept at form level.

This is very simple example in terms of complexity of the actual presentation page. Just think of very complex page and design your wicket components in a very loosely coupled components.

Posted in Wicket | Tagged: , , , | 2 Comments »

 
%d bloggers like this: