48 Developing Applications with WEM Framework
You can explore the Articles sample application to understand the basic architecture of an application that makes REST calls.
For information about developing applications with the WEM framework, see these topics:
About the Articles Sample Application's Structure
In the source directory for the Articles sample application, you will see source files, logger file, installer resources, home page files, and configuration files.
The following figure shows the source structure of the Articles sample application. On deployment, the following directories are copied from source to target: The contents of the lib
directory are copied to /WEB-INF/lib/
. The contents of the resources
directory are copied to /WEB-INF/classes/
.
Figure 48-1 Articles Sample Application Source Structure
![Description of Figure 48-1 follows Description of Figure 48-1 follows](img/sampleapp.jpg)
Description of "Figure 48-1 Articles Sample Application Source Structure"
Articles is a Java Web application developed on Spring MVC. The following pages are available:
-
/install.app
is the Articles installation page, which also displays a confirmation message when the application is successfully installed. -
/home.app
is the home page of the Articles application.
About the Articles Sample Application's Configuration Files
The Articles sample application’s configuration files are applicationContext.xml
and spring-servlet.xml
.
-
applicationContext.xml
(in/WEB-INF/
) holds SSO and application-specific configurations (such as a predefined user and the site on which to enable the data model and assets). -
spring-servlet.xml
(in/WEB-INF/
) is the default Spring configuration file. This file stores the Spring configuration and references the following controllers (described in Source Files):-
HomeController
-
InstallController
-
LayoutController
-
ProxyController
-
loggingconfig.xml
(in/<sitesshared>/config
) is the logging configuration file. On application deployment, it is copied from/<sitesshared>/config
towebcentersites\sites-home\template\config
.
-
Source Files
/sample app/articles/src/main/java/
The /sample/
folder contains the source files listed below:
-
Configuration.java
is populated (by the Spring framework) from theapplicationContext.xml
file. -
HomeController.java
is the home page controller, which renders a single home page. This controller reads the list of sample articles from the WebCenter Sites platform using the REST API and displays them on the home page.The sample articles consist of images and text, stored in
/sample app/articles/src/main/resources/install
. The sample articles are installed in the WebCenter Sites database byInstallController.java
. -
InstallController.java
registers the Articles application, and writes the application's asset model and sample assets to the database. -
LayoutController.java
displays the application's layout page (layout.app
) used by the WEM UI framework.LayoutController.java
is also used during the application registration procedure. -
ProxyController.java
delegates AJAX requests to the WebCenter Sites REST servlet. -
TldUtil.java
utility class contains TLD function implementations.
Installer Resources
/sample app/articles/src/main/resources/install
The /install/
folder contains the following resources, used by the InstallController
to construct the home page (Figure 48-3):
-
strategies.png
-
strategies.txt
-
tips.png
-
tips.txt
Home Page Files
/sample app/articles/src/main/webapp/images
The /images/
folder contains:
-
articles.png
icon (Figure 48-2), which represents the Articles application in the applications bar -
In Figure 48-3:
-
edit.png
is the icon for the Edit function -
save.png
is the icon for the Save function -
cancel.png
is the icon for the Cancel function
-
Scripts
/sample app/articles/src/main/webapp/scripts
The /scripts/
folder contains the json2.js
utility script, used to convert strings to and from JSON objects.
Styles
/sample app/articles/src/main/webapp/styles
The /styles/
folder contains main.css
, which specifies CSS styles used by this Web application.
Views
/sample app/articles/src/main/WEB-INF/jsp
The /jsp/
folder contains:
-
home.jsp
, which is used to render the home page view of the Articles application (Figure 48-3). -
layout.jsp
, which defines the application layout.
WEB-INF
/sample app/articles/src/main/WEB-INF
The /WEB-INF/
folder contains:
-
articles.tld
, the TLD declaration file -
spring-servlet.xml
, the Spring configuration file -
web.xml
, the Web application deployment descriptor
Making REST Calls
WebCenter Sites REST resources support two types of input and output formats: XML and JSON. If you would like to get specific return formats, use HTTP headers that specify the MIME type application/xml
or application/json
.
For example, when specifying input format to be XML, set Content-Type
to application/xml
. When specifying the output format, set Accept
(the expected format) to application/xml
. If other output formats are specified, they are ignored. The default is XML
, if not specified in Content-Type
or Accept
(for sample code, see Making REST Calls from JavaScript).
Topics:
Making REST Calls from JavaScript
-
Use the following code (in
home.jsp
) to perform AJAX calls to the asset REST services to save asset data. Note that the request is actually performed to the proxy controller which redirects the request to the destination REST service.Note:
We use the JSON stringify library to serialize a JavaScript object as a string. It is much more convenient to write JSON objects instead of strings.
// Form the URL pointing to the asset service // to the proxy controller, which will redirect this request to the CS REST servlet. var idarr = assetId.split(":"); var assetUrl = "${pageContext.request.contextPath}/REST/sites/${config.csSiteName}/types/" + idarr[0] + "/assets/" + idarr[1]; // For the data object to be posted. var data = { "attribute" : [ { "name" : "source", "data" : { "stringValue" : document.getElementById("source_e_" + assetId).value } }, { "name" : "cat", "data" : { "stringValue" : document.getElementById("cat_e_" + assetId).value } } ], "name" : document.getElementById("name_e_" + assetId).value, "description" : document.getElementById("desc_e_" + assetId).value, // This should be removed. "publist" : "${config.csSiteName}" }; // Convert JSON data to string. var strdata = JSON.stringify(data); // Perform AJAX request. var req = getXmlHttpObject(); req.onreadystatechange = function () { if (req.readyState == 4) { if (req.status == 200) { // On successful result // update the view controls with new values and switch the mode to 'view'. for (c in controls) { document.getElementById(controls[c] + "_v_" + assetId).innerHTML = document.getElementById(controls[c] + "_e_" + assetId).value; } switchMode(assetId, false); } else { // Error happened or the session timed out, // reload the current page to re-acquire the session. alert("Failed to call " + assetUrl + ", " + req.status + " " + req.statusText); window.location.reload( false ); } } }; // We put Content-Type and Accept headers // to tell CS REST API which format we are posting // and which one we are expecting to get. req.open("POST", assetUrl, true); req.setRequestHeader("Content-Type", "application/json;charset=utf-8"); req.setRequestHeader("Content-Length", strdata.length); req.setRequestHeader("Accept", "application/json"); req.send(strdata); }
Making REST Calls from Java
-
Use the code below (in
HomeController.java
) to call the assets search service to list all assets of typeFW_Article
. The code uses the Jersey Client library passing objects from therest-api-<version>.jar
library provided by the WEM Framework. This leverages strong typing in Java.It is important to note that a token must be acquired from Java code by calling the
SSOAssertion.get().createToken()
method. It is unnecessary to do so in JavaScript as that side is authenticated against WEM SSO.// Use Jersey client to query CS assets. Client client = Client.create(); String url = config.getRestUrl() + "/types/FW_Article/search"; WebResource res = client.resource( url ); // Construct URL and add token (for authentication purposes) // and fields (specify which fields to retrieve back) parameters. res = res.queryParam("fields", URLEncoder.encode("name,description,content,cat,source", "UTF-8")); res = res.queryParam("ticket", SSO.getSSOSession().getTicket(res.getURI().toString(), config.getCsUsername(), config.getCsPassword())); // Put Pragma: auth-redirect=false to avoid redirects to the CAS login page. Builder bld = res.header("Pragma", "auth-redirect=false"); // Make a network call. AssetsBean assets = bld.get(AssetsBean.class);
Note:
The custom
Pragma: auth-redirect=false
header instructs the CAS SSO filter not to redirect to the CAS sign-in page, but to return a 403 error instead, when no ticket is supplied or the supplied ticket is invalid.
Constructing URLs to Serve Binary Data
For the Articles application, you can leverage the Blob server in WebCenter Sites to serve BLOB data. You can use the getBlobUrl
function to construct a URL pointing to the binary data for a given attribute in a given asset.
-
blobUrl
points to the Blob server (http://localhost:8080/cs/BlobServer
by default.public String getBlobUrl(String assetType, String assetId, String attrName, String contentType) throws Exception { String contentTypeEnc = URLEncoder.encode(contentType, "UTF-8"); return blobUrl + "?" + "blobkey=id" + "&blobnocache=true" + "&blobcol=thumbnail" + "&blobwhere=" + assetId + "&blobtable=" + assetType + "&blobheader=" + contentTypeEnc + "&blobheadername1=content-type" + "&blobheadervalue1=" + contentTypeEnc; }
-
Alternatively, to get binary data, load an asset using the resource
/sites/{sitename}/types/{assettype}/assets/{id}
. When loaded, the asset contains the URL pointing to the BLOB server.
Accessing Parameters from the WEM Framework
With the WemContext
JavaScript Context object, you can empower applications to find out which user has logged in to which site. You can also enable applications to share data.
The UI container provides a JavaScript Context object (WemContext
) to all applications inside the container. The Context object is used by the applications to get details from the WEM Framework about the logged-in user and site (typically, to get the current site's name from the UI container). The Context object also provides various utility methods that the applications use to share data. The Context Object can be used by applications running in the same domain as WebCenter Sites or in different domains.
Note:
The wemcontext.html
file lists the exposed methods, summarized in Methods Available in Context Object.
Topics:
Initializing and Using Context Object in the Same Domain
To initialize and use Context Object for applications in the WebCenter Sites domain:
- Include
wemcontext.js
. - Retrieve an instance of the
WemContext
object. - Use the methods of
WemContext
.
<script src='http://<csinstalldomain>/<contextpath>/wemresources/js/WemContext.js'></script> <script type="text/javascript"> var wemContext = WemContext.getInstance(); // Instantiate Context Object var siteName = wemContext.getSiteName(); // Get Site Name var userName = wemContext.getUserName(); // Get UserName </script>
Initializing and Using Context Object for Cross-Domain Applications
To initialize and use Context Object for cross-domain applications:
<script type="text/javascript" src="../js/wemxdm.js"></script> <script type="text/javascript"> // Request the use of the JSON object WemXDM.ImportJSON("../js/json2.js"); var remote; window.onload = function() { // When the window is finished loading start setting up the interface remote = WemXDM.Interface(/** The channel configuration */ { // Register the url to hash.html. local: "../hash.html", // Register the url to the remote interface remote: "http://localhost:8080/cs/wemresources/wemcontext.html" }, /** The interface configuration */ { remote: { getSiteName :{}, ... } },/**The onReady handler*/ function(){ // This function will be loaded as soon as the page is loaded populateAttributes(); }); } </script> <script type="text/javascript"> /** Define local methods for accessing remote methods */ function getSiteName(){ remote.getSiteName(function(result){ alert("result = " + result); }); } ... </script>
Methods Available in Context Object
The following table lists and describes the methods available in Context Object.
Table 48-1 Methods Available in Context Object
Return Type | Method name and Description |
---|---|
|
Returns attribute value for the given attribute name. |
|
Returns all the attribute names. |
|
Returns cookie value for the given name. It has all restrictions of the normal browser cookie. |
|
Returns all the cookies. |
|
Returns locale. |
|
Returns the site ID. |
|
Returns the site name. |
|
Returns user object. |
|
Returns user name. |
|
Removes cookie. |
|
Sets attribute. These attributes can be accessed in other applications. |
|
Sets the cookie. |
Registering Applications with Different Views
In WEM Framework, when you register an application to expose it, an asset of type FW_Application
and another of type FW_View
are created for each view associated with the application. These asset types are enabled on AdminSite.
Their attributes are defined in the Java API Reference for Oracle WebCenter Sites. Programmatic registration is the preferred method. For an example of manual registration, see Registering Applications Manually in WEM Framework.
Topics:
Registering Applications with an iframe View
The section uses code from the Articles sample application to illustrate the registration process. Articles has a single view of type iframe. The same steps apply to JavaScript and HTML views.
To register an application:
Registering Applications with JavaScript and HTML Views
For applications that use HTML and JavaScript views, follow the steps in Registering Applications with an iframe View, but use the sample code and attributes listed in the following sections:
Rendering JavaScript View
Note:
JavaScript specified in the view is rendered (executed) when the application is rendered. Ensure the JavaScript does not conflict with other views.
Sample code:
window.onload = function () { if (GBrowserIsCompatible()) { var map = new GMap2(document.getElementById("map_canvas")); map.setCenter(new GLatLng(37.4419, -122.1419), 13); map.setUIToDefault(); } }
-
Rendering the JavaScript view from a source URL
Set the following attributes:
-
name
: Name of the view -
parentnode
: ID of the placeholder element (from step 2 in Registering Applications with an iframe View) -
viewtype
:fw.wem.framework.ScriptRenderer
, which renders JavaScript into the placeholder element -
sourceurl
: Path of the.js
file, which provides content for the view. For example:http://example.com:8080/js/drawTree.js
-
-
Rendering the JavaScript view from source code
Set the following attributes:
-
name
: Name of the view -
parentnode
: ID of the placeholder element (from step 2 in Registering Applications with an iframe View) -
viewtype
:fw.wem.framework.ScriptRenderer
, which renders JavaScript into the placeholder element -
javascriptcontent
: JavaScript code (sample provided above). The code must not contain<script>
tags.
-
Rendering HTML View
Note:
HTML specified in the view is rendered (executed) when the application is rendered.
Sample code:
<object width="480" height="385"> <param name="movie" value="http://www.localhost:8080/jspx/flash_slider_main.swf"></param> <param name="allowFullScreen" value="true"></param> <embed src=" http://www.localhost:8080/jspx/flash_slider_main.swf" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"> </embed> </object>
-
Rendering the HTML view from a source URL
Set the following attributes:
-
name
: Name of the view -
parentnode
: ID of the placeholder element (from step 2 in Registering Applications with an iframe View) -
viewtype
:fw.wem.framework.IncludeRenderer
, which renders JavaScript into the placeholder element -
sourceurl
: Path to the HTML file that provides content for the view. For example:http://example.com:8080/js/drawTree.jsp
.
-
-
Rendering the HTML view from source code
Set the following attributes:
-
view
: Name of the view -
parentnode
: ID of the placeholder element (from step 2 in Registering Applications with an iframe View) -
viewtype
:fw.wem.framework.IncludeRenderer
, which renders JavaScript into the placeholder element -
includecontent
: HTML content (sample provided above. The code must not contain<html
> or<body>
tags.
-