Shooting rabbits with sling
Introduction to Apache Jackrabbit &
Apache Sling
JCR
• Content Repository API for Java
• JSR-170 & JSR-283
• javax.jcr
• Object database
• Hierarchical data model
• Apache Jackrabbit – reference implementation
Mantra: everything is content
• Content is content
– Blogs, articles, posts, etc.
• Structured data
– List of addresses in e-mail database
• Unstructured data
– Word document
• ACLs
• Code
Content hierarchy
• JCR has tree-like data model
• Repository consists of items
• Item can be node or property
• Node children are properties or other nodes
• Properties are leaves
Node
• Nodes form content hierarchy
• Nodes are named
• Each node has primary type specifying it’s structure
(allowed and required children and properties)
– Something like class
– Eg. myapp:Contact requires properties myapp:givenName
and myapp:familyName
• Nodes can also have mixin types
– Something like interface
– Eg. mix:versionable, mix:lockable or myapp:Emailable
• Popular types:
– nt:base, nt:unstructured, nt:folder
Property
• Property contains data
• Types:
– string, binary, long, double, date, boolean, name,
path, reference
• Can be multivalued
Searching
• Node names and properties are indexed
• Jackrabbit uses Apache Lucene
• Supported query languages:
– XPath
– JCR-SQL
– JCR-SQL2 (recommended)
SQL2
SELECT * FROM [cq:PageContent] AS s
WHERE ISDESCENDANTNODE([/content])
AND s.[jcr:title] = ’Moja strona’
• Main purpose: find node by property contents
• Avoid queries with parent path (as it’s not
indexed)
– It’s better to create a mixin or marker property
• We don’t JOIN
• SQL and XPath are isomorphic
Versioning
• Any subtree can be versioned
• Add mixin mix:versionable
• node.checkin()
– Creates new version
– Makes the node read-only
• node.checkout()
– Allows to modify the node
• Usage examples:
– Page versions at many levels
Observation
• Event listener
• We can filter events with:
– Event type
– Path
– Node types
– An explicit list of nodes
• Usage examples:
– Automatic workflows
– Generating thumbnails
– “Last modified” date
– Indexing in internal and external search engine
Other features
• Locking
• Access control
– Users & groups
– Groups can be members of other groups
– Privileges on nodes to read, write, etc.
JCR – advantages and problems
• Advantages
– Site structure is easy to reflect
– Flexible
– Hierarchical structure
• Disadvantages
– Storing large amount of structured data is neither easy nor
efficient
• Don’t load CSV file with 1 000 000 rows
– Data has to be denormalized (as there is no JOINs)
– Clustering is tricky
• Master-slave works OK
• Waiting for Jackrabbit 3.0 – codename Oak
– Transactions…
Apache Sling
HTTP access to JCR repository
Apache Sling
• Web framework
• RESTful access to JCR nodes
• Powered by OSGi
• Support multiple scripting languages (JSP,
Groovy, …)
• Open source, developed by Adobe within
Apache foundation
REST
# Create / Update
$ curl -u admin:admin –d name=‚Java User Group‛ –d city=Poznan 
localhost:8080/content/hello
# Read
$ curl localhost:8080/content/hello.tidy.json
# Delete
$ curl -X DELETE -u admin:admin 
localhost:8080/content/hello
Resource URL
• Resource path: /content/hello
– http://localhost:8080/content/hello.xml
– http://localhost:8080/content/hello.json
– http://localhost:8080/content/hello.html
• There are simple built-in renderers
• Each can be overridden
sling:resourceType
• In order to create custom rendition we need
to set sling:resourceType property
• It’s a JCR path to some renderer
• Renderer can be JSP, Java Servlet, Scala,
Python, Groovy, Ruby or ESP (internal Sling
language, kind of backend JS)
• Content-centric: you don’t invoke script
directly
Sample HTML renderer
<html>
<head><title>ESP example</title>
</head>
<body>
<h1>
Hello
<%= currentNode.getProperty('name') %>
</h1>
<h2>
<%= currentNode.getProperty('city') %>
</h2>
</body>
</html>
How does it work?
• Get node path from
URL
• Get extension
• Get HTTP method
GET /content/home.html
• Find
sling:resourceType
• Choose appropriate
script
(POST.jsp, json.jsp, e
tc.)
/apps/jug/hellocomponent
• Render node using
found renderer and
appropriate script
Hello JUG!
URL decomposition
/content/corporate/jobs/developer.print.a4.html/mysuffix
• Resource path
• Selectors
• Extension
• Suffix
Resource path
/content/corporate/jobs/developer.print.a4.html/mysuffix
• Substring before the first dot
• Path to the resource in JCR
• This part of the URL defines data.
– Rest defines way of the presentation.
Extension
/content/corporate/jobs/developer.print.a4.html/mysuffix
• Defines content format
• Most common: html, json, xml
• But may be png
Selectors
/content/corporate/jobs/developer.print.a4.html/mysuffix
• Specifies additional variants of the given content type
• Optional
• Multiple selectors are allowed
Suffix
/content/corporate/jobs/developer.print.a4.html/mysuffix
• Additional information passed to the rendering script
• Similar to GET ?name=value parameter, but can be cached
Script resolution
GET /content/corporate/jobs/developer.print.a4.html/mysuffix
/content/corporate/jobs/developer/sling:resourceType = cognifide/hr/jobs
/apps/cognifide/hr/jobs:
1. jobs.print.a4.GET.html.esp
2. jobs.print.a4.html.esp
3. jobs.print.a4.esp
4. jobs.print.GET.html.esp
5. jobs.print.html.esp
6. jobs.print.esp
7. jobs.GET.html.esp
8. jobs.html.esp
9. jobs.GET.esp
10. jobs.esp
Composed resources
Page
title
Left column Main
<html>
<head><title><%= currentNode.getProperty(’title') %></title></head>
<body>
<div class=‚left_column‛>
<sling:include path=‚left‛ resourceType=‚foundation/parsys‛/>
</div>
<div class=‚main‛>
<sling:include path=‚main‛ resourceType=‚foundation/parsys‛/>
<div>
</body>
</html>
Paragraph system
<c:forEach var=‚par‛ items=‚${resource.children}‛>
<sling:include
path=‚${par.path}‛
resourceType=‚${par[‘sling:resourceType’]}‛/>
</c:forEach>
Left column
Article
list
Twitter
widget
Contact
info
Resource Resolver
• In JCR we had Node
• In Sling we have Resource
• Virtual tree of resources, reflecting the JCR
• ResourceResolver – transforms nodes to resources
• It’s possible to create own ResourceResolvers and
reflect other data sources
– Filesystem,
– MongoDB,
– PostgreSQL
• Many ResourceResolvers may work together
– Like mount in UNIX
Resolver usage
Resource res = resourceResolver.getResource(‚/content/hello‛);
ModifiableValueMap map = res.adaptTo(ModifiableValueMap.class);
String name = map.get(‚name‛, String.class);
map.put(‚name‛, name.toUpperCase());
resourceResolver.commit();
Node node = res.adaptTo(javax.jcr.Node);
Session = resourceResolver.adaptTo(javax.jcr.Session);
Why do we use resolver?
• API is friendlier than JCR
• Sling provides us resources and resolver in
many places
– Servlets
– Scripts
Servlets
• Like ordinary servlets but…
• Can be assigned to:
– Paths
– Selectors
– Extensions
– Resource types (so can act as rendering script)
• doGet(), doPost() methods are invoked with
– SlingHttpServletRequest and …Response
– Additional methods for getting requested resource,
resolver, decompose URL, etc.
Sample Sling servlet
@Component
@Service
@SlingServlet(resourceTypes = ‛jug/hellocomponent‛)
public class AuthCheckerServlet extends SlingSafeMethodsServlet {
@Reference
private ResourceResolverFactory resolverFactory;
public void doGet(SlingHttpServletRequest request,
SlingHttpServletResponse response) {
response.getWriter().println(‚Hello world‛);
}
}
Sling – pros and cons
• Similar to JCR
• Pros
– Natural reflection of site and filesystem structure
• Document repositories, Digital Asset Management
– OSGi stack
– Javascript has easy access to repository
• Cons
– Security issues
• internal resources available as xml and json,
• handling user generated content
– Lack of free tools, eg. repo explorer
Q&A

Shooting rabbits with sling

  • 1.
    Shooting rabbits withsling Introduction to Apache Jackrabbit & Apache Sling
  • 2.
    JCR • Content RepositoryAPI for Java • JSR-170 & JSR-283 • javax.jcr • Object database • Hierarchical data model • Apache Jackrabbit – reference implementation
  • 3.
    Mantra: everything iscontent • Content is content – Blogs, articles, posts, etc. • Structured data – List of addresses in e-mail database • Unstructured data – Word document • ACLs • Code
  • 4.
    Content hierarchy • JCRhas tree-like data model • Repository consists of items • Item can be node or property • Node children are properties or other nodes • Properties are leaves
  • 5.
    Node • Nodes formcontent hierarchy • Nodes are named • Each node has primary type specifying it’s structure (allowed and required children and properties) – Something like class – Eg. myapp:Contact requires properties myapp:givenName and myapp:familyName • Nodes can also have mixin types – Something like interface – Eg. mix:versionable, mix:lockable or myapp:Emailable • Popular types: – nt:base, nt:unstructured, nt:folder
  • 6.
    Property • Property containsdata • Types: – string, binary, long, double, date, boolean, name, path, reference • Can be multivalued
  • 7.
    Searching • Node namesand properties are indexed • Jackrabbit uses Apache Lucene • Supported query languages: – XPath – JCR-SQL – JCR-SQL2 (recommended)
  • 8.
    SQL2 SELECT * FROM[cq:PageContent] AS s WHERE ISDESCENDANTNODE([/content]) AND s.[jcr:title] = ’Moja strona’ • Main purpose: find node by property contents • Avoid queries with parent path (as it’s not indexed) – It’s better to create a mixin or marker property • We don’t JOIN • SQL and XPath are isomorphic
  • 9.
    Versioning • Any subtreecan be versioned • Add mixin mix:versionable • node.checkin() – Creates new version – Makes the node read-only • node.checkout() – Allows to modify the node • Usage examples: – Page versions at many levels
  • 10.
    Observation • Event listener •We can filter events with: – Event type – Path – Node types – An explicit list of nodes • Usage examples: – Automatic workflows – Generating thumbnails – “Last modified” date – Indexing in internal and external search engine
  • 11.
    Other features • Locking •Access control – Users & groups – Groups can be members of other groups – Privileges on nodes to read, write, etc.
  • 12.
    JCR – advantagesand problems • Advantages – Site structure is easy to reflect – Flexible – Hierarchical structure • Disadvantages – Storing large amount of structured data is neither easy nor efficient • Don’t load CSV file with 1 000 000 rows – Data has to be denormalized (as there is no JOINs) – Clustering is tricky • Master-slave works OK • Waiting for Jackrabbit 3.0 – codename Oak – Transactions…
  • 13.
    Apache Sling HTTP accessto JCR repository
  • 14.
    Apache Sling • Webframework • RESTful access to JCR nodes • Powered by OSGi • Support multiple scripting languages (JSP, Groovy, …) • Open source, developed by Adobe within Apache foundation
  • 15.
    REST # Create /Update $ curl -u admin:admin –d name=‚Java User Group‛ –d city=Poznan localhost:8080/content/hello # Read $ curl localhost:8080/content/hello.tidy.json # Delete $ curl -X DELETE -u admin:admin localhost:8080/content/hello
  • 16.
    Resource URL • Resourcepath: /content/hello – http://localhost:8080/content/hello.xml – http://localhost:8080/content/hello.json – http://localhost:8080/content/hello.html • There are simple built-in renderers • Each can be overridden
  • 17.
    sling:resourceType • In orderto create custom rendition we need to set sling:resourceType property • It’s a JCR path to some renderer • Renderer can be JSP, Java Servlet, Scala, Python, Groovy, Ruby or ESP (internal Sling language, kind of backend JS) • Content-centric: you don’t invoke script directly
  • 18.
    Sample HTML renderer <html> <head><title>ESPexample</title> </head> <body> <h1> Hello <%= currentNode.getProperty('name') %> </h1> <h2> <%= currentNode.getProperty('city') %> </h2> </body> </html>
  • 19.
    How does itwork? • Get node path from URL • Get extension • Get HTTP method GET /content/home.html • Find sling:resourceType • Choose appropriate script (POST.jsp, json.jsp, e tc.) /apps/jug/hellocomponent • Render node using found renderer and appropriate script Hello JUG!
  • 20.
  • 21.
    Resource path /content/corporate/jobs/developer.print.a4.html/mysuffix • Substringbefore the first dot • Path to the resource in JCR • This part of the URL defines data. – Rest defines way of the presentation.
  • 22.
    Extension /content/corporate/jobs/developer.print.a4.html/mysuffix • Defines contentformat • Most common: html, json, xml • But may be png
  • 23.
    Selectors /content/corporate/jobs/developer.print.a4.html/mysuffix • Specifies additionalvariants of the given content type • Optional • Multiple selectors are allowed
  • 24.
    Suffix /content/corporate/jobs/developer.print.a4.html/mysuffix • Additional informationpassed to the rendering script • Similar to GET ?name=value parameter, but can be cached
  • 25.
    Script resolution GET /content/corporate/jobs/developer.print.a4.html/mysuffix /content/corporate/jobs/developer/sling:resourceType= cognifide/hr/jobs /apps/cognifide/hr/jobs: 1. jobs.print.a4.GET.html.esp 2. jobs.print.a4.html.esp 3. jobs.print.a4.esp 4. jobs.print.GET.html.esp 5. jobs.print.html.esp 6. jobs.print.esp 7. jobs.GET.html.esp 8. jobs.html.esp 9. jobs.GET.esp 10. jobs.esp
  • 26.
    Composed resources Page title Left columnMain <html> <head><title><%= currentNode.getProperty(’title') %></title></head> <body> <div class=‚left_column‛> <sling:include path=‚left‛ resourceType=‚foundation/parsys‛/> </div> <div class=‚main‛> <sling:include path=‚main‛ resourceType=‚foundation/parsys‛/> <div> </body> </html>
  • 27.
    Paragraph system <c:forEach var=‚par‛items=‚${resource.children}‛> <sling:include path=‚${par.path}‛ resourceType=‚${par[‘sling:resourceType’]}‛/> </c:forEach> Left column Article list Twitter widget Contact info
  • 28.
    Resource Resolver • InJCR we had Node • In Sling we have Resource • Virtual tree of resources, reflecting the JCR • ResourceResolver – transforms nodes to resources • It’s possible to create own ResourceResolvers and reflect other data sources – Filesystem, – MongoDB, – PostgreSQL • Many ResourceResolvers may work together – Like mount in UNIX
  • 29.
    Resolver usage Resource res= resourceResolver.getResource(‚/content/hello‛); ModifiableValueMap map = res.adaptTo(ModifiableValueMap.class); String name = map.get(‚name‛, String.class); map.put(‚name‛, name.toUpperCase()); resourceResolver.commit(); Node node = res.adaptTo(javax.jcr.Node); Session = resourceResolver.adaptTo(javax.jcr.Session);
  • 30.
    Why do weuse resolver? • API is friendlier than JCR • Sling provides us resources and resolver in many places – Servlets – Scripts
  • 31.
    Servlets • Like ordinaryservlets but… • Can be assigned to: – Paths – Selectors – Extensions – Resource types (so can act as rendering script) • doGet(), doPost() methods are invoked with – SlingHttpServletRequest and …Response – Additional methods for getting requested resource, resolver, decompose URL, etc.
  • 32.
    Sample Sling servlet @Component @Service @SlingServlet(resourceTypes= ‛jug/hellocomponent‛) public class AuthCheckerServlet extends SlingSafeMethodsServlet { @Reference private ResourceResolverFactory resolverFactory; public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) { response.getWriter().println(‚Hello world‛); } }
  • 33.
    Sling – prosand cons • Similar to JCR • Pros – Natural reflection of site and filesystem structure • Document repositories, Digital Asset Management – OSGi stack – Javascript has easy access to repository • Cons – Security issues • internal resources available as xml and json, • handling user generated content – Lack of free tools, eg. repo explorer
  • 34.

Editor's Notes

  • #7 Show examples here: CRXDE and Eclipse “Helloworld”
  • #10 Eclipse example Versioning
  • #19 jug/hellocomponent
  • #34 Show CQ as demo – what page?