According this article, I've implemented #ManagedProperty(value="#{settings}") to my backing bean:
BEAN Bde.java:
#Entity
#Table(name="bdeDATA")
#ViewScoped
#ManagedBean(name="BDE")
public class Bde implements Serializable
{
/**/
private static final long serialVersionUID = -705775502999920673L;
#Transient
#ManagedProperty(value = "#{settings}")
private Settings settings;
#Id
private Date create_date;
private Integer person_ID;
public Date getCreate_date() {
return create_date;
}
public void setCreate_date(Date create_date) {
this.create_date = create_date;
}
public Integer getPerson_ID() {
return person_ID;
}
public void setPerson_ID(Integer person_ID) {
this.person_ID = person_ID;
try
{
Settings.PWKITEM = (Pwk)Tools.find(person_ID);
if (Settings.PWKITEM != null) settings.setUserfound(true); /// PROBLEMATIC
}
catch (Exception e)
{
Tools.setErrorMessage("NOT FOUND "+e.getMessage());
}
}
// ManagedProperty settings ---------------------------------------------
public Settings getSettings() {
return settings;
}
public void setSettings(Settings settings) {
this.settings = settings;
}
public void setUserfound (boolean userfound){
settings.setUserfound(userfound);
}
public boolean isUserfound() {
return settings.isUserfound();
}
}
Settings.java:
#SessionScoped
#ManagedBean(name="settings")
public class Settings implements Serializable
{
/**/
private static final long serialVersionUID = 8613411699115714416L;
public static Pwk PWKITEM = new Pwk();
private boolean userfound = false;
public boolean isUserfound() {
return userfound;
}
public void setUserfound(boolean userfound) {
this.userfound = userfound;
}
}
XHTML (ajax call setPerson_ID):
<h:inputText id="persId" value="#{bean.bdeitem.persId}">
<f:ajax event="blur" render="name" execute="#this" />
</h:inputText>
<h:inputText id="name" value="#{bean.pwkitem.name}"/>
Problem is in try/catch:
without the condition, object is found.
when I change the condition for example to if (Settings.PWKITEM != null) System.out.println("HELLO"), HELLO is writen to console.
if i try to add the userfound setter, it is catched ("NOT FOUND").
What I'm doing wrong?
Your question looks seriously confusing. You first show some bean code and then immediately say "I though that is an ajax problem,", before even mentioning any kind of problem. The rest of the question is not much different.
To directly answer the last part of your question though:
Ican't understand, why it find the item an writes the correct name to console, and immediatelly after that, it writes catch exception not found....????
You are accessing Settings statically. The instance you have declared at the class level seems to be useless. It's fully possible that if Tools.find throws an exception and thus no new value is assigned, that there is still an old value in the static Settings.PWKITEM field. There is nothing strange about that.
Do note that the log reads from top to bottom. So it's not that "***" is printed and then the exception is thrown, but the exception is first thrown and "Not Found" is printed, and only thereafter "***" is printed.
Additionally, your approach to all of this looks problematic. Declaring an Entity to also be a (JSF) backing bean is rarely a good idea. Using references to some kind of Service or DAO classes from within an entity is also not always a good idea, but doing this in a method that is supposedly a simple setter for an ID simply looks wrong.
Then using static references is even more wrong and to top if off, using underscores in method and non-static variable names goes against the common Java code convention.
Related
I am trying to get a List of custom object of type linked list into html using Sightly. But I a unable to read them in sightly. Sample Code is pasted below:
Java Bean:
public class MiniNavBean {
private String fPath;
private String activeAttr;
public MiniNavBean(String fPath, String activeAttr){
this.fPath = fPath;
this.activeAttr = activeAttr;
}
public String getFpath() {
return fPath;
}
public void setFpath(String fpath) {
this.fPath = fpath;
}
public String getActiveattr() {
return activeAttr;
}
public void setActiveattr(String activeattr) {
this.activeAttr = activeattr;
}
}
Java class which extends WCMUsePojo:
public class MiniNav extends WCMUsePojo {
private List<MiniNavBean> navList;
MiniNavBean miniNav;
public List<MiniNavBean> getNavList() {
return navList;
}
public void setNavList(List<MiniNavBean> navList) {
this.navList = navList;
}
#Override
public void activate() {
navList = new LinkedList<MiniNavBean>();
fPath = "fpaths";
activeAttr = "activeattrs;"
miniNav = new MiniNavBean(fpath, activeattr);
navList.add(miniNav);
}
}
Html file (Sightly):
<div data-sly-include="/apps/project/components/global.jsp"></div>
<div data-sly-use.mininav="com.components.MiniNav" data-sly-unwrap>
<div data-sly-list.navlist="${mininav.navList}">
<li>
<p>${navlist.fPath}</p>
<p>${navlist.activeAttr}</p>
</li>
</div>
When I am trying to execute the above code, I am able to see the linked list getting instantiated with the data in the java class. However when I am trying to display the values of the list in the front end, sightly is unable to read it.
Since the LinkedList is of CustomObject type(MiniNavBean) I suspect sightly is unable to read it as it doesn't know about this bean because we didn't refer that bean anywhere. Is there a way to fix this using sightly tags and read the data ?
Sightly would loop over Java objects too. I don't think it is issue with Sightly. Looks like your getters are wrong. Change your bean as shown below
public class MiniNavBean {
private String fPath;
private String activeAttr;
public MiniNavBean(String fPath, String activeAttr){
this.fPath = fPath;
this.activeAttr = activeAttr;
}
public String getfPath() {
return fPath;
}
public void setfPath(String fPath) {
this.fPath = fPath;
}
public String getActiveAttr() {
return activeAttr;
}
public void setActiveAttr(String activeAttr) {
this.activeAttr = activeAttr;
}
}
If you do not wish to change the bean, then you can access the getters directly in the Sightly file and check if it is working fine.
<div data-sly-include="/apps/project/components/global.jsp"></div>
<div data-sly-use.mininav="com.components.MiniNav" data-sly-unwrap>
<div data-sly-list.navlist="${mininav.navList}">
<li>
<p>${navlist.getFpath}</p>
<p>${navlist.getActiveattr}</p>
</li>
</div>
EDIT: To explain more based on the comments
You cannot access the fields which are private outside the class and are usually done using the public getter methods. However, in Sightly when you use the field name after the dot operator, you are not accessing the field directly, instead it calls the corresponding getter method based on the Java specification for naming getters / setters. So as per spec, your getters and setters were wrong in the bean due to which it didn't work.
Like I mentioned above, you can change only your bean and your code will work fine. Or you can leave your bean as is and change Sightly code to get things working.
In your example you are neither assigning a value to the navList member of MiniNav nor adding the MiniNavBean instance to it.
Add the following lines to your activate() method:
this.navList = new LinkedList<>();
this.navList.add(navList);
Also, the Java getters and HTL/Sightly accessors are not properly aligned, ie: for getFpath() you should use navlist.fpath
In case you already have those, are you getting any compile or runtime errors from HTL/Sightly?
HTL/Sightly is generally using reflection to lookup properties of objects so it does not care much about their type.
I'm working on a entity library. I put some bean-validation annotations on my Entities.
I strongly believe a bean-validation implementation in on the class path.
#javax.validation.constraints.NotNull works and #javax.validation.constraints.AssertTrue doesn't work.
class MyEntity {
#AssertTrue // does't work
public boolean hey() {
return false;
}
#NotNull // works; violation while persist
private String some;
}
What possibly did I do wrong with it?
I uses org.hibernate:hibernate-validator and changing it with org.apache.bval:bval-jsr doesn't make any difference.
UPDATE
The method is actually invoked. I check the log.
Here comes my method.
#AssertTrue(message = "a property must be eclusively system or owned")
private boolean execlusivelySystemOrOwned() {
logger.info("execlusivelySystemOrOwnded()");
final boolean result = system ^ (getOwner() != null);
logger.log(Level.INFO, "result: {0}", result);
return result;
}
I think I found the answer.
https://stackoverflow.com/a/12950573/330457
I had to rename the method to isExeclusivelySystemOrOwned.
That's why it's called Bean-Validation.
I will start by saying that:
I'm using ODA (godmode,khan,marcel).
I'm the only code signer.
sessionAsSigner is working the first time I load an XPage that calls it.
sessionAsSigner becomes null after I reload a page (cmd + R) but not when I'm subsequently referencing it in any action during in the context of the viewScope lifetime.
I'm implementing #Gidgerby 's concept of controller classes
I would also add that sessionAsSigner works consistently if I just prepare a simple XPage that does the following:
<p>
<xp:text value="session: #{session.effectiveUserName}" />
</p>
<p>
<xp:text value="sessionAsSigner: #{sessionAsSigner.effectiveUserName}" />
</p>
Now, I am not using SSJS. I'm JSF/EL oriented as much as I can, according to my current knowledge. So, the way I access Domino back-end is unconventional for a Domino XPages programmer.
Where I can't get getSessionAsSigner to work consistently is when I try to do the above mentioned thing...
Here is my XPage controller (backing bean):
public class TestPageController extends StandardXPageController {
private static final long serialVersionUID = 1L;
private AnswerDTO answer;
public TestPageController() {
loadQuotation();
}
private void loadQuotation() {
AnswerDAO answerDAO = Factory.createAnswerDAO();
try {
answer = answerDAO.read("doc_id");
} catch (Exception e) {
e.printStackTrace();
}
}
public AnswerDTO getAnswer() {
return answer;
}
}
AnswerDTO is a POJO. I'm using the DAO/DTO design pattern.
The AnswerDAO implementation - with simplified code (wrap method is just a mere mapping of fields) - as following:
public class AnswerDAODominoImpl implements AnswerDAO {
private transient Session s;
private transient Database db;
private Session getSession() {
if (s == null) {
s = XSPUtil.getCurrentSessionAsSigner();
}
return s;
}
private Database getDatabase() throws NotesException {
if (db == null) {
db = getSession().getDatabase("server_name", "server_path");
}
return db;
}
public AnswerDTO read(String id) throws Exception {
Database db = getDatabase();
return wrap(db.getDocumentByID(id));
}
}
This is the ViewHandler class:
public class ViewHandler extends ViewHandlerExImpl {
public ViewHandler(final javax.faces.application.ViewHandler delegate) {
super(delegate);
}
#SuppressWarnings("unchecked")
public UIViewRoot createView(final FacesContext context, final String pageName) {
try {
// pageName is the XPage name prefixing the slash (e.g. "/home")
String pageClassName = pageName.substring(1);
Class<? extends XPageController> controllerClass = null;
try {
controllerClass = (Class<? extends XPageController>) context.getContextClassLoader().loadClass(
"com.sea.xsp.controller." + StringUtil.getProperCaseString(pageClassName) + "PageController");
} catch (ClassNotFoundException cnfe) {
controllerClass = StandardXPageController.class;
}
XPageController controller = controllerClass.newInstance();
Map<String, Object> requestScope = (Map<String, Object>) context.getApplication().getVariableResolver().resolveVariable(context, "requestScope");
requestScope.put("controller", controller);
UIViewRootEx root = (UIViewRootEx) super.createView(context, pageName);
root.getViewMap().put("controller", controller);
requestScope.remove("controller");
// MethodBinding beforePageLoad = context.getApplication().createMethodBinding("#{controller.beforePageLoad}", new Class[] { PhaseEvent.class });
// root.setBeforePageLoad(beforePageLoad);
return root;
} catch (Exception e) {
e.printStackTrace();
}
return super.createView(context, pageName);
}
}
Basically, what the viewhandler does is to check the existence of a java class which prefix is the XPage name itself.
eg. test.xsp = something.something.package.TestPageController
This approach allows me to forget about declaring specific XPage related classes as generic managed beans in the faces-config.xml
All the XPages will get an easy handle to their corresponding backing bean that will always be named #{controller}
Now, having that being said if I simply write the following in an XPage, everything will work the first time, but not a second time (getSession() is OK, getSessionAsSigner is null), never ever again. I need to push a new change to the database (design update after any change to the java code and xsp.application.forcefullrefresh=true) and it will work again, but, again, just the first time the page is loaded.
<p>
<xp:text value="answer doc id: #{controller.answer.id}" />
</p>
Ideas?
This is possibly due to a bug we discovered a bit ago with the XPages runtime, somehow related to ClassLoader#loadClass. It turns out that using that as you do (and as I used to) can cause sessionAsSigner to stop working after the first page load. The fix is to switch to Class.forName(String, true, ClassLoader): https://github.com/jesse-gallagher/XPages-Scaffolding/commit/d65320fd6d98ff2fbaa814a95eb38ce7bad5a81d
What happens if you run through in Java debugger? Is it going into XSPUtil.getSessionAsSigner() the second time round?
I tend to use ExtLibUtil.resolveVariable() to get a handle on sessionAsSigner if godmode is enabled. Alternatively, there's org.openntf.domino.utils.Factory.getSessionAsSigner(). Do those give a different result?
(In RC3 that is still be available but is marked deprecated in favour of Factory.getSession(SessionType.SIGNER) because we're supporting implementations outside XPages, so there are more session types involved.)
I am new to JavaBeans and I need a little help to keep my first little JSF-project going.
I am writing a little web application where a user can search with certain criteria for buildings. So the user enters in the search form 'location', 'property type', 'asking price', 'number of rooms' and 'living space'.
My managed bean accept the requiry with setter/getter and now the data is to be transmitted to a SQL class, where they are processed and matching search results are returned. It sounds simple, but I can not find a solution.
My managed bean looks like this now:
package beans
//import statements
...
#ManagedBean
#RequestScoped
public class PropertySearchBean {
private String _place
private String _propertyType
private double _askingPrice
private int _rooms
private double _livingSpace
public ArrayList<SearchResults> results = new ArrayList<SearchResults>();
// empty constructor
...
// getter and setter for these 5 user inputs
...
public void initializeSearchResults() {
// do the SQL query, recieve search results
// add it as a new object of 'SearchResults'
SQLPropertySearch search = new SQLPropertySearch(_place, _propertyType,
_askingPrice, _rooms, _livingSpace);
ArrayList<Integer> idResults = search.getPropertyIDlist();
SQLProperty property;
if(!idResults.isEmpty()) {
for(int i=0; i<idResults.size(); i++) {
property = new SQLProperty(idResults.get(i));
results.add(new SearchResults(
property.getPropertyID(),
property.getPropertyName(),
// and so on..
));
}
}
}
public static class SearchResults {
int propertyID;
String propertyName;
// and so on..
public SearchResults(int propertyID, String propertyName) {
this.propertyID = propertyID;
this.propertyName = propertyName;
// and so on..
}
// getter and setter
public int getPropertyID() {
return propertyID;
}
public void setPropertyID(int propertyID) {
this.propertyID = propertyID;
}
// and so on..
}
public ArrayList<SearchResults> getResults() {
return results;
}
}
In my XHTML-file I go through each entry of my ArrayList results.
It looks like this:
<ui:repeat var="res" value="#{PropertySearchBean.results}">
<p>#{res.propertyID}</p>
<p>#{res.propertyName}</p>
</ui:repeat>
I don't have an idea how to initialize the ArrayList, because first thing to do is the search itself, with the user input.
I am thankful for any kind of help!
You've removed the getters and setters from your example to improve readability. I'll provide one implementation here to ensure a common understanding (especially regarding the leading underscores).
public String getPlace() {
return _place;
}
public void setPlace(String place) {
this._place = place;
}
The property 'place' will be accessible within your view by using the value binding #{propertySearchBean.place}(see below).
Your code is meant to perform a search. Therefore you'll have to transfer user input from your XHTML file (view) to your managed bean. To do so you need to add a form to your view. Each search query parameter is bound to your bean using a specific value binding. Additionally the form contains a <h:commandButton> tag which finally triggers initialization of the result list.
<h:form>
<h:outputLabel for="place" value="Place:" />
<h:inputText id="place" value="#{propertySearchBean.place}" />
<!-- Additional fields -->
<h:commandButton action="#{propertySearchBean.initializeSearchResults}"
value="Search"/>
</h:form>
Note: You've used the following code in your example
<ui:repeat var="res" value="#{PropertySearchBean.results}">
Make sure that the first letter of your bean name is lower-case (propertySearchBean instead of PropertySearchBean). So this needs to be updated to
<ui:repeat var="res" value="#{propertySearchBean.results}">
How can i use session.getAttribute in some java class which is not a servlet .Something like this maybe or some other trick?
<%
<jsp:useBean id="bean" class="ProfitBean" scope="application"/>
<jsp:setProperty name="bean" value='<%=session.getAttribute("idUser")%>'/>
%>
public class ProfitBean{
private int idUser;
public void setIdUser(int IdUser){
...
}
public int getIdUser(){
...
}
}
public class SomeClass{
public void doSomething(){
ProfitBean pb =new ProfitBean
int userId = pb.getIdUser();
}
}
A session need a Request. So the request must deliver the userId to your Application-Scope-ProfitBean.
You can use the Singleton antipattern in this case, so the ProfitBean.getInstance().get/setIdUser() will contain the same values.
private static ProfitBean profitBeanInstance;
#Deprecated
public ProfitBean(){
profitBeanInstance=this;
}
public static ProfitBean getInstance(){
if (profitBeanInstance == null) {
NullPointerException cause = new NullPointerException();
throw new IllegalStateException("The instance has not been created by blabla.jsp!", cause);
}
return profitBeanInstance;
}
WARNING: This Singleton will be available for any User. In "SomeClass" you cant ensure what user set this value.
If the class can't get it, it should ask for it.
In other words, just pass the desired value to it while invoking the method.
someClass.doSomething(session.getAttribute("idUser"));
Or, depending on the context.
someClass.doSomething(profitBean);