http://git-wip-us.apache.org/repos/asf/sling-site/blob/3a935d04/documentation/tutorials-how-tos.html ---------------------------------------------------------------------- diff --git a/documentation/tutorials-how-tos.html b/documentation/tutorials-how-tos.html index e05f226..b54b467 100644 --- a/documentation/tutorials-how-tos.html +++ b/documentation/tutorials-how-tos.html @@ -2,22 +2,22 @@ <head> <meta charset="utf-8"/> <title>Apache Sling on JBake</title> - <link rel="stylesheet" href="/res/css/site.css"/> - <link rel="stylesheet" href="/res/css/codehilite.css"/> + <link rel="stylesheet" href="/ng/res/css/site.css"/> + <link rel="icon" href="/ng/res/favicon.ico"/> <div class="title"> <div class="logo"> <a href="http://sling.apache.org"> - <img border="0" alt="Apache Sling" src="/res/logos/sling.svg"/> + <img border="0" alt="Apache Sling" src="/ng/res/logos/sling.svg"/> </a> </div><div class="header"> <a href="http://www.apache.org"> - <img border="0" alt="Apache" src="/res/logos/apache.png"/> + <img border="0" alt="Apache" src="/ng/res/logos/apache.png"/> </a> </div> </div> </head><body> <div class="menu"> - <strong><a href="/documentation.html">Documentation</a></strong><br/><a href="/documentation/getting-started.html">Getting Started</a><br/><a href="/documentation/the-sling-engine.html">The Sling Engine</a><br/><a href="/documentation/development.html">Development</a><br/><a href="/documentation/bundles.html">Bundles</a><br/><a href="/documentation/tutorials-how-tos.html">Tutorials & How-Tos</a><br/><a href="/documentation/configuration.html">Configuration</a><p></p><a href="http://s.apache.org/sling.wiki">Wiki</a><br/><a href="http://s.apache.org/sling.faq">FAQ</a><br/><p></p><strong>API Docs</strong><br/><a href="/apidocs/sling9/index.html">Sling 9</a><br/><a href="/apidocs/sling8/index.html">Sling 8</a><br/><a href="/apidocs/sling7/index.html">Sling 7</a><br/><a href="/apidocs/sling6/index.html">Sling 6</a><br/><a href="/apidocs/sling5/index.html">Sling 5</a><br/><a href="/javadoc-io.html">Archive at javadoc.io</a><br/><p></p><strong>Project info</strong><br/><a h ref="/downloads.cgi">Downloads</a><br/><a href="http://www.apache.org/licenses/">License</a><br/><a href="/contributing.html">Contributing</a><br/><a href="/news.html">News</a><br/><a href="/links.html">Links</a><br/><a href="/project-information.html">Project Information</a><br/><a href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a><br/><a href="http://ci.apache.org/builders/sling-trunk">Build Server</a><br/><a href="/project-information/security.html">Security</a><br/><p></p><strong>Source</strong><br/><a href="http://svn.apache.org/viewvc/sling/trunk">Subversion</a><br/><a href="git://git.apache.org/sling.git">Git</a><br/><a href="https://github.com/apache/sling">Github Mirror</a><br/><p></p><strong>Sponsorship</strong><br/><a href="http://www.apache.org/foundation/thanks.html">Thanks</a><br/><a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a><br/><a href="https://donate.apache.org/">Donate!</a><br/><a href="http://www.apache.org/foun dation/buy_stuff.html">Buy Stuff</a><br/><p></p><strong><a href="/sitemap.html">Site Map</a></strong> + <strong><a href="/ng/documentation.html">Documentation</a></strong><br/><a href="/ng/documentation/getting-started.html">Getting Started</a><br/><a href="/ng/documentation/the-sling-engine.html">The Sling Engine</a><br/><a href="/ng/documentation/development.html">Development</a><br/><a href="/ng/documentation/bundles.html">Bundles</a><br/><a href="/ng/documentation/tutorials-how-tos.html">Tutorials & How-Tos</a><br/><a href="/ng/documentation/configuration.html">Configuration</a><p></p><a href="http://s.apache.org/sling.wiki">Wiki</a><br/><a href="http://s.apache.org/sling.faq">FAQ</a><br/><p></p><strong>API Docs</strong><br/><a href="/ng/apidocs/sling9/index.html">Sling 9</a><br/><a href="/ng/apidocs/sling8/index.html">Sling 8</a><br/><a href="/ng/apidocs/sling7/index.html">Sling 7</a><br/><a href="/ng/apidocs/sling6/index.html">Sling 6</a><br/><a href="/ng/apidocs/sling5/index.html">Sling 5</a><br/><a href="/ng/javadoc-io.html">Archive at javadoc.io</a><br/><p></p ><strong>Project info</strong><br/><a >href="/ng/downloads.cgi">Downloads</a><br/><a >href="http://www.apache.org/licenses/">License</a><br/><a >href="/ng/contributing.html">Contributing</a><br/><a >href="/ng/news.html">News</a><br/><a href="/ng/links.html">Links</a><br/><a >href="/ng/project-information.html">Project Information</a><br/><a >href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a><br/><a >href="http://ci.apache.org/builders/sling-trunk">Build Server</a><br/><a >href="/ng/project-information/security.html">Security</a><br/><p></p><strong>Source</strong><br/><a > href="http://svn.apache.org/viewvc/sling/trunk">Subversion</a><br/><a >href="git://git.apache.org/sling.git">Git</a><br/><a >href="https://github.com/apache/sling">Github >Mirror</a><br/><p></p><strong>Sponsorship</strong><br/><a >href="http://www.apache.org/foundation/thanks.html">Thanks</a><br/><a >href="http://www.apache.org/foundation/sponsorship.html">Become a >Sponsor</a><br/><a href="https://donate.apache. org/">Donate!</a><br/><a href="http://www.apache.org/foundation/buy_stuff.html">Buy Stuff</a><br/><p></p><strong><a href="/ng/sitemap.html">Site Map</a></strong> </div> <div class="main"> <div class="row"><div class="small-12 columns"><section class="wrap"><header><h1>Tutorials & How-Tos</h1></header><p>{% for label, page in children %}* [{{ page.headers.title }}]({{ page.path }}) {% endfor %}</p></section></div></div> <div class="footer">
http://git-wip-us.apache.org/repos/asf/sling-site/blob/3a935d04/documentation/tutorials-how-tos/46-line-blog.html ---------------------------------------------------------------------- diff --git a/documentation/tutorials-how-tos/46-line-blog.html b/documentation/tutorials-how-tos/46-line-blog.html index 009ebdb..26c4061 100644 --- a/documentation/tutorials-how-tos/46-line-blog.html +++ b/documentation/tutorials-how-tos/46-line-blog.html @@ -2,22 +2,22 @@ <head> <meta charset="utf-8"/> <title>Apache Sling on JBake</title> - <link rel="stylesheet" href="/res/css/site.css"/> - <link rel="stylesheet" href="/res/css/codehilite.css"/> + <link rel="stylesheet" href="/ng/res/css/site.css"/> + <link rel="icon" href="/ng/res/favicon.ico"/> <div class="title"> <div class="logo"> <a href="http://sling.apache.org"> - <img border="0" alt="Apache Sling" src="/res/logos/sling.svg"/> + <img border="0" alt="Apache Sling" src="/ng/res/logos/sling.svg"/> </a> </div><div class="header"> <a href="http://www.apache.org"> - <img border="0" alt="Apache" src="/res/logos/apache.png"/> + <img border="0" alt="Apache" src="/ng/res/logos/apache.png"/> </a> </div> </div> </head><body> <div class="menu"> - <strong><a href="/documentation.html">Documentation</a></strong><br/><a href="/documentation/getting-started.html">Getting Started</a><br/><a href="/documentation/the-sling-engine.html">The Sling Engine</a><br/><a href="/documentation/development.html">Development</a><br/><a href="/documentation/bundles.html">Bundles</a><br/><a href="/documentation/tutorials-how-tos.html">Tutorials & How-Tos</a><br/><a href="/documentation/configuration.html">Configuration</a><p></p><a href="http://s.apache.org/sling.wiki">Wiki</a><br/><a href="http://s.apache.org/sling.faq">FAQ</a><br/><p></p><strong>API Docs</strong><br/><a href="/apidocs/sling9/index.html">Sling 9</a><br/><a href="/apidocs/sling8/index.html">Sling 8</a><br/><a href="/apidocs/sling7/index.html">Sling 7</a><br/><a href="/apidocs/sling6/index.html">Sling 6</a><br/><a href="/apidocs/sling5/index.html">Sling 5</a><br/><a href="/javadoc-io.html">Archive at javadoc.io</a><br/><p></p><strong>Project info</strong><br/><a h ref="/downloads.cgi">Downloads</a><br/><a href="http://www.apache.org/licenses/">License</a><br/><a href="/contributing.html">Contributing</a><br/><a href="/news.html">News</a><br/><a href="/links.html">Links</a><br/><a href="/project-information.html">Project Information</a><br/><a href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a><br/><a href="http://ci.apache.org/builders/sling-trunk">Build Server</a><br/><a href="/project-information/security.html">Security</a><br/><p></p><strong>Source</strong><br/><a href="http://svn.apache.org/viewvc/sling/trunk">Subversion</a><br/><a href="git://git.apache.org/sling.git">Git</a><br/><a href="https://github.com/apache/sling">Github Mirror</a><br/><p></p><strong>Sponsorship</strong><br/><a href="http://www.apache.org/foundation/thanks.html">Thanks</a><br/><a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a><br/><a href="https://donate.apache.org/">Donate!</a><br/><a href="http://www.apache.org/foun dation/buy_stuff.html">Buy Stuff</a><br/><p></p><strong><a href="/sitemap.html">Site Map</a></strong> + <strong><a href="/ng/documentation.html">Documentation</a></strong><br/><a href="/ng/documentation/getting-started.html">Getting Started</a><br/><a href="/ng/documentation/the-sling-engine.html">The Sling Engine</a><br/><a href="/ng/documentation/development.html">Development</a><br/><a href="/ng/documentation/bundles.html">Bundles</a><br/><a href="/ng/documentation/tutorials-how-tos.html">Tutorials & How-Tos</a><br/><a href="/ng/documentation/configuration.html">Configuration</a><p></p><a href="http://s.apache.org/sling.wiki">Wiki</a><br/><a href="http://s.apache.org/sling.faq">FAQ</a><br/><p></p><strong>API Docs</strong><br/><a href="/ng/apidocs/sling9/index.html">Sling 9</a><br/><a href="/ng/apidocs/sling8/index.html">Sling 8</a><br/><a href="/ng/apidocs/sling7/index.html">Sling 7</a><br/><a href="/ng/apidocs/sling6/index.html">Sling 6</a><br/><a href="/ng/apidocs/sling5/index.html">Sling 5</a><br/><a href="/ng/javadoc-io.html">Archive at javadoc.io</a><br/><p></p ><strong>Project info</strong><br/><a >href="/ng/downloads.cgi">Downloads</a><br/><a >href="http://www.apache.org/licenses/">License</a><br/><a >href="/ng/contributing.html">Contributing</a><br/><a >href="/ng/news.html">News</a><br/><a href="/ng/links.html">Links</a><br/><a >href="/ng/project-information.html">Project Information</a><br/><a >href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a><br/><a >href="http://ci.apache.org/builders/sling-trunk">Build Server</a><br/><a >href="/ng/project-information/security.html">Security</a><br/><p></p><strong>Source</strong><br/><a > href="http://svn.apache.org/viewvc/sling/trunk">Subversion</a><br/><a >href="git://git.apache.org/sling.git">Git</a><br/><a >href="https://github.com/apache/sling">Github >Mirror</a><br/><p></p><strong>Sponsorship</strong><br/><a >href="http://www.apache.org/foundation/thanks.html">Thanks</a><br/><a >href="http://www.apache.org/foundation/sponsorship.html">Become a >Sponsor</a><br/><a href="https://donate.apache. org/">Donate!</a><br/><a href="http://www.apache.org/foundation/buy_stuff.html">Buy Stuff</a><br/><p></p><strong><a href="/ng/sitemap.html">Site Map</a></strong> </div> <div class="main"> <div class="row"><div class="small-12 columns"><section class="wrap"><header><h1>46 Line Blog</h1></header><p>This tutorial is based on the first <em>Sling Gems</em> on dev.day.com: The <a href="http://dev.day.com/microsling/content/blogs/main/sling-46-lines-blog.html">Sling gems: a blog in 46 lines of code</a>. It has slightly been adapted to fit here.</p> <p>In this tutorial, the SlingPostServlet and the sling.js library are brought together using 46 (no kidding: <em>fourty-six</em>) lines of code to create a simple blog (or let's say <em>bloggish</em>) application.</p> @@ -30,29 +30,31 @@ <p>Then, login using <a href="http://localhost:8888/?sling:authRequestLogin=1">http://localhost:8888/?sling:authRequestLogin=1</a> which should prompt you for a username and password, use <em>admin</em> and <em>admin</em>. Once that's done, <a href="http://localhost:8888/index.html">http://localhost:8888/index.html</a> should say <em>You are currently logged in as user <em>admin</em> to workspace <em>default</em></em>.</p> <h2>Step 1: Creating content</h2> <p>The easiest way to create content in Sling is to use an HTTP POST request, let's use a simple HTML form:</p> -<html> -<body> -<h1>Sling microblog</h1> +<pre><code><html> + <body> + <h1>Sling microblog</h1> -<div> -<form method="POST"> -<input type="text" name="title" style="width:100%"/> + <div> + <form method="POST"> + Title:<br/> + <input type="text" name="title" style="width:100%"/> -<br/>Text:<br/> -<textarea style="width:100%" name="text"></textarea> + <br/>Text:<br/> + <textarea style="width:100%" name="text"></textarea> -<br/> -<input type="submit" value="save"/> -<input type="hidden" name=":redirect" value="*.html"/> + <br/> + <input type="submit" value="save"/> + <input type="hidden" name=":redirect" value="*.html"/> -<!-- used by Sling when decoding request parameters --> -<input type="hidden" name="_charset_" value="UTF-8"/> -</form> -</div> + <!-- used by Sling when decoding request parameters --> + <input type="hidden" name="_charset_" value="UTF-8"/> + </form> + </div> -<!-- code of step 2 comes here --> -</body> -</html> + <!-- code of step 2 comes here --> + </body> +</html> +</code></pre> <p>That's two input fields, a submit button and a hidden field that tells Sling what to do after the POST (in this case: redirect to the html view of the node that was just created).</p> <p>To test the form, start Sling and save the above script as {{/apps/blog/blog.esp}} [^esp] in the Sling repository - a WebDAV mount is the easiest way to do that. Browsing to <a href="http://localhost:8888/content/blog/*.html">http://localhost:8888/content/blog/*.html</a> [^port] should display the above form.</p> <p>[^esp]: ESP is Sling's server-side javascript language [^port]: This assumes your instance of Sling is running on port 8888. If that's not the case, adjust the example URLs accordingly.</p> @@ -63,34 +65,42 @@ If you get an error saying _javax.jcr.AccessDeniedException: ...not allowed to a <p>At this point you're probably looking at an empty form with an URL ending in <em>foo</em>, if you used that for the title. Or <em>foo_0</em> or <em>foo_1</em> if other _foo_s already existed. Don't worry about not seeing your content, we'll fix that right away.</p> <h2>Step 2: Where's my content?</h2> <p>To verify that our content has been created, we can have a look at the JSON data at <a href="http://localhost:8888/content/blog/foo.tidy.json">http://localhost:8888/content/blog/foo.tidy.json</a>, which should display our new node's values:</p> -<p>{ "jcr:primaryType": "nt:unstructured", "text": "This is the foo text", "title": "foo" }</p> +<pre><code>{ + "jcr:primaryType": "nt:unstructured", + "text": "This is the foo text", + "title": "foo" +} +</code></pre> <p>That's reassuring, but what we really want is for these values to be displayed on the editing form for our post.</p> <p>Thanks to the <em>sling.js</em> client library, we just need to add a <code>Sling.wizard()</code> call to our form to display those values. Let's first add a <code><head></code> element to our form to load the <em>sling.js</em> library, before the existing <code><body></code> of course:</p> -<head> -<script src="/system/sling.js"></script> -</head> +<pre><code><head> + <script src="/system/sling.js"></script> +</head> +</code></pre> <p>And add the <code>Sling.wizard()</code> after the form, where we had the <em>code of step 2 comes here</em> comment:</p> -<!-- code of step 2 comes here --> -<script>Sling.wizard();</script> +<pre><code><!-- code of step 2 comes here --> +<script>Sling.wizard();</script> +</code></pre> <p>Reloading the form at <code>http://localhost:8888/content/blog/*.html</code> and creating a new post should now redirect to an editable version of the post, with the form fields correctly initialized.</p> -<p>We can now create and edit posts; let's add some navigation, using more of the <em>sling.js</em> functionality.</p> +<p>We can now create and edit posts; let's add some navigation, using more of the <em>sling.js</em> functionality. </p> <h2>Step 3: Navigation</h2> <p>The <em>sling.js</em> library provides utilities to access and manipulate content. For our blog, we'll use the <code>getContent(path)</code> method to list the siblings of the current node.</p> <p>Add the following code to your script, after the <code>Sling.wizard()</code> call that was added in step 2:</p> -<h3>Navigation</h3> -<ul> -<li><em><a href="/content/blog/*.html">[Create new post]</a></em></li> -<script> -var posts = Sling.getContent("/content/blog", 2); -for(var i in posts) { -document.write("<li>" -+ "<a href='/content/blog/" + i + ".html'>" -+ posts[i].title -+ "</a></li>"); -} -</script> -</ul> -<p>The first link to <code>/content/blog/*</code> brings us back to our content creating form, which is nothing else than the editing form reading empty values and posting to the "magic star" URL.</p> +<pre><code><h3>Navigation</h3> +<ul> + <li><em><a href="/content/blog/*.html">[Create new post]</a></em></li> + <script> + var posts = Sling.getContent("/content/blog", 2); + for(var i in posts) { + document.write("<li>" + + "<a href='/content/blog/" + i + ".html'>" + + posts[i].title + + "</a></li>"); + } + </script> +</ul> +</code></pre> +<p>The first link to <code>/content/blog/*</code> brings us back to our content creating form, which is nothing else than the editing form reading empty values and posting to the "magic star" URL. </p> <p>The rest of the javascript runs client-side, as it is not embedded in <code><% %></code> code markers, calls the <code>sling.getContent</code> method to get two levels of node data below <code>/content/blog</code>, and displays links to nodes that it finds.</p> <p>That's a basic navigation, of course, in a real blog we'd need some paging and contextualization to cope with large numbers of posts.</p> <p>Nevertheless, with this addition our ESP script allows us to create, edit and navigate blog posts - not bad for 46 lines of code, including comments, whitespace and output formatting.</p> @@ -98,7 +108,9 @@ document.write("<li>" <p>You might have heard this mantra, which we apply in many areas of Sling.</p> <p>In this case, adding a new field to our blog posts could not be easier: just add an input field to the form, and Sling will do the rest.</p> <p>Adding this inside our script's <code><form></code> element, for example:</p> -<p><br/>Author:<br/> <input type="author" name="author" style="width:100%"/></p> +<pre><code><br/>Author:<br/> +<input type="author" name="author" style="width:100%"/> +</code></pre> <p>Allows us to add an author name to our blog posts. No need to define anything at the repository level, as Sling is using it in unstructured mode in this case, and no need to migrate existing data, the author field of existing posts will simply be empty.</p> <h2>I want my ESP!</h2> <p>Now wait...we said we were going to create an ESP script, but our "application" is just static HTML and some client javascript at this point.</p> http://git-wip-us.apache.org/repos/asf/sling-site/blob/3a935d04/documentation/tutorials-how-tos/getting-resources-and-properties-in-sling.html ---------------------------------------------------------------------- diff --git a/documentation/tutorials-how-tos/getting-resources-and-properties-in-sling.html b/documentation/tutorials-how-tos/getting-resources-and-properties-in-sling.html index 308f8c9..77ef8f0 100644 --- a/documentation/tutorials-how-tos/getting-resources-and-properties-in-sling.html +++ b/documentation/tutorials-how-tos/getting-resources-and-properties-in-sling.html @@ -2,57 +2,88 @@ <head> <meta charset="utf-8"/> <title>Apache Sling on JBake</title> - <link rel="stylesheet" href="/res/css/site.css"/> - <link rel="stylesheet" href="/res/css/codehilite.css"/> + <link rel="stylesheet" href="/ng/res/css/site.css"/> + <link rel="icon" href="/ng/res/favicon.ico"/> <div class="title"> <div class="logo"> <a href="http://sling.apache.org"> - <img border="0" alt="Apache Sling" src="/res/logos/sling.svg"/> + <img border="0" alt="Apache Sling" src="/ng/res/logos/sling.svg"/> </a> </div><div class="header"> <a href="http://www.apache.org"> - <img border="0" alt="Apache" src="/res/logos/apache.png"/> + <img border="0" alt="Apache" src="/ng/res/logos/apache.png"/> </a> </div> </div> </head><body> <div class="menu"> - <strong><a href="/documentation.html">Documentation</a></strong><br/><a href="/documentation/getting-started.html">Getting Started</a><br/><a href="/documentation/the-sling-engine.html">The Sling Engine</a><br/><a href="/documentation/development.html">Development</a><br/><a href="/documentation/bundles.html">Bundles</a><br/><a href="/documentation/tutorials-how-tos.html">Tutorials & How-Tos</a><br/><a href="/documentation/configuration.html">Configuration</a><p></p><a href="http://s.apache.org/sling.wiki">Wiki</a><br/><a href="http://s.apache.org/sling.faq">FAQ</a><br/><p></p><strong>API Docs</strong><br/><a href="/apidocs/sling9/index.html">Sling 9</a><br/><a href="/apidocs/sling8/index.html">Sling 8</a><br/><a href="/apidocs/sling7/index.html">Sling 7</a><br/><a href="/apidocs/sling6/index.html">Sling 6</a><br/><a href="/apidocs/sling5/index.html">Sling 5</a><br/><a href="/javadoc-io.html">Archive at javadoc.io</a><br/><p></p><strong>Project info</strong><br/><a h ref="/downloads.cgi">Downloads</a><br/><a href="http://www.apache.org/licenses/">License</a><br/><a href="/contributing.html">Contributing</a><br/><a href="/news.html">News</a><br/><a href="/links.html">Links</a><br/><a href="/project-information.html">Project Information</a><br/><a href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a><br/><a href="http://ci.apache.org/builders/sling-trunk">Build Server</a><br/><a href="/project-information/security.html">Security</a><br/><p></p><strong>Source</strong><br/><a href="http://svn.apache.org/viewvc/sling/trunk">Subversion</a><br/><a href="git://git.apache.org/sling.git">Git</a><br/><a href="https://github.com/apache/sling">Github Mirror</a><br/><p></p><strong>Sponsorship</strong><br/><a href="http://www.apache.org/foundation/thanks.html">Thanks</a><br/><a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a><br/><a href="https://donate.apache.org/">Donate!</a><br/><a href="http://www.apache.org/foun dation/buy_stuff.html">Buy Stuff</a><br/><p></p><strong><a href="/sitemap.html">Site Map</a></strong> + <strong><a href="/ng/documentation.html">Documentation</a></strong><br/><a href="/ng/documentation/getting-started.html">Getting Started</a><br/><a href="/ng/documentation/the-sling-engine.html">The Sling Engine</a><br/><a href="/ng/documentation/development.html">Development</a><br/><a href="/ng/documentation/bundles.html">Bundles</a><br/><a href="/ng/documentation/tutorials-how-tos.html">Tutorials & How-Tos</a><br/><a href="/ng/documentation/configuration.html">Configuration</a><p></p><a href="http://s.apache.org/sling.wiki">Wiki</a><br/><a href="http://s.apache.org/sling.faq">FAQ</a><br/><p></p><strong>API Docs</strong><br/><a href="/ng/apidocs/sling9/index.html">Sling 9</a><br/><a href="/ng/apidocs/sling8/index.html">Sling 8</a><br/><a href="/ng/apidocs/sling7/index.html">Sling 7</a><br/><a href="/ng/apidocs/sling6/index.html">Sling 6</a><br/><a href="/ng/apidocs/sling5/index.html">Sling 5</a><br/><a href="/ng/javadoc-io.html">Archive at javadoc.io</a><br/><p></p ><strong>Project info</strong><br/><a >href="/ng/downloads.cgi">Downloads</a><br/><a >href="http://www.apache.org/licenses/">License</a><br/><a >href="/ng/contributing.html">Contributing</a><br/><a >href="/ng/news.html">News</a><br/><a href="/ng/links.html">Links</a><br/><a >href="/ng/project-information.html">Project Information</a><br/><a >href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a><br/><a >href="http://ci.apache.org/builders/sling-trunk">Build Server</a><br/><a >href="/ng/project-information/security.html">Security</a><br/><p></p><strong>Source</strong><br/><a > href="http://svn.apache.org/viewvc/sling/trunk">Subversion</a><br/><a >href="git://git.apache.org/sling.git">Git</a><br/><a >href="https://github.com/apache/sling">Github >Mirror</a><br/><p></p><strong>Sponsorship</strong><br/><a >href="http://www.apache.org/foundation/thanks.html">Thanks</a><br/><a >href="http://www.apache.org/foundation/sponsorship.html">Become a >Sponsor</a><br/><a href="https://donate.apache. org/">Donate!</a><br/><a href="http://www.apache.org/foundation/buy_stuff.html">Buy Stuff</a><br/><p></p><strong><a href="/ng/sitemap.html">Site Map</a></strong> </div> <div class="main"> <div class="row"><div class="small-12 columns"><section class="wrap"><header><h1>Getting Resources and Properties in Sling</h1></header><p>The Resource is one of the central parts of Sling. Extending from JCR's Everything is Content, Sling assumes Everthing is a Resource. Thus Sling is maintaining a virtual tree of resources, which is a merger of the actual contents in the JCR Repository and resources provided by so called resource providers. By doing this Sling fits very well in the paradigm of the REST architecture.</p> <p>In this article we will explore a few ways to programmatically map a resource path (String) to a resource object (Resource) and its properties in Sling, from within an OSGI service, a servlet and a JSP.</p> <p>The whole game consists in first getting a <code>ResourceResolver</code> and then getting the <code>Resource</code> itself.</p> <h2>Within an OSGI Service/Compoment</h2> <p>You can access a resource through the <code>ResourceResolverFactory</code> service:</p> -<h1>!java</h1> -<p>@Reference private ResourceResolverFactory resolverFactory;</p> -<p>public void myMethod() { try { String resourcePath = "path/to/resource"; ResourceResolver resourceResolver = resolverFactory.getAdministrativeResourceResolver(null); Resource res = resourceResolver.getResource(resourcePath); // do something with the resource // when done, close the ResourceResolver resourceResolver.close(); } catch (LoginException e) { // log the error } }</p> +<pre><code>#!java +@Reference +private ResourceResolverFactory resolverFactory; + +public void myMethod() { + try { + String resourcePath = "path/to/resource"; + ResourceResolver resourceResolver = resolverFactory.getAdministrativeResourceResolver(null); + Resource res = resourceResolver.getResource(resourcePath); + // do something with the resource + // when done, close the ResourceResolver + resourceResolver.close(); + } catch (LoginException e) { + // log the error + } +} +</code></pre> <h2>Within a Servlet</h2> <p>You can access the resource defined by the request URL through the <code>SlingHttpServletRequest</code>:</p> -<h1>!java</h1> -<p>// req is the SlingHttpServletRequest Resource res = req.getResource();</p> +<pre><code>#!java +// req is the SlingHttpServletRequest +Resource res = req.getResource(); +</code></pre> <p>You can access any resource by first accessing the <code>ResourceResolver</code>:</p> -<h1>!java</h1> -<p>String resourcePath = "path/to/resource"; // req is the SlingHttpServletRequest ResourceResolver resourceResolver = req.getResourceResolver(); Resource res = resourceResolver.getResource(resourcePath);</p> +<pre><code>#!java +String resourcePath = "path/to/resource"; +// req is the SlingHttpServletRequest +ResourceResolver resourceResolver = req.getResourceResolver(); +Resource res = resourceResolver.getResource(resourcePath); +</code></pre> <h2>Within a JSP file</h2> -<p>When you use the <code><sling:defineObjects></code> tag in a JSP file, you have access to a few handy objects, one of them is <code>resource</code>, the resource that is resolved from the URL. Another one is <code>resourceResolver</code>, the <code>ResourceResolver</code> defined through the <code>SlingHttpServletRequest</code>.</p> +<p>When you use the <code><sling:defineObjects></code> tag in a JSP file, you have access to a few handy objects, one of them is <code>resource</code>, the resource that is resolved from the URL. Another one is <code>resourceResolver</code>, the <code>ResourceResolver</code> defined through the <code>SlingHttpServletRequest</code>. </p> <p>To access a resource:</p> -<h1>!jsp</h1> -<p><sling:defineObjects> <% String resourcePath = "path/to/resource"; Resource res = resourceResolver.getResource(resourcePath); %></p> +<pre><code>#!jsp +<sling:defineObjects> +<% + String resourcePath = "path/to/resource"; + Resource res = resourceResolver.getResource(resourcePath); +%> +</code></pre> <p>If needed you can adapt a Sling Resource to a JCR Node:</p> -<h1>!java</h1> -<p>Node node = resource.adaptTo(Node.class);</p> +<pre><code>#!java +Node node = resource.adaptTo(Node.class); +</code></pre> <p>Note: <code>resource.adaptTo(Node.class)</code> may return null if the resource is not backed by a JCR node. This is particularly the case for <code>NonExistingResource</code> resources or resource provided by a non-JCR resource provider.</p> <h2>Accessing a Property</h2> <p>The <code>ValueMap</code> is an easy way to access properties of a resource. With most resources you can use <code>Adaptable.adaptTo(Class)</code> to adapt the resource to a value map:</p> -<h1>!java</h1> -<p>// res is the Resource ValueMap properties = res.adaptTo(ValueMap.class);</p> +<pre><code>#!java +// res is the Resource +ValueMap properties = res.adaptTo(ValueMap.class); +</code></pre> <p>You can also access the properties through the <code>ResourceUtil</code> utility class:</p> -<h1>!java</h1> -<p>// res is the Resource ValueMap properties = ResourceUtil.getValueMap(res);</p> +<pre><code>#!java +// res is the Resource +ValueMap properties = ResourceUtil.getValueMap(res); +</code></pre> <p>Then, to access a specific String property called <code>propName</code>:</p> -<h1>!java</h1> -<p>String rule = properties.get(propName, (String) null);</p> +<pre><code>#!java +String rule = properties.get(propName, (String) null); +</code></pre> <p>For more details about resources and how to access them in Sling, you can refer to the <a href="/documentation/the-sling-engine/resources.html">Sling documentation about Resources</a>.</p></section></div></div> <div class="footer"> <div class="timestamp"> http://git-wip-us.apache.org/repos/asf/sling-site/blob/3a935d04/documentation/tutorials-how-tos/how-to-manage-events-in-sling.html ---------------------------------------------------------------------- diff --git a/documentation/tutorials-how-tos/how-to-manage-events-in-sling.html b/documentation/tutorials-how-tos/how-to-manage-events-in-sling.html index e55ee4e..e633722 100644 --- a/documentation/tutorials-how-tos/how-to-manage-events-in-sling.html +++ b/documentation/tutorials-how-tos/how-to-manage-events-in-sling.html @@ -2,22 +2,22 @@ <head> <meta charset="utf-8"/> <title>Apache Sling on JBake</title> - <link rel="stylesheet" href="/res/css/site.css"/> - <link rel="stylesheet" href="/res/css/codehilite.css"/> + <link rel="stylesheet" href="/ng/res/css/site.css"/> + <link rel="icon" href="/ng/res/favicon.ico"/> <div class="title"> <div class="logo"> <a href="http://sling.apache.org"> - <img border="0" alt="Apache Sling" src="/res/logos/sling.svg"/> + <img border="0" alt="Apache Sling" src="/ng/res/logos/sling.svg"/> </a> </div><div class="header"> <a href="http://www.apache.org"> - <img border="0" alt="Apache" src="/res/logos/apache.png"/> + <img border="0" alt="Apache" src="/ng/res/logos/apache.png"/> </a> </div> </div> </head><body> <div class="menu"> - <strong><a href="/documentation.html">Documentation</a></strong><br/><a href="/documentation/getting-started.html">Getting Started</a><br/><a href="/documentation/the-sling-engine.html">The Sling Engine</a><br/><a href="/documentation/development.html">Development</a><br/><a href="/documentation/bundles.html">Bundles</a><br/><a href="/documentation/tutorials-how-tos.html">Tutorials & How-Tos</a><br/><a href="/documentation/configuration.html">Configuration</a><p></p><a href="http://s.apache.org/sling.wiki">Wiki</a><br/><a href="http://s.apache.org/sling.faq">FAQ</a><br/><p></p><strong>API Docs</strong><br/><a href="/apidocs/sling9/index.html">Sling 9</a><br/><a href="/apidocs/sling8/index.html">Sling 8</a><br/><a href="/apidocs/sling7/index.html">Sling 7</a><br/><a href="/apidocs/sling6/index.html">Sling 6</a><br/><a href="/apidocs/sling5/index.html">Sling 5</a><br/><a href="/javadoc-io.html">Archive at javadoc.io</a><br/><p></p><strong>Project info</strong><br/><a h ref="/downloads.cgi">Downloads</a><br/><a href="http://www.apache.org/licenses/">License</a><br/><a href="/contributing.html">Contributing</a><br/><a href="/news.html">News</a><br/><a href="/links.html">Links</a><br/><a href="/project-information.html">Project Information</a><br/><a href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a><br/><a href="http://ci.apache.org/builders/sling-trunk">Build Server</a><br/><a href="/project-information/security.html">Security</a><br/><p></p><strong>Source</strong><br/><a href="http://svn.apache.org/viewvc/sling/trunk">Subversion</a><br/><a href="git://git.apache.org/sling.git">Git</a><br/><a href="https://github.com/apache/sling">Github Mirror</a><br/><p></p><strong>Sponsorship</strong><br/><a href="http://www.apache.org/foundation/thanks.html">Thanks</a><br/><a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a><br/><a href="https://donate.apache.org/">Donate!</a><br/><a href="http://www.apache.org/foun dation/buy_stuff.html">Buy Stuff</a><br/><p></p><strong><a href="/sitemap.html">Site Map</a></strong> + <strong><a href="/ng/documentation.html">Documentation</a></strong><br/><a href="/ng/documentation/getting-started.html">Getting Started</a><br/><a href="/ng/documentation/the-sling-engine.html">The Sling Engine</a><br/><a href="/ng/documentation/development.html">Development</a><br/><a href="/ng/documentation/bundles.html">Bundles</a><br/><a href="/ng/documentation/tutorials-how-tos.html">Tutorials & How-Tos</a><br/><a href="/ng/documentation/configuration.html">Configuration</a><p></p><a href="http://s.apache.org/sling.wiki">Wiki</a><br/><a href="http://s.apache.org/sling.faq">FAQ</a><br/><p></p><strong>API Docs</strong><br/><a href="/ng/apidocs/sling9/index.html">Sling 9</a><br/><a href="/ng/apidocs/sling8/index.html">Sling 8</a><br/><a href="/ng/apidocs/sling7/index.html">Sling 7</a><br/><a href="/ng/apidocs/sling6/index.html">Sling 6</a><br/><a href="/ng/apidocs/sling5/index.html">Sling 5</a><br/><a href="/ng/javadoc-io.html">Archive at javadoc.io</a><br/><p></p ><strong>Project info</strong><br/><a >href="/ng/downloads.cgi">Downloads</a><br/><a >href="http://www.apache.org/licenses/">License</a><br/><a >href="/ng/contributing.html">Contributing</a><br/><a >href="/ng/news.html">News</a><br/><a href="/ng/links.html">Links</a><br/><a >href="/ng/project-information.html">Project Information</a><br/><a >href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a><br/><a >href="http://ci.apache.org/builders/sling-trunk">Build Server</a><br/><a >href="/ng/project-information/security.html">Security</a><br/><p></p><strong>Source</strong><br/><a > href="http://svn.apache.org/viewvc/sling/trunk">Subversion</a><br/><a >href="git://git.apache.org/sling.git">Git</a><br/><a >href="https://github.com/apache/sling">Github >Mirror</a><br/><p></p><strong>Sponsorship</strong><br/><a >href="http://www.apache.org/foundation/thanks.html">Thanks</a><br/><a >href="http://www.apache.org/foundation/sponsorship.html">Become a >Sponsor</a><br/><a href="https://donate.apache. org/">Donate!</a><br/><a href="http://www.apache.org/foundation/buy_stuff.html">Buy Stuff</a><br/><p></p><strong><a href="/ng/sitemap.html">Site Map</a></strong> </div> <div class="main"> <div class="row"><div class="small-12 columns"><section class="wrap"><header><h1>How to Manage Job in Sling</h1></header><p>Apache Sling supports the execution of jobs with the guarantee of processing the job at least once. This can be seen as an extensions of the OSGi event admin, although jobs are not started or processed by OSGi events leveraging the OSGi event admin.</p> <p>For more details please refer to the following resources:</p> @@ -48,37 +48,84 @@ <h2>Listening to OSGI Events</h2> <p>To listen to OSGi events in Sling you just need to register an <strong>org.osgi.service.event.EventHandler</strong> service with an <strong>event.topics</strong> property that describes which event topics the handler is interested in.</p> <p>To listen to a Sling <strong>resource added</strong> events, for example, you'll set the <em>event.topics</em> property to <strong>org.apache.sling.api.SlingConstants.TOPIC_RESOURCE_ADDED</strong> in the class annotations:</p> -<p>:::java @Property(name=org.osgi.service.event.EventConstants.EVENT_TOPIC, value=org.apache.sling.api.SlingConstants.TOPIC_RESOURCE_ADDED)</p> +<pre><code> :::java + @Property(name=org.osgi.service.event.EventConstants.EVENT_TOPIC, + value=org.apache.sling.api.SlingConstants.TOPIC_RESOURCE_ADDED) +</code></pre> <p>The javadocs of the TOPIC_ constants in the <a href="/apidocs/sling6/org/apache/sling/api/SlingConstants.html">org.apache.sling.api.SlingConstants</a> class lists and explains the available event topics available in Sling.</p> <h2>Starting a job</h2> <p>To start a job, the <em>JobManager</em> service can be used. It needs a job topic and a payload. In our case we define our dropbox job topic and give the resource path as the payload:</p> -<p>:::java final String resourcePath = ...; // path to the resource to handle final Map<String, Object> payload = new HashMap<String, Object>(); payload.put("resourcePath", resourcePath); // start job this.jobManager.addJob(JOB_TOPIC, payload);</p> +<pre><code>:::java + final String resourcePath = ...; // path to the resource to handle + final Map<String, Object> payload = new HashMap<String, Object>(); + payload.put("resourcePath", resourcePath); + // start job + this.jobManager.addJob(JOB_TOPIC, payload); +</code></pre> <p>To receive the resource event, the service needs to implement the <strong>org.osgi.service.event.EventHandler</strong> interface and register it as an EventHandler service:</p> -<p>:::java @Component(immediate=true) // immediate should only be used in rare cases (see below) @Service(value=EventHandler.class) public class DropBoxService implements EventHandler { ... }</p> +<pre><code>:::java +@Component(immediate=true) // immediate should only be used in rare cases (see below) +@Service(value=EventHandler.class) +public class DropBoxService implements EventHandler { + ... +} +</code></pre> <p>Usually a service should be lazy and therefore not declare itself to be immediate (in the Component annotation). However as this service is an event handler and might receive a lot of events even concurrently, it is advised to set the immediate flag to true on the component. Otherwise our event handler would be created and destroyed with every event coming in.</p> <p>To start the job we need a reference to the JobManager:</p> -<p>:::java @Reference private JobManager jobManager;</p> +<pre><code>:::java +@Reference +private JobManager jobManager; +</code></pre> <p>The job topic for dropbox job events needs to be defined:</p> -<p>:::java /** The job topic for dropbox job events. */ public static final String JOB_TOPIC = "com/sling/eventing/dropbox/job";</p> +<pre><code>:::java +/** The job topic for dropbox job events. */ +public static final String JOB_TOPIC = "com/sling/eventing/dropbox/job"; +</code></pre> <p>The <strong>org.osgi.service.event.EventHandler#handleEvent(Event event)</strong> method needs to be implemented:</p> <p>Its logic is as follows:</p> <ul> <li>The OSGI event is analyzed.</li> - <li>If the event is a file that has been added to <em>/tmp/dropbox</em>:</li> - <li>An job is created with 1 property:</li> - <li>A property for the file path.</li> - <li>The job is started</li> + <li>If the event is a file that has been added to <em>/tmp/dropbox</em>: + <ul> + <li>An job is created with 1 property: + <ul> + <li>A property for the file path.</li> + </ul> + </li> + <li>The job is started</li> + </ul> + </li> </ul> <p>For example:</p> -<p>:::java public void handleEvent(final Event event) { // get the resource event information final String propPath = (String) event.getProperty(SlingConstants.PROPERTY_PATH); final String propResType = (String) event.getProperty(SlingConstants.PROPERTY_RESOURCE_TYPE);</p> -<p>// a job is started if a file is added to /tmp/dropbox if ( propPath.startsWith("/tmp/dropbox") && "nt:file".equals(propResType) ) { // create payload final Map<String, Object> payload = new HashMap<String, Object>(); payload.put("resourcePath", propPath); // start job this.jobManager.addJob(JOB_TOPIC, payload); logger.info("the dropbox job has been started for: {}", propPath); } }</p> +<pre><code>:::java +public void handleEvent(final Event event) { + // get the resource event information + final String propPath = (String) event.getProperty(SlingConstants.PROPERTY_PATH); + final String propResType = (String) event.getProperty(SlingConstants.PROPERTY_RESOURCE_TYPE); + + // a job is started if a file is added to /tmp/dropbox + if ( propPath.startsWith("/tmp/dropbox") && "nt:file".equals(propResType) ) { + // create payload + final Map<String, Object> payload = new HashMap<String, Object>(); + payload.put("resourcePath", propPath); + // start job + this.jobManager.addJob(JOB_TOPIC, payload); + logger.info("the dropbox job has been started for: {}", propPath); + } +} +</code></pre> <p>The complete code for the <strong>DropBoxService</strong> service is available <a href="DropBoxService.java">here</a>.</p> <h2>Consuming Job Events</h2> <p>Now that you have implemented a service that starts a job when a file is uploaded to <strong>/tmp/dropbox</strong>, you will implement the service <strong>DropBoxEventHandler</strong> that processes those jobs and moves the files to a location according to their MIME types.</p> <p>To process to the job that have been defined before the property <strong>job.topics</strong> needs to be set to <strong>DropBoxService.JOB_TOPIC</strong> in the class annotations:</p> -<p>:::java @Property(name="job.topics", value=DropBoxService.JOB_TOPIC)</p> +<pre><code>:::java +@Property(name="job.topics", + value=DropBoxService.JOB_TOPIC) +</code></pre> <p>In addition the service needs to implement the <strong>org.apache.sling.event.jobs.consumer.JobConsumer</strong> interface:</p> -<p>:::java public class DropBoxEventHandler implements JobConsumer {</p> +<pre><code>:::java +public class DropBoxEventHandler implements JobConsumer { +</code></pre> <p>Some class fields need to be defined:</p> <ul> <li>The default logger.</li> @@ -86,9 +133,18 @@ <li>The destination paths of the files.</li> </ul> <p>For example:</p> -<p>:::java /** Default log. */ protected final Logger logger = LoggerFactory.getLogger(this.getClass());</p> -<p>@Reference private ResourceResolverFactory resolverFactory;</p> -<p>private final static String IMAGES_PATH = "/dropbox/images/"; private final static String MUSIC_PATH = "/dropbox/music/"; private final static String MOVIES_PATH = "/dropbox/movies/"; private final static String OTHER_PATH = "/dropbox/other/";</p> +<pre><code>:::java +/** Default log. */ +protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + +@Reference +private ResourceResolverFactory resolverFactory; + +private final static String IMAGES_PATH = "/dropbox/images/"; +private final static String MUSIC_PATH = "/dropbox/music/"; +private final static String MOVIES_PATH = "/dropbox/movies/"; +private final static String OTHER_PATH = "/dropbox/other/"; +</code></pre> <p>The <strong>org.apache.sling.event.jobs.consumer.JobConsume#process(Job job)</strong> method needs to be implemented:</p> <p>Its logic is as follows:</p> <ul> @@ -98,9 +154,47 @@ <li>The file is moved to the new location by using a JCR session (as the Sling Resource API doesn't support move atm)</li> </ul> <p>or in Java Code:</p> -<p>:::java public JobResult process(final Job job) { ResourceResolver adminResolver = null; try { adminResolver = resolverFactory.getAdministrativeResourceResolver(null);</p> -<p>final String resourcePath = (String) job.getProperty("resourcePath"); final String resourceName = resourcePath.substring(resourcePath.lastIndexOf("/") + 1);</p> -<p>final Resource res = adminResolver.getResource(resourcePath); if ( res.isResourceType("nt:file") ) { final String mimeType = res.getResourceMetadata().getContentType(); String destDir; if (mimeType.equals("image/png")) { destDir = IMAGES_PATH; } else if (mimeType.equals("audio/mpeg")) { destDir = MUSIC_PATH; } else if (mimeType.equals("video/x-msvideo")) { destDir = MOVIES_PATH; } else { destDir = OTHER_PATH; } final Session adminSession = adminResolver.adaptTo(Session.class); adminSession.move(resourcePath, destDir + resourceName); adminSession.save(); logger.info("The file {} has been moved to {}", resourceName, destDir); } return JobResult.OK; } catch (final Exception e) { logger.error("Exception: " + e, e); return JobResult.FAILED; } finally { if (adminResolver != null) { adminResolver.close(); } } }</p> +<pre><code>:::java +public JobResult process(final Job job) { + ResourceResolver adminResolver = null; + try { + adminResolver = resolverFactory.getAdministrativeResourceResolver(null); + + final String resourcePath = (String) job.getProperty("resourcePath"); + final String resourceName = resourcePath.substring(resourcePath.lastIndexOf("/") + 1); + + final Resource res = adminResolver.getResource(resourcePath); + if ( res.isResourceType("nt:file") ) { + final String mimeType = res.getResourceMetadata().getContentType(); + String destDir; + if (mimeType.equals("image/png")) { + destDir = IMAGES_PATH; + } + else if (mimeType.equals("audio/mpeg")) { + destDir = MUSIC_PATH; + } + else if (mimeType.equals("video/x-msvideo")) { + destDir = MOVIES_PATH; + } + else { + destDir = OTHER_PATH; + } + final Session adminSession = adminResolver.adaptTo(Session.class); + adminSession.move(resourcePath, destDir + resourceName); + adminSession.save(); + logger.info("The file {} has been moved to {}", resourceName, destDir); + } + return JobResult.OK; + } catch (final Exception e) { + logger.error("Exception: " + e, e); + return JobResult.FAILED; + } finally { + if (adminResolver != null) { + adminResolver.close(); + } + } +} +</code></pre> <p>The complete code for the <strong>DropBoxEventHandler</strong> service is available <a href="DropBoxEventHandler.java">here</a>.</p></section></div></div> <div class="footer"> <div class="timestamp"> http://git-wip-us.apache.org/repos/asf/sling-site/blob/3a935d04/documentation/tutorials-how-tos/installing-and-upgrading-bundles.html ---------------------------------------------------------------------- diff --git a/documentation/tutorials-how-tos/installing-and-upgrading-bundles.html b/documentation/tutorials-how-tos/installing-and-upgrading-bundles.html index 90cd71d..ea04f52 100644 --- a/documentation/tutorials-how-tos/installing-and-upgrading-bundles.html +++ b/documentation/tutorials-how-tos/installing-and-upgrading-bundles.html @@ -2,22 +2,22 @@ <head> <meta charset="utf-8"/> <title>Apache Sling on JBake</title> - <link rel="stylesheet" href="/res/css/site.css"/> - <link rel="stylesheet" href="/res/css/codehilite.css"/> + <link rel="stylesheet" href="/ng/res/css/site.css"/> + <link rel="icon" href="/ng/res/favicon.ico"/> <div class="title"> <div class="logo"> <a href="http://sling.apache.org"> - <img border="0" alt="Apache Sling" src="/res/logos/sling.svg"/> + <img border="0" alt="Apache Sling" src="/ng/res/logos/sling.svg"/> </a> </div><div class="header"> <a href="http://www.apache.org"> - <img border="0" alt="Apache" src="/res/logos/apache.png"/> + <img border="0" alt="Apache" src="/ng/res/logos/apache.png"/> </a> </div> </div> </head><body> <div class="menu"> - <strong><a href="/documentation.html">Documentation</a></strong><br/><a href="/documentation/getting-started.html">Getting Started</a><br/><a href="/documentation/the-sling-engine.html">The Sling Engine</a><br/><a href="/documentation/development.html">Development</a><br/><a href="/documentation/bundles.html">Bundles</a><br/><a href="/documentation/tutorials-how-tos.html">Tutorials & How-Tos</a><br/><a href="/documentation/configuration.html">Configuration</a><p></p><a href="http://s.apache.org/sling.wiki">Wiki</a><br/><a href="http://s.apache.org/sling.faq">FAQ</a><br/><p></p><strong>API Docs</strong><br/><a href="/apidocs/sling9/index.html">Sling 9</a><br/><a href="/apidocs/sling8/index.html">Sling 8</a><br/><a href="/apidocs/sling7/index.html">Sling 7</a><br/><a href="/apidocs/sling6/index.html">Sling 6</a><br/><a href="/apidocs/sling5/index.html">Sling 5</a><br/><a href="/javadoc-io.html">Archive at javadoc.io</a><br/><p></p><strong>Project info</strong><br/><a h ref="/downloads.cgi">Downloads</a><br/><a href="http://www.apache.org/licenses/">License</a><br/><a href="/contributing.html">Contributing</a><br/><a href="/news.html">News</a><br/><a href="/links.html">Links</a><br/><a href="/project-information.html">Project Information</a><br/><a href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a><br/><a href="http://ci.apache.org/builders/sling-trunk">Build Server</a><br/><a href="/project-information/security.html">Security</a><br/><p></p><strong>Source</strong><br/><a href="http://svn.apache.org/viewvc/sling/trunk">Subversion</a><br/><a href="git://git.apache.org/sling.git">Git</a><br/><a href="https://github.com/apache/sling">Github Mirror</a><br/><p></p><strong>Sponsorship</strong><br/><a href="http://www.apache.org/foundation/thanks.html">Thanks</a><br/><a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a><br/><a href="https://donate.apache.org/">Donate!</a><br/><a href="http://www.apache.org/foun dation/buy_stuff.html">Buy Stuff</a><br/><p></p><strong><a href="/sitemap.html">Site Map</a></strong> + <strong><a href="/ng/documentation.html">Documentation</a></strong><br/><a href="/ng/documentation/getting-started.html">Getting Started</a><br/><a href="/ng/documentation/the-sling-engine.html">The Sling Engine</a><br/><a href="/ng/documentation/development.html">Development</a><br/><a href="/ng/documentation/bundles.html">Bundles</a><br/><a href="/ng/documentation/tutorials-how-tos.html">Tutorials & How-Tos</a><br/><a href="/ng/documentation/configuration.html">Configuration</a><p></p><a href="http://s.apache.org/sling.wiki">Wiki</a><br/><a href="http://s.apache.org/sling.faq">FAQ</a><br/><p></p><strong>API Docs</strong><br/><a href="/ng/apidocs/sling9/index.html">Sling 9</a><br/><a href="/ng/apidocs/sling8/index.html">Sling 8</a><br/><a href="/ng/apidocs/sling7/index.html">Sling 7</a><br/><a href="/ng/apidocs/sling6/index.html">Sling 6</a><br/><a href="/ng/apidocs/sling5/index.html">Sling 5</a><br/><a href="/ng/javadoc-io.html">Archive at javadoc.io</a><br/><p></p ><strong>Project info</strong><br/><a >href="/ng/downloads.cgi">Downloads</a><br/><a >href="http://www.apache.org/licenses/">License</a><br/><a >href="/ng/contributing.html">Contributing</a><br/><a >href="/ng/news.html">News</a><br/><a href="/ng/links.html">Links</a><br/><a >href="/ng/project-information.html">Project Information</a><br/><a >href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a><br/><a >href="http://ci.apache.org/builders/sling-trunk">Build Server</a><br/><a >href="/ng/project-information/security.html">Security</a><br/><p></p><strong>Source</strong><br/><a > href="http://svn.apache.org/viewvc/sling/trunk">Subversion</a><br/><a >href="git://git.apache.org/sling.git">Git</a><br/><a >href="https://github.com/apache/sling">Github >Mirror</a><br/><p></p><strong>Sponsorship</strong><br/><a >href="http://www.apache.org/foundation/thanks.html">Thanks</a><br/><a >href="http://www.apache.org/foundation/sponsorship.html">Become a >Sponsor</a><br/><a href="https://donate.apache. org/">Donate!</a><br/><a href="http://www.apache.org/foundation/buy_stuff.html">Buy Stuff</a><br/><p></p><strong><a href="/ng/sitemap.html">Site Map</a></strong> </div> <div class="main"> <div class="row"><div class="small-12 columns"><section class="wrap"><header><h1>Installing and Upgrading Bundles</h1></header><p>Excerpt: Explains how to install, upgrade and uninstall Bundles using the Sling Management console.</p> <div class="note"> @@ -52,7 +52,9 @@ We recommend to use the Apache Felix Web Console. The documentation below descri <p>Currently management of known OSGi Bundle Repositories is very simple. If a configured bundle repository is not available on startup, it will be marked as being inactive. If you know the repository is now available, you may click on the <em>Refresh</em> button, to activate it. Similarly, the contents of the repository may be modified by for example adding new bundles or updating bundles in the repository, these changes will be made known to Sling by clicking the <em>Refresh</em> button.</p> <p>There exists no GUI functionality yet to add a new repository to the list of known repositories. Instead you may submit a request with parameters <code>action</code> whose value must be <code>refreshOBR</code> and <code>repository</code> whose value must be the URL to the repository descriptor file generally called <code>repository.xml</code>.</p> <p>For example, if you run Sling on <code>http://localhost:7402/sample</code> with default location of the Sling Management Console, the following request would add a repository at <code>/tmp/repo/repository.xml</code> in the filesystem:</p> -<p>:::html http://localhost:7402/sample/system/console/bundlerepo?action=refreshOBR&repository=file:///tmp/repo/repository.xml</p> +<pre><code>:::html +http://localhost:7402/sample/system/console/bundlerepo?action=refreshOBR&repository=file:///tmp/repo/repository.xml +</code></pre> <p>Note: Only use <code>file:</code> URLs if you know Sling has access to the named file !</p></section></div></div> <div class="footer"> <div class="timestamp"> http://git-wip-us.apache.org/repos/asf/sling-site/blob/3a935d04/documentation/tutorials-how-tos/jackrabbit-persistence.html ---------------------------------------------------------------------- diff --git a/documentation/tutorials-how-tos/jackrabbit-persistence.html b/documentation/tutorials-how-tos/jackrabbit-persistence.html index cd3ab79..ffdf210 100644 --- a/documentation/tutorials-how-tos/jackrabbit-persistence.html +++ b/documentation/tutorials-how-tos/jackrabbit-persistence.html @@ -2,22 +2,22 @@ <head> <meta charset="utf-8"/> <title>Apache Sling on JBake</title> - <link rel="stylesheet" href="/res/css/site.css"/> - <link rel="stylesheet" href="/res/css/codehilite.css"/> + <link rel="stylesheet" href="/ng/res/css/site.css"/> + <link rel="icon" href="/ng/res/favicon.ico"/> <div class="title"> <div class="logo"> <a href="http://sling.apache.org"> - <img border="0" alt="Apache Sling" src="/res/logos/sling.svg"/> + <img border="0" alt="Apache Sling" src="/ng/res/logos/sling.svg"/> </a> </div><div class="header"> <a href="http://www.apache.org"> - <img border="0" alt="Apache" src="/res/logos/apache.png"/> + <img border="0" alt="Apache" src="/ng/res/logos/apache.png"/> </a> </div> </div> </head><body> <div class="menu"> - <strong><a href="/documentation.html">Documentation</a></strong><br/><a href="/documentation/getting-started.html">Getting Started</a><br/><a href="/documentation/the-sling-engine.html">The Sling Engine</a><br/><a href="/documentation/development.html">Development</a><br/><a href="/documentation/bundles.html">Bundles</a><br/><a href="/documentation/tutorials-how-tos.html">Tutorials & How-Tos</a><br/><a href="/documentation/configuration.html">Configuration</a><p></p><a href="http://s.apache.org/sling.wiki">Wiki</a><br/><a href="http://s.apache.org/sling.faq">FAQ</a><br/><p></p><strong>API Docs</strong><br/><a href="/apidocs/sling9/index.html">Sling 9</a><br/><a href="/apidocs/sling8/index.html">Sling 8</a><br/><a href="/apidocs/sling7/index.html">Sling 7</a><br/><a href="/apidocs/sling6/index.html">Sling 6</a><br/><a href="/apidocs/sling5/index.html">Sling 5</a><br/><a href="/javadoc-io.html">Archive at javadoc.io</a><br/><p></p><strong>Project info</strong><br/><a h ref="/downloads.cgi">Downloads</a><br/><a href="http://www.apache.org/licenses/">License</a><br/><a href="/contributing.html">Contributing</a><br/><a href="/news.html">News</a><br/><a href="/links.html">Links</a><br/><a href="/project-information.html">Project Information</a><br/><a href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a><br/><a href="http://ci.apache.org/builders/sling-trunk">Build Server</a><br/><a href="/project-information/security.html">Security</a><br/><p></p><strong>Source</strong><br/><a href="http://svn.apache.org/viewvc/sling/trunk">Subversion</a><br/><a href="git://git.apache.org/sling.git">Git</a><br/><a href="https://github.com/apache/sling">Github Mirror</a><br/><p></p><strong>Sponsorship</strong><br/><a href="http://www.apache.org/foundation/thanks.html">Thanks</a><br/><a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a><br/><a href="https://donate.apache.org/">Donate!</a><br/><a href="http://www.apache.org/foun dation/buy_stuff.html">Buy Stuff</a><br/><p></p><strong><a href="/sitemap.html">Site Map</a></strong> + <strong><a href="/ng/documentation.html">Documentation</a></strong><br/><a href="/ng/documentation/getting-started.html">Getting Started</a><br/><a href="/ng/documentation/the-sling-engine.html">The Sling Engine</a><br/><a href="/ng/documentation/development.html">Development</a><br/><a href="/ng/documentation/bundles.html">Bundles</a><br/><a href="/ng/documentation/tutorials-how-tos.html">Tutorials & How-Tos</a><br/><a href="/ng/documentation/configuration.html">Configuration</a><p></p><a href="http://s.apache.org/sling.wiki">Wiki</a><br/><a href="http://s.apache.org/sling.faq">FAQ</a><br/><p></p><strong>API Docs</strong><br/><a href="/ng/apidocs/sling9/index.html">Sling 9</a><br/><a href="/ng/apidocs/sling8/index.html">Sling 8</a><br/><a href="/ng/apidocs/sling7/index.html">Sling 7</a><br/><a href="/ng/apidocs/sling6/index.html">Sling 6</a><br/><a href="/ng/apidocs/sling5/index.html">Sling 5</a><br/><a href="/ng/javadoc-io.html">Archive at javadoc.io</a><br/><p></p ><strong>Project info</strong><br/><a >href="/ng/downloads.cgi">Downloads</a><br/><a >href="http://www.apache.org/licenses/">License</a><br/><a >href="/ng/contributing.html">Contributing</a><br/><a >href="/ng/news.html">News</a><br/><a href="/ng/links.html">Links</a><br/><a >href="/ng/project-information.html">Project Information</a><br/><a >href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a><br/><a >href="http://ci.apache.org/builders/sling-trunk">Build Server</a><br/><a >href="/ng/project-information/security.html">Security</a><br/><p></p><strong>Source</strong><br/><a > href="http://svn.apache.org/viewvc/sling/trunk">Subversion</a><br/><a >href="git://git.apache.org/sling.git">Git</a><br/><a >href="https://github.com/apache/sling">Github >Mirror</a><br/><p></p><strong>Sponsorship</strong><br/><a >href="http://www.apache.org/foundation/thanks.html">Thanks</a><br/><a >href="http://www.apache.org/foundation/sponsorship.html">Become a >Sponsor</a><br/><a href="https://donate.apache. org/">Donate!</a><br/><a href="http://www.apache.org/foundation/buy_stuff.html">Buy Stuff</a><br/><p></p><strong><a href="/ng/sitemap.html">Site Map</a></strong> </div> <div class="main"> <div class="row"><div class="small-12 columns"><section class="wrap"><header><h1>Jackrabbit Persistence</h1></header><p>Out-of-the-box the embedded Jackrabbit repository used by Sling (the Embedded Jackrabbit Repository bundle) uses Derby to persist the JCR nodes and properties. For some applications or environments it may be required or required to replace Derby with another backing store such as PostgreSQL or Oracle.</p> <p>This page is based on the journey of Tony Giaccone to get Sling running with a PostgreSQL based Jackrabbit instance.</p> @@ -34,22 +34,29 @@ <p>Another option is to create the bundle on your own using Peter Kriens' <a href="http://bnd.bndtools.org/">bnd Tool</a>:</p> <ol> <li>Get the JDBC driver for your database from the driver provider</li> - <li>Wrap the JDBC driver library into an OSGi bundle:</li> + <li>Wrap the JDBC driver library into an OSGi bundle: + <pre><code>:::sh +# Example for PostgreSQL JDBC 3 driver 8.4-701 +$ java -jar bnd.jar wrap postgresql-8.4-701.jdbc3.jar +$ mv postgresql-8.4-701.jdbc3.bar postgresql-8.4-701.jdbc3-bnd.jar +</code></pre> + </li> + <li> + <p>Deploy the driver to your local Maven 2 Repository (Required if adding the JDBC driver to a Maven build, e.g. using the Sling Launchpad Plugin)</p> + <pre><code>:::sh +$ mvn install:install-file \ + -DgroupId=postgresql -DartifactId=postgresql -Dversion=8.4.701.jdbc3 \ + -Dpackaging=jar -Dfile=postgresql-8.4-701.jdbc3-bnd.jar +</code></pre> + </li> </ol> -<p>:::sh</p> -<h1>Example for PostgreSQL JDBC 3 driver 8.4-701</h1> -<p>$ java -jar bnd.jar wrap postgresql-8.4-701.jdbc3.jar $ mv postgresql-8.4-701.jdbc3.bar postgresql-8.4-701.jdbc3-bnd.jar</p> -<ol> - <li>Deploy the driver to your local Maven 2 Repository (Required if adding the JDBC driver to a Maven build, e.g. using the Sling Launchpad Plugin)</li> -</ol> -<p>:::sh $ mvn install:install-file -DgroupId=postgresql -DartifactId=postgresql -Dversion=8.4.701.jdbc3 -Dpackaging=jar -Dfile=postgresql-8.4-701.jdbc3-bnd.jar</p> <p>Tony reports no success with the Spring Source bundle, whily the bnd approach worked for the PostgreSQL JDBC driver.</p> <h2>Replace Derby in a running Sling Instance</h2> <p>To replace Derby in a running Sling instance follow these steps (e.g. through the Web Console at <code>/system/console</code>):</p> <ol> <li>Uninstall the Apache Derby bundle</li> <li>Install the JDBC bundle prepared in the first step</li> - <li>Stop the Jackrabbit Embedded Repository bundle This needs to be reconfigured and restarted anyway. So lets just stop it to prevent failures in the next step.</li> + <li>Stop the Jackrabbit Embedded Repository bundle<br/>This needs to be reconfigured and restarted anyway. So lets just stop it to prevent failures in the next step.</li> <li>Refresh the packages (click the <em>Refresh Packages</em> button)</li> </ol> <p>Alternatively, you may wish to stop Sling after uninstalling Derby and installing the JDBC bundle. Technically, this is not required, though.</p> @@ -58,8 +65,38 @@ <p>To prepare a repository.xml file before first startup, use the <a href="http://svn.apache.org/repos/asf/sling/trunk/bundles/jcr/jackrabbit-server/src/main/resources/repository.xml"><code>repository.xml</code></a> as a template and modify it by replacing the <code><PersistenceManager></code> elements to refer to the selected persistence manager.</p> <p>If the file already exists, you can modifiy this existing file and there is no need to get the original from the SVN repository.</p> <p>For example to use PostgreSQL instead of Derby modify the <code><PersistenceManager></code> elements as follows:</p> -<p>:::xml <Repository> ... <Workspace name="${wsp.name}"> ... <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.PostgreSQLPersistenceManager"> <param name="driver" value="org.postgresql.Driver"/> <param name="url" value="jdbc:postgresql://localhost:5432/YOUR_DB_NAME_HERE"/> <param name="schema" value="postgresql"/> <param name="user" value="YOUR_USER_HERE"/> <param name="password" value="YOUR_PASSWORD_HERE"/> <param name="schemaObjectPrefix" value="jcr_${wsp.name}_"/> <param name="externalBLOBs" value="false"/> </PersistenceManager> ... </Workspace></p> -<p><Versioning rootPath="${rep.home}/version"> ... <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.PostgreSQLPersistenceManager"> <param name="driver" value="org.postgresql.Driver"/> <param name="url" value="jdbc:postgresql://localhost:5432/YOUR_DB_NAME_HERE"/> <param name="schema" value="postgresql"/> <param name="user" value="YOUR_USER_HERE"/> <param name="password" value="YOUR_PASSWORD_HERE"/> <param name="schemaObjectPrefix" value="version_"/> <param name="externalBLOBs" value="false"/> </PersistenceManager> </Versioning> ... </Repository></p> +<pre><code>:::xml +<Repository> + ... + <Workspace name="${wsp.name}"> + ... + <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.PostgreSQLPersistenceManager"> + <param name="driver" value="org.postgresql.Driver"/> + <param name="url" value="jdbc:postgresql://localhost:5432/YOUR_DB_NAME_HERE"/> + <param name="schema" value="postgresql"/> + <param name="user" value="YOUR_USER_HERE"/> + <param name="password" value="YOUR_PASSWORD_HERE"/> + <param name="schemaObjectPrefix" value="jcr_${wsp.name}_"/> + <param name="externalBLOBs" value="false"/> + </PersistenceManager> + ... + </Workspace> + + <Versioning rootPath="${rep.home}/version"> + ... + <PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.PostgreSQLPersistenceManager"> + <param name="driver" value="org.postgresql.Driver"/> + <param name="url" value="jdbc:postgresql://localhost:5432/YOUR_DB_NAME_HERE"/> + <param name="schema" value="postgresql"/> + <param name="user" value="YOUR_USER_HERE"/> + <param name="password" value="YOUR_PASSWORD_HERE"/> + <param name="schemaObjectPrefix" value="version_"/> + <param name="externalBLOBs" value="false"/> + </PersistenceManager> + </Versioning> + ... +</Repository> +</code></pre> <p>Modify the <code>url</code>, <code>user</code>, and <code>password</code> parameters to match your database setup.</p> <p>If you reconfigure Jackrabbit to use the new persistence manager, the existing repository data in the <code>sling/jackrabbit</code> directory, except the <code>repository.xml</code> file, of course, should now be removed.</p> <p>Finally either start Sling or start the Jackrabbit Embedded Repository bundle.</p> http://git-wip-us.apache.org/repos/asf/sling-site/blob/3a935d04/documentation/tutorials-how-tos/testing-sling-based-applications.html ---------------------------------------------------------------------- diff --git a/documentation/tutorials-how-tos/testing-sling-based-applications.html b/documentation/tutorials-how-tos/testing-sling-based-applications.html index 942dfd5..61fe741 100644 --- a/documentation/tutorials-how-tos/testing-sling-based-applications.html +++ b/documentation/tutorials-how-tos/testing-sling-based-applications.html @@ -2,28 +2,28 @@ <head> <meta charset="utf-8"/> <title>Apache Sling on JBake</title> - <link rel="stylesheet" href="/res/css/site.css"/> - <link rel="stylesheet" href="/res/css/codehilite.css"/> + <link rel="stylesheet" href="/ng/res/css/site.css"/> + <link rel="icon" href="/ng/res/favicon.ico"/> <div class="title"> <div class="logo"> <a href="http://sling.apache.org"> - <img border="0" alt="Apache Sling" src="/res/logos/sling.svg"/> + <img border="0" alt="Apache Sling" src="/ng/res/logos/sling.svg"/> </a> </div><div class="header"> <a href="http://www.apache.org"> - <img border="0" alt="Apache" src="/res/logos/apache.png"/> + <img border="0" alt="Apache" src="/ng/res/logos/apache.png"/> </a> </div> </div> </head><body> <div class="menu"> - <strong><a href="/documentation.html">Documentation</a></strong><br/><a href="/documentation/getting-started.html">Getting Started</a><br/><a href="/documentation/the-sling-engine.html">The Sling Engine</a><br/><a href="/documentation/development.html">Development</a><br/><a href="/documentation/bundles.html">Bundles</a><br/><a href="/documentation/tutorials-how-tos.html">Tutorials & How-Tos</a><br/><a href="/documentation/configuration.html">Configuration</a><p></p><a href="http://s.apache.org/sling.wiki">Wiki</a><br/><a href="http://s.apache.org/sling.faq">FAQ</a><br/><p></p><strong>API Docs</strong><br/><a href="/apidocs/sling9/index.html">Sling 9</a><br/><a href="/apidocs/sling8/index.html">Sling 8</a><br/><a href="/apidocs/sling7/index.html">Sling 7</a><br/><a href="/apidocs/sling6/index.html">Sling 6</a><br/><a href="/apidocs/sling5/index.html">Sling 5</a><br/><a href="/javadoc-io.html">Archive at javadoc.io</a><br/><p></p><strong>Project info</strong><br/><a h ref="/downloads.cgi">Downloads</a><br/><a href="http://www.apache.org/licenses/">License</a><br/><a href="/contributing.html">Contributing</a><br/><a href="/news.html">News</a><br/><a href="/links.html">Links</a><br/><a href="/project-information.html">Project Information</a><br/><a href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a><br/><a href="http://ci.apache.org/builders/sling-trunk">Build Server</a><br/><a href="/project-information/security.html">Security</a><br/><p></p><strong>Source</strong><br/><a href="http://svn.apache.org/viewvc/sling/trunk">Subversion</a><br/><a href="git://git.apache.org/sling.git">Git</a><br/><a href="https://github.com/apache/sling">Github Mirror</a><br/><p></p><strong>Sponsorship</strong><br/><a href="http://www.apache.org/foundation/thanks.html">Thanks</a><br/><a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor</a><br/><a href="https://donate.apache.org/">Donate!</a><br/><a href="http://www.apache.org/foun dation/buy_stuff.html">Buy Stuff</a><br/><p></p><strong><a href="/sitemap.html">Site Map</a></strong> + <strong><a href="/ng/documentation.html">Documentation</a></strong><br/><a href="/ng/documentation/getting-started.html">Getting Started</a><br/><a href="/ng/documentation/the-sling-engine.html">The Sling Engine</a><br/><a href="/ng/documentation/development.html">Development</a><br/><a href="/ng/documentation/bundles.html">Bundles</a><br/><a href="/ng/documentation/tutorials-how-tos.html">Tutorials & How-Tos</a><br/><a href="/ng/documentation/configuration.html">Configuration</a><p></p><a href="http://s.apache.org/sling.wiki">Wiki</a><br/><a href="http://s.apache.org/sling.faq">FAQ</a><br/><p></p><strong>API Docs</strong><br/><a href="/ng/apidocs/sling9/index.html">Sling 9</a><br/><a href="/ng/apidocs/sling8/index.html">Sling 8</a><br/><a href="/ng/apidocs/sling7/index.html">Sling 7</a><br/><a href="/ng/apidocs/sling6/index.html">Sling 6</a><br/><a href="/ng/apidocs/sling5/index.html">Sling 5</a><br/><a href="/ng/javadoc-io.html">Archive at javadoc.io</a><br/><p></p ><strong>Project info</strong><br/><a >href="/ng/downloads.cgi">Downloads</a><br/><a >href="http://www.apache.org/licenses/">License</a><br/><a >href="/ng/contributing.html">Contributing</a><br/><a >href="/ng/news.html">News</a><br/><a href="/ng/links.html">Links</a><br/><a >href="/ng/project-information.html">Project Information</a><br/><a >href="https://issues.apache.org/jira/browse/SLING">Issue Tracker</a><br/><a >href="http://ci.apache.org/builders/sling-trunk">Build Server</a><br/><a >href="/ng/project-information/security.html">Security</a><br/><p></p><strong>Source</strong><br/><a > href="http://svn.apache.org/viewvc/sling/trunk">Subversion</a><br/><a >href="git://git.apache.org/sling.git">Git</a><br/><a >href="https://github.com/apache/sling">Github >Mirror</a><br/><p></p><strong>Sponsorship</strong><br/><a >href="http://www.apache.org/foundation/thanks.html">Thanks</a><br/><a >href="http://www.apache.org/foundation/sponsorship.html">Become a >Sponsor</a><br/><a href="https://donate.apache. org/">Donate!</a><br/><a href="http://www.apache.org/foundation/buy_stuff.html">Buy Stuff</a><br/><p></p><strong><a href="/ng/sitemap.html">Site Map</a></strong> </div> <div class="main"> <div class="row"><div class="small-12 columns"><section class="wrap"><header><h1>Testing Sling-based applications</h1></header><p>Automated testing of OSGi components and services can be challenging, as many of them depend on other services that must be present or simulated for testing.</p> <p>This page describes the various approaches that we use to test Sling itself, and introduces a number of tools that can help testing OSGi and HTTP-based applications.</p> <p>[TOC]</p> <h2>Unit tests</h2> -<p>When possible, unit tests are obviously the fastest executing ones, and it's easy to keep them close to the code that they're testing.</p> +<p>When possible, unit tests are obviously the fastest executing ones, and it's easy to keep them close to the code that they're testing. </p> <p>We have quite a lot of those in Sling, the older use the JUnit3 TestCase base class, and later ones use JUnit4 annotations. Mixing both approaches is possible, there's no need to rewrite existing tests.</p> <h2>Tests that use a JCR repository</h2> <p>Utility classes from our <a href="https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/testing">commons/testing</a> module make it easy to get a real JCR repository for testing. That's a bit slower than pure unit tests, of course, but this only adds 1-2 seconds to the execution of a test suite.</p> @@ -36,15 +36,22 @@ <p>The problem with mocks is that it can become hard to make sure you're actually testing something, and not just "mocking mocks". At a certain level of complexity, it becomes quicker and clearer to actually start an OSGi framework for automated tests.</p> <h3>Side note: injecting services in private fields</h3> <p>To inject (real or fake) services in others for testing, without having to create getters and setters just for this, you could use a reflection-based trick, as in the below example. Utilities such as the <a href="http://junit-addons.sourceforge.net/junitx/util/PrivateAccessor.html">PrivateAccessor</a> from <a href="http://junit-addons.sourceforge.net/">junit-addons</a> make that simpler.</p> -<h1>!java</h1> -<p>// set resource resolver factory // in a ServletResolver object which has a private resourceResolverFactory field</p> -<p>ServletResolver servletResolver = .... Class<?> resolverClass = servletResolver.getClass().getSuperclass(); final java.lang.reflect.Field resolverField = resolverClass.getDeclaredField("resourceResolverFactory"); resolverField.setAccessible(true); resolverField.set(servletResolver, factory);</p> +<pre><code>#!java +// set resource resolver factory +// in a ServletResolver object which has a private resourceResolverFactory field + +ServletResolver servletResolver = .... +Class<?> resolverClass = servletResolver.getClass().getSuperclass(); +final java.lang.reflect.Field resolverField = resolverClass.getDeclaredField("resourceResolverFactory"); +resolverField.setAccessible(true); +resolverField.set(servletResolver, factory); +</code></pre> <h2>Pax Exam</h2> <p><a href="http://team.ops4j.org/wiki/display/paxexam/Pax+Exam">Pax Exam</a> allows you to easily start an OSGi framework during execution of a JUnit test suite.</p> <p>We currently use it for our <a href="https://svn.apache.org/repos/asf/sling/trunk/installer/it">Sling installer integration tests</a> for example. As parts of the installer interact directly with the OSGi framework, it felt safer to test it in a realistic situation rather than mock everything.</p> <p>Such tests are obviously slower than plain unit tests and tests that use mocks. Our installer integration tests, using Pax Exam, take about a minute to execute on a 2010 macbook pro.</p> <h2>Server-side JUnit tests</h2> -<p>The tools described on the <a href="/documentation/bundles/org-apache-sling-junit-bundles.html">JUnit server-side testing support</a> page allow for running JUnit tests on an live Sling instance, as part of the normal integration testing cycle.</p> +<p>The tools described on the <a href="/documentation/bundles/org-apache-sling-junit-bundles.html">JUnit server-side testing support</a> page allow for running JUnit tests on an live Sling instance, as part of the normal integration testing cycle. </p> <h2>HTTP-based integration tests</h2> <p>The <a href="https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules">Sling HTTP Testing Rules</a> allow writing integration tests easily. They are primarily meant to be used for tests that use http against a Sling instance and make use of the <a href="https://svn.apache.org/repos/asf/sling/trunk/testing/http/clients">org.apache.sling.testing.clients</a> which offer a simple, immutable and extendable way of working with specialized testing clients.</p> <p>The JUnit rules incorporate boiler-plate logic that is shared in tests and take the modern approach of using rules rather than inheritance. The <code>SlingRule</code> (for methods) or <code>SlingClassRule</code> (for test classes) are base rules, chaining other rules like <code>TestTimeoutRule</code>, <code>TestDescriptionRule</code>, <code>FilterRule</code>. The <code>SlingInstanceRule</code> extends that and starts a Sling instance if needed and also allows instantiating a <code>SlingClient</code> pointing to the instance and automatically configure the base url, credentials, etc.</p> @@ -52,14 +59,32 @@ <p>Starting an integration is very simple out of the box, but is very extendable, both by combining or configuring the junit rules and by using the versatile <code>SlingClient</code> (which can be extended or adapted by calling <code>adaptTo(MyClient.class)</code> without losing the client configuration)</p> <p>The <a href="https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules/README.md">README</a> provides more detail, as do <a href="https://svn.apache.org/repos/asf/sling/trunk/testing/junit/rules/src/test/java">the tests</a>. The <a href="https://svn.apache.org/repos/asf/sling/trunk/testing/http/clients">Sling HTTP Testing Clients</a> provide simple explanations, and unit tests.</p> <h4>Maven Dependency</h4> -<h1>!xml</h1> -<p><dependency> <groupId>org.apache.sling</groupId> <artifactId>org.apache.sling.testing.rules</artifactId> <version>0.1.0-SNAPSHOT</version> </dependency></p> +<pre><code>#!xml +<dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.testing.rules</artifactId> + <version>0.1.0-SNAPSHOT</version> +</dependency> +</code></pre> <h4>Simple Example using SlingInstanceRule</h4> -<h1>!java</h1> -<p>public class MySimpleIT {</p> -<p>@ClassRule public static SlingInstanceRule instanceRule = new SlingInstanceRule();</p> -<p>@Rule public SlingRule methodRule = new SlingRule(); // will configure test timeout, description, etc.</p> -<p>@Test public void testCreateNode() { SlingClient client = instanceRule.getAdminClient(); client.createNode("/content/myNode", "nt:unstructured"); Assert.assertTrue("Node should be there", client.exists("/content/myNode")); //client.adaptTo(OsgiConsoleClient.class).editConfigurationWithWait(10, "MYPID", null, myMap); } }</p> +<pre><code>#!java +public class MySimpleIT { + + @ClassRule + public static SlingInstanceRule instanceRule = new SlingInstanceRule(); + + @Rule + public SlingRule methodRule = new SlingRule(); // will configure test timeout, description, etc. + + @Test + public void testCreateNode() { + SlingClient client = instanceRule.getAdminClient(); + client.createNode("/content/myNode", "nt:unstructured"); + Assert.assertTrue("Node should be there", client.exists("/content/myNode")); + //client.adaptTo(OsgiConsoleClient.class).editConfigurationWithWait(10, "MYPID", null, myMap); + } +} +</code></pre> <h2>Summary</h2> <p>Combining the above testing techniques has worked well for us in creating and testing Sling. Being able to test things at different levels of integration has proved an efficient way to get good test coverage without having to write too much boring test code.</p></section></div></div> <div class="footer">