340 likes | 557 Views
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
E N D
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:Contactrequires properties myapp:givenNameand myapp:familyName • Nodes can also have mixintypes • Something like interface • Eg. mix:versionable, mix:lockableor 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 sWHERE ISDESCENDANTNODE([/content])AND s.[jcr:title] = ’Mojastrona’ • 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 mixinmix: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:resourceTypeproperty • 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>
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: • jobs.print.a4.GET.html.esp • jobs.print.a4.html.esp • jobs.print.a4.esp • jobs.print.GET.html.esp • jobs.print.html.esp • jobs.print.esp • jobs.GET.html.esp • jobs.html.esp • jobs.GET.esp • jobs.esp
Composed resources <html> <head><title><%= currentNode.getProperty(’title') %></title></head> <body> <div class=“left_column”> <sling:includepath=“left” resourceType=“foundation/parsys”/> </div> <div class=“main”> <sling:include path=“main” resourceType=“foundation/parsys”/> <div> </body> </html>
Paragraph system <c:forEachvar=“par” items=“${resource.children}”> <sling:include path=“${par.path}” resourceType=“${par[‘sling:resourceType’]}”/> </c:forEach>
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 mountin 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 ResourceResolverFactoryresolverFactory; public void doGet(SlingHttpServletRequest request, SlingHttpServletResponseresponse) { 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