Pages

Friday, 20 December 2013

A starter on Apache Sling and its use in Adobe CQ

What is Sling?

In a few words, Apache Sling can be described as a RESTful web framework implementation, primarily a content-driven framework that sits on top of the JCR (Java Content Repository). It is an Apache Open Source project, originally started as an internal project by Day Software. One of the primary usages of Sling is for storing and managing content on the JCR.

Benefits
  • Supports multiple languages (JSP, ESP, scala, etc..)
  • Easy to interact with, deploy a whole application in one go (when used in CQ, just a HTTP POST call to /apps/install/, etc.)
  • Stateless and RESTful (based on HTTP)
  • Flexible enough so as to power small and simple applications as well as large enterprise level systems
  • Provides an easy-to-extend API library which enables easy extension of the core functionality
  • Built as a series of OSGi bundles and makes use of a number of OSGi core and services. The OSGi framework is a specification to build modular and extensible applications, providing significant benefits like easy deployment; as OSGi bundles which are essentially JAR files with metadata, reusability, dependency management, etc.

CQ5 with Sling

Sling is the backbone for building web applications in Adobe CQ/AEM; it is content-centric. This means that processing of a request is focused on the content, as each (HTTP) request is mapped onto content in the form of a JCR resource (a repository node). As in JCR, everything is content, in Sling, everything is a resource. Thus, Sling manages a virtual tree of resources, which is a merger of actual contents in the JCR repository and resources provided by the so-called resource provider.

Let us analyze the following URI and how it maps to a particular resource/script in CQ–
URI : http://myhost/tools/spy.printable.a4.html/a/b?x=12
protocol
host
content path
selector(s)
extension
suffix
param(s)
http://
myhost
tools/spy
.printable.a4.
html
a/b
x=12

The mapping of the protocol and the host is fairly straightforward. But the magic begins starting from the content path mapping, i.e., from the above example, tools/spy is mapped as the resource itself (which is holding the content). Then, the script is retrieved from the resource properties in the combination with certain parts of the request (i.e., selectors and/or extensions) In the above example, the selector(s), are options provided for how to render the content (in this case, a printable format with A4 as the page size and the .html extension specifies the script to be used for rendering.) The suffix can be used to specify additional information and the param(s) are specific to the script which are generally used to render content dynamically.
Thus from the above example, you can see that a URI mapping in sling with CQ happens a bit differently. It goes without saying that you cannot call a script in sling directly as this would break the strict concept of a RESTful server; you would mix resources and representations. This means, that if you call the script (which is the representation) directly, you would be hiding the resource inside your script, so the sling framework no longer knows about it. This has some serious implications like losing automatic handling of methods other than GET (POST, DELETE, PUT).

Conclusion
Apache Sling is really a great tool to checkout if someone wants to get started in RESTful Web Applications, doing it the right way. It is very flexible and dynamic. Also, there are many tools available today to connect Sling with the popular Java technologies like Apache Maven plugin, Apache felix SCR plugins, etc.

Tuesday, 17 December 2013

Query Builder in Brief

  • QueryBuilder is an API used to build Queries for Query Engine.
  • The generated queries are compatible with HTML forms also.
  • Allows us to add and remove conditions
  • Allows us to copy and paste of Queries
  •  Easily extensible
  • This QueryBuilder resides at server side and accepts a query description, creates and runs an XPath query.
  • The Query Description is simply a set of predicates.
  • Predicates are nothing but conditions. For each predicate type there is an evaluator component PredicateEvaluator that knows how to handle that specific predicate for XPath, filtering and facet extraction.

Standard Predicates:

  •  path
  •  property
  • type
  • fulltext
  •  range
  •  daterange
  • nodename
  •  similar
  • tagid & tag
  • language
  • event
  •  Also we can have the following predicates: 
    • group of predicates
    • like brackets 
    • order by predicates

Example usages

 From HTTP Form Post Request:
 Session session = request.getResourceResolver().adaptTo(Session.class);
 Query query = queryBuilder.createQuery(PredicateGroup.create(request.getParameterMap()), session);
 SearchResult result = query.getResult();
 ...
 
From key/value map:
 Map map = new HashMap();
 map.put("path", "/content");
 map.put("type", "nt:file");
 Query query = builder.createQuery(PredicateGroup.create(map), session);
 SearchResult result = query.getResult();
 ...
 
From predicates:
 PredicateGroup group = new PredicateGroup();
 group.add(new Predicate("mypath", "path").set("path", "/content"));
 group.add(new Predicate("mytype", "type").set("type", "nt:file"));
 Query query = builder.createQuery(group, session);
 SearchResult result = query.getResult();
 ...
 
QueryBuilder Debugger:
You can test and debug the queries at this URL



//Sample Application that retrieves the images from a DAM

<%@include file="/libs/foundation/global.jsp"%><%
%><%@page session="false"%>
<%@page import="com.day.cq.tagging.*, com.day.cq.wcm.api.*" %>

<%@page
import ="java.util.*,
javax.jcr.*,
org.apache.sling.api.resource.*,
org.apache.sling.api.scripting.*,
org.apache.sling.jcr.api.*,
com.day.cq.search.*,
com.day.cq.dam.api.Asset,
com.day.cq.search.result.*"
%>

<%        SlingRepository slingRep=sling.getService (SlingRepository.class);
            Session session=slingRep.loginAdministrative (null);
            //Instantiation of Map Object useful for storing the Query Description
Map<String, String> map=new HashMap<String, String>();
QueryBuilder queryBuilder;
            //Writing Query Description that goes to form a Query
map.put ("type", "dam:Asset");
map.put ("property", "jcr:content/metadata/dc:format");
map.put ("property.value", "image/jpeg");
            //resource resolving
queryBuilder=resource.getResourceResolver ().adaptTo(QueryBuilder.class);
            //creating query based on the Query Description
Query query=queryBuilder.createQuery (PredicateGroup.create(map),session);
            //Getting and storing the Results
SearchResult searchRes=query.getResult ();
String assPath=null;
            //Iterating for the no of times the requested resource found
for (Hit hit:searchRes.getHits()){
                       //Storing the path where the resource found
           String path1=hit.getPath ();
                       //Getting the resource from the path found
           Resource rs=resourceResolver.getResource (path1);
                       //Storing the resource into Asset object
          Asset asset=rs.adaptTo (Asset.class);
                      //Getting the path from the Asset object where the fetched data stored
          assPath=asset.getPath();
                      //finally rendering the asset data on the Page
             %><img src="<%=asset.getRendition ("cq5dam.thumbnail.140.100.png").getPath() %>" ></img>
<%
}
%>

Monday, 16 December 2013

Keyboard shortcuts in CRXDE Lite

Ctrl-G - Go to path/Search
Ctrl-Shift-R - Reload selected node
Ctrl-O - Open selected file
Ctrl-N - Create a node
Ctrl-Alt-N - Create a node
Ctrl-Shift-N - Create a file
Ctrl-M - Move a node
Ctrl-Shift-C - Copy node to clipboard
Ctrl-Shift-V - Paste node from clipboard
Shift-Del - Delete node ( When focus is on Repository Tree)
Shift-Del - Delete property (When focus is on Property Editor)
 

Java Content Assist/IntelliSense in CRXDE is not working for CQ 5.5

Below are the series of steps:

1) Stop CRXDE if it is running
2) Upload crxde-missing-libs-1.0.zip into our CQ 5.5 instance through package manager - You can download it from Packgae Share
3) Refresh /etc/crxde folder in CRXDE Lite
4) Start CRXDE - Contextual help should start working here
5) If it still doesn’t work then Stop CRXDE, delete .crxde folder from your user home directory and restart CRXDE. It should work after this action.


CQ Developer Tricks

 Here are a list of tricks that are useful for Developers.


Remove #cf/
Don’t want to see/wait for the content-finder while refreshing pages, just remove #cf/ in your url.

?debug=layout
Shows you all details of the components used on your page

?debugConsole=true
Runs Firebug Lite inside your browser

?wcmmode=(edit|preview|design|disabled)
This parameter sets your WcmMode in the specified mode, makes testing for a particular WcmMode easier .

?debugClientLibs=true
Writes out all Clientlib categories as separate files (check your HTML-source).

CTRL+SHIFT+U
In combination with ?debugClientLibs=true will show you timing information of your page

http://server/libs/cq/ui/content/dumplibs.html
Shows you all information around the clientlibs used in your CQ5-environment.


Thursday, 12 September 2013

How to remove the default decoration around the component in CQ

We can remove the default decoration around the component in CQ by setting a property cq:noDecoration to true to it.

Disabling the "Target" context menu item on cq:editConfig in AEM v5.6

We can disable this menu at component level by setting cq:editConfig/cq:disableTargeting to true. 

Converting InputStream to String

    private String convertToString(InputStream inputStreamObj)             throws IOException {         if (inputStreamObj != null) {     ...