Stripes #SessionScope hides Stripes:errors - java

I need to use #SessionScope to make a list stay in the page after refreshing, but when I use it, Stripes:error is not diplaying any more. Stripes:error runs actually(as I see nothing will happen) but it just doesn't show the error message in the page any more. I'm sure there is something with #SessionScope because when I run the code without it all the errors shown in the page.
Any Idea of how to fix this?
Note: I also tried to use #Wizard(startEvents="event") and it lets errors to be shown but doesn't do anything with saving the list in the page!
java
#SessionScope
#UrlBinding("/Student/import.action")
public class ImportAction implements ActionBean {
private String userCheckBox;
public Resolution importStudents() throws IOException {
if (userCheckBox == null) {
this.getContext().getValidationErrors().add("userCheckBox",new SimpleError(error));
}
return new RedirectResolution("import.action");
}
public String getUserCheckBox() {
return userCheckBox;
}
public void setUserCheckBox(String userCheckBox) {
this.userCheckBox = userCheckBox;
}
}
jsp
<stripes:checkbox name="userCheckBox"/>
<stripes:errors field="userCheckBox"/>
<stripes:submit name="importStudents" value="Import"/>

I don't know if this is the correct way to do this but instead of using #SessionScope how about storing the list in the session directly via your subclassed ActionBeanContext? For example, mine has
public class IlmpActionBeanContext extends ActionBeanContext {
private static final String REQUEST_TOKEN = "request_token";
public Token getRequestToken() {
return (Token) this.getRequest().getSession()
.getAttribute(IlmpActionBeanContext.REQUEST_TOKEN);
}
public void setRequestToken(final Token requestToken) {
this.getRequest()
.getSession()
.setAttribute(IlmpActionBeanContext.REQUEST_TOKEN, requestToken);
}

Related

Can't pass several path parameters in Vaadin using RouterLink

I'm new to Vaadin and trying to understand how to make View to get several parameters from URL.
For example
http://www.some.com/book/18/page/41
Numbers 18 and 41 are parameters.
I've found that I can implement HasUrlParameter<T> and then use setParameter method, but it can be used only for one parameter.
Are you using #WildcardParameter in your setParameter method? Wildcard URL parameters
Assuming that greet (The book in your case) is the route, then the code below sets 18\page\41. Since it's a string you would need to parse it and extract values you need, but the value is there.
#Route("greet")
public class WildcardGreeting extends Div
implements HasUrlParameter<String> {
#Override
public void setParameter(BeforeEvent event,
#WildcardParameter String parameter) {
if (parameter.isEmpty()) {
setText("Welcome anonymous.");
} else {
setText(String.format(
"Handling parameter %s.",
parameter));
}
}
}
P.S. Not related to the question, but looking at your URL, could it be that query parameters suit you better Query parameters?
There is no built-in suppor for having multiple parameters for Java views in Vaadin. What you can do is to annotate the parameter with #WildcardParameter so that multiple path segments can be captured into one parameter. You would then have to manually manage the contents of that value - concatenating strings when generating URLs and parsing strings in setParameter.
Support for multiple parameters is being worked on right now, but the work is not yet completed. It is not yet clear which future version of Vaadin will get this feature, but my guess right now is that it would be either version 14.3 or 14.4.
It seems like Vaadin 14 has got an update and got support for multiple path parameters.
Example:
#Route("user/:userID/:messageID/edit")
public class UserProfileEdit extends Div implements BeforeEnterObserver {
private String userID;
private String messageID;
#Override
public void beforeEnter(BeforeEnterEvent event) {
userID = event.getRouteParameters().get("userID").get();
messageID = event.getRouteParameters().get("messageID").get();
}
}
Source: https://vaadin.com/docs/v14/flow/routing/tutorial-router-templates
A simple example with the solution
#Route("book")
public class BookView extends Div implements HasUrlParameter<String> {
#Override
public void setParameter(BeforeEvent event, #WildcardParameter String parameter) {
if (!parameter.isEmpty()) {
String params[] = parameter.split("/");
if (params.length == 1) {
// Do something ..
} else if (params.length == 2) {
// Do another thing ..
} else {
// Do something else
}
}
}
}
The link can be created like this:
new RouterLink("No params", BookView.class);
new RouterLink("One param", BookView.class, "18");
new RouterLink("Two param", BookView.class, "18/edit");

How To set named locators for allure report?

I've saw a video where is possible to set named locators for allure report
to get view $(locatorname).click - passed:
There is code:
public class Named extends NamedBy {
private final By origin;
private String name;
public Named(By origin) {
this.origin = origin;
}
public Named as(String name) {
this.name = name;
}
#Override
public String toString() {
return Objects.nonNull(name) ? name : this.origin.toString();
}
#Override
public List<WebElement> findElements(SearchContext context) {
return new Named(By.id(id));
}
}
And code for elements:
SelenideElement button = $(id("someid").**as("locatorName")**)
and then should be possible to work with this element.
But i can't.
I dont have method as when i try to create selenideElement.
Pls help. such report is mush more readble.
video URL: https://youtu.be/d5gjK6hZHE4?t=1300
Your example doesn't seem to be valid. At least, a method as must return this. Moreover, id in the overridden findElements is missing. Plus, it's not really clear why you extend NamedBy instead of By.
Anyway, that's just a wrapper around By. To see those locators' names in report you have to follow a previous example in a video first (event listener), before completing NamedBy implementation.
P.S. To make it works the same way as was introduced in the code snippet, you have to add an additional creational logic, e.g.:
public static NamedBy id(String locator) {
return new NamedBy(By.id(locator));
}

Can I have a single instance of Interface

In my Android application I have a class which gives me static string values; something like this:
public class VehicleInfo {
public static String getVehicleEnginePower(boolean isNew) {
return isNew ? "1800CC" : "1600CC";
}
}
Now I have another category, so I will have to pass another Boolean, and I will get the value I need. However, these categories will keep on increasing. So I looked into the Open/Closed principle which looks promising for quick enhancement. To ensure this I will make the VehicleInfo class as an Interface and then I will have other classes implement VehicleInfo.
public interface VehicleInfo {
String getVehicleEnginePower();
}
public class NewVehicle implements VehicleInfo {
#Override
public String getVehicleEnginePower() {
return "1800CC";
}
}
and the other category classes will also be something like this. In this way I will have to add another class for all the new categories.
The question I wanted to ask is: is there a way that I can have single instance of this interface? Because in the whole application flow, a user will only be able to see one category until he switches to another category.
I don't want to instantiate these classes at multiple points. To clarify my question, I want to do something like this at the start of my application:
if (isNew) {
VehicleInfo vehicleInfor = new NewVehicle();
}
And in the whole application, whenever I call VehicleInfo.getVehicleEnginePower, it should always return engine power from the NewVehicle class.
Is something like this possible? Or am I just being silly and I will have to instantiate this interface on multiple points?
Maybe you need a singleton here
public class VehicleInfoManager {
private static VehicleInfoManager INSTANCE = new VehicleInfoManager();
private VehicleInfo currentVehicleInfo;
public static VehicleInfoManager getInstance() {
return INSTANCE;
}
public void setCurrentVehicleInfo(VehicleInfo info) {
this.currentVehicleInfo = info;
}
public String getVehicleEnginePower() {
return this.currentVehicleInfo.getVehicleEnginePower();
}
private VehicleInfoManager() {
// Constructor private by default
}
}
Then you can call it from everywhere like this
VehicleInfoManager.getInstance().getVehicleEnginePower()
//Or set current info like this
VehicleInfoManager.getInstance().setCurrentVehicleInfo(new NewVehicle())
Just be careful as currentVehicleInfo is null by default so you need to handle null pointer cases.
If I understand your question correctly.
My solution to this would be Enum
public enum VehicleEnginePower {
NEW ("1800CC"),
OLD ("1600CC"),
private final String name;
private Modes(String s) {
name = s;
}
public String toString() {
return this.name;
}
}
Then you can do
if (isNew) {
String powerOfEngine = VehicleEnginePower.NEW.toString();
}

How to avoid the use of static variables?

I'm quite new to OOP concepts, and right now I am developing a small system, it has a login system. I have saved the user info in a database, and when I log in, I have made it so it retrieves and assigns the user info(name, privileges, etc) to a set of static variables in my staff class to use later. I was wondering is there a way around this, to save the variables while the program is running after log in to be used later in other forms. The reason I assigned them to static variables while the user has logged in, is so that I don't have to retrieve his user info everytime I need to use them(for example to check which form to fall back to if the user presses back and has certain privileges)
If you want this the OOP way, you would typically define a UserInfo class, which will hold the relevant information (passed in via constructor). If you need to change between different users, the most common solution would be to store the UserInfos in a container such as a HashMap, and have one of the attributes (possibly a dedicated one) act as key to the users. Later you can just get the information object for a given user.
In most cases using static variables is a mistake, not just for the clutter it causes but for the on-going pain of remembering it.
There are some generally accepted exceptions though. Loggers are acceptable when made static.
You are in need of a session static Context. I.e. a context that is static for one session (i.e. login).
class Context {
private static final Context context = new Context();
String userName;
String userPriveliges;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPriveliges() {
return userPriveliges;
}
public void setUserPriveliges(String userPriveliges) {
this.userPriveliges = userPriveliges;
}
public static Context getContext() {
return context;
}
}
One approach is to use the Singleton Pattern. This allows you to avoid static fields at the cost of a static method.
public class LoginInfo {
private String username;
private List<String> privileges;
private static INSTANCE = new LoginInfo();
private LoginInfo() {
}
public void initFromDB() {
}
// Everything else is non-static but this
public static getInstance() {
return INSTANCE;
}
}
public class Form1 {
public void doSomething() {
LoginInfo info = LoginInfo.getInstance();
}
}
public class Form2 {
public void doSomething() {
LoginInfo info = LoginInfo.getInstance();
}
}
The other approach is Dependency Inversion. In this case, the users of LoginInfo get the information from outside, somehow.
public class Form1 {
private LoginInfo loginInfo;
public Form1(LoginInfo loginInfo) {
this.loginInfo = loginInfo;
}
public void doSomething() {
}
}
public class Form2 {
private LoginInfo loginInfo;
public Form2(LoginInfo loginInfo) {
this.loginInfo = loginInfo;
}
public void doSomething() {
}
}
Somewhere else:
// The Hollywood Principle - don't call me, I'll call you
public void login() {
LoginInfo loginInfo = new LoginInfo();
form1 = new Form1(loginInfo);
form2 = new Form2(loginInfo);
}
The Dependency Inversion approach has the benefit of the nasty side effects of static variables and methods, at the cost of some wiring. There are frameworks such as Spring, CDI and Guice that help you with that part.
Also, Singletons are Pathalogical Liars.
Instead of using static use final. I mean un-initialised final. But it will work only if after logged offing you exit from application. If you are not existing after logged off then use registry to save users. Java has inbuilt registry, you can use it to save anything. It also has password protection, and you can use that registry as cookies of web applications. Here are few linksconstant-vs-staticbad design practice statichow to avoid static
You can pass variables through constructors. Otherwise you can use a singleton class. There's no other way.

JSF ViewHandlerWrapper causes NullPointerException

I have a little issue with a JSF ViewHandlerWrapper that I've coded. It works fine most of the times, but at times I will get a NullPointerException from the very core of Mojarra and thus started to wonder whether I implemented my ViewHandlerWrapper correctly.
public class TokenViewHandler extends ViewHandlerWrapper {
private ViewHandler parent;
public TokenViewHandler(ViewHandler parent) {
this.parent = parent;
}
#Override
public ViewHandler getWrapped() {
return parent;
}
#Override
public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException {
final String token = UUID.randomUUID().toString();
findAndModifyForms(viewToRender, token, context);
getWrapped().renderView(context, viewToRender);
}
private void findAndModifyForms(final UIComponent component, final String token, final FacesContext ctx) {
if (component instanceof UIForm) {
final HtmlInputHidden hidden = (HtmlInputHidden) ctx.getApplication().createComponent(HtmlInputHidden.COMPONENT_TYPE);
hidden.setValue(token);
component.getChildren().add(hidden);
} else {
for (UIComponent tempComponent : component.getChildren()) {
findAndModifyForms(tempComponent, token, ctx);
}
}
}
}
From the code you quickly realize that I want to add a inputHidden-component with a UUID value to each form on the view.
As I haven't found any good examples for ViewHandlerWrappers I assumed that it should look like a ExceptionHandlerWrapper but since I get the occassional NPE using my ViewHandler, I assume that something is wrong and I can't seem to see it.
This seems to be related to a bug in partial state saving, see issue 1414.
The IceFaces guys encountered a similar problem and they got it (temporarily) fixed by adding the following line:
facesContext.getViewRoot().addComponentResource(facesContext, new UIOutput(), "head");
Give it a try. Do it before rendering the view.

Categories

Resources