Additional Blogs by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

Disclaimer

Please note that in addition to the SCN Terms of Use, the following terms and conditions govern your use of any sample code or sample applications.  Sample code and sample applications are provided only as examples and for illustrative purposes. SAP sample code and sample applications are NOT FOR PRODUCTION OR COMMERCIAL USE, unless otherwise specifically noted.

SAP grants you a nonexclusive copyright license to use any sample code or sample applications to generate the same or similarly functioning code/applications for internal testing and evaluation. You may not demonstrate, test, examine, evaluate or otherwise use them in a live operating environment, or with data that has not been sufficiently backed up. You may not rent, lease, lend, or resell SAP sample code or sample applications.  All sample code and sample applications are provided "AS IS" without any warranties of any kind. The implied warranties of non-infringement, merchantability and fitness for a particular purpose are expressly disclaimed.

How to share your documents from ABAP with SAP Mobile Documents

In this article we will explain how you can develop an ABAP client for SAP Mobile Documents. This client will be able to create a share with a public link and upload documents from your ABAP system into the share on SAP Mobile Documents. This article is part of the step-by-step Implementation and Integration Guide for SAP Mobile Documents.

Prerequisites

For the scenario in this article you need an ABAP system and a SAP Mobile Documents system. The ABAP sample code runs on an ABAP system with SAP_BASIS 7.40. The SAP Mobile Documents system must allow sharing. This setting can be configured in the administration tool of SAP Mobile Documents.

The ABAP client will communicate with the SAP Mobile Documents server via the CMIS protocol. CMIS is an open standard. You can find the specification on: CMIS Specification, Version 1.1.

Overview

The sample code for our ABAP client consists of the following objects:

  • an ABAP class ZCL_DEMO_SHARING_SERVICE,
  • an ABAP exception class ZCX_DEMO_SHARING_EXCEPTION,
  • a report ZDEMO_SHARING_CLIENT,
  • an XSL transformation ZDEMO_PARSE_REPOSITORY_INFOS,
  • and an XSL transformation ZDEMO_PARSE_CREATE_SHARE_RESP.


The class ZCL_DEMO_SHARING_SERVICE is the main part of the client. It offers methods for the following tasks:

  • Read information about the repositories of the SAP Mobile Documents system
  • Create a share in the sharing repository
  • Create a public link for the share
  • Upload a document into the share

The report ZDEMO_SHARING_CLIENT demonstrates how to call these methods one after another. When you execute the report, it will create a new share with a sample document in it, and the share can be accessed with a public link. Finally, the report opens a browser with this public link.

The two XSL transformations ZDEMO_PARSE_REPOSITORY_INFOS and ZDEMO_PARSE_CREATE_SHARE_RESP parse the HTTP responses that the SAP Mobile Documents server sends back to the ABAP system.


The sample code is attached at the end of this article. There is also a webinar: How to integrate your ABAP documents into SAP Mobile Documents.

Part 1: The report ZDEMO_SHARING_CLIENT

The report ZDEMO_SHARING_CLIENT starts with a selection screen (listing 1, lines 4-9) where you can enter values for the following parameters:

ParameterDescription
nameName of the share.
descDescription of the share.
daysNumber of days until the public link of the share expires.
enupA boolean. If true, then a user who accesses the share with the public link is allowed to make changes.
passPassword to access the share with the public link.
destAn SM59 destination to the Mobile Documents server.

The field for parameter pass is a password field (lines 19-25).

In line 29 we create an instance of the ZCL_DEMO_SHARING_SERVICE class. The constructor gets the name of the SM59 destination. It uses this destination to create an instance of IF_HTTP_CLIENT, such that it can communicate with the SAP Mobile Documents server. Next, the constructor sends the first request to the server to read the repository information. This is explained in part 2. The repository information are needed for the subsequent steps.

In line 31 we create a share with the given name and description. The CREATE_SHARE method is explained in part 3. It returns the object ID of the new share, which we need for the steps that follow. At this point the share is still empty and does not yet have a public link.

Listing 1: Report ZDEMO_SHARING_CLIENT

Next we create the public link (listing 2, line38) and determine the URL for public access (line 44). This is explained in part 4.

In line 46 we upload a small XML document to the share. In this example the file content is hard-coded. Of course, the file content might come from another source. The CREATE_DOCUMENT method is explained in part 5. Finally we close the connection to the server (line 52) and open the public link in a browser (line 54). This will open the public web UI of Mobile Documents.

Listing 2: Report ZDEMO_SHARING_CLIENT continued

Connection to the SAP Mobile Documents Server

In order to create a share and upload documents into it, the ABAP system needs a connection to the SAP Mobile Documents server. We use an HTTP connection. The connection data is configured in a destination in transaction SM59 (Configuration of RFC Connections).

  1. Create a destination in transaction SM59 of type G (HTTP Connections to External Server).
  2. In the Technical Settings of the destination enter the target host and the service number (port) of the SAP Mobile Documents server.
  3. In the Logon & Security section define a logon procedure. The user that logs on will be the owner of the shares that are being created.
  4. In the Special Options section accept cookies.

Part 2: How to retrieve repository information

In this part we ask the SAP Mobile Documents system about its repositories and their properties. For information about the architecture of SAP Mobile Documents see the Developer's Guide. We assume that sharing is configured in the SAP Mobile Documents system. Then one of the repositories is the sharing repository. We need the following of its properties:

  • The root folder URL,
  • The ID of the user's home folder,
  • The sharing base URL.

This information is retrieved in method ZCL_DEMO_SHARING_SERVICE->GET_REPOSITORY_INFOS (listing 3). We call this method in the constructor of ZCL_DEMO_SHARING_CLIENT after we have created an instance of IF_HTTP_CLIENT from the SM59 destination. Method GET_REPOSITORY_INFOS uses the http client to send a GET request with URL /mcm/json to the SAP Mobile Documents server. In lines 7-9, we wrap the http client object into a rest client object. In lines 10-12, we set the request URL "/mcm/json". This is the URL to read the repository information.

In the communication with the SAP Mobile Documents server we use a CSRF token to protect against cross-site request forgery (see: Using the CSRF Token). We set the request header X-CSRF-Token=fetch in order to obtain a CSRF token from the server (lines 13-15). After the call (line 18), we get the token from the X-CSRF-Token response header (line 33). We need this token for all following requests in the same CMIS session.

Listing 3: Class ZCL_DEMO_SHARING_SERVICE, Method GET_REPOSITORY_INFOS

The response will be a JSON document (line 34) that contains the repository information. It has the following structure:

The keys of this JSON object are repository IDs. Each of them is mapped to an object with the properties of the repository. Among the repositories is the sharing repository. It is the unique one with the property "sharing". We must parse the JSON to extract the data that we need for the next steps, namely the root folder URL, the home folder ID, and the sharing base URL.


How to parse the JSON response data


In lines 37-39 (listing 3), we use the ABAP statement CALL TRANSFORMATION with the XSL transformation ZDEMO_PARSE_REPOSITORY_INFOS for parsing. Generally, an XSL transformation maps XML to XML. However, CALL TRANSFORMATION allows also JSON data and ABAP data as source or target (see ABAP 2 JSON and JSON 2 ABAP with ST).  An XML representation for both, JSON and ABAP data is defined. In order to map JSON to ABAP we have to implement an XSLT or a Simple Transformation that maps the corresponding XML representations. That is what ZDEMO_PARSE_REPOSITORY_INFOS does. It maps the XML representation of the repository info JSON to the XML representation of an ABAP structure. The following picture shows the JSON data, the ABAP structure, and their XML representations.


Picture 4: Parsing the repository information

Listings 5 shows the XSLT that transforms the XML representation of the JSON data into the XML representation of the ABAP structure.

Listing 5: XSL Transformation ZDEMO_PARSE_REPOSITORY_INFOS

Listing 6 shows how the transformation is invoked. We set the json string as source and the field repository_info as target.

Listing 6: CALL TRANSFORMATION Statement

Part 3: How to create a share from within the ABAP system

Next we create the share. On the CMIS level, a share is a folder in the sharing repository. Therefore the CREATE_SHARE method of our ABAP client sends a request to the server that executes the CMIS operation "create folder".


The CREATE_SHARE method is similar to GET_REPOSITORY_INFOS. We wrap the http client into a rest client, set the root folder URL (a component of the repository information), and the CSRF token from the previous call (listing 7, lines 7-16).

Listing 7: Class ZCL_DEMO_SHARING_SERVICE, Method CREATE_SHARE

In lines 17-28 we write the body of the post request that is sent in line 30. It contains the parameters for the "create folder" CMIS operation. They are listed in the table below. Parameter "cmisaction" specifies the the operation and parameter "objectId" the parent folder of the new folder. The parent folder of a share is the home folder of the user who owns the share. This home folder ID is one of the components of the repository information which we have obtained in part 2.

The create folder operation also accepts a list of properties. We set three properties: name, description, and object type. Note that we need two parameters for each property, namely one for the property ID and another one for the property value.

Parameter NameValue
cmisaction"createFolder"
objectIdThe id of the parent folder of the share = home folder ID.
succinct"true"
propertyId[0]"cmis:name"
propertyValue[0]The name of the share
propertyId[1]"cmis:description"
propertyValue[1]The description of the share
propertyId[2]"cmis:objectTypeId"
propertyValue[2]"mcm:share"

The response of the create share request contains the properties of the share, in particular its object ID. Since we need the object ID for the following steps, we must parse the response. The response is a JSON with a structure as in listing 8.

Listing 8: JSON Response of the Create Share Call

Again we use CALL TRANSFORMATION with an XSL transformation for parsing (listing 7, lines 45-47). XSL Transformation ZDEMO_PARSE_CREATE_SHARE_RESP extracts the object ID of the share from the response (listing 9).


Listing 9: XSL Transformation ZDEMO_PARSE_CREATE_SHARE_RESP

Part 4: How to create a public link

Up to now we have created an empty share. The next step is to create a public link for the share. A share can be accessed via a public link if it has the secondary object type "mcm:publicLink". The secondary object types of a CMIS object are stored as a multi-value property ("cmis:secondaryObjectTypeIds") at the object. Therefore we will update this property of the shared folder. At the same time we update further properties. We do this to protect the public access of the share with a password, to define how long the public access shall be valid, and to define whether or not upload is allowed.


Method CREATE_PUBLIC_LINK of our ABAP client sends a request to the server that executes the CMIS operation "update properties". The method is similar to the previous methods. Its code is contained in the attached file. The table below shows the parameters for the update properties operation.

Parameter NameValue
cmisaction"update"
objectIdThe share id
succinct"true"
propertyId[0]"mcm:enableUpload"
propertyValue[0]"true"
propertyId[1]"mcm:sharePassword"
propertyValue[1]The password
propertyId[2]"mcm:validToDate"
propertyValue[2]The timestamp of the expiration date in milliseconds since 1.1.1970, UTC
propertyId[3]"cmis:secondaryObjectTypeIds"
propertyValue[3]"mcm:publicLink"

Remark: no gaps are allowed in the sequence of indices of the property IDs and property values.


Computation of the Public Link

Method GET_PUBLIC_LINK returns the public link. The public link is the concatenation of the sharing base URL (a component of the repository information) and the share ID.

Part 5: How to upload a document

Method ZCL_DEMO_SHARING_SERVICE->CREATE_DOCUMENT uploads a document into the share. It sends a POST request with the root folder URL of the sharing repository. The content type of the request is "multipart/form-data", and the form data are listed in the table below.

NameValue

Content-Type: text/html; charset=utf-8

Content-Length: ......

content-disposition: form-data; name="objectid"

The share id.
More generally, if you want to put the document into
a subfolder of the share, it is the id of the parent folder.

Content-Type: text/html; charset=utf-8

Content-Length: 14

content-disposition: form-data; name="cmisaction"

"createDocument"

Content-Type: text/html; charset=utf-8

Content-Length: 9

content-disposition: form-data; name="propertyId[0]"

"cmis:name"

Content-Type: text/html; charset=utf-8

Content-Length: ......

content-disposition: form-data; name="propertyValue[0]"

The document name

Content-Type: text/html; charset=utf-8

Content-Length: 17

content-disposition: form-data; name="propertyId[1]"

"cmis:objectTypeId"

Content-Type: text/html; charset=utf-8

Content-Length: 13

content-disposition: form-data; name="propertyValue[1]"

"cmis:document"

Content-Type: application/xml; charset=utf-8

Content-Length: ......

content-disposition: form-data; name="......"; filename="......"

The content of the document
10 Comments