Skip to Content

This guide provides instructions on how to Upload a document for a task to design your custom ECM using BPM API as a Restful Service.


Applies to:

This Document Holds good for all CE 7.3 SP05 onwards. This service can be called from UI5 Screen as an Ajax call.


Summary:

This guide describes step-by-step how to upload a document for a Task to design custom ECM using BPM API as a rest full service.


About Me:

Piyas Kumar Das

As a Sr. Netweaver Consultant, I’ve been undertaking consulting assignments leveraging on my undermentioned NetWeaver skills.

  • Business Process Management (SAP NW BPM)
  • Restful Services using BPM api to be used in UI5 Screens.
  • SAP Web Dynpro Java (SAP WD4J)
  • SAP Business Rules Management (SAP BRMS)
  • SAP Composit Application Framework (SAP CAF)
  • Master Data Management (SAP NW MDM)
  • Enterprise Portal (SAP EP)
  • Services creation using NWDS (SAP EJB)
  • Enterprise SOA


Prerequisites:

You should have read through the document :How to Start a BPM Process using BPM API as a RESTful service.


We will be discussing following points in detail in this document –


  1. Adding Libraries.
  2. Setting up the foundation for using Libraries.
  3. Creating Deploy-able Object.
  4. Accessing the methods exposed.

Adding Libraries:


Step 1 : Refer the document to add libraries.


Setting up the foundation for using Library:

Step 1 : Create a new DC of type “Web Module”.

/wp-content/uploads/2014/03/1_413113.jpg

Step 2 : Define a dependency between the Web Module and the library DC. Add only the “api” public part from the External library DC to the Web module DC.1.JPG

Step 3 : Create 2 packages (1 for Business Objects, 1 for the Restful Services)

/wp-content/uploads/2014/03/1_413113.jpg

Step 4 : Create Business Objects as shown below:


import java.io.InputStream;
public class ECMFile {
  private String id;
  private String name;
  private String type;
  private String path;
  private String url;
  private long size;
  InputStream file;
  public String getId() {
  return id;
  }
  public void setId(String id) {
  this.id = id;
  }
  public String getName() {
  return name;
  }
  public void setName(String name) {
  this.name = name;
  }
  public String getType() {
  return type;
  }
  public void setType(String type) {
  this.type = type;
  }
  public String getPath() {
  return path;
  }
  public void setPath(String path) {
  this.path = path;
  }
  public String getUrl() {
  return url;
  }
  public void setUrl(String url) {
  this.url = url;
  }
  public long getSize() {
  return size;
  }
  public void setSize(long size) {
  this.size = size;
  }
  public InputStream getFile() {
  return file;
  }
  public void setFile(InputStream file) {
  this.file = file;
  }
}





public class FileDto {
  String folderId = null;
  String documentId = null;
    byte[] file = null;
    public String getDocumentId() {
        return documentId;
    }
    public void setDocumentId(String documentId) {
        this.documentId = documentId;
    }
  public String getFolderId() {
  return folderId;
  }
  public void setFolderId(String folderId) {
  this.folderId = folderId;
  }
    public byte[] getFile() {
        return file;
    }
    public void setFile(byte[] file) {
        this.file = file;
    }
}




Step 5.1 : Create a ECM Document Service class file and write a code as shown below:


package rest.converter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.apache.cxf.helpers.IOUtils;
import bo.ECMFile;
import bo.FileDto;
import com.sap.ecm.Application;
import com.sap.ecm.Ecm;
import com.sap.ecm.exceptions.EcmException;
import com.sap.ecm.item.File;
import com.sap.ecm.item.Folder;
import com.sap.ecm.item.Node;
import com.sap.ecm.item.Property;
import com.sap.ecm.item.value.Content;
import com.sap.ecm.item.value.Value;
import com.sap.ecm.name.EcmName;
import com.sap.ecm.name.Path;
import com.sap.ecm.repository.Repository;
import com.sap.ecm.repository.Session;
import com.sap.security.api.IUser;
import com.sap.security.api.UMException;
import com.sap.security.api.UMFactory;
import com.sap.tc.webdynpro.clientserver.uielib.standard.api.WDFileDownloadBehaviour;
import com.sap.tc.webdynpro.progmodel.api.WDResourceFactory;
import com.sap.tc.webdynpro.services.sal.datatransport.api.IWDResource;
import com.sap.tc.webdynpro.services.sal.url.api.WDWebResourceType;
public class ECMDocumentService {
  protected static final String THE_NAMESPACE = "http://sap.com/reuse/attachment_properties";
    private static final String ECM_FACTORY_PROPERTY = "ecm/default";
    private Context ctx;
    private Ecm ecm;
    private Folder rootFolder;
    private static final String rootFolderPath = "/BPM_Attachments"; // The folder in which you want to put the document.
    private Application application;
    private Session session;
    private Node rootNode;
    public ArrayList<String> uploadDocument(FileDto fileDto)
    {
        ArrayList<String> fileNameList = new ArrayList<String>();
        try
        {
            ctx = new InitialContext();
            ecm = (Ecm) ctx.lookup(Ecm.JNDI_LOOKUP_KEY);
            IUser usr = UMFactory.getUserFactory().getUserByLogonID("Administrator");
            EcmName ecmName = EcmName.get("", "default");
            application = ecm.connect(ecmName);
            Repository repository = application.getRepository(ecmName);
            session = repository.login(repository.getCredentials(usr));
            rootNode = session.getWorkspace().getNode(Path.getPath(rootFolderPath));
            rootFolder = (Folder) rootNode;
            boolean folderExists = false;
            for (Node currentNode : rootFolder.getChildren())
            {
            if ((currentNode) instanceof Folder && currentNode.getName().equals(fileDto.getFolderId()))
                {
            rootFolder = (Folder) currentNode;
            System.err.println("Folder already exists : "+rootFolder.getName());
            folderExists = true;
                    break;
                }
            }
            if (!folderExists)
            {
                rootFolder = rootFolder.createFolder(fileDto.getFolderId());
                System.err.println("Folder created : "+rootFolder.getName());
            }
            Value value = session.getValueFactory().createValue(fileDto.getDocumentId());
            List<Property> props = new ArrayList<Property>();
            props.add(session.getValueFactory().createProperty(ecmName, value));
            // write file
            long size = -1;
            ByteArrayInputStream bais = new ByteArrayInputStream(fileDto.getFile());
            File file = rootFolder.createFile(fileDto.getDocumentId(), null, props, bais, null, size);
            System.err.println("File uploaded :"+file.getName());
        } catch(EcmException e) {
        System.err.println("EcmException : "+e.getMessage());
  } catch (NamingException e) {
            System.err.println("NamingException : "+e.getMessage());
        } catch (UMException e) {
            System.err.println("UMException : "+e.getMessage());
        }
        finally //cleanup
        {
        cleanupECMSession();
        }
        return fileNameList;
    }
    public FileDto downloadDocument(String requestId)
    {
    List<ECMFile> files = getFolderContent(requestId);
    if(files.size() == 0)
    return null;
    FileDto fileDto = new FileDto();
    ECMFile ecmFile = files.get(0);
    if(ecmFile != null)
    {
    try
    {
    byte[] bytes = IOUtils.readBytesFromStream(ecmFile.getFile());
    fileDto.setDocumentId(ecmFile.getName());
    fileDto.setFile(bytes);
    }
    catch (IOException e)
    {
    System.err.println("IOException : "+e.getLocalizedMessage());
  }
    }
    return fileDto;
    }
    public List<ECMFile> getFolderContent(String folderId)
    {
        List<ECMFile> files = new ArrayList<ECMFile>();
    if(folderId == null || folderId.trim().length() == 0)
    return null;
        try
        {
        IUser usr = UMFactory.getUserFactory().getUserByLogonID("Administrator");
        Context ctx = new InitialContext();
            ecm = (Ecm) ctx.lookup(Ecm.JNDI_LOOKUP_KEY);
            application = ecm.connect("","");
            Repository repository = application.getRepository(EcmName.get("", "default")) ;
            session = repository.login(repository.getCredentials(usr));
            Node root = session.getWorkspace().getNode(com.sap.ecm.name.Path.getPath("/BPM_Attachments/PRC_"+folderId));
            List<Node> children = ((Folder) root).getChildren();
            for (Node child:children)
         {
          if (child instanceof File)
          {
          File file = (File)child;
          ECMFile ecmFile = new ECMFile();
          Content content = file.getContent();
     
          ecmFile.setId(file.getId());
          ecmFile.setName(file.getName());
          ecmFile.setPath(file.getPath().toString());
          ecmFile.setSize(content.getSize());
          ecmFile.setType(content.getType());
          ecmFile.setFile(content.getStream());
          ecmFile.setUrl(content.getContentURL());
          files.add(ecmFile);
          }
         }
        }catch(EcmException e) {
        System.err.println("EcmException : "+e.getMessage());
  } catch (NamingException e) {
            System.err.println("NamingException : "+e.getMessage());
        } catch (UMException e) {
            System.err.println("UMException : "+e.getMessage());
        }
        finally //cleanup
        {
            cleanupECMSession();
        }
        return files;
    }
    private void cleanupECMSession()
    {
    if (session != null)
    {
            session.logout();
    }
    if (ecm != null)
    {
        try
        {
                ecm.disconnect(application);
            }
        catch (Exception e)
        {
                System.err.println("Exception : "+e.getMessage());
            }
    }
    }
}



Step 5.2 : Create a restful service class file and write a code as shown below or if you are continuing from the document then just copy past the methods only:


import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.URI;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.activation.DataHandler;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import bo.FileDto;
import bo.Material;
import bo.MaterialCreation;
import bo.TaskHeader;
import bo.TaskHeaders;
import com.sap.bpm.api.BPMFactory;
import com.sap.bpm.exception.api.BPMException;
import com.sap.bpm.pm.api.ProcessDefinition;
import com.sap.bpm.pm.api.ProcessDefinitionManager;
import com.sap.bpm.pm.api.ProcessInstance;
import com.sap.bpm.pm.api.ProcessInstanceManager;
import com.sap.bpm.pm.api.ProcessStartEvent;
import com.sap.bpm.pm.api.ProcessStartManager;
import com.sap.bpm.tm.api.Status;
import com.sap.bpm.tm.api.TaskAbstract;
import com.sap.bpm.tm.api.TaskDetail;
import com.sap.bpm.tm.api.TaskInstanceManager;
import com.sap.tc.logging.Location;
import commonj.sdo.DataObject;
import commonj.sdo.helper.XMLHelper;
@Path("/MaterialCreationService")
@Produces({MediaType.APPLICATION_XML})
public class MaterialCreationToRestService {
  private static final Location location = Location.getLocation(MaterialCreationToRestService.class);
  private final String PRE_TASK_URI = "bpm://bpm.sap.com/task-instance/";
  @Path("/uploadDocument/{documentId}")
    @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.APPLICATION_JSON)
    public void uploadDocument(MultipartBody multipartBody, @javax.ws.rs.core.Context HttpServletRequest req,
    @PathParam("documentId") String documentId) throws IOException
    {
    System.err.println("ECMDocumentService -> uploadDocument");
    System.err.println("Document ID : "+documentId);
    ECMDocumentService ecmDocumentService = new ECMDocumentService();
    String filename = extractFilenameFromContentDisposition(multipartBody.getAllAttachments().get(0).getContentDisposition().toString());
    System.err.println("File Name : "+filename);
    if(documentId == null || documentId.trim().length() == 0)
    return;
        String folderId = getProcessInstanceForTaskInstance(documentId);
        System.err.println("Folder ID : "+folderId);
        if(folderId == null || folderId.trim().length() == 0)
    return;
    List<Attachment> attachments = multipartBody.getAllAttachments();
        DataHandler dataHandler = attachments.get(0).getDataHandler();
        InputStream is = dataHandler.getInputStream();
        byte[] bArray = new byte[is.available()];
        is.read(bArray);
        FileDto fileDto = new FileDto();
        fileDto.setFolderId("PRC_"+folderId);
        fileDto.setDocumentId(filename);
        fileDto.setFile(bArray);
        ecmDocumentService.uploadDocument(fileDto);
    }
  private String extractFilenameFromContentDisposition(String requestString)
    {
    if(requestString == null || requestString.trim().length() == 0)
    return requestString;
    String fileName = null;
    Pattern regex = Pattern.compile("(?<=filename=\").*?(?=\")");
    Matcher regexMatcher = regex.matcher(requestString);
    if (regexMatcher.find()) {
       fileName = regexMatcher.group();
    }
    return fileName;
  }
  private String getProcessInstanceForTaskInstance(String taskInstanceId)
  {
  System.err.println("ArticleMaintenanceService -> getTaskDetails");
  System.err.println("Task Instance ID: "+taskInstanceId);
  try
  {
  URI taskInstId = new URI("bpm://bpm.sap.com/task-instance/" + taskInstanceId);
  ProcessInstanceManager processInstanceManager = BPMFactory.getProcessInstanceManager();
  ProcessInstance processInstance = processInstanceManager.getProcessInstanceForTaskInstanceId(taskInstId);
  String processInstanceId = extractID(processInstance.getId().toString());
  System.err.println("Process Instance ID : "+processInstanceId);
  return processInstanceId;
  }
  catch (Exception e)
  {
  System.err.println("Exception : "+e.getMessage());
  }
  return null;
  }
  private String extractID(String instanceId)
  {
  if(instanceId == null || instanceId.trim().length() == 0)
  return instanceId;
  String [] ids = instanceId.split("/");
  return ids[ids.length-1];
  }
}



Step 6 & Step 7 is same as mentioned in the document. If you are continuing then you can ignore these steps.


Creating Deploy-able Object & Accessing the methods exposed.


Refer the document to “Creating Deploy-able Object” & “Accessing the methods exposed” as it is the same.


The next part of this document is : How to Download A Document From the custom ECM for a process using BPM API as a RESTful service.

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply