Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
former_member182534
Active Participant

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:

piyaskumar.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".

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.

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

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.

Labels in this area