cancel
Showing results for 
Search instead for 
Did you mean: 

Create the calculatedAttributeGetter methods dynamically

Former Member
0 Kudos

Hello,

are there any way to create calculated context attribute dynamically on runtime? I use a FileDownloadUI and want to Load the InputStream on Demand in order to increase the performance. How can I define setter and getter methods by using the method setCalculatedAttributeAccessor(IWDCalculatedAttributeAccessor). I am looking for some piece of code.

regards,

Sharam

Accepted Solutions (0)

Answers (2)

Answers (2)

BeGanz
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hallo Sharam,

why do have to create the calculated context attribute getter method dynamically in order to utilize the on-demand streaming concept in NW 04s?

The most interesting use case for utilizing on-demand streams combined with objects of type IWDResource is <i>Downloading Files in Tables</i>. I've written a new article dealing with exactly this use case, which will be published on SDN very soon. The solution does not need to create the calcualted context attributes on-demand. The data node, to which the table is bound, contains two attributes:

- one of dictionary type Resource: this attribute is initialized with so-called 0-byte resource objects which only contain the mime's metadata but not the binary file content.

- one calculated attribute of type IWDInputStream, defined statically: the related getter method is invoked for every node element (table row) as soon as the user triggers the FileDownload on the UI. The method streams back the binary data of the 0-byte resource stored in the same node element. You can reference the clicked node element with the corresponding method parameter passed by the Web Dynpro Runtime.

My new article will give you an in-depth description together with a running sample application.

Ok, in your special use case you have not 300 node elements in a table's data node but you have 300 attributes in a context node of cadinality x..1. Is there really a UI with a form containing 300 FileDownload UI elements pointing to 300 different mime objects. Why not better using a table for this purpose and then there is no need to create 300 calculated context attributes on demand.

But even in this case you can

Best regards, Bertram

Former Member
0 Kudos

Hello Bertram,

thank you for your answer. I have read your article about <i>"Uploading and Downloading Files in Web Dnypro Java".</i> In my application I want do the same but from my back-end system (remote). Furthermore, I have to load the Inputstream of my FileDownload UI on demand. Therefore I found the following link:

<a href="http://help.sap.com/saphelp_nw2004s/helpdata/en/42/f6ec5a09321bc7e10000000a11466f/frameset.htm">http://help.sap.com/saphelp_nw2004s/helpdata/en/42/f6ec5a09321bc7e10000000a11466f/frameset.htm</a>.

If I use the piece of code from your article to download a <u>local file</u>, it works fine. But how is it possible to download a file from a back-end system on demand. I tried it with the following piece of code, but I always get: <u>java.lang.NullPointerException</u>. Could you please have a look on my code.

  
public void wdDoInit()
  {
		IWDAttributePointer attributePointer = 
			wdContext.currentContextElement().getAttributePointer("onDemandStream");
	
		IWDResource resource = WDResourceFactory.createResource(
				attributePointer,
				e.getFile_Name(),
				WDWebResourceType.PDF
				);	

		wdContext.currentContextElement().setResource(resource);
  }


public com.sap.tc.webdynpro.progmodel.api.IWDInputStream getOnDemandStream(IPrivateDPView.IContextElement element)
  {
	IWDInputStream stream = null;	
	try {			
		URL url = new java.net.URL(e.getUrl());
		URLConnection conn = url.openConnection();
		InputStream is = conn.getInputStream();
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		int length;			
		byte[] part = new byte[1024 * 4];
		while ((length = is.read(part)) != -1) {
			outputStream.write(part, 0, length);
		}				
		is.close();						
							
		stream = (IWDInputStream) is;  <--- ???
		
	} catch (Exception ex){		
	}		
	
	return stream;
}

regards,

Sharam

Former Member
0 Kudos

Sharam,

I dont' understand your coding completely, however one line in getter catches my attention:


stream = (IWDInputStream) is;  <--- ???

With this line you should always get ClassCastException (instead of NullPointerException). So I'm wondering how your code works with local file -- seems that calculated attribute getter used absolutely different coding previously.

Anyway, replace this line with:


stream = WDResourceFactory.createInputStream( outputStream.toByteArray() );

Or better yet, replace complete method:


public com.sap.tc.webdynpro.progmodel.api.IWDInputStream
  getOnDemandStream(IPrivateDPView.IContextElement element)
{
  try {			
    final java.net.URL url = new java.net.URL( e.getUrl() );
    return WDResourceFactory.createInputStream( url.openStream() );
  } catch (java.io.IOException ex) {		
    wdComponentAPI.getMessageManager().reportException(
      new WDNonFatalException(ex), false
    );
    return null;
  }
}

Valery Silaev

SaM Solutions

http://www.sam-solutions.net

Message was edited by:

Valery Silaev

Former Member
0 Kudos

Hello Valery,

if I try it with the following piece of code I get always instead of my pdf document the following message:

--ejjeeffe0

content-Type: application/pdf

content-length: 993051

x-comId: KM_Programming.pdf

%pdf1.2

%ÄEIO

stream H%}..........

so I can not see the pdf document. What could be the problem?


public com.sap.tc.webdynpro.progmodel.api.IWDInputStream
  getOnDemandStream(IPrivateDPView.IContextElement element)
{
  try {			
    final java.net.URL url = new java.net.URL( e.getUrl() );
    return WDResourceFactory.createInputStream( url.openStream() );
  } catch (java.io.IOException ex) {		
    wdComponentAPI.getMessageManager().reportException(
      new WDNonFatalException(ex), false
    );
    return null;
  }
}

  public void wdDoInit()
  {
		IWDAttributePointer attributePointer = 
			wdContext.currentContextElement().getAttributePointer("onDemandStream");
	
		IWDResource resource = WDResourceFactory.createResource(
				attributePointer,
				"test.pdf",
				WDWebResourceType.PDF
				);	

		wdContext.currentContextElement().setResource(resource);
}

regards,

Sharam

BeGanz
Product and Topic Expert
Product and Topic Expert
0 Kudos

This thread addresses the same issue like thread

.

Regards, Bertram Ganz, Web Dynpro Java Forum moderator

Former Member
0 Kudos
Former Member
0 Kudos

Hello Stefanie,

thank you for your replay, that is exact what I want to do but not manually. My problem is to create the calculatedAttributeGetter methods dynamically. I need in some cases more then 300 attributes, so I can not create every calculatedAttributeGetter by my self.

I have create the needed attributes dynamically and now I want to give every attribute the calculatedAttributeGetter dynamically. How can I do that?


for (int i = 0; i < node.size(); i++){
wdContext.getNodeInfo().addAttribute("onDemandStream"+i,"com.sap.tc.webdynpro.progmodel.api.IWDInputStream");

regards,

Sharam

Former Member
0 Kudos

Hi ,

Check my weblog <a href="https://www.sdn.sap.comhttp://www.sdn.sap.comhttp://www.sdn.sap.com/irj/sdn/weblogs?blog=/cs/weblog/view/wlg/3596">link</a>

This is used in the code i have posted in the weblog. Check the function calculateSum for the same.

Regards

Bharathwaj