Getting Started A Developer Setting Up a Clean System

This tutorial lists all the steps for setting up a a clean system for developing applications with the Adobe Digital Enterprise Platform (ADEP).

If you are new to ADEP and would like to watch a few introduction videos on how to install the Platform and get stated, please check out the “Getting Started” Playlist on our YouTube channel:

http://www.youtube.com/user/ADEPDevelopers#grid/user/E09E3EA550109D45

Prerequisites

A clean Windows system that meets the minimum platform requirements

  1. Sun JDK 6 update 24 or higher
  2. The ADEP Experience Server .jar file
  3. Flash Builder 4.5.0 Installer

Also the following:

  1. ADEP Tooling update site URL (You will find this pre-configured now in Flash Builder)
  2. A valid Flash Builder 4.5.0 serial number
  3. A valid ADEP Experience Server license file (*Note: this tutorial does not cover the license file acquisition process. To initiate the process a user can click the ‘Obtain a license’ presented on the startup screen)

Cheet Sheat

Please read the document here for a step by step cheat sheet on creating your application from scratch in Flash Builder:

Setting Up A Clean System

HelloADEPApplicationUI

HelloADEPApplicationUI

 

 

 

 

 

 

 

 

You may already have existing Flex applications that you would like to run on the Experience Server. If so, check out this demonstration for how to change your Flex Project settings:

Submit a file using POST request in CRX

This simple example shows how we can submit a file using a POST request to a JSP from an html form. I used CRXDE for creating the project.

Create a new project in CRXDE by right clicking on the Project Navigator page and selecting Build->Create Project. Give a project name and the package name that you will be using. I will be using simplePOSTRequest as the project name.

  • A new folder is created under apps with the name simplePOSTRequest. In CRXDE Lite you will find under the content node that a new node is created with the name “simplePOSTRequest”. On the node the slingResourceType property is set which points to simplePOSTRequest/components/sample.
  • In simplePOSTRequest/components/sample, under the apps folder you will find a components folder with html.jsp page already created. This is the page that is invoked when you go to http://localhost:7402/simplePOSTRequest.html.

Now modify the html page and add a simple html form which takes a file as in input and has a submit button.  Save the project.

Now, go to http://localhost:7402/simplePOSTRequest.html and select a file and click upload. You will get a 200 OK status message which means that the request was successful (See image below).

We did not have any POST request handling logic at this point, so where did the file go? If you go to CRXDE Lite, you will see under the simplePOSTRequest node in content node that a new node is created. The name of the node is the name we specified for the File input type in the html form.

If we want to create a JSP file and want the POST request to be redirected to that JSP create a POST.jsp file under apps/simplePOSTRequest/components/sample.

Now if you click the upload button, you will see the new page will be invoked and no nodes will be created in the crx. You can access the form data from the HttpServletRequest or SlingHttpServletRequest object in POST.jsp.

Here is the POST.jsp that displays the submitted file details. (Click to enlarge)

 

“Getting Started” – A Developer In the Box!

The core of our new Adobe Digital Enterprise Platform comes in a very small box (you could probably email the entire server to yourself as an attachment!) but we managed to squeeze in an important element. When you launch the Quick Start there is a rather unremarkable little link in the top right hand corner called, “Getting Started“. Click it and we bring you to a whole set of running applications with developer tutorials and sample code.

You don’t need to wade through lots of documentation when trying to build your first application. Just fire up the samples, see applications running right away, download the source code, follow the tutorials and you’ll be an ADEP expert in no time!

Here is what you see when you select “Getting Started”:

(Click to enlarge)

These links are split into two groups. The first is a set of “Spotlights”. They show you some basics of what the platform can do to help you build great web applications and they link to this blog for more details. The second group is a more in-depth set of sample applications that use multiple frameworks together; such as Composite Applications, Data Services, CRX and Task Management. They run out of box and come with tutorials that show you how to recreate the application yourself with sample code.

Furthermore if you need even more samples and code we have a handy link in Package Share that will download lots of deep dive (and running!) applications for Data Services and the Composite Application Framework. Once you download the Package it automatically adds more links to the page above.

Our objective is to help you learn our platform in a way that is “by developers for developers“. Our core engineering team (in between fixing bugs!) produces all of this content and the articles on this blog. We can’t wait to see what you build with the Adobe Digital Enterprise Platform.

Using REST To Access CRX Content in Flex

When building a Flex application that reads content from a CRX Repository, RESTful HTTP requests are an ideal pattern for reading both meta data that describes your content as well as the raw content bytes.

In this example we look at:

  1. Writing Flex application can browse and display many different types of content (images, documents etc) read from CRX using REST.
  2. After reading the actual content, how to display it in your Flex application using one of many new “UX Components” provided in the SDK for the Adobe Digital Enterprise Platform.

Consider a typical “master / detail” tree view application where the user browses and displays content:

(click to enlarge)

Let’s look at how such an application is built.

First the init() method used when the app starts up:


private function init():void 
{ 
    //Read CRX first time and load nodes 
     NodeService.execute(hostRoot, classificationsLoaded, loadFailed);
    classTree.dataDescriptor=new NodeDataDescriptor(); 
}

The “NodeService” Class above is used to make an HTTP Request to CRX to get back a list of content nodes


public class NodeService 
{
    public static function execute(
        path:String, resultHandler:Function, faultHandler:Function):void 
    { 
        var httpService:HTTPService = new HTTPService(); 
        httpService.url = path + ".2.json"; 
        httpService.method = HTTPRequestMessage.GET_METHOD;
        httpService.resultFormat = "text"; 
        httpService.addEventListener( ResultEvent.RESULT, resultHandler ); 
        httpService.addEventListener( FaultEvent.FAULT, faultHandler ); httpService.send(); 
    } 
} 

Next the JSON response is decoded into an array collection used for the nodes to be displayed in the tree. Each node will contain the properties (name, content type etc) of the node as well as a URL pointer to its content stream.


private function classificationsLoaded(e:ResultEvent):void 
{
    var resultStr:String = new String(e.message.body); 
    var jsondecoder:JSONDecoder = new JSONDecoder();
     var data:ObjectProxy = jsondecoder.decode(resultStr); 
    var tmpArr:Array = []; 
    var patternExclude:RegExp = /(sling:|jcr:|cq:)/i; 
    var patternInclude:RegExp = /(sling:Folder)/i; 
    for (var p:String in data) { 
        if(p.search(patternInclude)>0 || p.search(patternExclude)<0) { 
            var tmpObj:CustomNode = new CustomNode(); 
            tmpObj.name = p; mpObj.path = hostRoot + "/" + p; tmpObj.parent = null; 
            if(data[p] is ObjectProxy) tmpObj.hasChildren = containsChildren(data[p]); else
                tmpObj.hasChildren = false; tmpArr.push(tmpObj); 
         } 
    } 
    ac = new ArrayCollection(tmpArr); 

Finally a click handler for each node in the tree uses the node properties to supply data to a “UX Component” which can render the content within a boundary area in the Flex application. In this case either display the content or just display more tree nodes if the selected node is not a leaf node.

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:xoawv="com.adobe.ep.ux.webdocumentviewer.domain.*"
    ...

private function onItemClick(e:ListEvent): void {
    var tmpObj:CustomNode = classTree.selectedItem as CustomNode;
    if(!tmpObj.hasChildren){
        viewer.unload();
        viewer.url = tmpObj.path;
        viewer.contentType = "text/plain";
        viewer.loadDocument();
        }else {
            if (tmpObj) {
                if (!tmpObj.childrenLoaded) {
                    tmpObj.loadChildren();
                    tmpObj.addEventListener(
                      CustomNode.CHILDREN_LOADED, onItemChildrenLoaded);
                }
            }
        }
     } } ... <mx:HBox width="100%" height="100%" backgroundColor="#FFFFFF">
    <s:Panel width="20%" height="100%" title="CRX Structure">
        <mx:Tree id="classTree" dataProvider="{ac}" width="100%" height="100%"
            itemOpen="onItemOpen(event)" itemClick="onItemClick(event)" />
    </s:Panel>
        <mx:VBox  width="80%" height="100%" >
        <s:Panel width="100%" height="100%" title="Document Viewer">
        <xoawv:WebDocumentViewer id="viewer" width="100%" height="100%" />
    </s:Panel>
<mx:HBox width="100%">

Introducing the Composite Application Framework

Web and Mobile applications built using the Adobe Digital Enterprise Platform permit modular development of a user interface, such that you can compose an application out of multiple individual components (could be HTML or Flash based).

The “Composite Application Framework” lets you assemble your application by hosting its constituent parts as content managed in the CRX Repository. Then you can modify  layout properties and change your application administratively (by editing content in the Repository after your application) has  been developed and deployed. No need to rebuild and redeploy the whole application.

The individual components of your application are called, “Tiles“. In the example below one Tile is a JSP based HTML application built with Apache Sling. The other Tile is a classic Flex application that shows a data grid. Both Tiles may be developed and maintained separately but brought together by the framework to form a “Composite Web Application”.

The Composite Application Framework also provides communication of data and objects between each Tile via a “Shared Global Application Content”. In the example below a “watch” attribute (any string) may be configured in the Flex Tile, then a value for that attribute gets set by the HTML Tile.

(or click below to see a screen shot)

Now let’s look at the code behind each Tile (HTML and Flex)

html.jsp

Here is the JSP used to display the HTML tile able to communicate data with Flex.

Note the following aspects:

  1. A java script utility mosaicBridge.js is imported in order to obtain the mosaicApp.getContext() function which you can use to get/set attributes on the Global Contecxt. This java script needs to be part of your web application.
  2. The buttons in the HTML simply call function in the script block that wrap use of the mosaicBridge.js utility.

(Click to enlarge)

Flex Application Tile

Here is the MXML code used for the Flex Tile.

Note the following aspects:

  1. The data grid relies on a dataProvider which is a simple array collection
  2. There is a “mosaicApp” object of type IApplication which is injected by the Composite Application Framework allowing your flex application to access the Global Shared Context. This Tile adds itself as a “watcher” for an attribute with a given name.
  3. Now any time there is a change to a property in the shared global context, the Tile gets an onChange event for the property being watched and simply adds it to the dataProvider used for the grid.

(Click to enlarge)

 

http://www.thinkdigit.com/adobe/Internet/Adobe-launches-YouTube-channel-for-ADEP-Developers_7188.html

Dynamic HTML with Apache Sling

This example shows how a simple Web UI is built using Apache Sling such that text content in the page is dynamic in that it can change easily without the need to re-author any HTML.

The example uses a  JSP to render some HTML with a very simple style sheet. Let’s say this is the web UI we we want to arrive at looks like this:

Two things to notice first:

  1. The URL is /content/samples/testdrive/dynamichtml.html. That URL structure (especially the /content part) is important. It is literally the same as a node path in your CRX content repository
  2. The web page is showing a title and some body text that it claims to be “dynamic”. What does that mean? Well, as we shall see, these values are not literally coded in the HTML but come from “JCR Properties” of the node in the CRX content repository sitting at the end of the node path.

Traditional JEE web developers would use a WAR file in which all of the assets (JSPs, scripts etc.) are held in a folder within the ZIP structure of the WAR”. This is possible to mimic in the CRX Repository but it is not the best practice when using Sling.

Let’s start by looking at the JSP that renders this page:

(Click to Enlarge)

Notice the HTML in the JSP is using two variables “currentNodeTilte” and “currentNodeBody“. These variables in turn come from the currentNode binding which gives you access to the JCR node where the .html request was made. Now let’s consider where the JSP is stored and how it is referenced.

First we start by defining a content node (under /content) where requests will be made for a “.html” rendition:

(Click to Enlarge)

This is a simple content node under /content/samples/testdrive/dynamichtml with some text properties (including our title and body). Notice in particular the property called “sling:resourceType“. That property is used to reference the location of the JSP.

The JSP is placed under the /apps folder and its location is referenced by the the resourceType in your content node. This approach permits some useful

(Click to Enlarge)

There are some advatages to this approach:

  1. Anonymous end users don’t literally need read access to the JSP, They just talk to the content node and ask it for “.html“. It is then the Sling framework on the server that executes the JSP and returns the requested “.html” rendition of the content node. That’s why, in this case, we have called it “html.jsp“.
  2. You can re-use this JSP as the base web application for requests to other URLs. All you need is another content node that uses the same sling:resourceType and sets its own properties for the dynamic text.

Although the JSP is under /apps that reference to “currentNode” still binds to the node under /content where the HTML request was made. Therefore the JSP gets to substitute text in the HTML based on the “title” and “body” properties of the actual content node.

In addition within the JSP you will see that it its HTML references a style sheet. However style sheets are not part of the base web application. The style sheet belongs under /etc/clientlibs. Then the JSP simply references it under it literal path in this case, /etc/clientlibs/aep/samples/testdrive/dynamichtml/style.css.

(Click to Enlarge)

So in summary to build our simple web UI correctly with Apache  Sling we needed to:

  1. Write a JSP called “html.jsp” and place it under a location in the /apps folder.
  2. Create a node for the web UI whose folder hierarchy matches the intended URL. Then set the sling:resourceType property of the node to point to the location of your html.jsp in the /apps folder. Therefore when anyone requests a “.html” rendition for that node (called dynamichtml) , Sling will know how to do it.
  3. Within your JSP implementation refer to the style sheet .css file from a folder location under /etc/clientlibs.