Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
0 Kudos

Introduction

I often read questions of users in SDN where they ask of how to download a KM file in Web Dynpro Java. The knowledge seems to be missing in SDN and so I try to close the little gap. 

Downloading files in KM can be done in different ways, e. g. using the Filedownload UI. This blog however describes how you can download a KM document in a another way, e. g. with the Tree UI element or other elements which uses actions.

Used Technologies

SAP Netweaver Portal 7.0 SP16 including Knowledge Management & Collaboration

Prerequisites

You should be familiar in programming Web Dynpro Java. If not you should go through some other blogs or tutorials to get familiar with. Some good resources you will find here: Tutorials & Samples for Web Dynpro Java

The code sample used in this blog can be integrated in every UI element which is able to trigger actions. Possible scenarios are for example:

  • clicking on a node in Tree UI element
  • clicking on a table row
  • clicking on a link to action UI element
  • etc.
You should have an existing Web Dynpro Project with at least one View containing at least one UI element which is able to call an action.

Step by Step Solution 

Step 1: Create new Value Attribute 'FileResource' in your Component Controller's Context

Within your Context in Component Controller you should create a new Value Attribute called 'FileResource' and set its type to 'IWDResource'. The Context can be similar to the one in the screenshot below:

After that map this Value Attribute to the Context of your View Controller. Therefore create a data link from your View to your Component Controller.

Step 2: Defining a new Action

To open files in place or to download them we need a new action in Web Dynpro. Therefore we have to create a new action in the corresponding view with no parameters.

 

Step 3: Implementation of method onActionOpenFile() in View Controller

In this example we will download a file called test.txt which is stored in KM under /documents. 

// get the current user
IWDClientUser wdClientUser = WDClientUser.getCurrentUser();
com.sap.security.api.IUser sapUser = wdClientUser.getSAPUser();
IUser epUser = WPUMFactory.getUserFactory().getEP5User(sapUser);
//Establish a Resource Context
IResourceContext resourceContext = new ResourceContext(epUser);
//get a resource factory
IResourceFactory resourceFactory = ResourceFactory.getInstance();
//Get a RID for the file
RID file = RID.getRID("/documents/test.txt");
// get the file itself from KM
IResource resource = resourceFactory.getResource(file, resourceContext);
// collections can not be opened, therefore we have to ignore them
if (!resource.isCollection()) {
    byte[] bcontent = this.getByteArrayFromResource(resource);
    //get resource type
    WDWebResourceType resourceType = WDWebResourceType.getWebResourceTypeForFileExtension(resource.getRID().extension());
    IWDResource iwdResource = null;
    //resource type is known
    if (resourceType != null) {
        iwdResource = WDResourceFactory.createResource(bcontent, resource.getName(), resourceType );
    }
    // resource type is not known
    else {
        iwdResource = WDResourceFactory.createResource(bcontent, resource.getName(), WDWebResourceType.UNKNOWN);
    }
    // save resource in context
    wdContext.currentContextElement().setFileResource(iwdResource);
    // call method downloadFile() in Component Controller
    wdThis.wdGetMyTestCompController().downloadFile();
}

Create a private method called getByteArrayFromResource() in the View

private byte[] getByteArrayFromResource(IResource resource) throws Exception {
     IContent content = resource.getContent();
     InputStream in = content.getInputStream();
     ByteArrayOutputStream out = new ByteArrayOutputStream();
     int length;
     byte[] part = new byte[10 * 1024];
     while ((length = in.read(part)) != -1) {
          out.write(part, 0, length);
     }
     in.close();

     return out.toByteArray();
}

Step 4: Define a new method downloadFile() in Component Controller

For downloading files we take use of the creation of external popups. Therefore we have to create a new method in the Component Controller called downloadFile.

Step 5: Implementation of method downloadFile() in Component Controller

public void downloadFile( )
  {
    //@@begin createExternalPopup()
    // get the resource from the context
    IWDResource resource = wdContext.currentContextElement().getFileResource();
    //create an external window. A download dialog should appear
    IWDWindow window = wdComponentAPI.getWindowManager().createNonModalExternalWindow(resource.getUrl(WDFileDownloadBehaviour.AUTO.ordinal()) ,"Title");
    //@@end
  }

One thing I should mention here in this Code. "WDFileDownloadBehaviour.AUTO.ordinal()" will open the file directly in the Browser if the Browser can read the file. Otherwise a download dialog appers. Other possibilities here are:

  • WDFileDownloadBehaviour.ALLOW_SAVE.ordinal()
  • WDFileDownloadBehaviour.OPEN_INPLACE.ordinal()

The first one will show the download dialog for every file. The second one tries to display every file directly in the Browser.

Result

As result you should be able to download files from KM to your local PC without using the Filedownload UI Element.

8 Comments