cancel
Showing results for 
Search instead for 
Did you mean: 

Checking Empty Date-InputFields (reportContextAttributeMessage)

detlev_beutner
Active Contributor
0 Kudos

Hi there,

If i have an InputField mapped to an attribute of type date and if check this InputField (so in fact: if I check the attribute) for being a correct (whatever that means) date, then I have one serious problem:

If the user has not typed in something, the value is null. I can check this, but when I try to report a message like "Please type in something" bound to this context attribute, the server throws an exception that for reporting messages for a context attribute this attribute must not be null.

Any workaround?!

Thanks in advance

Detlev

Accepted Solutions (0)

Answers (1)

Answers (1)

Former Member
0 Kudos

Hi Detlev,

That sounds like a bug. In order to get more information please send us code and stacktrace from the server.

Best regards,

Karin

detlev_beutner
Active Contributor
0 Kudos

Hi Karin,

ok, here is a (the) part of the code:

Date from = wdContext.currentGenericRoleElement().getValidFrom();

if (from == null){

msgMgr.reportContextAttributeMessage(wdContext.currentGenericRoleElement(), wdContext.getNodeInfo().getAttribute(wdContext.currentGenericRoleElement().VALID_FROM), IMessageRequestAuthorizationComponent.EMPTY_START_DATE, null, true);

}

And the stack trace:

java.lang.IllegalArgumentException: The node element and attribute info MUST NOT be null

at com.sap.tc.webdynpro.progmodel.controller.MessageManager.reportContextAttributeMessage(MessageManager.java:934)

at com.btexx.client.reqauth.RequestAuthorizationComponent.validateDates(RequestAuthorizationComponent.java:189)

at com.btexx.client.reqauth.wdp.InternalRequestAuthorizationComponent.validateDates(InternalRequestAuthorizationComponent.java:3351)

at com.btexx.client.reqauth.FilesystemRolesView.onActionSave(FilesystemRolesView.java:209)

at com.btexx.client.reqauth.wdp.InternalFilesystemRolesView.wdInvokeEventHandler(InternalFilesystemRolesView.java:883)

at com.sap.tc.webdynpro.progmodel.generation.DelegatingView.invokeEventHandler(DelegatingView.java:97)

at com.sap.tc.webdynpro.progmodel.controller.Action.fire(Action.java:68)

at com.sap.tc.webdynpro.clientserver.task.WebDynproMainTask.handleAction(WebDynproMainTask.java:90)

at com.sap.tc.webdynpro.clientserver.task.WebDynproMainTask.handleActionEvent(WebDynproMainTask.java:291)

at com.sap.tc.webdynpro.clientserver.task.WebDynproMainTask.execute(WebDynproMainTask.java:538)

at com.sap.tc.webdynpro.clientserver.cal.AbstractClient.executeTasks(AbstractClient.java:49)

at com.sap.tc.webdynpro.clientserver.cal.ClientManager.doProcessing(ClientManager.java:239)

at com.sap.tc.webdynpro.serverimpl.defaultimpl.DispatcherServlet.doWebDynproProcessing(DispatcherServlet.java:130)

at com.sap.tc.webdynpro.serverimpl.defaultimpl.DispatcherServlet.doContent(DispatcherServlet.java:92)

at com.sap.tc.webdynpro.serverimpl.defaultimpl.DispatcherServlet.doPost(DispatcherServlet.java:42)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)

at com.sap.engine.services.servlets_jsp.server.HttpHandlerImpl.runServlet(HttpHandlerImpl.java:373)

at com.sap.engine.services.servlets_jsp.server.HttpHandlerImpl.handleRequest(HttpHandlerImpl.java:250)

at com.sap.engine.services.httpserver.server.RequestAnalizer.startServlet(RequestAnalizer.java:319)

at com.sap.engine.services.httpserver.server.RequestAnalizer.startServlet(RequestAnalizer.java:297)

at com.sap.engine.services.httpserver.server.RequestAnalizer.invokeWebContainer(RequestAnalizer.java:696)

at com.sap.engine.services.httpserver.server.RequestAnalizer.handle(RequestAnalizer.java:221)

at com.sap.engine.services.httpserver.server.Client.handle(Client.java:92)

at com.sap.engine.services.httpserver.server.Processor.request(Processor.java:146)

at com.sap.engine.core.service630.context.cluster.session.ApplicationSessionMessageListener.process(ApplicationSessionMessageListener.java:37)

at com.sap.engine.core.cluster.impl6.session.UnorderedChannel$MessageRunner.run(UnorderedChannel.java:71)

at com.sap.engine.core.thread.impl3.ActionObject.run(ActionObject.java:37)

at java.security.AccessController.doPrivileged(Native Method)

at com.sap.engine.core.thread.impl3.SingleThread.execute(SingleThread.java:94)

at com.sap.engine.core.thread.impl3.SingleThread.run(SingleThread.java:140)

Thanks in avance

Detlev

Former Member
0 Kudos

Hi Detlev,

the VALID_FROM attribute is not on the root level of the context, but you try to retrieve the attribute info from there. The returned attribute info will be null and so the exception raised by the framework is correct.

Please try


wdContext.nodeGenericRole().getNodeInfo().
  getAttribute(wdContext.currentGenericRoleElement().VALID_FROM)

instead of


wdContext.getNodeInfo().
  getAttribute(wdContext.currentGenericRoleElement().VALID_FROM)

Hope that helps.

Regards

Stefan

detlev_beutner
Active Contributor
0 Kudos

Hi Stefan,

thanks! Another proof, why pair-programming is the better way

The reason for my mistake was that within the original view, the attributes have been root attributes, but I have delegated the validation methods into the component controller - there, the dates are within this node GenericRole.

But with this, we also see some weakness of the API:

When I passed over the validation method with copy&paste, I immediately had to change the line

Date from = wdContext.currentContextElement().getValidFrom()

into

Date from = wdContext.currentGenericRoleElement.getValidFrom()

because the method "getValidFrom()" does not exist for inner class IContextElement but for IGenericRoleElement.

In contrast, IGenericRoleNode does only offer the generic method getNodeInfo(). If there would have been generated direct access methods like "attributeValidFrom", I would have seen the problem immediately (and code would be more compact).

Hey, that's a great idea, isn't it?!

Best regards

Detlev

Former Member
0 Kudos

Hi Detlev,

extreme programming is a nice idea, but, no customer wants to pay for it

But, regarding the possible weakness of the API i cannot agree, since the problems result partially from your usage of the API.

1. You don't use the static IDs of the generated Context Element interface in a static manner. Otherwise you would have noticed that <b>IContextElement.VALID_FROM</b> was gone by getting compiler errors. The context "maps" all nodes in all levels to the root programmatically, so it's not possible for you to detect the move, if you use <b>wdContext.currentXXElement().VALID_FROM</b> like you've done it.

2. If you call the method getNodeInfo() from the parent node of the current element you will get compile-time checks for this also. Example:

<b>wdContext.currentRoleElement().node().getNodeInfo(IRoleElement.ATTR);</b>

This is not really a compact statement, but it works.

Hope that helps

Best regards

Stefan

detlev_beutner
Active Contributor
0 Kudos

Hi Stefan,

ok, at least now I got the better static approach.

Nevertheless, the weakness I discribed had nothing to do with the static or non-static access, because it was the generic access method (getAttribute) I complained about. As I have seen now, obviously also the (not so nice) non-static way I have used led to a compile time error and braught me to a change. So it definitely was possible for me to detect the move so far, when I used wdContext.currentContextElement().VALID_FROM. This part I had to "repair" to wdContext.currentGenericRoleElement().VALID_FROM! (But this only changed and corrected the parameter for getAttribute, which in fact was called on the wrong object).

And about your second point: I don't get you, because getNodeInfo has no parameters. Additionally, now it's you who tries to get information via an instance where the node is enough (As far as I can see, there is no sense to access nodeInfo via an Element.)

So far, I insist on the API having this weakness described before. Maybe there is an additional way to retrieve the AttributeInfo, but I don't see it nor did you show it...

Best regards

Detlev

Former Member
0 Kudos

Hi Detlev,

ok, let's continue the discussion

1. the wdContext.currentRoleElement().node().getNodeInfo(IRoleElement.ATTR); is wrong of course (nobody is perfect), just replace this by

wdContext.currentRoleElement().node().getNodeInfo().getAttribute(IRoleElement.ATTR);

which is the same as

wdContext.nodeRole().getNodeInfo().getAttribute(IRoleElement.ATTR);

And then, if you've done this, simply forget it, since i somehow had in mind, that you used the element->node approach. You didn't, since you accessed the rootnode, so it's my fault again. It seems to be not my best day today...

2. Anyway, the weakness you insist exists. There's no relation from the attribute info x to it's parent node info y which is checkable by the compiler. You have won

Best regards

Stefan

detlev_beutner
Active Contributor
0 Kudos

Hi Stefan,

You'll have a chance for a revanche next time

After having discussed this to an end, I hope that someone still follows this discussion and IMPLEMENT MORE SPECIFIC ATTRIBUTEINFO ACCESSORS... Hope this was loud enough

Best regards

Detlev