Skip Headers
Oracle® Fusion Middleware Developer's Guide for Oracle WebCenter
11g Release 1 (11.1.1.4.0)

Part Number E10148-12
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

51 Using Oracle WebCenter REST APIs

Oracle WebCenter provides a set of REST APIs for retrieving and modifying server data. This chapter discusses the WebCenter REST APIs.

This chapter includes the following sections:

More on OTN

This chapter includes some examples that demonstrate how to use WebCenter REST APIs. For more examples, see the Oracle WebCenter Demonstrations and Samples page on the Oracle Technology Network (OTN) at:

http://www.oracle.com/technology/products/webcenter/release11_demos.html

51.1 Introduction to REST

REST (REpresentational State Transfer) is an architectural style for making distributed resources available through a uniform interface that includes uniform resource identifiers (URIs), well-defined operations, hypermedia links, and a constrained set of media types. Typically, these operations include reading, writing, editing, and removing, and media types include JSON and XML/ATOM.

REST commands use standard HTTP methods as requests to point to the resource being used. Every request returns a response, indicating the status of the operation. If the request results in an object being retrieved, created, or updated, the response includes a standard representation of that object.

REST supports multiple clients, both from client machines and other servers, and it can be used from just about any client or development technology, including Java, JavaScript, Ruby on Rails, PHP, .Net, and so on.

Tip:

For a good general introduction to REST, see the Wikipedia article Representational State Transfer at http://en.wikipedia.org/wiki/Representational_State_Transfer.

REST is typically used with Rich Internet Applications (RIA) that are client-side scripted and require the ability to interact with data from a server-side application. For example, the WebCenter iPhone App uses WebCenter REST APIs to interact with a WebCenter Spaces application. The native iPhone client is written in Objective-C, and the REST APIs enable the client to send and retrieve application data.

51.2 Before You Begin: Performing Required Configurations

All of the REST APIs, except for the navigations REST API, require WebCenter Spaces. For information on the navigation REST API, see Section 13.3.2, "Using the Navigation REST APIs."

51.2.1 Introduction

Before you can use the WebCenter REST APIs, you must perform the server-side configurations described in this section. You must perform two separate configurations. You must configure an identity asserter and you must seed required entries in the credential store, which enables the REST security tokens to function properly.

Perform these configuration tasks when WebCenter Spaces is installed for the first time or if you otherwise know the configuration tasks have not been previously performed.

For more information on security tokens, see Section 51.9, "Security Considerations for WebCenter REST APIs."

Note:

This configuration is not required for the navigation REST APIs or for the CMIS REST APIs.

51.2.2 Configuring an Identity Asserter

First, you must configure an identity asserter before using the REST APIs. For detailed instructions, see "Configuring the REST Service" in the Oracle Fusion Middleware Administrator's Guide for Oracle WebCenter.

51.2.3 Configuring the WebLogic Server Credential Store

The second configuration step is to configure the WLS credential store. To configure the credential store, execute these commands while the server is running. You do not have to restart the server after executing these commands.

createCred(map="o.webcenter.jf.csf.map", key="keygen.algorithm",
    user="keygen.algorithm", password="AES")
createCred(map="o.webcenter.jf.csf.map", key="cipher.transformation",
    user="cipher.transformation", password="AES/CBC/PKCS5Padding") 

51.3 Understanding the Username-Based Security Token Encryption

To provide additional security, every URI, for both href and template attributes, includes a security token parameter that is based on the authenticated username (a utoken).

The security generation algorithm uses a randomly generated "salt" along with the username. The salt ensures that if any of the parameters used to perform encryption become compromised, existing tokens can be invalidated and new ones generated. Most importantly, because the username is used as part of the user token generation algorithm, the salt prevents having to change all user names in the event of a compromise.

The salt is stored in the Credential Store Framework (CSF) in the map o.webcenter.jf.csf.map against key user.token.salt. You can change the value of this key (and other keys used for token encryption) by accessing CSF in Oracle Enterprise Manager.

Caution:

If you change the encryption key values, all existing username based security tokens will immediately become invalid. Only change these values under extraordinary circumstances, like an algorithm parameter compromise.

51.4 Benefits of Using REST

Many excellent articles have been published about REST and the benefits of the RESTful style of software architecture. Some of these benefits include:

51.5 Introduction to WebCenter REST APIs

In addition to enabling mobile access, WebCenter REST APIs allow you to take advantage of Web 2.0 technologies like Ajax, JavaScript, and JSON to create rich, interactive browser-based user interfaces and to access and modify WebCenter and WebCenter Spaces data. In general, the WebCenter REST commands provide a more natural and easy-to-use alternative to a SOAP-style web services approach.

Table 51-1 describes the Oracle WebCenter REST APIs provided for WebCenter Services features.

Table 51-1 Summary WebCenter Services Features Supported by REST APIs

REST API Description Chapter

Discussions

Enable a client to post, read, update, and delete discussion forums, topics, and messages.

Section 33.3.8, "Using the Discussions Service REST APIs."

Lists

Enables a client to browse all the lists associated with a named group space; search list columns given a search term; create new lists; add, update, and remove list rows; and similar sorts of list-related tasks

Section 43.4, "Using the Lists Service REST APIs."

People Connections

Enable a client to view profile data; manage connection lists, feedback, and messages; create new activities and view activities for users, lists, and group spaces.

Section 35.3.5, "Using the People Connections Service REST APIs."

WebCenter Spaces

Enable a client to retrieve group space metadata and view, create, update, and delete group space lists and list items. You can also retrieve group space membership information.

Section 50.3, "Using the WebCenter Spaces REST APIs."

Content Management

Uses the CMIS (Content Management Interoperability Services) RESTful server binding to provide access to the CM VCR (Content Management Virtual Content Repository).

Oracle Fusion Middleware Content Management REST Service Developer's Guide.

Activity Graph

Enables you to create your own interface for providing recommendations for connections, group spaces, and items using the underlying Activity Graph engine.

Section 41.3.2, "Using the Activity Graph Service REST APIs."

Events

Lets you access calendar events associated with a named group space.

Section 48.3.2, "Using the Events Service REST APIs."

Feedback

Enables a client to create, read, and delete feedback in a social networking application.

Section 35.3.5.3, "Feedback REST APIs."

Search

Lets you post, read, update, and delete searches. You can specify keywords and the scope of the search; for example, the iPhone could search for "smith" in all spaces, documents and wiki pages.

Section 40.3.7, "Using the Search Service REST APIs."

Tags

Enables a client to read, post, update, and delete tags and tagged items.

Section 39.3.2, "Using the Tags Service REST APIs."

Navigation

Use the navigation REST APIs to create your own interface for displaying navigations.

Note: The navigation REST APIs do not share the resource index described in this chapter.

Section 13.3.2, "Using the Navigation REST APIs."

Personalization

Enables you to access the Personalization Conductor.

Section 62.4, "Using Personalization APIs Externally."

Pagelets

Allows remote web services to retrieve information about resources and pagelets. Inject pagelets into non-proxied pages, allowing the Pagelet Producer to act as a portlet provider for Oracle WebCenter Interaction, Oracle WebLogic Portal, or other third-party portals.

Section 58.2.3, "Using REST APIs."


51.6 Understanding the Link Model

Hypermedia is at the core of two of the most successful web-based formats: HTML and ATOM. HTML and ATOM allow consumers to navigate to other hypermedia documents through links. For example, Oracle's link element is based on HTML and ATOM links.

Hypermedia drives RESTful application state (known as HATEOAS: Hypermedia As The Engine Of Application State).

Note:

HATEOAS analogy to define application state:

Suppose you are completing your taxes in your favorite browser. You finish entering your W-2 data and move on to deductions when the browser crashes. The state you lost—the fact that you were on deductions and still needed to enter data—is the application state; not the W-2 data entered (that is, change states from the current state).

HATEOAS dictates that this state—the application state—be captured wholly in hypermedia. Application state is where you are in the application, not what data you've entered into the application. One of the benefits of this approach is that it simplifies the client and server, because they do not need to be aware of the state they are in. The link contains all the state information necessary to process the request.

Given a set of top-level URI entry points to a RESTful service, all interactions beyond those entry points are driven by hypermedia links returned in response representations. This link-centered approach helps keep the client from becoming too tightly coupled to the server URLs. The client is using URLs given to it by the server, therefore the client code does not break if the server URLs change format.

Understanding this link model helps you understand how to use the data the service returns to navigate the REST APIs.

This section describes the hypermedia link model used by WebCenter's RESTful services. It includes the following subsections:

51.6.1 The Resource Index

In WebCenter, the Resource Index is your starting point for all authenticated access. The Resource Index provides access to the set of top-level URI entry points. It provides the way in to all the available WebCenter RESTful services. The Resource Index URI is the only URI that you need to know.

The WebCenter Resource Index URI is:

http://host:port/rest/api/resourceIndex

Note:

Access to the Resource Index always requires authentication; however, you can (optionally) access the CMIS resource entry point anonymously using the following URI:

http://host:port/rest/api/cmis/repository

See also Section 51.10, "Security Considerations for CMIS REST APIs."

The first step in using the WebCenter REST APIs is to send a GET request to the Resource Index. The response varies depending on the services available and the media type of the request. Example 51-1 shows how the response might look if you made an Ajax request using JavaScript (and possibly a client-side scripting library, such as Dojo) to retrieve the JSON data for the Resource Index. Note that this is an abridged sample response and does not include all of the links actually present in a real response.

Example 51-1 Response to a GET on the Resource Index

{
  "resourceType": "urn:oracle:webcenter:resourceindex",
  "links": [
    {
      "template": "opaque-template-uri",
      "resourceType": "urn:oracle:webcenter:messageBoard",
      "href": "opaque-uri",
      "capabilities": "urn:oracle:webcenter:read"
    },
    {
      "resourceType": "urn:oracle:webCenter:cmis",
      "href": "opaque-uri",
      "capabilities": "urn:oracle:webcenter:read"
    },
    {
      "template": "opaque-template-uri",
      "resourceType": "urn:oracle:webcenter:discussions:forums",
      "href": "opaque-uri",
      "capabilities": "urn:oracle:webcenter:read"
    },
    {
      "resourceType": "urn:oracle:webcenter:resourceindex",
      "rel": "self",
      "href": "http://host:port/rest/api/resourceIndex",
      "capabilities": "urn:oracle:webcenter:read"
    },
    {
      "template": "opaque-template-uri",
      "resourceType": "urn:oracle:webcenter:activities:stream",
      "href": "opaque-uri",
      "capabilities": "urn:oracle:webcenter:read"
    },
    {
      "template": "opaque-template-uri",
      "resourceType": "urn:oracle:webcenter:people:person",
      "capabilities": "urn:oracle:webcenter:read"
    },
    {
      "template": "opaque-template-uri",
      "resourceType": "urn:oracle:webcenter:feedback",
      "href": "opaque-uri",
      "capabilities": "urn:oracle:webcenter:read"
    },
    {
      "template": "opaque-template-uri",
      "resourceType": "urn:oracle:webcenter:spaces",
      "href": "opaque-uri",
      "capabilities": "urn:oracle:webcenter:read"
    },
    {
      "template": "opaque-template-uri",
      "resourceType": "urn:oracle:webcenter:people",
      "href": "opaque-uri",
      "capabilities": "urn:oracle:webcenter:read"
    }
  ]
}

By interpreting the links returned in the Resource Index data, you can retrieve the URI entry point for an individual service by locating the URI for the resource type you want to use. You can then continue navigating through the hypermedia until you can perform the required operation. Example 51-2 shows a method that locates a URI given the Resource Index JSON data.

Example 51-2 Locating the URI for a Particular Service in the Resource Index

/* Parse the resourceIndex to find the specified URL and
 * return it.
 *
 * @Param jsonData the JSON data retrieved from calling
 *        the /rest/api/resourceIndex URL.
 * @Param strResourceType the resource type of the URL
 *        you want to retrieve from the resourceIndex data.
 *        E.g., 'urn:oracle:webcenter:activities:stream'
 */
function getResourceURL(jsonData, strResourceType)
{
  // Using the HATEOAS model, we browse the returned links
  // looking for the one with the correct resource type.
  for (var i = 0; i < data.links.length; i++) {
    if (data.links[i].resourceType == strResourceType) {
      return data.links[i].href;
    }
  }
}

51.6.2 The Anatomy of a Link

Example 51-3 and Example 51-4 show the anatomy of a hypermedia link as XML and in JSON document fragments, respectively.

Example 51-3 Link in an XML Document Fragment

<links>
  <link href="opaque-URI"
        template="opaque-template-URI (optional)"
        rel="rel-name"
        title="human-readable-title (optional)"
        type="media-type (optional)"
        resourceType="resource-type"
        capabilities="operation"/>
  ...repeat as needed...
</links>

Example 51-4 Link in a JSON Document Fragment

"links": [
  {
    "href":"opaque-URI",
    "template":"opaque-template-URI (optional)",
    "rel":"rel-name",
    "title":"human-readable-title (optional)",
    "type":"media-type (optional)",
    "resourceType":"resource-type",
    "capabilities":"operation"
  },
  ...repeat as needed...
]

The resourceType, rel, and capabilities attributes of the hypermedia link provide metadata that enable clients to determine which URI (href or template) to use, without having to parse the URIs directly. The URIs are opaque—the metadata determines which link is useful in a given circumstance.

Multiword field, element, and attribute names are formatted in camel case, unless the representation is attempting to conform to a specification not under the service author's direct control. Acronyms are treated as normal words with their case adjusted accordingly (for example, fooXml or xmlFoo). See Example 51-5 and Example 51-6.

Example 51-5 XML Naming Convention

<myElement>text</myElement>

Example 51-6 JSON Naming Convention

{"myElement": "text"}

This section includes the following subsections that describe the different attributes of the hypermedia link:

51.6.2.1 Resource Type

The resourceType link attribute indicates the type of resource to which the link points. Clients should use the resourceType to determine the expected response bodies for GET and POST and allowable request bodies for POST and PUT.

For more information, see Section 51.8, "Navigating Hypermedia Using HTTP."

51.6.2.2 Relationship

The rel link attribute indicates the relationship of the linked object to the current object (that is, the object that contains the list of links). The value of this attribute is a space-separated list of the following currently supported values:

  • self—The linked object is the current object

  • related—The linked object is related to the current object

  • via—The linked object is the source of the information for the current object

  • alternate—The linked object is a substitute for the current object (typically, the same object in another format, such as an HTML page that displays the current object)

  • urn:oracle:webcenter:parent—The linked object is the parent of the current object. That is, the linked object owns the current object

    Note:

    Some REST APIs for some WebCenter features may contain additional rel link attributes. See the REST API documentation for each specific feature for more information.

51.6.2.3 Capabilities

The capabilities link attribute indicates which methods are supported by the linked resource.

Links are returned only if a client is allowed to access that resource. User authorization can affect the capabilities a client has with the links returned in a response representation. In general, services only return the capabilities that the current authorized user has permission to execute and that the resource supports.

If there is no link, then the client cannot access the resource. If a link has no capabilities, then it is not returned to the client, meaning that the client does not have permission to do anything with that link (even read it).

Capability-based expression of hypermedia links communicates the range of operations that the client can expect to succeed, which allows the client to dynamically configure any associated UI to provide the best overall user experience.

The value of this attribute is a space-separated list of the following values:

  • urn:oracle:webcenter:create—This maps to the HTTP verb POST

  • urn:oracle:webcenter:read—This maps to the HTTP verb GET

  • urn:oracle:webcenter:update—This maps to the HTTP verb PUT

  • urn:oracle:webcenter:delete—This maps to the HTTP verb DELETE

Note:

The resourceIndex link only returns the read capability, even if the user is authorized with additional capabilities.

Note:

Querying a resource for the allowed HTTP verbs using OPTIONS returns the verbs that the resource can support in general, and does not take a user's access into account. The capabilities attribute in a link describes exactly what the current user can do with the current resource. OPTIONS may return more HTTP verbs than the current user is allowed.

51.6.2.4 Media Type

The type link attribute indicates the media types supported by the linked object.

All REST services, except for CMIS, support both XML (application/xml) and JSON (application/json) media type. CMIS currently supports only ATOM. For more information about CMIS REST APIs, see the Oracle Fusion Middleware Content Management REST Service Developer's Guide.

51.6.2.5 Templates

The template link attribute indicates that the client can use a URI template, instead of the href URI, to provide parameterized values for the linked object. Links must include at least an href or a template URI, but can include both.

Some hypermedia links support request query parameters that allow the client to configure the link in different ways. Rather than force the client to know the URI format and manually build the URI, URI templates are used. These templates allow client code to easily insert data into a URI without having to understand exactly how the URI works. This maintains the opacity of hypermedia URIs and protects the client from changes to the URI format.

Example 51-7 shows a URI template including several request query parameters.

Example 51-7 URI Template

http://host:port/.../lists?startIndex={startIndex}&itemsPerPage={itemsPerPage}&q={searchTerms}&projection={projection]

WebCenter REST APIs use a simple slot replacement syntax that follows many industry URI template schemes.

For example, using the template in Example 51-7, to see 10 list items on the first page, the client would provide a value of 1 for the startIndex parameter and a value of 10 for the itemsPerPage parameter, as shown in Example 51-8.

Example 51-8 URI Template with Parameter Values

http://host:port.../lists?startIndex=1&itemsPerPage=10

You must URL-encode special or reserved character in parameter values. For example, to search lists for a person named Günter, you must URL-encode the ü as shown in Example 51-9.

Example 51-9 Encoding Special Characters in URI Templates

http://host:port.../lists?q=G%FCnter

Note:

All unused parameters must be removed from a template before it can be used. Clients may not submit unprocessed templates to the service that produced it; doing so results in undefined behavior, generally returning a status code of 500.

Clients must process templates into valid URI form before submitting to the server. Clients must replace slots with appropriate values, taking care to properly URI encode any value replacing the slot token. If a client does not have a suitable value for one or more of the slots in the template, then it must replace the slot token with an empty string.

Common Request Query Parameters

Many resources support a common set of request query parameters. For example, when retrieving a collection of entities, it is common to change the shape of the results set by limiting the quantity or details of the results. The REST framework uses the following request parameters to scope results and provide security:

  • startIndex—Specifies the index of the first matching result that should be included in the result set (0-n ... zero based). This is used for pagination.

  • itemsPerPage—Specifies the maximum number of results to return in the response (1-n). This is used for pagination.

  • qSpecifies implementation-specific searching. Searches may be specified using the following format (square brackets [] denote optional values):

    [[field1:[operand]][:]value1[;field2:operand:value2]]
    

    For example:

    &q=login:equals:monty
    &q=title:contains:issues
    &q=creator:equals:monty;description:contains:Urgent
    

    While each resource uses the same format for the q parameter, the way search is implemented is different depending on the resource being searched. For more information about how each resource implements search, see the chapter for the specific service.

  • projectionReserved for implementation-specific projection of model representations, such as variable recursion depth, field or attribute filtering. Valid values are summary or details.

    For example, requesting a projection of summary for a collection of lists, returns only the title, description, and hypermedia links. Requesting a projection of details results in the server sending back a collection of lists that includes all the column metadata for each list. This may require additional processing time or database queries on the server.

    The following example request results in the response entity containing a deeper object graph.

    http://host:port/...lists&projection=details
    
  • data—Returns a comma separated list of data sets and items. This parameter lets clients specify what data they would like to receive. For example, a mobile device application might use this parameter to limit the amount of XML data returned. If both the projection and data query string parameters are present, the data parameter will be used to determine which data to return. If you specify the constant 'data' as the data parameter, all the basic information will be returned for the resource.

For information about how these parameters are supported by specific resources, see the chapter for the appropriate service.

51.7 Understanding Items Hypermedia

A collection of items makes up the actual content of responses. This is at the same level as the links section described previously. Each item (including the top-level tag in each response) has one common attribute (resourceType) in addition to resource-specific content and format. For details beyond the resourceType, see the chapter for the specific service.

See Example 51-13 for an example that describes a collection of entities/items. Example 51-15 describes a single entity/item.

51.8 Navigating Hypermedia Using HTTP

You can navigate REST service hypermedia in a similar way to that used to browse and interact with HTML or an ATOM feed. Interactions are performed on the resources identified by links using HTTP methods. The REST services return response codes and response bodies to the client, and the client uses the hypermedia in the response to drive further interactions.

Table 51-2 describes the general pattern followed when constructing opaque resource URIs. The resourceType differentiates whether the HTTP method operates on a collection of resources or an individual resource.

Table 51-2 HTTP Methods

HTTP Method Response for a Collection of Resources Response for an Individual Resource

GET

Returns resource collection container (200 HTTP response code)

Returns resource (200 HTTP response code)

PUT

Cannot update a collection of resources (405 HTTP response code)

Updates and returns resource (200 HTTP response code)

POST

Creates and returns a new resource within the collection.

Note: Can return a 201 or 204 HTTP response code. The returned code depends on whether the newly created object is directly addressable or not. For instance, activities cannot be addressed individually, so they return a 204 no-content response code.

Cannot create a resource within an individual resource (405 HTTP response code)

DELETE

Cannot delete a collection of resources (405 HTTP response code)

Deletes resource (204 HTTP response code)


Collection resources generally support reading a collection (GET) and creating a subordinate to that collection (POST). Individual resources generally support reading a resource (GET), updating a resource (PUT), and deleting a resource (DELETE).

HTTP Response Status Codes

Table 51-3 describes the potential response status codes.

Table 51-3 HTTP Response Status Codes

HTTP Response Status Code Description

200

OK. Upon successful completion of a GET or PUT. This is accompanied by a resource representation as a response body.

201

Created. Upon successful completion of a POST. This has a location header to the newly-created resource.

204

No content, or any request that does not return content. For example, creating an object that cannot be linked. Upon successful completion of a DELETE.

400

Bad Request. The URI was malformed or could not be processed; for example, the IDs were not formatted correctly, or the ID was supplied in the URI on a POST.

401

Unauthorized. Client may retry by submitting credentials. This may be accompanied with a fault response body to help diagnose the issue.

403

Forbidden. Client does not have permission to perform a particular action, such as creating or deleting a resource. Re-authenticating as the same user does not help. This may be accompanied with a fault response body to help diagnose the issue.

404

Not Found. Referencing a specific resource with an ID, but that resource does not exist.

405

Method Not Allowed. This includes a list of valid methods for the requested resource.

406

Not Acceptable. The Accept header media type(s) sent by the client are not supported for the requested operation.This may be accompanied with a fault response body to help diagnose the issue.

409

Conflict. Possibly the resource ID is in use, or an entity has been modified by another process during an update.This may be accompanied with a fault response body to help diagnose the issue.

422

Bad entity body, the data in the body, although syntactically correct, was not valid, or could not be processed; for example, invalid data when updating a row.

500

Internal server error. The server encountered an unexpected condition that prevented it from fulfilling the request.

501

Not Implemented. The server does not support the functionality required to fulfill the request. This is the appropriate response when the server does not recognize the request method and is not capable of supporting it for any resource.


51.9 Security Considerations for WebCenter REST APIs

All of the WebCenter REST URIs reference protected resources (similar to protected web pages) and require authentication for access.

Note:

The one exception to the authenticated access rule is access to the CMIS resources. CMIS resources can be accessed anonymously through the CMIS URI entry point:

http://host/port/rest/api/cmis/repository

See also Section 51.10, "Security Considerations for CMIS REST APIs."

You can pass this authentication in with the request using basic authentication, or you can configure the client and the WebCenter REST service to use single sign-on. For more information about single sign-on, see the section "Configuring a WebCenter Application to Use Single Sign-On" in the Oracle Fusion Middleware Administrator's Guide for Oracle WebCenter.

Basic authentication sends the user's password in plain text. If you use this type of authentication, you should consider securing the connection using SSL. For more information, see the section "Configuring WebCenter Applications and Components to Use SSL" in the Oracle Fusion Middleware Administrator's Guide for Oracle WebCenter.

To provide additional security, every URI, for both href and template attributes, includes a security token parameter. The security token is user-scoped. This means that it is based on and scoped to an authenticated user and can be bookmarked or cached across that user's sessions. These security tokens help prevent Cross-Site Request Forgery (CSRF) attacks.

For example:

<link
  template="opaque-template-uri/@me?startIndex={startIndex}&itemsPerPage={itemsPerPage}
     &token=generated-token" resourceType="urn:oracle:webcenter:messageBoard"
     href="opaque-uri/@me?token=generated-token" capabilities="urn:oracle:webcenter:read"
/>

Note:

The security token is not used for authentication or identity propagation.

WebCenter REST APIs operate under the identity of the authenticated user. For example, the group space REST APIs only return information for, and allow changes to, group spaces to which the user has access.

51.10 Security Considerations for CMIS REST APIs

The CMIS REST APIs do not use the same authentication scheme as the other WebCenter REST APIs. Whereas other WebCenter REST APIs do not allow unauthenticated access and prompt the user for authentication before allowing access, the CMIS REST APIs do allow unauthenticated access.

If a document requires authentication information and does not receive that information (because it is being accessed by an unauthenticated user), a 404 error is returned. This does not necessarily mean that the document cannot be found, rather that the (unauthenticated) user does not have the appropriate permissions to access the document. For the request to succeed, it should include basic authentication headers to identify the current user.

CMIS stands for Content Management Interoperability Services, a standard REST interface for Enterprise Content Management Systems. For more information, see Oracle Fusion Middleware Content Management REST Service Developer's Guide.

51.11 Understanding Common Types

This section describes the common types that are shared by multiple WebCenter REST APIs.

51.11.1 Common Types

Common types provide a consistent way to reference objects used in the WebCenter REST APIs.

This section includes the following subsections:

51.11.1.1 personReference

This is a generic data type that represents a user in the system. It is used by several APIs, for example to identify the author of a message board or feedback message, or a user's manager or direct reports. It is made up of the following elements:

  • guid—The GUID of the user

  • id—The login ID of the user

  • displayName—The display name of the user

The personReference also includes a link to the user's profile icon. You can control the size of the icon by providing values: small, medium, or large.

Depending on where the personReference type is included, it can also return links to the associated REST APIs of the generating response. For example, if the personReference type is included as the author in a message board response, it includes links to message board services.

51.11.1.2 groupSpaceReference

This is a generic data type that represents a group space. It is used by several APIs, for example in the activity stream, to identify a group space in which a particular activity occurred. It is made up on the following elements:

  • guid—The GUID of the group space

  • name—The name of the group space

  • displayName—The display name of the group space

The groupSpaceReference also includes an html link, rest link, and icon link.

51.11.2 Portable Contact Types

Portable Contact types provide users with a standard way to access their address books and friends lists over the web. Portable Contact types are used by the Profile component of the People Connections service.

Note:

These types are based on the Portal Contact Types in WebCenter. They may include additional data.

This section includes the following subsections:

51.11.2.1 name Portable Contact Type

This is a portable contact type that provides information about the user's name. It is made up of the following elements:

  • formatted—The formatted version of the full name of the user, for example, Michael David Jones Ph.D.

  • familyName—The family name, or last name, of the user, for example Jones

  • givenName—The given name, or first name, of the user, for example Michael

  • honorificSuffix—The honorific suffix of the user, for example, Esq. or Ph.D.

  • initials—The first initials of the user, for example, M. D.

  • maidenName—The maiden name of the user

Some of the elements may not be present depending on the user repository configuration and data.

51.11.2.2 address Portable Contact Type

This is a portable contact type that provides information about the user's address. It is made up of the following elements:

  • formatted—The formatted version of the full address

  • type—The type of the address, for example, Home, Work

  • streetAddress—The street address

  • poBox—The post office box number

  • locality—The city or locality

  • region—The state or region

  • postalCode—The zip code or postal code

  • country—The country

Some of the elements may not be present depending on the user repository configuration and data.

51.11.2.3 organization Portable Contact Type

This is a portable contact type that provides information about the user's organizational affiliation. It is made up of:

  • name—The name of the organization

  • employeeNumber—The employee number of the user

  • employeeType—The employee type of the user.

  • department—The department within the organization to which the user belongs

  • defaultGroup—The default group to which the user belongs

  • title—The job title of the user within the organization

  • description—A textual description of the user's role within the organization

  • expertise—The expertise of the user within the organization

  • startDate—The date when the user joined the organization

Some of the elements may not be present depending on the user repository configuration and data.

51.11.2.4 value Portable Contact Type

This is a generic object that contains data for a wide variety of contact information. It is made up of the following elements:

  • primary—A boolean value that identifies whether this is the primary piece of information of this type for this person. The primary element may not be present and is only relevant if there are multiple values for the same type of data.

  • value—The value for this type

  • type—The type of information. Valid types are:

    • standard: with valid values of work, home, other

    • phoneNumber: with valid values of work, home, fax, pager, mobile

    • photos: with a valid value of thumbnail

51.12 Managing Caches

Client-side developers need to know how to handle HTTP cache headers in both requests and responses. Individual resources that have a "last modified" date are also return entity tags. The entity tags can be used to make retrieval of a specific entity more efficient. To learn more about the use of entity tags in caching, please see the Hypertext Transfer Protocol specification.

51.13 Configuring a Proxy Server

A proxy server is typically employed to avoid cross-domain request problems associated with making XMLHttpRequest (XHR) calls from a browser client. These calls are typically associated with the Ajax development technique for creating rich, interactive client-side interfaces. REST APIs are typically used within this kind of client-side development scenario.

For more information on setting up a proxy server, see "Configuring a Proxy Server" in the Oracle Fusion Middleware Administrator's Guide for Oracle WebCenter.

51.14 WebCenter REST API Examples

This section includes some examples illustrating how to use the WebCenter REST APIs. It includes the following subsections:

51.14.1 Navigating the Message Board Hypermedia

This section includes examples to illustrate how to navigate the REST service hypermedia. The examples show how to read messages on a message board, post messages to another user's message board, and delete unwanted messages.

This section includes the following subsections:

51.14.1.1 Accessing the Resource Index

The first step is always to access the Resource Index (Example 51-10).

Example 51-10 Accessing the Resource Index

GET /resourceIndex

This request returns a list of the top-level URI entry points to the RESTful services, including the entry point for the message board (Example 51-11).

Example 51-11 Response to Accessing the Resource Index

200 OK
Accept: application/json;charset=UTF-8

{
  "resourceType": "urn:oracle:webcenter:resourceindex",
  "links": [
    {
      "resourceType": "urn:oracle:webcenter:resourceindex",
      "capabilities": "urn:oracle:webcenter:read",
      "rel": "self",
      "href": "http://host:port/rest/api/resourceIndex"
    },
    {
      "resourceType": "urn:oracle:webcenter:messageBoard",
      "capabilities": "urn:oracle:webcenter:read",
      "href": "opaque-messageBoard-URI"
    },
  ...repeating for other services...
}

You can examine this list to find the URI that you require to access your message board. You should look for the link with a resourceType of urn:oracle:webcenter:messageBoard. The href for this link is the one that you require to access your message board.

For other resources rel, type, and template also help find the correct link.

51.14.1.2 Reading Messages

Once you have determined the correct URI for your message board, you can send a GET request to that URI to read your messages (Example 51-12).

To read messages on a message board, you must be logged in.

Example 51-12 Retrieving Messages from Your Message Board (GET)

GET /opaque-messageBoard-URI
 

The response provides information about all the messages on your message board (Example 51-13).

Example 51-13 Response to Retrieving Messages from Your Message Board

200 OK
Accept: application/json;charset=UTF-8
 
{
  "resourceType": "urn:oracle:webcenter:messageBoard",
  "links": [
    {
      "resourceType": "urn:oracle:webcenter:messageBoard",
      "capabilities": "urn:oracle:webcenter:read urn:oracle:webcenter:create",
      "rel": "self",
      "href": "opaque-messageBoard-URI"
    }
  ]
  "items": [
    {
      "resourceType": "urn:oracle:webcenter:messageBoard:message",
      "links": [
        {
          "resourceType": "urn:oracle:webcenter:messageBoard:message",
          "capabilities": "urn:oracle:webcenter:read urn:oracle:webcenter:delete",
          "rel": "self",
          "href": "opaque-message-URI"
        }
      ]
      "id": "89add57c-7a35-4d35-b24f-ea9259612eb8",
      "body": "What's up?  It's been a while.  Some of us are going to Conner O'Neal's after work.  Want to go?",
      "created": "2009-09-10T11:18:46.696-0700",
      "author": {
        "id": "carl",
        "displayName": "carl",
        "guid": "649A27F09D5C11DEBFAA799CBD41D9B8",
        "links": [
          {
            "resourceType": "urn:oracle:webcenter:people:person",
            "capabilities": "urn:oracle:webcenter:read",
            "rel": "via",
            "href": "opaque-person-URI"
          },
          {
            "resourceType": "urn:oracle:webcenter:messageBoard",
            "capabilities": "urn:oracle:webcenter:read urn:oracle:webcenter:create",
            "href": "opaque-messageBoard-URI-for-Carl"
          },
          {
            "type": "text/html",
            "resourceType": "urn:oracle:webcenter:spaces:profile",
            "capabilities": "urn:oracle:webcenter:read",
            "rel": "alternate",
            "href": "opaque-profile-URI"
          }
        ]
      },
    }
  ],
  "startIndex": 0,
  "itemsPerPage": 1,
}

From the response you can see that you have read and create capabilities on your message board. So you can read its contents and post new messages.

In addition, the response also includes a collection of items (in this case the collection consists of just a single item). These items, with a resourceType of urn:oracle:webcenter:messageBoard:message, are the messages on your message board. The capabilities attribute for the message indicates that, for this particular message, you can read it or delete it from your message board.

For each message, the response provides the following information:

  • id—the identifier of the message

  • body—the text of the message

  • author—the author of the message. The author element is also made up of several other elements:

    • id—the identifier, or user name, of the author of the message

    • displayName—the name of the author, formatted for display

    • guid—the globally unique identifier of the author

Within the author element there is also a collection of three links. The resourceType of these links are:

  • urn:oracle:webcenter:people:person—enables you to view information about the author of the message

  • urn:oracle:webcenter:messageBoard—enables you to read or create a message on the author's message board

  • urn:oracle:webcenter:spaces:profile—enables you to read a text/html document of the author's profile

51.14.1.3 Creating a New Message

Now that you have read the message on your message board, you probably want to reply to Carl on his message board. To do this you should send a POST request to the URI for Carl's message board.

To find the correct URI, use the href from the author link with resourceType of urn:oracle:webcenter:messageBoard.

A POST request creates a subordinate resource of the resource to which you post it. In this case, we are posting to the messageBoard, so we should post its subordinate resource: message (Example 51-14).

Example 51-14 Creating a Message on Another User's Message Board (POST)

POST opaque-messageBoard-URI-for-Carl
Accept: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
 
{
    "body": "sure; see you guys at 6."
}

The response shows that your message was successfully created on Carl's message board (Example 51-15).

Example 51-15 Response to Creating a Message on Another User's Message Board

201 Created
Content-Type: application/json;charset=UTF-8
 
{ 
  "id": "36b8464f-afda-44b5-90ad-8ecedcb040a3", 
  "body": "sure; see you guys at 6.", 
  "created": "2009-09-10T12:21:09.785-0700", 
  "resourceType": "urn:oracle:webcenter:messageBoard:message", 
  "links": [ 
    { 
      "resourceType": "urn:oracle:webcenter:messageBoard:message", 
      "capabilities": "urn:oracle:webcenter:read urn:oracle:webcenter:update urn:oracle:webcenter:delete", 
      "rel": "self", 
      "href": "opaque-message-URI" 
    },
  "author": { 
    "id": "mike", 
    "displayName": "mike", 
    "guid": "649657609D5C11DEBFAA799CBD41D9B8", 
    "links": [ 
      { 
        "resourceType": "urn:oracle:webcenter:people:person", 
        "capabilities": "urn:oracle:webcenter:read", 
        "rel": "self", 
        "href": "opaque-person-URI" 
      }, 
      { 
        "resourceType": "urn:oracle:webcenter:messageBoard", 
        "capabilities": "urn:oracle:webcenter:read urn:oracle:webcenter:create", 
        "href": "opaque-messageBoard-URI" 
      }, 
      { 
        "type": "text/html", 
        "resourceType": "urn:oracle:webcenter:spaces:profile", 
        "capabilities": "urn:oracle:webcenter:read", 
        "rel": "alternate", 
        "href": "opaque:profile:URI" 
      } 
    ] 
  }
  ] 
}

51.14.1.4 Updating a Message

A PUT request is very similar to a POST request, except that it is performed on the resource being edited, instead of on the parent resource.

From the response to your earlier POST request, when you created your message on Carl's message board, you can see that you have read, update, and delete capabilities on the message. You can also see that the href provides the URI for your message. Something came up at work and you must stay a bit later. Using the URI for your message, you can now send a PUT request to update the message and let Carl know that you are going to be late (Example 51-16).

Example 51-16 Updating a Message (PUT)

PUT opaque:message:URI
Accept: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
 
{
    "body": "working late; see you guys at 7."
}

The response is nearly identical to that of POST, except that the body contains your updated message (Example 51-17).

Example 51-17 Updating a Message

200 OK
Content-Type: application/json;charset=UTF-8
 
{ 
  "id": "36b8464f-afda-44b5-90ad-8ecedcb040a3", 
  "body": "working late; see you guys at 7.", 

...deleted for brevity...

}

51.14.1.5 Deleting a Message

Performing a DELETE request on a resource deletes it, if you have the delete capability on the resource. The link to your message on Carl's message board supports delete.

You decide to delete the message that you left on Carl's message board (Example 51-18).

Example 51-18 Deleting a Message (DELETE)

DELETE opaque:message:URI

The response is simply a status code of 204 (Example 51-19).

Example 51-19 Response to Deleting a Message

204 NO CONTENT

Note:

DELETE is idempotent, meaning that it can be sent multiple times with the same result. Therefore if you try to delete the same object twice, you still receive the same 204 response even though it has previously been deleted.

51.14.2 Displaying Activity Stream Data

To properly display Activity Stream data, you must:

  • Retrieve the Activity Stream URI entry point

  • Retrieve the Activity Stream data

  • Process the Activity Stream data for display

More on OTN

This sample is available on the Oracle WebCenter Demonstrations and Samples page on the Oracle Technology Network (OTN) at:

http://www.oracle.com/technology/products/webcenter/release11_demos.html

In Example 51-20:

  • The getResourceURL method shows you how to retrieve the URI entry point for the Activity Stream service by retrieving the JSON data for the main Resource Index (/rest/api/resourceIndex) and locating the URI for the Activity Stream resource in that data.

  • The formatMessage method processes the Activity Stream data into a displayable format. This involves locating an individual message and replacing any template parameters in the message with the name of the object or user that corresponds to that parameter. The parameters also include links to display the object or user. They may contain links to REST services for those objects or users, if available.

Note:

To get the Resource Index and Activity Stream JSON data, make Ajax requests using Javascript (and possibly a client-side scripting library like Dojo) and pass the resulting data into the appropriate methods.

Example 51-20 Displaying Activity Stream Data

/* Parse the resourceIndex to find the specified URL and
 * return it.
 *
 * @Param jsonData the JSON data retrieved from calling
 *        the /rest/api/resourceIndex URL.
 * @Param strResourceType the resource type of the URL
 *        you want to retrieve from the resourceIndex data.
 *        E.g., 'urn:oracle:webcenter:activities:stream'
 */
function getResourceURL(jsonData, strResourceType)
{
  // Using the HATEOAS model, we browse the returned links
  // looking for the one with the correct resource type.

  for (var i = 0; i < data.links.length; i++) {
    if (data.links[i].resourceType == strResourceType) {
      return data.links[i].href;
    }
  }
}


/* Parse the resourceIndex to find the activity stream URL and
 * then load it.
 *
 * @Param jsonData the JSON data retrieved from calling
 *        the /rest/api/resourceIndex URL.
 */
function getActivitiesURL(jsonData)
{
  // Parse the JSON data to get the activities URI entry point.

  var strHref = getResourceURL(jsonData,
    'urn:oracle:webcenter:activities:stream');

  // INSERT CODE HERE: Implement getting the JSON data from the
  // strHref URL with the Accept header set to "application/json",
  // and use the formatMessage(index, jsonData) function to get
  // the displayable activity message for each activity.

}


/* Replace activity message parameters.
 *
 * @Param index the index of the activity to process
 * @Param jsonData the JSON data retrieved from calling
 *        the /rest/api/resourceIndex URL.
 */
function formatMessage(index, jsonData)
{
  var activity = jsonData.items[index];
  var strMessage = activity.message;

  // Look for activity parameters and replace them in the message.

  if (activity.templateParams && activity.templateParams.items) {
    for (var i = 0; i < activity.templateParams.items.length; i++) {
      var param = activity.templateParams.items[i];

      // Each parameter also has a set of links which at least
      // includes an HTML link and possibly a REST API link.

      strMessage = strMessage.replace(param.key, param.displayName);
    }
  }
  if (activity.detail) {
    strMessage = strMessage + "<br><font size='1'>" +
      activity.detail + "</font>";
  }
  return strMessage;
}

51.14.3 Using the WebCenter People Connections Service REST APIs with Ext

Ext is a popular JavaScript library for building tables and forms and linking them to REST web services. The following example illustrates how to display a list of connections from the People Connections service REST APIs using an Ext JsonStore and GridPanel.

For more information about Ext, see:

http://www.extjs.com/

Note:

You must run Ext on a web server. If that server is not your WebCenter instance, then you will run into cross-site scripting problems. If you cannot run the example on your WebCenter server, and you want to use Ext, then consider a proxy, such as Apache or WebCenter Ensemble.
More on OTN

This sample is available on the Oracle WebCenter Demonstrations and Samples page on the Oracle Technology Network (OTN) at:

http://www.oracle.com/technology/products/webcenter/release11_demos.html

This section includes the following subsections:

51.14.3.1 Creating the HTML Page

Example 51-21 shows the simple HTML page. The HTML page must reference the required Ext files and the JavaScript file, connections.js. The body of the page contains a destination div. The GridPanel is rendered in this div.

Example 51-21 The HTML Page

<head>
    <link rel="stylesheet" type="text/css" href="../../extjs/resources/css/ext-all.css" />
    <script type="text/javascript" src="../../extjs/adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="../../extjs/ext-all.js"></script>
    <script type="text/javascript" src="connections.js"></script>
</head>

<body>
    <div id="connections"></div>
</body>

51.14.3.2 Creating the JavaScript File

The JavaScript file, connections.js, enables the population of the list when the page loads. Example 51-22 shows that all of the JavaScript is a parameter to Ext.onReady().

Example 51-22 connections.js as a Parameter to Ext.onReady

Ext.onReady(function() {
        //our code goes here
});

The JavaScript does the following:

  1. First, it queries the Resource Index (Example 51-23).

    Notice that the example asks for responses in JSON format.

    Example 51-23 Querying the Resource Index

    //Connection Information
    var resourceIndexURL = "http://webcenter_server/rest/api/resourceIndex";
    var peopleServiceURN = "urn:oracle:webcenter:people";
    var connectionsURN = "urn:oracle:webcenter:people:person:list";
    var connectionsRel = "urn:oracle:webcenter:people:person:list:connections";
     
    //create a request for the resourceIndex
    Ext.Ajax.request({
            url: resourceIndexURL,
            method: 'GET',
            success: function(response, opts) {
                    //locate the people connections entry point
                    var index = Ext.decode(response.responseText);
                    for (x in index.links) {
                            if (index.links[x].resourceType == peopleServiceURN)
                                    getMe(index.links[x].href);
                    }
            },
            failure: function(response, opts) {
                 alert('Could not communicate with the REST server.');
               },
            headers: {
                    'Accept': 'application/json'
            },
    });
    
  2. Next, the JavaScript sends an authenticated request to the People Connections entry point, and gets the Connections list URL from the response (Example 51-24).

    By default, the REST API uses Basic authentication for secure APIs. In the example, credentials for passing to the Connections list URL are Base64 encoded. Ext does not have a Base64 utility object itself, but one has been developed for it at:

    http://extjs.com/forum/showthread.php?p=167166

    Example 51-24 Getting the Connections List URL

    function getMe(requestURL) {
            //Encode a token to identify yourself with secure parts of the REST API.
            var unencodedToken = "username" + ":" + "password";
            var encodedToken = "Basic " + Ext.util.base64.encode(unencodedToken);
     
            //call the connections entry point
            Ext.Ajax.request({
                    url: requestURL,
                    method: 'GET',
                    success: function(response, opts) {
                            //locate the link for my connections
                            if (index.links[x].resourceType == connectionsURN) {
                                    if (index.links[x].rel == connectionsRel)
                                            getMyConnections(index.links[x].href, encodedToken);
                            }
                    },
                    failure: function(response, opts) {
                            alert('Could not communicate with the REST server.');
                    },
                    headers: {
                            'Accept': 'application/json',
                            'Authorization' : encodedToken
                    },
            });
    }
    
  3. The next step is to send an authenticated request to the Connections list URL (Example 51-25).

    Example 51-25 Sending an Authenticated Request to the Connections List URL

    function getMyConnections(requestURL, encodedToken) {
            Ext.Ajax.request({
                    url: requestURL,
                    method: 'GET',
                    success: function(response, opts) {
                                    displayData(response, opts);
                       },
                    failure: function(response, opts) {
                         alert('Could not communicate with the REST server.');
                       },
                    headers: {
                            'Accept': 'application/json',
                            'Authorization' : encodedToken
                    },
            });
    }
    
  4. Then, the JavaScript adds the response to a JsonStore (Example 51-26).

    Previously, this example named displayData() as the handler for a successful call to the Connections list URL. Now, it creates the function and adds the JsonStore code. In the JsonStore, the data model for the data is defined and mapped to results expected from the REST call.

    Example 51-26 Adding the Response to a JsonStore

    function displayData(response, opts) {
            //create a datamodel to display the JSON
            var store = new Ext.data.JsonStore({
                    // store configs
                    autoDestroy: true,
                    storeId: 'forumStore',
                    // reader configs
                    root: 'items',
                    idProperty: 'id',
                    fields: ['displayName', {name:'email', mapping:'emails.value'},
                             {name:'phone', mapping:'phoneNumbers[0].value'}]
            });
    }
    
  5. The JavaScript creates an Ext GridPanel to display the JsonStore by including the code in Example 51-27 in displayData().

    The grid defines columns and a title. It also includes other display options, such as the size of the table.

    Example 51-27 Creating a GridPanel to Display the JsonStore

    //create the Grid
    var grid = new Ext.grid.GridPanel({
        store: store,
        columns: [
            {id: 'conn', header: 'Connection', width: 80, sortable: true, dataIndex: 'displayName'},
            {header: 'Email', width: 120, sortable: true, dataIndex: 'email'},
            {id: 'phone', header: 'Phone', width: 120, sortable: true, dataIndex: 'phone'}
        ],
        stripeRows: true,
        autoExpandColumn: 'conn',
        height: 200,
        width: 400,
        title: 'My Connections',
        viewConfig: {scrollOffset: 2}
    });
    
  6. Finally, the code renders the GridPanel by including the line in Example 51-28 in displayData().

    Example 51-28 Rendering the GridPanel

    grid.render('connections');
    

51.14.3.3 The Result

Figure 51-1 shows the list of connections from the People Connections service REST APIs.

Figure 51-1 The Connections List

The Connections list resulting from the code in the example
Description of "Figure 51-1 The Connections List"

51.14.4 Updating User Status

The following example shows how to use REST APIs to update a user's WebCenter profile status.

Note:

You must host the sample on a web server (for example, Apache or Oracle HTTP Server) or an application server. To avoid cross site scripting errors, you should proxy URL access to the REST service. On Apache or OHS, the conf commands would look like (change myspaceshost and port accordingly):
ProxyPass /webcenter/ http://myspaceshost:port/webcenter/
ProxyPassReverse /webcenter/ http://myspaceshost:port/webcenter/
ProxyPass /rest/ http://myspaceshost:port/rest/
ProxyPassReverse /rest/ http://myspaceshost:port/rest/
ProxyPreserveHost on
More on OTN

This sample is available on the Oracle WebCenter Demonstrations and Samples page on the Oracle Technology Network (OTN) at:

http://www.oracle.com/technology/products/webcenter/release11_demos.html

Updating user status involves making a sequence of asynchronous AJAX calls to get the URL for the status object:

urn:oracle:webcenter:resourceindex
   urn:oracle:webcenter:people
      urn:oracle:webcenter:people:person:status

The HTML page for updating user status (Example 51-29) includes an input field where users can enter the new status message (statusMessage). Clicking the Update Status button (or pressing Enter) calls the updateStatus method to make the initial call to the Resource Index.

Example 51-29 HTML Body

<body>
<div>New status message:&nbsp;<input id="statusMessage" type="text"
   onkeyup="{if (event.keyCode==13) updateStatus();}" maxlength="250"
   size="60" /></div>
<div>
<button id="button1" onclick="updateStatus();">Update Status</button>
</div>
<div id="statusResults"></div>
</body>

Figure 51-2 shows the HTML page.

Figure 51-2 New Status Message HTML Page

HTML page for entering new status

The code in Example 51-30 retrieves the Resource Index (resourceIndexURL variable set to /rest/api/resourceIndex). The Resource Index is returned as an AJAX request object (resourceIndexRequest).

Example 51-30 Retrieving the Resource Index

function updateStatus() {
   // Set the UI to busy state. This is cleared in the success and error callbacks
   setUIBusy("Updating status...");
   //get the Resource Index
   resourceIndexRequest.get(
      resourceIndexURL,
      resourceIndexCallback,
      clearUIBusy);
}

The getResourceURL method shown in Example 51-31 traverses the links in the data returned by a REST call to find a specified string (URN) that identifies the required resource type.

Example 51-31 Traversing the Links

function getResourceURL(data, strResourceType) {
   for (var i = 0; i < data.links.length; i++) {
      if (data.links[i].resourceType == strResourceType) {
         return data.links[i].href;
      }
   }
   return null;
}

Example 51-32 uses getResourceURL to parse the Resource Index to find the user profile URL. The data is returned as an AJAX request object (profileRequest).

Example 51-32 Retrieving the User Profile

function resourceIndexCallback(data) {
   //get my user profile
   profileRequest.get(
      getResourceURL(data, 'urn:oracle:webcenter:people'),
      profileCallback,
      clearUIBusy);
}

Example 51-33 takes the new status message provided by the user in the HTML page (statusMessage) and uses request.put to update the status object (retrieved by again calling getResourceURL).

Example 51-33 Retrieving the Status Object

function profileCallback(data) {
   profile = data;
   // get the URL for the status object
   var url = getResourceURL(data, 'urn:oracle:webcenter:people:person:status');
   // get the new status and escape double quotes
   var newStatus = document.getElementById
      ('statusMessage').value.replace(/\"/g. "\\\"");
   //send a JSON string representing the new status object
   var statusMessage = '{"note": "' + newStatus + '"}';
   statusRequest.put(
      getResourceURL(data, 'urn:oracle:webcenter:people:person:status'),
         statusMessage, renderStatusPutResults, clearUIBusy);
}

The renderStatusPutResults method, shown in Example 51-34, renders the new status object.

Example 51-34 Rendering the New Status Object

function renderStatusPutResults(data) {
   var name = profile.displayName;
   // get the URL for my profile HTML page in WebCenter Spaces
   var profileURL = getResourceURL(profile,
      'urn:oracle:webcenter:spaces:profile');
   var html = 'Status for <a href="' + profileURL + '" target="_blank">'
      + name + '</a> is: ' + data.note;
   // clear the UI busy state and print the new status message
   clearUIBusy(html);
}

Example 51-35 shows the code for disabling and reenabling the UI.

Example 51-35 Disabling the UI

function setUIBusy(message) {
   document.getElementById('statusResults').innerHTML = message;
   document.getElementById('button1').disabled = true;
   document.getElementById('statusMessage').disabled = true;
}

function clearUIBusy(message) {
   document.getElementById('statusResults').innerHTML = message;
   document.getElementById('button1').disabled = false;
   document.getElementById('statusMessage').disabled = false;
}

Example 51-36 shows the library that assists in AJAX calls. Most of this is not WebCenter specific and works for any XHR requests to a service that returns JSON.

The library includes a reusable XHR object. This object supports HTTP GET, POST, PUT, and DELETE. All functions are asynchronous and take a URL and two callback functions, one for success, and one for failure. Success calls are made with a JavaScript object containing the return data. Failure calls are made with an error string. POST and PUT also take a data argument which must be a JSON string.

Example 51-36 AJAX Library

function AjaxRequest() {
   // constructor to create an object oriented AJAX request
   var xhr = null;

   // get XHR object. Should work for IE 6+, Safari, and Mozilla based browsers
   if (window.XMLHttpRequest) {
      xhr = new window.XMLHTTPRequest;
   } else {
      try {
         xhr = new ActiveXObject('MSXML2.XMLHTTP.3.0');
      } catch (ex) {
         xhr = null;
      }
   }
   if (xhr == null) {
      alert("Your browser does not support AJAX");
   }

   this.get = function(url, callback, errorCallback) {
      xhr.open('GET', url, true);
      // the REST APIs return XML by default. Please return JSON
      xhr.setRequestHeader('Accept', 'application/json; charset=utf-8');
      sendRequest(null, callback, errorCallback);
   };

   this.post = function(url, data, callback, errorCallback) {
      xhr.open('POST', url, true);
      // set headers to send and receive JSON
      xhr.setRequestHeader('Accept', 'application/json; charset=utf-8');
      xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
      sendRequest(data, callback, errorCallback);
   };

   this.put = function(url, data, callback, errorCallback) {
      xhr.open('PUT', url, true);
      // set headesr to send and receive JSON
      xhr.setRequestHeader('Accept', 'application/json; charset=utf-8');
      xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
      sendRequest(data, callback, errorCallback);
   };

   this.deleteResource = function(url, callback, errorCallback) {
      xhr.open('DELETE', url, true);
      sendRequest(null, callback, errorCallback);
   };

   // set the callbacks and send the request with data, if any
   function sendRequest(data, callback, errorCallback) {
      xhr.onreadystatechange = function () {
         processResponse(xhr, callback, errorCallback);
      };
      xhr.send(data);
   }

   function processResponse(xhr, callback, errorCallback) {
      var data = null;
      // can get called here many times. 4 means really done
      if (xhr.readyState == 4) {
         // let's call any HTTP codes in the 200s success
         if (xhr.status >= 200 && xhr.status <300) {
            // convert response text into a JSON object. This is insecure.
            // data should not be blindly evaluated from the server return.
            // consider using json2.js http://www.JSON.org/js.html
            data = eval('(' + xhr.responseText + ')');
            callback(data);
         } else {
            // we got an error. Format an error string
            data = 'Error: ' + xhr.status + ' ' + xhr.statusText + '<br />'
               + xhr.responseText;
            errorCallback(data);
         }
      }
   }
}