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.