In an attempt to implement the FacesContextListener, which seems to be the ideal place for the current challenge we are facing, I still struggle with its implementation. Attempts to declare it in the faces-config.xml or a construction similar to the ApplicationListener failed (as I probably reference things wrong (except for the class itself of course)).
Can someone provide directions / a short example regarding the implementation of the FacesContextListener?
Create a Java class which implements FacesContextListener interface.
package ch.hasselba.xpages;
import javax.faces.context.FacesContext;
import com.ibm.xsp.event.FacesContextListener;
public class MyFacesContextListener implements FacesContextListener {
public void beforeContextReleased(FacesContext fc) {
System.out.println("beforeContextReleased");
}
public void beforeRenderingPhase(FacesContext fc) {
System.out.println("beforeRenderingPhase");
}
}
Now, add an instance of the class to your XPage:
importPackage( ch.hasselba.xpages )
var fcl = new ch.hasselba.xpages.MyFacesContextListener();
facesContext.addRequestListener( fcl );
Hope this helps!
EDIT:
Here is a Java implementation with an anonymous Listener:
package ch.hasselba.xpages;
import javax.faces.context.FacesContext;
import com.ibm.xsp.context.FacesContextExImpl;
import com.ibm.xsp.event.FacesContextListener;
public class MyObject {
private transient FacesContextListener mFCListener;
public MyObject() {
mFCListener = new FacesContextListener() {
public void beforeContextReleased(FacesContext fc) {
System.out.println("Before Releasing.");
}
public void beforeRenderingPhase(FacesContext fc) {
System.out.println("Before Rendering.");
}
};
FacesContextExImpl fc = (FacesContextExImpl) FacesContext.getCurrentInstance();
fc.addRequestListener( this.mFCListener );
}
}
Related
Thera are some tranlations in com.liferay.plugins.admin.web or com.liferay.portal.instances.web module which I'd like to override. With other modules I've followed succesfully this tutorial:
https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/overriding-a-modules-language-keys
In this case, com.liferay.plugins.admin.web module has no servlet.context.name, which is required in class properties. Is there any way to override this tranlations? Thanks for help in advance!
The best solution is to create a translation module which extends from ResourceBundle:
package com.galian.extranet.resourcebundle;
import com.liferay.portal.kernel.language.UTF8Control;
import java.util.Enumeration;
import java.util.ResourceBundle;
import org.osgi.service.component.annotations.Component;
/**
* #author
*
*/
#Component(immediate = true, property = { "language.id=en_US" }, service = ResourceBundle.class)
public class DefaultCustomResourceBundle extends ResourceBundle {
#Override
public Enumeration<String> getKeys() {
return _resourceBundle.getKeys();
}
#Override
protected Object handleGetObject(String key) {
return _resourceBundle.getObject(key);
}
private final ResourceBundle _resourceBundle = ResourceBundle.getBundle("content.Language", UTF8Control.INSTANCE);
}
Your module project structure will be like this:
One of the interactions I want to test is that a class Foo is supposed to pass a Stream<Changes> to FooListener.someChangesHappened. Is there a Mockito idiom to verify that a stream contained the expected objects?
Assuming you are just verifying the argument to a mock implementation, and are not actually using it, here is a custom Hamcrest Matcher that will get the job done. It gets hairy when you need to read from the Stream more than once, because Streams are not built for that. You'll notice that this solution even needs to protect itself from JUnit calling matches more than once.
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.not;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.verify;
#RunWith(MockitoJUnitRunner.class)
public class Foo {
#Mock
FooListener fooListener;
#Before
public void happen() {
fooListener.someChangesHappened(Stream.of(Changes.ONE, Changes.TWO, Changes.THREE));
}
#Test
public void contains() {
verify(fooListener).someChangesHappened(argThat(streamThat(hasItem(Changes.TWO))));
}
#Test
public void doesNotContain() {
verify(fooListener).someChangesHappened(argThat(streamThat(not(hasItem(Changes.FOUR)))));
}
private static <T> Matcher<Stream<T>> streamThat(Matcher<Iterable<? super T>> toMatch) {
return new IterableStream<>(toMatch);
}
private interface FooListener {
void someChangesHappened(Stream<Changes> stream);
}
private enum Changes {
ONE, TWO, THREE, FOUR
}
private static class IterableStream<T> extends TypeSafeMatcher<Stream<T>> {
Matcher<Iterable<? super T>> toMatch;
List<T> input = null;
public IterableStream(Matcher<Iterable<? super T>> toMatch) {
this.toMatch = toMatch;
}
#Override
protected synchronized boolean matchesSafely(Stream<T> item) {
// This is to protect against JUnit calling this more than once
input = input == null ? item.collect(Collectors.toList()) : input;
return toMatch.matches(input);
}
#Override
public void describeTo(Description description) {
description.appendText("stream that represents ");
toMatch.describeTo(description);
}
}
}
I use the following workaround in order to control the behaviour of a #Decorator since I couldn't find a way to deactivate it.
if (!FacesContext.getCurrentInstance().getViewRoot().getViewId()
.endsWith("decoratorDemo.xhtml")) {
return transInterBean.getTransactionalInsertRecords();
} else {
...
}
Is there no way to decide at runtime whether a decorator should be applied?
package com.cdi.decorators;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.enterprise.inject.Any;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import com.cdi.cdibeans.TransactionalInterceptor;
import com.cdi.cdibeans.TransactionalInterceptorBean;
#Decorator
public abstract class TransactionalInterceptorDecorator implements
TransactionalInterceptor {
/**
*
*/
private static final long serialVersionUID = -1191671082441891759L;
#Inject
#Delegate
#Any
TransactionalInterceptorBean transInterBean;
#Override
public ArrayList<String> getTransactionalInsertRecords()
throws SQLException {
ArrayList<String> records = new ArrayList<String>();
if (!FacesContext.getCurrentInstance().getViewRoot().getViewId()
.endsWith("decoratorDemo.xhtml")) {
return transInterBean.getTransactionalInsertRecords();
} else {
Iterator<String> iter = transInterBean
.getTransactionalInsertRecords().iterator();
while (iter.hasNext()) {
String record = iter.next();
records.add(record);
records.add(">>>Decorator<<< Added record ... ");
}
if (records.isEmpty()) {
records.add(">>>Decorator<<< Currently there are no records yet!");
}
return records;
}
}
}
Deltaspike has an exclude feature ... may be this could help, I didn't try it with decorators.
this code produces NullPointerException. I don't know why. When I put the code from constructor to some other void with #PostConstruct - it works. I tried to initiate klientFacade - but it's not working, either. The class KlientFacade is #Stateless.
package view;
import entity.Klient;
import facade.KlientFacade;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import static util.Messages.addFlashMessage;
#ManagedBean
#ViewScoped
public class ManageClient implements Serializable {
#EJB
private KlientFacade klientFacade;
private List<Klient> clientList;
public List<Klient> returnClientList(){
return getKlientFacade().findAll();
}
public ManageClient() {
clientList = new ArrayList<>();
clientList = returnClientList();
}
public String removeClient(Klient klient){
addFlashMessage("Klient ["+klient.getLogin()+"] został usunięty.");
getKlientFacade().remove(klient);
return "manage";
}
public List<Klient> getClientList() {
return clientList;
}
public void setClientList(List<Klient> clientList) {
this.clientList = clientList;
}
public KlientFacade getKlientFacade() {
return klientFacade;
}
public void setKlientFacade(KlientFacade klientFacade) {
this.klientFacade = klientFacade;
}
}
Well its because injected objects are not instantiated before the constructor call. Thats why you are not getting NPE with #PostConstruct annotation. If you still need to access injected fields in constructor, try http://openejb.apache.org/constructor-injection.html.
I am trying to create an action in which the server needs to response an array list of objects over the wire to the client through GWTP Action.
Category class
package com.business.share;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
public class Category implements Serializable{
Long id;
protected String name;
protected String description;
protected boolean status;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean getStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
}
GetCategories class
package com.business.client.action;
import java.util.ArrayList;
import com.gwtplatform.dispatch.shared.ActionImpl;
import com.business.client.action.GetCategoriesResult;
import com.business.share.Category;
public class GetCategories extends ActionImpl<GetCategoriesResult> {
private ArrayList<Category> categories;
#SuppressWarnings("unused")
public GetCategories() {
// For serialization only
}
public GetCategories(ArrayList<Category> categories) {
this.categories = categories;
}
public ArrayList<Category> getCategories() {
return categories;
}
}
GetCategoriesResult class
package com.business.client.action;
import java.util.ArrayList;
import com.gwtplatform.dispatch.shared.Result;
import com.business.share.Category;
public class GetCategoriesResult implements Result {
private ArrayList<Category> categories;
#SuppressWarnings("unused")
private GetCategoriesResult() {
// For serialization only
}
public GetCategoriesResult(ArrayList<Category> categories) {
this.categories = categories;
}
public ArrayList<Category> getCategories() {
return categories;
}
}
GetCategoriesActionHandler class
package com.business.server.handler;
import java.util.ArrayList;
import com.gwtplatform.dispatch.server.actionhandler.ActionHandler;
import com.business.client.action.GetCategories;
import com.business.client.action.GetCategoriesResult;
import com.business.share.Category;
import com.google.inject.Inject;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;
import com.gwtplatform.dispatch.server.ExecutionContext;
import com.gwtplatform.dispatch.shared.ActionException;
public class GetCategoriesActionHandler implements
ActionHandler<GetCategories, GetCategoriesResult> {
#Inject
public GetCategoriesActionHandler() {
}
#Override
public GetCategoriesResult execute(GetCategories action,
ExecutionContext context) throws ActionException {
ArrayList<Category> categories = new ArrayList<Category>();
// dummy data
Category cat1 = new Category();
cat1.setName("cat1");
cat1.setDescription("cat1 desc");
cat1.setStatus(true);
Category cat2 = new Category();
cat1.setName("cat2");
cat1.setDescription("cat2 desc");
cat1.setStatus(false);
categories.add(cat1);
categories.add(cat2);
return new GetCategoriesResult(categories);
}
#Override
public void undo(GetCategories action, GetCategoriesResult result,
ExecutionContext context) throws ActionException {
}
#Override
public Class<GetCategories> getActionType() {
return GetCategories.class;
}
}
And this is a piece of code in CategoryPresenter, which sends async to server.
#Override
protected void onReset() {
super.onReset();
GetCategories getCategoriesAction = new GetCategories();
dispatchAsync.execute(getCategoriesAction, getCategoriesCallback);
}
private final AsyncCallback<GetCategoriesResult> getCategoriesCallback =
new AsyncCallback<GetCategoriesResult>() {
#Override
public void onFailure(Throwable caught) {
}
#Override
public void onSuccess(GetCategoriesResult result) {
getView().getCategoryListBox().clear();
ArrayList<Category> categories = result.getCategories();
for(Category category : categories) {
getView().getCategoryListBox().addItem(category.getName());
}
}
};
I don't know what wrong with this piece of code, but GWT compiler always gives error like this.
Compiling module com.business.Business
Validating newly compiled units
Ignored 3 units with compilation errors in first pass.
Compile with -strict or with -logLevel set to TRACE or DEBUG to see all errors.
Finding entry point classes
[ERROR] Errors in 'file:/.blah..blah..blah../businessapp/src/com/business/client/presenter/CategoryPresenter.java'
[ERROR] Line 75: No source code is available for type com.business.share.Category; did you forget to inherit a required module?
[ERROR] Errors in 'file:/.blah..blah..blah../businessapp/src/com/business/client/action/GetCategoriesResult.java'
[ERROR] Line 11: No source code is available for type com.business.share.Category; did you forget to inherit a required module?
[ERROR] Unable to find type 'com.business.client.Business'
[ERROR] Hint: Previous compiler errors may have made this type unavailable
[ERROR] Hint: Check the inheritance chain from your module; it may not be inheriting a required module or a module may not be adding its source path entries properly
Following this error message, it means, com.business.share.Category is not found, but this file is physically stored in that package already. I don't understand why GWT could not find it. I noticed anywhere that I make call Category class, it brings this error always.
Somebody's got an idea on what's going on?
[EDIT]
The problem is solved.
In my Business.gwt.xml, I have
<source path='shared'/>
But my share package is com.business.share (without d)
I just rename the package name from share to shared.
Try to add an empty constructor to the Category class.