Shooting rabbits with sling

fallsnowpeasInternet and Web Development

Nov 12, 2013 (3 years and 6 months ago)

67 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


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

s
ling: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
, etc.)

/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.
j
obs.
print.a4
.
html
.esp

3.
j
obs.
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
,


h
andling user generated content


Lack of free tools,
eg
.
r
epo explorer

Q&A