Content REST API Example

The following example uses JQuery with the new WebCenter REST APIs released in PS3. The source for this example, implemented in JavaScript and html, is here. The source must be customized before use:

  • Supply the username and password for a WebCenter user by editing the relevant JavaScript variables.
  • Supply the URL of the resourceIndex for the WebCenter REST API, e.g. http://localhost/rest/api/resourceIndex.
  • Use a proxy to ensure that the sample files and the WebCenter REST API share the same domain. See below for quick steps to use apache mod_proxy to accomplish this.

Sample Overview

In this example, we implement a file upload feature using JavaScript. New files are uploaded to the root folder of the selected group space. Existing files are uploaded as revisions. The screenshot illustrates the file upload UI:

c1

Sample HowTo

Step 1: Get Space Info for Upload Form

Our upload form has a select list of spaces. To get that list, we make a call to the spaces api from the resourceIndex. The resourceIndex is a list of links that have resourceTypes and URL templates. Your code should hard code the resourceType, not the template. The space resourceType is urn:oracle:webcenter:spaces. For each space, we are interested in the space name and the link with rel="self". In JQuery:

$.ajax({url: resourceIndex, dataType: "xml", username: username, password: password, success: function(xml) {
 //we are uploading to particular space. first we get a list of all spaces, so the user can pick
 var link = $(xml).find("link[resourceType=urn:oracle:webcenter:spaces]");
 var spacesEndpoint = searchEndpoint = link.attr("template");
 var spaceListData = new Array();
 spacesEndpoint = spacesEndpoint.replace('&search={search}', '');
 spacesEndpoint = spacesEndpoint.replace('{itemsPerPage}', '20');
 $.ajax({url: spacesEndpoint, dataType: "xml", username: username, password: password, success: function(xml) {
  //for each group space, we capture the name and a URL template with rel='self'
  $(xml).find("space").each(
   function() {
    var selfURLtemplate = $("//link[resourceType='urn:oracle:webcenter:space'][rel='self']", this).attr("template");
    spaceListData.push(new Array($(this).children("displayName").text(), selfURLtemplate));
   });
  //we populate the space select box with the data
  var spacelist = document.getElementById("space_list");
  for (x in spaceListData) {
   spacelist.innerHTML += ("<option value='" + spaceListData[x][1] + "'>" + spaceListData[x][0] + "</option>");
  }
 }
});

Since we have a copy of the resourceIndex, we also get the cmis repositoryId, which we'll need in later steps:

link = $(xml).find("link[resourceType=urn:oracle:webcenter:cmis]");
var cmisEndpoint = link.attr("template");
cmisEndpoint = cmisEndpoint.replace('repositoryId={repositoryId}', '');
$.ajax({url: cmisEndpoint, dataType: "xml", username: username, password: password, success: function(xml) {
 cmisRepositoryId = $(xml).find("[nodeName=cmis:repositoryId]").text();}
});

Step 2: Construct an Upload Form in HTML

We construct an upload form which we will manipulate and submit using JavaScript. In this example, we actually construct two forms because the form we submit must not have extraneous inputs that the cmis API is not expecting. Also, the form MUST use name="fileUpload" for the file input and it MUST also include comments, fileName and _method inputs, but these don't necessarily need values. In html:

<form id="upload_form" style="padding-top:4px" enctype="multipart/form-data" method="post">
 Upload: <input type="file" name="fileUpload" size="40"><br></br>
 <input type="hidden" name="comments" value=""/>
 <input type="hidden" name="fileName" value=""/>
 <input type="hidden" name="_method" value=""/>
</form>
<form id="space_selector_form" style="padding-top:4px" action="javascript:upload()">
 To Space: <select name="upload_space" id="space_list"></select><br></br>
 <input type="submit" value="upload"/>
</form>

Step 3: Implement the upload() Function

The upload function first checks to see if the file already exists (using filename). If so, the function posts a revision to that file. If not, the function posts the new file to the children feed of the root folder of the group space. In JQuery:

function upload() {
 var uploadForm = document.getElementById("upload_form");
 var file = uploadForm.fileUpload.value;
 var spaceSelectorForm = document.getElementById("space_selector_form");
 var spaceUrl = spaceSelectorForm.upload_space.value;
 spaceUrl = spaceUrl.replace("{projection}", "details"); //only the "details" projection includes the cmis link
 $.ajax({url: spaceUrl, dataType: "xml", username: username, password: password, success: function(xml) {
  var link = $(xml).find("link[resourceType=urn:oracle:webcenter:cmis:folder]");
  var cmisEndpoint = link.attr("href"); //in the content API case, look for href not template
  $.ajax({url: cmisEndpoint, dataType: "xml", username: username, password: password, success: function(xml2) {
   //we need to construct an objectbypath API call to check if our document already exists
   var pathPrefix = $(xml2).find("[nodeName=cmis:propertyString][queryName=cmis:path]").text(); //note ":" has meaning in jquery selector syntax
   var cmisObjectByPathEndpoint = cmisEndpoint.substring(0, cmisEndpoint.indexOf("objectbyid?") - 1);
   cmisObjectByPathEndpoint = cmisObjectByPathEndpoint + "/objectbypath/" + cmisRepositoryId + "?path=" + pathPrefix + "/" + file;
   $.ajax({url: cmisObjectByPathEndpoint, dataType: "xml", username: username, password: password, success: function(xml3) {
    //a successful call means the file exists, so we are adding a new revision
    var revisionUrl = $(xml3).find("[nodeName=atom:link][rel=edit-media]").attr("href"); //look for rel=edit-media when making revisions
    uploadForm.action = revisionUrl;
    uploadForm.fileName.value = file;
    uploadForm._method.value = "put";
    uploadForm.submit();
    }
   , error: function(XMLHttpRequest, textStatus, errorThrown) {
    //an error means the file does not yet exist in the repository, so we will add a new file
    //we add new files to the root folder's children feed in this case
    var childrenFeed = $(xml2).find("[nodeName=atom:link][type=application/atom+xml;type=feed][rel=down]").attr("href");
    uploadForm.action = childrenFeed;
    uploadForm.fileName.value = file;
    uploadForm.submit();
    }
   });
  }});
 }});
}

Note that the content API does not use templates. In fact, we need to construct the URL that we call to determine whether or not the file already exists in the root folder. This is the most complicated part of the upload logic. In our example, pathPrefix would change depending on the folder in which you are checking.

Proxy Configuration

Let's assume you are running the sample code on your local apache server (localhost) and you want to create a localhost proxy for your WebCenter REST API. Follow these steps:

  1. Uncomment the following lines in httpd.conf:
      LoadModule proxy_module modules/mod_proxy.so
      LoadModule proxy_http_module modules/mod_proxy_http.so
  2. Add the following lines to httpd.conf:
     ProxyPass /WebCenter/ http://my.webcenter.instance:8888/webcenter/
     ProxyPassReverse /WebCenter/ http://my.webcenter.instance:8888/webcenter/
     ProxyPass /rest/ http://my.webcenter.instance:8888/rest/
     ProxyPassReverse /rest/ http://my.webcenter.instance:8888/rest/
     ProxyPreserveHost on
  3. Save httpd.conf and restart apache.