Author Archive: Gary Gilchrist

What is ADEP?

Our recent release of the Adobe Digital Enterprise Platform contains not only software but a library of documentation that has been authored by the Adobe Learning team with direct input from all our engineers around the world.

One of our most important documents is a very short introduction that you read first, called “Adobe Digital Enterprise Platform Overview“. This was a very tricky document to write because there is a lot to say about ADEP, from its architecture & guiding principles to a precise description of each of the components and frameworks offered to developers. But how do you do that with accuracy while at the same time being extremely brief ..?

Well I think we managed it. The Overview gives enough information for anyone to quickly understand (in plain simple English) what ADEP is all about, starting with a simple graphic and then describing all the basic features and capabilities:

You can read it online at Adobe Digital Enterprise Platform Overview, or if you would like to skim a PDF, I have attached a copy here:

Also we have been editing and validating all our ADEP Technical Documentation. You can browse the whole library here:

In particular, I suggest you make a bee line for the document called “Developing for ADEP Experience Services“. This is intended to give you as a developer a total gloves-off crash course on the new Experience Server, with links to more detailed information too. You can check that one out here:

We hope you find the documentation useful and we are always improving it. You can also log on and add comments & feedback if you see an error or just have a suggestion.

Happy hacking-

Gary.

 

Solution Spotlight: A look inside Integrated Content Review

I’d like to continue my Solutions focus this week with a look at the architecture of another solution built on top of ADEP – “Integrated Content and Review”.

This solution was originally designed by our Solutions Engineering team to help manage document approval work flows. This worked by authoring a “template” that defined stages in a review with participants in each stage. One of the great things about that solution (compared to a typical BPM process) is that it was dynamic. You could actually tweak the review participants while the approval workflow was “in flight”, or even force it into another stage from a management console.

The team took this concept a step further, by building “Integrated Content Review” on ADEP with a focus on Creative Campaigns (for example advertising). In addition they provided integration with Creative Suite for creative professionals to interact with the solution right within Photoshop.

If you would like a look at the live Integrated Content Review solution, check out the YouTube recording made this week on ADEPDevelopers

Here is a high level architecture diagram of how the Solution Engineering team designed their solution, pointing out some important aspects of ADEP it relies upon:

(Click to enlarge)

As in my last example, the solution is presented through a web portal application that takes advantage of ADEP UX Components (a design technology for end user applications, see: Craig Randall’s post at what is a UX component)

The solution is constructed again using “Building Blocks”. These Building Blocks (you see two of them) contribute both UX Components to the web application and additional Services that run on both the Experience Server and Document Server. Building Blocks are individual Packages that Adobe and our partners use to deliver consistent repeatable solutions. For example, Integrated Content & Review could share these Building Blocks with other solutions that need similar functionality (such as creating a project schedule)

Looking into the Building Blocks used by Customer Communications we see:

Project Management”. This Building Block provides the UI and Services needed to manage multiple “projects” that might run simultaneously during a campaign. These projects can be related to each other (such as one project dependent child projects). Projects can also have “assets” which are work items that need to be produced during the project according to “schedule’ of participants who need to review and approve the assets.

Here are some interesting points to note about the design:

  1. Projects are defined as “templates” which get stored as content in the CRX Repository via Data Services (with our built an “Assembler” for JCR). There is a Project Manager Core service that provides all the operations necessary to create and update project templates or even create a new template that extends from a common base template. These project templates are based on the Apache Velocity project.
  2. There is a Work Item Handler which is responsible for scheduling activities needed for assets in a project. For example, creating a Task for a creative professional to provide an image. The Work Item Handler invokes a service in the RCA Building Block that in turn manages the events needed to trigger notifications and work flow processes.

Review & Comment”. This Building Block (also called “RCA”) provides the UI and Services need to manage a review cycle for content. That is the initiation, revision, revocation and update of a review for “assets” that are being created as part of a project.

Here are some interesting points to note about the design:

  1. A Template Engine (Apache Velocity) executes the Template in order to to trigger “schedules” that involve assigning review tasks for project assets at different stages of the project.
  2. The Building Block contains a service used to dispatch events used by the solution to trigger notifications or to advance a review stage to the next reviewer. This eventing system is internally based on Spring Events.
  3. The Scheduler Service is used to actually trigger Process Management Tasks on the Document Server by invoking Orchestrations that are provided as part of the Building Block. All such invocation from the Experience Server is performed using the Document Services SDK. When stages of an Orchestration complete there is a call back mechanism that helps the Scheduler manage the review, for example when a review Task on the Document Server has been completed. This is performed using a DSC that calls back to the Experience Server.
  4. Sometimes a Task might not be to review existing content but to create new content. In this case the Scheduler can create a Task that will be visible in Photoshop as part of a “Task List” UI (part of Project “Salsa”). A user in Photoshop then creates the requisite asset which then gets used as the payload of the Task he/she completes.
  5. The Building Block takes advantage of PDF as the standard format for all assets being reviewed and will convert assets to PDF automatically when needed. This relies on the PDF Generation and PDF Assembler Document Services running on the Document Server.

These Building Blocks are deployed on ADEP (both Experience Server and Document Server). Document Server integration is of particular importance to this solution because of the reliance on Process Management (used by RCA to generate Tasks and route them to end users). In addition the solution depends upon the Document Server for Identity Management (Users and Groups) typically integrated with an organization’s LDAP.

There is some more information about this solution on adobe.com at: Integrated Content Review

Solution Spotlight: A look inside Customer Communications

I thought I would take a slight detour from the core ADEP Platform frameworks this week and share with you some insight on one of our Solutions built on top of ADEP, “Customer Communications”.

This solution was designed by our Solutions Engineering team to address a pattern seen over the years with our Document Server customers, particularly financial  institutions. As part of a typical document based workflow (like replying to a dispute initiated by a customer on a web site) it is necessary to quickly draft a letter based not only on common paragraph segments but dynamic data; say the personal information of the customer and the legal requirements of the State / Province in which the dispute was made. Such letters might need to be crafted on screen by a business user or they might be generated automatically.

Here is a high level architecture diagram of how the Solution Engineering team designed their solution, pointing out some important aspects of ADEP it relies upon:

The solution is presented through a web portal application that takes advantage of ADEP UX Components (a design technology for end user applications, see: Craig Randall’s post at http://craigrandall.net/archives/2011/06/what-is-a-ux-component)

The solution is constructed using “Building Blocks”. The Building Blocks (you see three of them) contribute both UX Components to the web application and additional Services that run on the Experience Server. Building Blocks are individual Packages that Adobe and our partners use to deliver consistent repeatable solutions. For example, Customer Communications shares some of these same Building Blocks with other solutions.

Looking into the Building Blocks used by Customer Communications we see that:

  1. A “Data Dictionary”. It is used to manage all the templates and letter assets that are used to generate letters. This data is stored in the CRX Content repository (JCR compliant). The Data Dictionary also integrates with external sources of data (like SAP Web Services or custom databases) to get data used in letters such as customer address details etc. Both the storage of letter assets in the CRX repository and integration with third party data sources is provided via Data Services as a standard framework in the Experience Server.
  2. An “Asset Composer”. This provides the UI and Services needed to author new letter templates and letter assets (paragraphs). The Asset Composer integrates with the Document Server to render letters (needed during authoring) by invoking customizable Orchestrations which in turn rely on our standard Document Services. It also persists those assets and letter templates in the CRX repository, again using Data Services.
  3. An “Expression Manager”.  This is a technology for auto completing additional data (for example calculating an age based on DOB) as well as data validation (required fields, formatted strings etc.). It offers a server side service that is used by the Data Dictionary to augment known data (e.g. a customer name and address) with additional derived data as one record ready for inclusion within a letter (e.g. a ZIP code). It also provides UI libraries for defining and calculating these expressions.

These three Building Blocks are deployed on the ADEP Experience Server. In addition to Data Services and CRX, the other technology point of particular need to this solution is Document Server integration because the solution includes a set of customizable orchestrations around generation of letters using PDF Forms and Assembler. This aspect of the Experience Server provides seamless integration with process orchestrations and User Security which is needed at both design time (using Forms to render letters for preview) and run time for generation of letters.

There is some more information about this solution on adobe.com at: Customer Communications

Happy Hacking

-Gary.

“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.