Przykład 1 – rozszerzenie języka wyrażeń
Załóżmy, że zaimplementowaliśmy własny mechanizm warunkowego renderowania komponentów JSF (w zależności od posiadanych przez użytkownika ról)
Wyrażenie #{userHasRole['EMPLOYEE, MANAGER']} powinno zwracać true lub false. Wymaga to utworzenia własnego mechanizmu przetwarzającego, który w pierwszym kroku zinterpretuje ciąg znaków userHasRole , a następnie ciąg 'EMPLOYEE, MANAGER'. Mechanizm ten to nic innego jak rozszerzenie klasy ELResolver , której najważniejszą dla nas jest metoda:
public Object getValue(ELContext context, Object base, Object property)
Poniżej kod własnego resolver'a
package kuba.demo.el; import java.beans.FeatureDescriptor; import java.util.Iterator; import javax.el.ELContext; import javax.el.ELResolver; import kuba.demo.UserRolesController; public class UserRolesResolver extends ELResolver{ @Override public Object getValue(ELContext context, Object base, Object property) { // base=null property=userHasRole if(base==null && "userHasRole".equals(property)){ context.setPropertyResolved(true); return new UserRolesController(); } // base=UserRolesController property=EMPLOYEE, MANAGER if(base instanceof UserRolesController && property instanceof String){ context.setPropertyResolved(true); return UserRolesController.checkUserAccess((String)property); } return false; } @Override public Class getType(ELContext context, Object base, Object property) { if (base instanceof UserRolesController) { context.setPropertyResolved(true); return UserRolesController.class; } return null; } @Override public Class getCommonPropertyType(ELContext context, Object base) { if (base instanceof UserRolesController) { context.setPropertyResolved(true); return String.class; } return null; } @Override public boolean isReadOnly(ELContext context, Object base, Object property) { if (base instanceof UserRolesController) { context.setPropertyResolved(true); return true; } return false; } @Override public void setValue(ELContext context, Object base, Object property, Object value) { } @Override public IteratorgetFeatureDescriptors(ELContext context, Object base) { return null; } }
Ja, na potrzeby niniejszego przykładu, dodałem jeszcze klasę pomocniczą UserRolesController przechowującą i sprawdzającą role użytkownika
package kuba.demo; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.StringTokenizer; public class UserRolesController { public static boolean checkUserAccess(String roleNames) { ListuserRoles = new ArrayList (Arrays.asList("ADMIN", "MANAGER", "USER" )); StringTokenizer token = new StringTokenizer(roleNames,","); while (token.hasMoreTokens()) { String roleName = ((String)token.nextElement()).trim(); if(userRoles.contains(roleName)){ return true; } } return false; } }
Aby nasza klasa przetwarzająca EL była widoczna w aplikacji, musimy dodać następujący w pis w pliku faces-config.xml
Jest tutaj pewna niekonsekwencja twórców specyfikacji. Nie istnieje bowiem możliwość rejestracji własnego resolver'a przy pomocy odpowiedniej adnotacji – tak jak odbywa się to w przypadku innych elementów JSF 2.0.
Przykład 2 – dodanie funkcji do języka wyrażeń
Załóżmy, że chcemy na tronie JSF wywołać przy pomocy EL własną funkcję przyjmującą dwa argumenty
W tym celu musimy zaimplementować statyczną metodę
package kuba.demo.el; public class SumELFunction { public static int sumTwoArgs(int arg1, int arg2){ return arg1 + arg2; } }
oraz odwzorować ją w znajdującej się w katalogu WEB-INF bibliotece znaczników el.taglib.xml
pozostaje jeszcze zarejestrować bibliotekę w pliku web.xml
Brak komentarzy:
Prześlij komentarz