You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2019/05/20 11:23:20 UTC

svn commit: r1859550 [9/26] - in /jackrabbit/site/live/archive: ./ wiki/ wiki/JCR/ wiki/JCR/attachments/ wiki/JCR/attachments/115513387/ wiki/JCR/attachments/115513390/ wiki/JCR/attachments/115513408/ wiki/JCR/attachments/115513413/ wiki/JCR/attachment...

Added: jackrabbit/site/live/archive/wiki/JCR/DavidsModel_115513389.html
URL: http://svn.apache.org/viewvc/jackrabbit/site/live/archive/wiki/JCR/DavidsModel_115513389.html?rev=1859550&view=auto
==============================================================================
--- jackrabbit/site/live/archive/wiki/JCR/DavidsModel_115513389.html (added)
+++ jackrabbit/site/live/archive/wiki/JCR/DavidsModel_115513389.html Mon May 20 11:23:18 2019
@@ -0,0 +1,366 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Apache Jackrabbit : DavidsModel</title>
+        <link rel="stylesheet" href="styles/site.css" type="text/css" />
+        <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+
+    <body class="theme-default aui-theme-default">
+        <div id="page">
+            <div id="main" class="aui-page-panel">
+                <div id="main-header">
+                    <div id="breadcrumb-section">
+                        <ol id="breadcrumbs">
+                            <li class="first">
+                                <span><a href="index.html">Apache Jackrabbit</a></span>
+                            </li>
+                                                    <li>
+                                <span><a href="Home_70731.html">Home</a></span>
+                            </li>
+                                                </ol>
+                    </div>
+                    <h1 id="title-heading" class="pagetitle">
+                                                <span id="title-text">
+                            Apache Jackrabbit : DavidsModel
+                        </span>
+                    </h1>
+                </div>
+
+                <div id="content" class="view">
+                    <div class="page-metadata">
+                        
+        
+    
+        
+    
+        
+        
+            Created by <span class='author'> ASF Infrabot</span> on May 20, 2019
+                        </div>
+                    <div id="main-content" class="wiki-content group">
+                    <h1 id="DavidsModel-David&#39;sModel:Aguideforcontentmodeling">David's Model: A guide for content modeling</h1>
+
+<style type='text/css'>/*<![CDATA[*/
+div.rbtoc1558350680461 {padding: 0px;}
+div.rbtoc1558350680461 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1558350680461 li {margin-left: 0px;padding-left: 0px;}
+
+/*]]>*/</style><div class='toc-macro rbtoc1558350680461'>
+<ul class='toc-indentation'>
+<li><a href='#DavidsModel-David&#39;sModel:Aguideforcontentmodeling'>David&#39;s Model: A guide for content modeling</a>
+<ul class='toc-indentation'>
+<li><a href='#DavidsModel-Intro'>Intro</a></li>
+<li><a href='#DavidsModel-SevenSimplerules'>Seven Simple rules</a>
+<ul class='toc-indentation'>
+<li><a href='#DavidsModel-Rule#1:DataFirst,StructureLater.Maybe.'>Rule #1: Data First, Structure Later. Maybe.</a>
+<ul class='toc-indentation'>
+<li><a href='#DavidsModel-Explanation'>Explanation</a></li>
+<li><a href='#DavidsModel-Example'>Example</a></li>
+<li><a href='#DavidsModel-Discussion'>Discussion</a></li>
+</ul>
+</li>
+<li><a href='#DavidsModel-Rule#2:Drivethecontenthierarchy,don&#39;tletithappen.'>Rule #2: Drive the content hierarchy, don&#39;t let it happen.</a>
+<ul class='toc-indentation'>
+<li><a href='#DavidsModel-Explanation.1'>Explanation</a></li>
+<li><a href='#DavidsModel-Example.1'>Example</a></li>
+<li><a href='#DavidsModel-Discussion.1'>Discussion</a></li>
+</ul>
+</li>
+<li><a href='#DavidsModel-Rule#3:Workspacesareforclone(),merge()andupdate().'>Rule #3: Workspaces are for clone(), merge() and update().</a>
+<ul class='toc-indentation'>
+<li><a href='#DavidsModel-Explanation.2'>Explanation</a></li>
+<li><a href='#DavidsModel-Example.2'>Example</a></li>
+<li><a href='#DavidsModel-Discussion.2'>Discussion</a></li>
+</ul>
+</li>
+<li><a href='#DavidsModel-Rule#4:BewareofSameNameSiblings.'>Rule #4: Beware of Same Name Siblings.</a>
+<ul class='toc-indentation'>
+<li><a href='#DavidsModel-Explanation.3'>Explanation</a></li>
+<li><a href='#DavidsModel-Example.3'>Example</a></li>
+<li><a href='#DavidsModel-Discussion.3'>Discussion</a></li>
+</ul>
+</li>
+<li><a href='#DavidsModel-Rule#5:Referencesconsideredharmful.'>Rule #5: References considered harmful.</a>
+<ul class='toc-indentation'>
+<li><a href='#DavidsModel-Explanation.4'>Explanation</a></li>
+<li><a href='#DavidsModel-Example.4'>Example</a></li>
+<li><a href='#DavidsModel-Discussion.4'>Discussion</a></li>
+</ul>
+</li>
+<li><a href='#DavidsModel-Rule#6:FilesareFilesareFiles.'>Rule #6: Files are Files are Files.</a>
+<ul class='toc-indentation'>
+<li><a href='#DavidsModel-Explanation.5'>Explanation</a></li>
+<li><a href='#DavidsModel-Example.5'>Example</a></li>
+<li><a href='#DavidsModel-Discussion.5'>Discussion</a></li>
+</ul>
+</li>
+<li><a href='#DavidsModel-Rule#7:ID&#39;sareevil.'>Rule #7: ID&#39;s are evil.</a>
+<ul class='toc-indentation'>
+<li><a href='#DavidsModel-Explanation.6'>Explanation</a></li>
+<li><a href='#DavidsModel-Example.6'>Example</a></li>
+<li><a href='#DavidsModel-Discussion.6'>Discussion</a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+
+<h2 id="DavidsModel-Intro">Intro</h2>
+<p>In various discussions I found that developers are somewhat at unease with the features and functionalities presented by JCR when it comes to content modeling. There is no guide and very little experience yet on how to model content in a repository  and why one content model is better than the other.</p>
+
+<p>While in the relational world the software industry has a lot of experience on how to model data, we are still at the early stages for the content repository space.</p>
+
+<p>I would like to start filling this void by expressing my personal opinions on how content should be modeled, hoping that this could some day graduate into something more meaningful to the developers community, which is not just &quot;my opinion&quot; but something that is more generally applicable.  So consider this my quickly evolving first stab at it.</p>
+
+<p>Disclaimer: These guidelines express my personal, sometimes controversial views. I am looking forward to debate these guidelines and refine them.</p>
+
+<h2 id="DavidsModel-SevenSimplerules">Seven Simple rules</h2>
+
+<h3 id="DavidsModel-Rule#1:DataFirst,StructureLater.Maybe.">Rule #1: Data First, Structure Later. Maybe.</h3>
+
+<h4 id="DavidsModel-Explanation">Explanation</h4>
+<p>I recommend not to worry about a declared data  structure in an ERD sense. Initially. </p>
+
+<p>Learn to love nt:unstructured (&amp; friends) in development.</p>
+
+<p>I think <a href="http://www.betaversion.org/~stefano/linotype/news/93/" class="external-link" rel="nofollow">Stefano pretty much sums this one up</a>.</p>
+
+<p>My bottom-line: Structure is expensive and in many cases it is entirely unnecessary to explicitly declare structure to the  underlying storage.</p>
+
+<p>There is an implicit contract about structure that your application inherently uses. Let's say I store the modification date of a blog post in a &quot;lastModified&quot; property. My App will automatically know to read the modification date from that same property again, there is  really no need to declare that explicitly.</p>
+
+<p>Further data constraints like mandatory or type and value constraints should only be applied where required for data integrity reasons.</p>
+
+<h4 id="DavidsModel-Example">Example</h4>
+<p>The above example of using a &quot;lastModified&quot; Date property on for example &quot;blog post&quot; node, really does not mean that there is a need for a special nodetype. I would definitely use &quot;nt:unstructured&quot; for my blog post nodes at least initially.  Since in my blogging application all I am going to do is to display  the lastModified date anyway (possibly &quot;order by&quot; it) I barely care if  it is a Date at all. Since I implicitly trust my blog-writing application  to put a &quot;date&quot; there anyway, there really is no need to declare the  presence of a &quot;lastModified&quot; date in the form a of nodetype.</p>
+
+<h4 id="DavidsModel-Discussion">Discussion</h4>
+
+<p><a href="http://www.nabble.com/DM-Rule--1%3A-Data-First%2C-Structure-Later.-Maybe.-tf4039967.html" class="external-link" rel="nofollow">http://www.nabble.com/DM-Rule--1%3A-Data-First%2C-Structure-Later.-Maybe.-tf4039967.html</a></p>
+
+<hr/>
+<h3 id="DavidsModel-Rule#2:Drivethecontenthierarchy,don&#39;tletithappen.">Rule #2: Drive the content hierarchy, don't let it happen.</h3>
+
+<h4 id="DavidsModel-Explanation.1">Explanation</h4>
+<p>The content hierarchy is a very valuable asset.  So don't just let it happen, design it.  If you don't have a &quot;good&quot;, human-readable name for a node,  that's probably that you should reconsider.  Arbitrary numbers are hardly ever a &quot;good name&quot;.</p>
+
+<p>While it may be extremely easy to quickly put an existing  relational model into a hierarchical model, one should put  some thought in that process.</p>
+
+<p>In my experience access control and containment are usually good drivers for the content hierarchy. Think of it as if it was your filesystem. Maybe even use files and folders to model it on your local disk.</p>
+
+<p>Personally I prefer hierarchy conventions over the nodetyping system  in a lot of cases initially, and introduce the typing later.</p>
+
+<h4 id="DavidsModel-Example.1">Example</h4>
+<p>I would model a simple blogging system as follows.  Please note that initially I don't even care about the  respective nodetypes that I use at this point.</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>/content/myblog
+/content/myblog/posts
+/content/myblog/posts/what_i_learned_today
+/content/myblog/posts/iphone_shipping
+
+/content/myblog/comments/iphone_shipping/i_like_it_too
+/content/myblog/comments/iphone_shipping/i_like_it_too/i_hate_it
+</pre>
+</div></div>
+
+<p>I think one of the things that become apparent is that we all understand the structure of the content based on the example without any further explanations.</p>
+
+<p>What may be unexpected initially is why I wouldn't store the  &quot;comments&quot; with the &quot;post&quot;, which is due to access control which I would like to be applied in a reasonably hierarchical way.</p>
+
+<p>Using the above content model I can easily allow the &quot;anonymous&quot;  user to &quot;create&quot; comments, but keep the anonymous user on a  read-only basis for the rest of the workspace.</p>
+
+<h4 id="DavidsModel-Discussion.1">Discussion</h4>
+
+<p><a href="http://www.nabble.com/DM-Rule--2%3A-Drive-the-content-hierarchy%2C-don%27t-let-it-happen.-tf4039994.html" class="external-link" rel="nofollow">http://www.nabble.com/DM-Rule--2%3A-Drive-the-content-hierarchy%2C-don%27t-let-it-happen.-tf4039994.html</a></p>
+
+<hr/>
+<h3 id="DavidsModel-Rule#3:Workspacesareforclone(),merge()andupdate().">Rule #3: Workspaces are for clone(), merge() and update().</h3>
+<h4 id="DavidsModel-Explanation.2">Explanation</h4>
+<p>If you don't use clone(), merge() or update() methods in your  application a single workspace is probably the way to go.</p>
+
+<p>&quot;Corresponding nodes&quot; is a concept defined in the JCR spec. Essentially, it boils down to nodes that represent the same content, in different so-called workspaces.</p>
+
+<p>JCR introduces the very abstract concept of Workspaces which leaves a lot of developers unclear on what to do with them. I would like to propose to put your use of workspaces to the following to test.</p>
+
+<p>If you have a considerable overlap of &quot;corresponding&quot; nodes (essentially the nodes with the same UUID) in multiple workspaces you probably put workspaces to good use.</p>
+
+<p>If there is no overlap of nodes with the same UUID you are probably abusing workspaces.</p>
+
+<p>Workspaces should not be used for access control. Visibility of content for a particular group of users is not a good argument to separate things into different workspaces. JCR features &quot;Access Control&quot; in the content repository to provide for that.</p>
+
+<p>Workspaces are the boundary for references and query.</p>
+
+<h4 id="DavidsModel-Example.2">Example</h4>
+<p>Use workspaces for things like: </p>
+<ul>
+	<li>v1.2 of your project vs. a v1.3 of your project</li>
+	<li>a &quot;development&quot;, &quot;qa&quot; and a &quot;published&quot; state of content
+<br class="atl-forced-newline"/></li>
+</ul>
+
+
+<p>Do not use workspaces for things like:</p>
+<ul>
+	<li>user home directories</li>
+	<li>distinct content for different target audiences like public, private, local, ...</li>
+	<li>mail-inboxes for different users
+<br class="atl-forced-newline"/></li>
+</ul>
+
+
+<h4 id="DavidsModel-Discussion.2">Discussion</h4>
+
+<p><a href="http://www.nabble.com/DM-Rule--3%3A-Workspaces-are-for-corresponding-nodes.-tf4040010.html" class="external-link" rel="nofollow">http://www.nabble.com/DM-Rule--3%3A-Workspaces-are-for-corresponding-nodes.-tf4040010.html</a></p>
+
+<hr/>
+<h3 id="DavidsModel-Rule#4:BewareofSameNameSiblings.">Rule #4: Beware of Same Name Siblings.</h3>
+<h4 id="DavidsModel-Explanation.3">Explanation</h4>
+<p>While Same Name Siblings (SNS) have been introduced into the spec to allow  compatibility with data structures that are designed for and expressed through XML and therefore are extremely valuable to JCR, SNS come with a substantial  overhead and complexity for the repository.</p>
+
+<p>Any path into the content repository that contains an SNS in one of its path segments becomes much less stable, if an SNS is removed or reordered, it has an impact on  the paths of all the other SNS and their children.</p>
+
+<p>For import of XML or interaction with existing XML SNS maybe necessary and useful but I have never used SNS, and never will in my &quot;green field&quot; data models.</p>
+
+<h4 id="DavidsModel-Example.3">Example</h4>
+<p>Use </p>
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>/content/myblog/posts/what_i_learned_today
+/content/myblog/posts/iphone_shipping
+</pre>
+</div></div>
+
+<p>instead of </p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>/content/blog[1]/post[1]
+/content/blog[1]/post[2]
+</pre>
+</div></div>
+
+<h4 id="DavidsModel-Discussion.3">Discussion</h4>
+
+<p><a href="http://www.nabble.com/DM-Rule--4%3A-Beware-of-Same-Name-Siblings.-tf4040024.html" class="external-link" rel="nofollow">http://www.nabble.com/DM-Rule--4%3A-Beware-of-Same-Name-Siblings.-tf4040024.html</a></p>
+
+<hr/>
+<h3 id="DavidsModel-Rule#5:Referencesconsideredharmful.">Rule #5: References considered harmful.</h3>
+<h4 id="DavidsModel-Explanation.4">Explanation</h4>
+<p>References imply referential integrity. I find it important to understand that references do not just add additional cost for the repository managing the referential integrity, but they also are costly from a content flexibility perspective.</p>
+
+<p>Personally I make sure I only ever use references when I really  cannot deal with a dangling reference and otherwise use a path, a name or a string UUID to refer to another node.</p>
+
+<h4 id="DavidsModel-Example.4">Example</h4>
+<p>Let's assume I allow &quot;references&quot; from a document (a) to another document (b). If I model this relation using reference properties  this means that the two documents are linked on a repository level. I cannot export/import document (a) individually, since the reference property's target may not exist. Other operations like merge, update, restore or clone are affected as well.</p>
+
+<p>So I would either model those references as &quot;weak-references&quot; (in JCR v1.0 his essentially boils down to string properties  that contain the uuid of the target node) or simply use a path.  Sometimes the path is more meaningful to begin with.</p>
+
+<p>I think there are usecases where a system really can't work if a reference is dangling, but I just can't come up with a  good &quot;real&quot; yet simple example from my direct experience.</p>
+
+<h4 id="DavidsModel-Discussion.4">Discussion</h4>
+
+<p><a href="http://www.nabble.com/DM-Rule--5%3A-References-considered-harmful.-tf4040042.html" class="external-link" rel="nofollow">http://www.nabble.com/DM-Rule--5%3A-References-considered-harmful.-tf4040042.html</a></p>
+
+<hr/>
+<h3 id="DavidsModel-Rule#6:FilesareFilesareFiles.">Rule #6: Files are Files are Files.</h3>
+<h4 id="DavidsModel-Explanation.5">Explanation</h4>
+<p>If a content model exposes something that even remotely &quot;smells&quot;  like a file or a folder I try to use (or extend from) nt:file, nt:folder and nt:resource.</p>
+
+<p>In my experience a lot of generic applications allow interaction with nt:folder and nt:files implicitly and know how to handle and display those event if they are enriched with additional meta-information. For example a direct interaction with file server implementations  like CIFS or Webdav sitting on top of JCR become implicit.</p>
+
+<p>I think as good rule of thumb one could use the following: <br/>
+If you need to store the filename and the mime-type then  nt:file/nt:resource is a very good match.  If you could have multiple &quot;files&quot; an nt:folder is a  good place to store them.</p>
+
+<p>If you need to add meta information for your resource, let's say an &quot;author&quot; or a &quot;description&quot; property, extend  nt:resource not the nt:file.  I rarely extend nt:file and frequently extend nt:resource.</p>
+
+<h4 id="DavidsModel-Example.5">Example</h4>
+<p>Let's assume that someone would like to upload an image to a blog entry at:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>/content/myblog/posts/iphone_shipping
+</pre>
+</div></div>
+
+<p>and maybe the initial gut reaction would be to add a binary property containing the picture. </p>
+
+<p>While there certainly are good usecases to use just a binary  property (let's say the name is irrelevant and the mime-type  is implicit) in this case I would recommend the following  structure for my blog example.</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>/content/myblog/posts/iphone_shipping/attachments [nt:folder]
+/content/myblog/posts/iphone_shipping/attachments/front.jpg [nt:file]
+/content/myblog/posts/iphone_shipping/attachments/front.jpg/jcr:content [nt:resource]
+</pre>
+</div></div>
+
+<h4 id="DavidsModel-Discussion.5">Discussion</h4>
+
+<p><a href="http://www.nabble.com/DM-Rule--6%3A-Files-are-Files-are-Files.-tf4040063.html" class="external-link" rel="nofollow">http://www.nabble.com/DM-Rule--6%3A-Files-are-Files-are-Files.-tf4040063.html</a></p>
+
+<hr/>
+
+<h3 id="DavidsModel-Rule#7:ID&#39;sareevil.">Rule #7: ID's are evil.</h3>
+
+<h4 id="DavidsModel-Explanation.6">Explanation</h4>
+<p>In relational databases IDs are a necessary means to express  relations, so people tend to use them in content models aswell.  Mostly for the wrong reasons through.</p>
+
+<p>If your content model is full of properties that end in &quot;Id&quot; you  probably are not leveraging the hierarchy properly. </p>
+
+<p>It is true that some nodes need a stable identification throughout  their live cycle. Much fewer than you might think though.  mix:referenceable provides such a mechanism built into the repository,  so there really is no need to come up with an additional means of identifying a node in a stable fashion.</p>
+
+<p>Keep also in mind that items can be identified by path, and as much as &quot;symlinks&quot; make way more sense for most users than hardlinks  in a unix filesystem, a path makes a sense for most applications to refer to a target node.</p>
+
+<p>More importantly, it is **mix**:referenceable which means that it  can be applied to a node at the point in time when you actually  need to reference it.</p>
+
+<p>So let's say just because you would like to be able to potentially reference a node of type &quot;Document&quot; does not mean that your &quot;Document&quot; nodetype has to extend from mix:referenceable in a static fashion since it can be added to any instance of the &quot;Document&quot; dynamically.</p>
+
+<h4 id="DavidsModel-Example.6">Example</h4>
+
+<p>use:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>/content/myblog/posts/iphone_shipping/attachments/front.jpg
+</pre>
+</div></div>
+
+<p>instead of:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>
+[Blog]
+- blogId
+- author
+
+[Post]
+- postId
+- blogId
+- title
+- text
+- date
+
+[Attachment]
+- attachmentId
+- postId
+- filename
++ resource (nt:resource)
+</pre>
+</div></div>
+
+<h4 id="DavidsModel-Discussion.6">Discussion</h4>
+
+<p><a href="http://www.nabble.com/DM-Rule--7%3A-ID%27s-are-evil.-tf4040076.html" class="external-link" rel="nofollow">http://www.nabble.com/DM-Rule--7%3A-ID%27s-are-evil.-tf4040076.html</a></p>
+                    </div>
+
+                    
+                                                      
+                </div>             </div> 
+            <div id="footer" role="contentinfo">
+                <section class="footer-body">
+                    <p>Document generated by Confluence on May 20, 2019 11:11</p>
+                    <div id="footer-logo"><a href="http://www.atlassian.com/">Atlassian</a></div>
+                </section>
+            </div>
+        </div>     </body>
+</html>

Propchange: jackrabbit/site/live/archive/wiki/JCR/DavidsModel_115513389.html
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/site/live/archive/wiki/JCR/DavidsModel_115513389.html
------------------------------------------------------------------------------
    svn:executable = *

Added: jackrabbit/site/live/archive/wiki/JCR/Direct-Binary-Access_115513390.html
URL: http://svn.apache.org/viewvc/jackrabbit/site/live/archive/wiki/JCR/Direct-Binary-Access_115513390.html?rev=1859550&view=auto
==============================================================================
--- jackrabbit/site/live/archive/wiki/JCR/Direct-Binary-Access_115513390.html (added)
+++ jackrabbit/site/live/archive/wiki/JCR/Direct-Binary-Access_115513390.html Mon May 20 11:23:18 2019
@@ -0,0 +1,184 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Apache Jackrabbit : Direct Binary Access</title>
+        <link rel="stylesheet" href="styles/site.css" type="text/css" />
+        <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+
+    <body class="theme-default aui-theme-default">
+        <div id="page">
+            <div id="main" class="aui-page-panel">
+                <div id="main-header">
+                    <div id="breadcrumb-section">
+                        <ol id="breadcrumbs">
+                            <li class="first">
+                                <span><a href="index.html">Apache Jackrabbit</a></span>
+                            </li>
+                                                    <li>
+                                <span><a href="Home_70731.html">Home</a></span>
+                            </li>
+                                                </ol>
+                    </div>
+                    <h1 id="title-heading" class="pagetitle">
+                                                <span id="title-text">
+                            Apache Jackrabbit : Direct Binary Access
+                        </span>
+                    </h1>
+                </div>
+
+                <div id="content" class="view">
+                    <div class="page-metadata">
+                        
+        
+    
+        
+    
+        
+        
+            Created by <span class='author'> ASF Infrabot</span> on May 20, 2019
+                        </div>
+                    <div id="main-content" class="wiki-content group">
+                    <h1 id="DirectBinaryAccess-OakDirectBinaryAccess">Oak Direct Binary Access</h1>
+
+<h2 id="DirectBinaryAccess-Summary">Summary</h2>
+<p>Oak Direct Binary Access is a capability of Oak wherein Oak allows an authenticated client to upload or download blobs directly to/from the blob store, assuming the authenticated user has appropriate permission to do so.  The primary value of this feature is that the I/O of transferring large binary files to or from the blob store can be offloaded entirely from Oak and performed directly between a client application and the blob store.  The availability of this feature is subject to certain capabilities being available in the <em>DataStore</em> implementation as well as the service provider underlying that implementation.</p>
+
+<h2 id="DirectBinaryAccess-Javadocs">Javadocs</h2>
+
+<ul>
+	<li><a href="http://jackrabbit.apache.org/api/trunk/org/apache/jackrabbit/api/JackrabbitValueFactory.html" class="external-link" rel="nofollow">JackrabbitValueFactory</a> for uploading - cast <code>ValueFactory</code> to this and use <code>initiateBinaryUpload()</code> and <code>completeBinaryUpload()</code></li>
+	<li><a href="http://jackrabbit.apache.org/api/trunk/org/apache/jackrabbit/api/binary/BinaryDownload.html" class="external-link" rel="nofollow">BinaryDownload</a> for downloading - cast a <code>Binary</code> to this and call <code>getURI()</code></li>
+	<li>other elements are in the <a href="http://jackrabbit.apache.org/api/trunk/org/apache/jackrabbit/api/binary/package-summary.html" class="external-link" rel="nofollow">org.apache.jackrabbit.api.binary package</a>
+<br class="atl-forced-newline"/></li>
+</ul>
+
+
+<style type='text/css'>/*<![CDATA[*/
+div.rbtoc1558350680513 {padding: 0px;}
+div.rbtoc1558350680513 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1558350680513 li {margin-left: 0px;padding-left: 0px;}
+
+/*]]>*/</style><div class='toc-macro rbtoc1558350680513'>
+<ul class='toc-indentation'>
+<li><a href='#DirectBinaryAccess-OakDirectBinaryAccess'>Oak Direct Binary Access</a>
+<ul class='toc-indentation'>
+<li><a href='#DirectBinaryAccess-Summary'>Summary</a></li>
+<li><a href='#DirectBinaryAccess-Javadocs'>Javadocs</a></li>
+<li><a href='#DirectBinaryAccess-Motivation'>Motivation</a></li>
+<li><a href='#DirectBinaryAccess-FeaturesOverview'>Features Overview</a>
+<ul class='toc-indentation'>
+<li><a href='#DirectBinaryAccess-DirectBinaryDownload'>Direct Binary Download</a></li>
+<li><a href='#DirectBinaryAccess-DirectBinaryUpload'>Direct Binary Upload</a></li>
+</ul>
+</li>
+<li><a href='#DirectBinaryAccess-Security'>Security</a>
+<ul class='toc-indentation'>
+<li><a href='#DirectBinaryAccess-URLs'>URLs</a></li>
+<li><a href='#DirectBinaryAccess-Authentication'>Authentication</a></li>
+<li><a href='#DirectBinaryAccess-Authorization'>Authorization</a></li>
+</ul>
+</li>
+<li><a href='#DirectBinaryAccess-OtherApproaches'>Other Approaches</a>
+<ul class='toc-indentation'>
+<li><a href='#DirectBinaryAccess-DirectBinaryDownload(Sept/Oct2017)'>Direct Binary Download (Sept / Oct 2017)</a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+
+<h2 id="DirectBinaryAccess-Motivation">Motivation</h2>
+<p>The transfer of binary data through Oak has a significant impact on the overall performance of the system.  Every time a binary is uploaded or downloaded the data flows from the storage location through Oak and on to the client.  Handling this I/O impacts Oak's performance.  This new capability offloads the transfer of data so it takes place directly between client and storage, while still relying upon Oak to manage the content hierarchy and enforce permissions.</p>
+
+<p>Use cases <a href="JCR-Binary-Usecase_115513420.html#JCRBinaryUsecase-UC6">UC6</a> and <a href="JCR-Binary-Usecase_115513420.html#JCRBinaryUsecase-UC13">UC13</a> from <a href="JCR-Binary-Usecase_115513420.html">JCR Binary Usecase</a> are related to this capability and can be at least partially addressed by it. </p>
+
+<h2 id="DirectBinaryAccess-FeaturesOverview">Features Overview</h2>
+<p>This capability offers two basic features:  Direct Binary Download and Direct Binary Upload.</p>
+
+<h3 id="DirectBinaryAccess-DirectBinaryDownload">Direct Binary Download</h3>
+<p>This feature allows a client application to download a binary directly from a supported storage location via a URL.  The application user must be successfully authenticated to the system and must have permission to read the binary object in question in order to obtain a <em>Binary</em> object.  Using this object, the client may then cast it to a <em>BinaryDownload</em>.  If successful, the client may then call a new JCR API, <em>getURI(BinaryDownloadOptions)</em>, which returns a URL that the client may then use to read the binary directly.</p>
+
+<p>This block diagram shows the main parties involved for downloading (<a href="attachments/115513390/115513391.gliffy" data-linked-resource-id="115513391" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="oak-direct-binary-download-block-diagram.gliffy" data-linked-resource-content-type="application/gliffy+json" data-linked-resource-container-id="115513390" data-linked-resource-container-version="1">oak-direct-binary-download-block-diagram.gliffy</a>):</p>
+
+<p><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image" src="attachments/115513390/115513393.png" data-image-src="attachments/115513390/115513393.png" data-unresolved-comment-count="0" data-linked-resource-id="115513393" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="oak-direct-binary-download-block-diagram.png" data-base-url="https://cwiki.apache.org/confluence" data-linked-resource-content-type="image/png" data-linked-resource-container-id="115513390" data-linked-resource-container-version="1"></span></p>
+
+<h3 id="DirectBinaryAccess-DirectBinaryUpload">Direct Binary Upload</h3>
+<p>This feature allows a client application to upload a binary directly to a supported storage location via one or more URLs.  This is done in a three-step process.  First, the application obtains a reference to the active <em>ValueFactory</em>.  If this is an instance of <em>JackrabbitValueFactory</em>, the application then calls a new JCR API, <em>initiateBinaryUpload(long, int)</em>, passing two arguments:  the maximum expected or known size of the binary, and the maximum number of upload URLs that the client can support.  A <em>BinaryUpload</em> object will be returned containing instructions to aid in completing the upload, including one or more URLs to use and an upload token that is required later.  Second, the client application may then use one or more of the provided URLs, which can be obtained by calling <em>getUploadURIs()</em> on the returned <em>BinaryUpload</em> object, to upload the binary directly to the storage.  Multi-part uploads are supported and handled automat
 ically if desired - all the client need do is upload chunks of the binary using the provided URLs in sequence.  When all the uploads are complete, the client then uses the <em>JackrabbitValueFactory</em> to call a new JCR API, <em>completeBinaryUpload(String)</em>, providing a signed upload token that can be obtained by calling <em>getUploadToken()</em> on the <em>BinaryUpload</em> object that was returned from the original call to <em>initiateHttpUpload(long, int)</em>, and returning a <em>Binary</em>.  Calling <em>completeHttpUpload(String)</em> notifies the storage provider of the upload parts to be assembled into a single binary object, and also allows that the corresponding property need not be created until after the binary upload is complete, at which point the returned <em>Binary</em> can be associated to the property.</p>
+
+
+<p>This block diagram shows the main parties involved for uploading (<a href="attachments/115513390/115513394.gliffy" data-linked-resource-id="115513394" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="oak-direct-binary-upload-block-diagram.gliffy" data-linked-resource-content-type="application/gliffy+json" data-linked-resource-container-id="115513390" data-linked-resource-container-version="1">oak-direct-binary-upload-block-diagram.gliffy</a>):</p>
+
+<p><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image" src="attachments/115513390/115513392.png" data-image-src="attachments/115513390/115513392.png" data-unresolved-comment-count="0" data-linked-resource-id="115513392" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="oak-direct-binary-upload-block-diagram.png" data-base-url="https://cwiki.apache.org/confluence" data-linked-resource-content-type="image/png" data-linked-resource-container-id="115513390" data-linked-resource-container-version="1"></span></p>
+
+<p>The following sequence diagram shows the detailed steps. Note that the &quot;Oak&quot; agent aggregates the JCR, Root/Tree, <a class="createlink" href="/confluence/pages/createpage.action?spaceKey=JCR&amp;title=NodeStore&amp;linkCreation=true&amp;fromPageId=115513390">NodeStore</a> and <a class="createlink" href="/confluence/pages/createpage.action?spaceKey=JCR&amp;title=BlobStore&amp;linkCreation=true&amp;fromPageId=115513390">BlobStore</a> layers. (<a href="https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG5cbnBhcnRpY2lwYW50IEMgYXMgUmVtb3RlIENsaWVudFxucGFydGljaXBhbnQgQSBhcyBTZXJ2ZXIgQXBwbGljYXRpb25cbnBhcnRpY2lwYW50IE8gYXMgT2FrXG5wYXJ0aWNpcGFudCBEIGFzIERhdGFTdG9yZVxucGFydGljaXBhbnQgUyBhcyBBenVyZSBvciBTM1xuXG5Ob3RlIG92ZXIgRDpzdGFydHVwXG5hY3RpdmF0ZSBEXG5ELT4-UzogY29ubmVjdCBhbmQgY29uZmlndXJlXG5cbk5vdGUgbGVmdCBvZiBDOiBQaGFzZSAxOiBpbml0aWF0ZVxuQy0-PitBOiByZXF1ZXN0IHRvIHVwbG9hZCBhIGJpbmFyeVxuQS0-PitPOiBpbml0aWF0ZUh0dHBVcGxvYWQocGF0aCwgbWF4U2l6ZSw
 gbWF4UGFydHMpXG5Ob3RlIG92ZXIgTzogcGVybWlzc2lvbiBjaGVjazxicj50byBzZXRfcHJvcGVydHk8YnI-YXQgcGF0aFxuXG5PLT4-K0Q6IGluaXRpYXRlSHR0cFVwbG9hZChtYXhTaXplLCBtYXhQYXJ0cylcblxubG9vcCB1bnRpbCB1bnVzZWQgYmxvYiBpZCBmb3VuZFxuICAgTm90ZSBvdmVyIEQ6IG5ldyByYW5kb20gYmxvYiBpZFxuICAgIEQtPj5TOiBjaGVjayBpZiAgYmxvYiBpZCBleGlzdHNcbmVuZFxuXG5Ob3RlIG92ZXIgRDogY2FsY3VsYXRlIG51bWJlcjxicj5vZiBwYXJ0cyB1c2luZzxicj5zdG9yYWdlIGxpbWl0c1xub3B0IGlmIG11bHRpcGFydFxuICBELT4-UzogaW5pdGlhdGUgbXVsdGlwYXJ0IHVwbG9hZCAoUzMpXG5lbmRcblxuTm90ZSBvdmVyIEQ6IGdlbmVyYXRlPGJyLz5wcmUtc2lnbmVkIFVSTChzKVxuTm90ZSBvdmVyIEQ6IGdlbmVyYXRlIHNlY3VyZTxicj51cGxvYWQgdG9rZW48YnI-dy8gYmxvYiBpZDxicj5tdWx0aXBhcnQgZmxhZzxicj5hbmQgdXBsb2FkIGlkIChTMylcbkQtLT4-LU86IGBwYXJ0VVJMc2AsIGB1cGxvYWRUb2tlbmBcblxuTy0tPj4tQTogYHBhcnRVUkxzYCwgYHVwbG9hZFRva2VuYFxuQS0tPj4tQzoganNvbiB3aXRoIGBwYXJ0VVJMc2AsIGBjb21wbGV0ZVVSTGBcblxuTm90ZSBsZWZ0IG9mIEM6IFBoYXNlIDI6IHVwbG9hZFxuXG5sb29wIGZvciBlYWNoIHBhcnQgKGNodW5rKSBhbmQgcGFydFVSTFxuICAgIEMtPj5TOiB1cGxvYWQgYmluYXJ5IHBhcnQgdG8gYHBh
 cnRVUkxgIFxuZW5kXG5cbk5vdGUgbGVmdCBvZiBDOiBQaGFzZSAzOiBjb21wbGV0ZSA8YnI-JiBwZXJzaXN0XG5cbkMtPj4rQTogcmVxdWVzdCB0byBgY29tcGxldGVVUkxgXG5BLT4-K086IGNvbXBsZXRlSHR0cFVwbG9hZCh1cGxvYWRUb2tlbilcbk8tPj4rRDogY29tcGxldGVIdHRwVXBsb2FkKHVwbG9hZFRva2VuKVxuXG5Ob3RlIG92ZXIgRDogdmFsaWRhdGUgdXBsb2FkVG9rZW5cbk5vdGUgb3ZlciBEOiBleHRyYWN0IGJsb2IgaWQ8YnI-ZXh0cmFjdCBpZiBtdWx0aXBhcnQ8YnI-ZXh0cmFjdCBtdWx0aXBhcnQ8YnI-dXBsb2FkIGlkIChTMylcblxub3B0IGlmIHNpbmdsZSBwdXRcbiAgRC0-PlM6IGNoZWNrIGlmIG9iamVjdCBleGlzdHNcbmVuZFxuXG5vcHQgZWxzZSBpZiBtdWx0aXBhcnRcbiAgRC0-PlM6IGdldCBwYXJ0IGxpc3RcbiAgRC0-PlM6IGNvbXBsZXRlIG11bHRpcGFydCB1cGxvYWRcbmVuZFxuXG5ELS0-Pi1POiBgYmxvYklkYFxuTy0tPj4tQTogSkNSIEJpbmFyeSBgYmluYXJ5YFxuXG5BLT4-TzogY3JlYXRlIG50OmZpbGUgc3RydWN0dXJlXG5BLT4-Tzogc2V0IGBiaW5hcnlgIGFzIGpjcjpkYXRhXG5BLT4-Tzogc2F2ZSgpXG5cbk5vdGUgb3ZlciBPOiBwZXJzaXN0IGluIE5vZGVTdG9yZTxicj53LyBibG9iSWQgcmVmZXJlbmNlXG5cbk5vdGUgb3ZlciBBOiB0cmlnZ2VyIGFueTxicj5hcHBsaWNhdGlvbiBldmVudHM8YnI-dXBvbiBiaW5hcnkgdXBsb2FkPGJyPihpZiBuZWVkZWQpXG5cbkEtL
 T4-LUM6IGRvbmVcblxuIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifX0" class="external-link" rel="nofollow">sources for the diagram</a>)</p>
+
+<p><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image" src="attachments/115513390/115513395.svg" data-image-src="attachments/115513390/115513395.svg" data-unresolved-comment-count="0" data-linked-resource-id="115513395" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="oak-direct-binary-upload-sequence-diagram.svg" data-base-url="https://cwiki.apache.org/confluence" data-linked-resource-content-type="image/svg+xml" data-linked-resource-container-id="115513390" data-linked-resource-container-version="1"></span></p>
+
+
+<h2 id="DirectBinaryAccess-Security">Security</h2>
+<p>There are a number of security-related aspects to be considered for this capability.</p>
+
+<h3 id="DirectBinaryAccess-URLs">URLs</h3>
+<p>This new capability allows clients to interact directly with storage via URLs.  Obviously this increases the security exposure of the storage in question.  However, the risk can be managed via signed URLs with short TTLs.  Thus to improve security it is strongly recommended to use a storage service provider that:</p>
+<ul>
+	<li>Can provide URLs for both storing and retrieving content directly to/from the storage provider</li>
+	<li>Enforces TTLs on provided URLs and disallows their use after the TTL has expired</li>
+	<li>Signs URLs and includes a signature in the URL, which is used to verify both the origin of the URL and that the contents of the URL have not been altered since approval</li>
+	<li>Enforces permissions on provided URLs to only perform the action(s) originally requested when the URL was obtained</li>
+</ul>
+
+
+<p>Both Amazon AWS S3 and Microsoft Azure Blob Storage meet these requirements, and thus both <em>!S3DataStore</em> and <em>AzureDataStore</em> can be configured for this purpose.  Note that it will still be incumbent upon administrators to avoid configuring the system in insecure ways (for example, configuring a TTL that is far too large to be reasonably secure).</p>
+
+<h3 id="DirectBinaryAccess-Authentication">Authentication</h3>
+<p>To interact with this capability programmatically via the JCR API, a client needs to establish a valid session which requires valid user credentials to authenticate.</p>
+
+<h3 id="DirectBinaryAccess-Authorization">Authorization</h3>
+<p>To obtain a download URL, a valid <em>Binary</em> object must be obtained which is an instance of <em>BinaryImpl</em>.  This can be obtained via an authenticated session calling into the JCR API ot request a <em>Binary</em> for an existing object.  Because the binary must be obtained first from the JCR, it has already been established that the user represented by the session has permission to read the binary, so giving the URL for use by this user is acceptable.</p>
+
+<p>Once a binary is uploaded (direct or otherwise), an authenticated session must have the correct permission to associate the <em>Binary</em> with a binary property in the JCR.  Thus it is not possible to add a binary to the repository by using direct binary upload unless sufficient permissions exist to add the property.  Note that may be possible to upload the binary to blob storage this way; however, this is also possible to do using the traditional upload mechanism.  Such unreferenced binaries are not considered part of the repository and will be garbage collected.  If a client wishes to avoid uploading a binary when no permission exists to add the binary to a property, the client should first check for adequate permission at the property path and then perform the upload.</p>
+
+<h2 id="DirectBinaryAccess-OtherApproaches">Other Approaches</h2>
+
+<h3 id="DirectBinaryAccess-DirectBinaryDownload(Sept/Oct2017)">Direct Binary Download (Sept / Oct 2017)</h3>
+<p>A proposal was submitted in September / October of 2017 to evaluate a form of direct binary download support for Oak.  This proposal was discussed in <a href="https://issues.apache.org/jira/browse/OAK-6575" class="external-link" rel="nofollow">OAK-6575</a> as well as in <a href="https://markmail.org/thread/7eiwvkuv3ybv2vyz" class="external-link" rel="nofollow">this thread</a> and <a href="https://markmail.org/thread/zh6zxdxytnyonqms" class="external-link" rel="nofollow">this thread</a> on oak-dev and in <a href="https://markmail.org/thread/tdxl3ufzzryzo5po" class="external-link" rel="nofollow">this thread</a> and <a href="https://markmail.org/thread/3p7hho25skygy5xt" class="external-link" rel="nofollow">this thread</a> on sling-dev.  A primary difference between this proposal and the one from 2017 is that the 2017 proposal was to support an ability to convert a <em>Binary</em> directly to a signed download URL using newly added code, whereas this proposal takes the approach of a 
 client requesting a URL for a <em>Binary</em> directly via API.</p>
+
+<p>Each proposal takes a somewhat different approach to address a similar problem (although the scope of this proposal is more broad as it covers upload as well as download).  It's important to take into account the conversations that took place about this issue in 2017 as we move forward.</p>
+                    </div>
+
+                                        <div class="pageSection group">
+                        <div class="pageSectionHeader">
+                            <h2 id="attachments" class="pageSectionTitle">Attachments:</h2>
+                        </div>
+
+                        <div class="greybox" align="left">
+                                                            <img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
+                                <a href="attachments/115513390/115513391.gliffy">oak-direct-binary-download-block-diagram.gliffy</a> (application/gliffy+json)
+                                <br/>
+                                                            <img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
+                                <a href="attachments/115513390/115513392.png">oak-direct-binary-upload-block-diagram.png</a> (image/png)
+                                <br/>
+                                                            <img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
+                                <a href="attachments/115513390/115513393.png">oak-direct-binary-download-block-diagram.png</a> (image/png)
+                                <br/>
+                                                            <img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
+                                <a href="attachments/115513390/115513394.gliffy">oak-direct-binary-upload-block-diagram.gliffy</a> (application/gliffy+json)
+                                <br/>
+                                                            <img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
+                                <a href="attachments/115513390/115513395.svg">oak-direct-binary-upload-sequence-diagram.svg</a> (image/svg+xml)
+                                <br/>
+                                                    </div>
+                    </div>
+                    
+                                                      
+                </div>             </div> 
+            <div id="footer" role="contentinfo">
+                <section class="footer-body">
+                    <p>Document generated by Confluence on May 20, 2019 11:11</p>
+                    <div id="footer-logo"><a href="http://www.atlassian.com/">Atlassian</a></div>
+                </section>
+            </div>
+        </div>     </body>
+</html>

Propchange: jackrabbit/site/live/archive/wiki/JCR/Direct-Binary-Access_115513390.html
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/site/live/archive/wiki/JCR/Direct-Binary-Access_115513390.html
------------------------------------------------------------------------------
    svn:executable = *

Added: jackrabbit/site/live/archive/wiki/JCR/EncodingAndEscaping_115513396.html
URL: http://svn.apache.org/viewvc/jackrabbit/site/live/archive/wiki/JCR/EncodingAndEscaping_115513396.html?rev=1859550&view=auto
==============================================================================
--- jackrabbit/site/live/archive/wiki/JCR/EncodingAndEscaping_115513396.html (added)
+++ jackrabbit/site/live/archive/wiki/JCR/EncodingAndEscaping_115513396.html Mon May 20 11:23:18 2019
@@ -0,0 +1,167 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Apache Jackrabbit : EncodingAndEscaping</title>
+        <link rel="stylesheet" href="styles/site.css" type="text/css" />
+        <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+
+    <body class="theme-default aui-theme-default">
+        <div id="page">
+            <div id="main" class="aui-page-panel">
+                <div id="main-header">
+                    <div id="breadcrumb-section">
+                        <ol id="breadcrumbs">
+                            <li class="first">
+                                <span><a href="index.html">Apache Jackrabbit</a></span>
+                            </li>
+                                                    <li>
+                                <span><a href="Home_70731.html">Home</a></span>
+                            </li>
+                                                </ol>
+                    </div>
+                    <h1 id="title-heading" class="pagetitle">
+                                                <span id="title-text">
+                            Apache Jackrabbit : EncodingAndEscaping
+                        </span>
+                    </h1>
+                </div>
+
+                <div id="content" class="view">
+                    <div class="page-metadata">
+                        
+        
+    
+        
+    
+        
+        
+            Created by <span class='author'> ASF Infrabot</span> on May 20, 2019
+                        </div>
+                    <div id="main-content" class="wiki-content group">
+                    <h1 id="EncodingAndEscaping-EncodingandEscaping">Encoding and Escaping</h1>
+
+<p>This pages covers escaping/encoding of paths, names, and values in the context of JCR-based web applications.</p>
+
+<h2 id="EncodingAndEscaping-Why?">Why?</h2>
+
+<p><p><a href="http://www.day.com/specs/jcr/2.0/3_Repository_Model.html#3.2%20Names" class="external-link" rel="nofollow">JCR node names</a> have a certain character set, which is actually very broad and includes almost all of unicode minus some special characters such as /, [, ], |, : and &#42; (used to build paths, address same-name siblings etc. in JCR), and it cannot be "." or ".." (obviously).</p></p>
+
+<p>For XPath queries, the underlying model is that of the JCR repository as an XML document, hence every path step in the XPath is seen as XML name (ISO9075), which is more restrictive than JCR node names and most importantly does not allow names starting with digits. But they can be escaped.</p>
+
+<p>Furthermore, in XPath queries there is the full text search using &quot;jcr:contains()&quot; and this has its own query string format itself, which in Jackrabbit will be that of Lucene.</p>
+
+<p>Then you might often use JCR for web applications where you map URLs to JCR paths - note that JCR node names allow for more than what URLs allow, most notably the space for example.</p>
+
+<p>There are utility methods for escaping/encoding in the <code>org.apache.jackrabbit.util.ISO9075</code> and <code>org.apache.jackrabbit.util.Text</code> classes. Although developed under Jackrabbit, they are part of the JCR Commons module (jackrabbit-jcr-commons) which only depends on the JCR API.</p>
+
+<h2 id="EncodingAndEscaping-Escapingpaths">Escaping paths</h2>
+
+<p>If you're building a path from user-supplied names, you need to escape illegal JCR characters (eg &quot;item:1&quot; becomes &quot;item%3A1&quot;):</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>String path = &quot;/foo/&quot; + Text.escapeIllegalJcrChars(name);
+</pre>
+</div></div>
+
+<p>Such paths are useful for JCR methods like <code>Node.addNode(...), Session.getItem(...)</code> etc., but usually only when you create nodes in the first place. Once the node exists, its name just needs to be passed around, but no escaping should happen for accessing the node, since it will already be in the right form, of course.</p>
+
+<h2 id="EncodingAndEscaping-Encodingpathinqueries">Encoding path in queries</h2>
+
+<p>If you want to use paths in XPath queries, though, you need to escape according to ISO9075 rules (eg &quot;1hr0&quot; becomes &quot;_x0031_hr0&quot;):</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>String query = &quot;/jcr:root&quot; + ISO9075.encodePath(node.getPath()) + &quot;/&quot; + ISO9075.encode(name);
+</pre>
+</div></div>
+
+<p>For a user-supplied string, this could lead to something like <code>ISO9075.encode(Text.escapeIllegalJcrChars(name))</code>. But in most cases the path given to a query is from a known node, so there is no need for escaping it with <code>Text.escapeIllegalJcrChars(name)</code>, so just the ISO9075 encoding is required.</p>
+
+<h2 id="EncodingAndEscaping-Escapingvaluesinqueries">Escaping values in queries</h2>
+
+<p>For values inserted into the queries, you should do escaping to prevent incorrect values and query injection. Generally, if you enclose values in single quotes, you just need to replace any literal single quote character with <code>_</code> (two consecutive single quote characters). </p>
+
+<h2 id="EncodingAndEscaping-Escapingtextinfulltext(contains)clauses">Escaping text in fulltext (contains) clauses</h2>
+
+<p>Jackrabbit Oak uses the <a href="https://lucene.apache.org/core/4_7_1/queryparser/org/apache/lucene/queryparser/classic/package-summary.html" class="external-link" rel="nofollow">Apache Lucene grammar for fulltext search</a>. So to escape user-supplied text for use in contains, you will need to either filter out all the special characters, or escape them. So for example, to filter out the special characters, use:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>String filteredContains = searchTerm.replaceAll(&quot;[\\Q+-&amp;|!(){}[]^\&quot;~*?:\\/\\E]&quot;, &quot;&quot;);
+String q =
+  &quot;/jcr:root/foo/element(*, foo)&quot; +
+  &quot;[jcr:contains(@title, &#39;&quot; + filteredContains.replaceAll(&quot;&#39;&quot;, &quot;&#39;&#39;&quot;) + &quot;&#39;)]&quot; +
+  &quot;[@itemID = &#39;&quot; + itemID.replaceAll(&quot;&#39;&quot;, &quot;&#39;&#39;&quot;) + &quot;&#39;]&quot;;
+</pre>
+</div></div>
+
+<p>Only for Jackrabbit 2.x: use <code>Text.escapeIllegalXpathSearchChars(...)</code> for calls to <code>jcr:contains(...)</code> (see also <a href="https://issues.apache.org/jira/browse/JCR-1248" class="external-link" rel="nofollow">JCR-1248</a>):</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>String q =
+  &quot;/jcr:root/foo/element(*, foo)&quot; +
+  &quot;[jcr:contains(@title, &#39;&quot; + Text.escapeIllegalXpathSearchChars(searchTerm).replaceAll(&quot;&#39;&quot;, &quot;&#39;&#39;&quot;) + &quot;&#39;)]&quot; +
+  &quot;[@itemID = &#39;&quot; + itemID.replaceAll(&quot;&#39;&quot;, &quot;&#39;&#39;&quot;) + &quot;&#39;]&quot;;
+</pre>
+</div></div>
+
+<p>Note that other special characters (like &quot;@&quot; or &quot;.&quot;) are_ usually_ ignored by the Lucene parser, however if a &quot;*&quot; (wildcard) is used, then they are_ not'' ignored. So:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>jcr:contains(., &#39;hello.world&#39;) =&gt; works (all documents that contain both the exact words &quot;hello&quot; and &quot;world&quot;)
+jcr:contains(., &#39;hello world&#39;) =&gt; works (all documents that contain both the exact words &quot;hello&quot; and &quot;world&quot;)
+
+jcr:contains(., &#39;*hello world*&#39;) =&gt; works (all documents that contain a word ending with &quot;hello&quot; and starting with &quot;world&quot;) 
+jcr:contains(., &#39;*hello.world*&#39;) =&gt; does not work (no results)
+jcr:contains(., &#39;hello.world*&#39;) =&gt; does not work (no results)
+jcr:contains(., &#39;*hello.world&#39;) =&gt; does not work (no results)
+</pre>
+</div></div>
+
+<p>If the search text only contains special characters, then all indexed nodes are returned:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>/jcr:root//*[jcr:contains(., &#39;.&#39;)] =&gt; *:*
+/jcr:root//*[jcr:contains(., &#39;..&#39;)] =&gt; *:*
+/jcr:root//*[jcr:contains(., &#39;/&#39;)] =&gt; *:*
+/jcr:root//*[jcr:contains(., &#39;//&#39;)] =&gt; *:*
+/jcr:root//*[jcr:contains(., &#39;*&#39;)] =&gt; :fulltext:*
+/jcr:root//*[jcr:contains(., &#39;**&#39;)] =&gt; :fulltext:**
+/jcr:root//*[jcr:contains(., &#39;○&#39;)] =&gt; :fulltext:â (○ is WHITE CIRCLE U+25CB)
+/jcr:root//*[jcr:contains(., &#39;○○&#39;)] =&gt; +:fulltext:â +:fulltext:â
+/jcr:root//*[jcr:contains(., &#39;☯︎&#39;)] =&gt; :fulltext:â (☯ is YIN YANG U+262F U+FE0E)
+/jcr:root//*[jcr:contains(., &#39;¥︎&#39;)] =&gt; :fulltext:â (¥ is YEN SIGN U+00A5)
+</pre>
+</div></div>
+
+<p>On the other hand, if an empty string or just spaces are used, the query fails with &quot;Invalid expression&quot;:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>/jcr:root//*[jcr:contains(., &#39;&#39;)]
+/jcr:root//*[jcr:contains(., &#39; &#39;)]
+/jcr:root//*[jcr:contains(., &#39;  &#39;)]
+</pre>
+</div></div>
+
+
+<h2 id="EncodingAndEscaping-Escaping/encodinginURIs">Escaping/encoding in URIs</h2>
+
+<p>There are further encoding/decoding methods in the <code>Text</code> class for dealing with URIs in a webapp. The allowed chars for JCR names contains the URI set plus a few others (eg. spaces). Thus the URI set is actually more constrained. Therefore, if you have a valid URI, you can map it directly onto a JCR path without having to worry about escaping (this is by design). If you go the other way, ie. have a JCR path and want to create an URI for it, you simply use plain URI escaping for it. To make everything simpler in the context of URIs, one suggestion is to only create JCR nodes with names that are valid URIs. </p>
+
+<h2 id="EncodingAndEscaping-Seealso">See also</h2>
+
+<ul>
+	<li><a href="ExamplesPage_115513397.html">ExamplesPage</a></li>
+</ul>
+                    </div>
+
+                    
+                                                      
+                </div>             </div> 
+            <div id="footer" role="contentinfo">
+                <section class="footer-body">
+                    <p>Document generated by Confluence on May 20, 2019 11:11</p>
+                    <div id="footer-logo"><a href="http://www.atlassian.com/">Atlassian</a></div>
+                </section>
+            </div>
+        </div>     </body>
+</html>

Propchange: jackrabbit/site/live/archive/wiki/JCR/EncodingAndEscaping_115513396.html
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/site/live/archive/wiki/JCR/EncodingAndEscaping_115513396.html
------------------------------------------------------------------------------
    svn:executable = *

Added: jackrabbit/site/live/archive/wiki/JCR/ExamplesPage_115513397.html
URL: http://svn.apache.org/viewvc/jackrabbit/site/live/archive/wiki/JCR/ExamplesPage_115513397.html?rev=1859550&view=auto
==============================================================================
--- jackrabbit/site/live/archive/wiki/JCR/ExamplesPage_115513397.html (added)
+++ jackrabbit/site/live/archive/wiki/JCR/ExamplesPage_115513397.html Mon May 20 11:23:18 2019
@@ -0,0 +1,312 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Apache Jackrabbit : ExamplesPage</title>
+        <link rel="stylesheet" href="styles/site.css" type="text/css" />
+        <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+
+    <body class="theme-default aui-theme-default">
+        <div id="page">
+            <div id="main" class="aui-page-panel">
+                <div id="main-header">
+                    <div id="breadcrumb-section">
+                        <ol id="breadcrumbs">
+                            <li class="first">
+                                <span><a href="index.html">Apache Jackrabbit</a></span>
+                            </li>
+                                                    <li>
+                                <span><a href="Home_70731.html">Home</a></span>
+                            </li>
+                                                </ol>
+                    </div>
+                    <h1 id="title-heading" class="pagetitle">
+                                                <span id="title-text">
+                            Apache Jackrabbit : ExamplesPage
+                        </span>
+                    </h1>
+                </div>
+
+                <div id="content" class="view">
+                    <div class="page-metadata">
+                        
+        
+    
+        
+    
+        
+        
+            Created by <span class='author'> ASF Infrabot</span> on May 20, 2019
+                        </div>
+                    <div id="main-content" class="wiki-content group">
+                    <h2 id="ExamplesPage-ApacheJackrabbitExamples">Apache Jackrabbit Examples</h2>
+<p>This page will be used to show solutions to common problems related to Apache Jackrabbit and the JCR API. These examples shouldn't be considered Best Practices - general error checking and exception handling have been omitted to keep the example code simple.</p>
+
+<p>Please feel free to add your own examples.</p>
+
+<style type='text/css'>/*<![CDATA[*/
+div.rbtoc1558350680579 {padding: 0px;}
+div.rbtoc1558350680579 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1558350680579 li {margin-left: 0px;padding-left: 0px;}
+
+/*]]>*/</style><div class='toc-macro rbtoc1558350680579'>
+<ul class='toc-indentation'>
+<li><a href='#ExamplesPage-ApacheJackrabbitExamples'>Apache Jackrabbit Examples</a></li>
+<li><a href='#ExamplesPage-ImportingaFile'>Importing a File</a></li>
+<li><a href='#ExamplesPage-RenamingaNode'>Renaming a Node</a></li>
+<li><a href='#ExamplesPage-RegisteraNodeType'>Register a Node Type</a></li>
+<li><a href='#ExamplesPage-RegisteraNodeType\[CND\]'>Register a Node Type [CND]</a></li>
+<li><a href='#ExamplesPage-VersioningBasics'>Versioning Basics</a></li>
+<li><a href='#ExamplesPage-CreatingaWorkspace'>Creating a Workspace</a></li>
+<li><a href='#ExamplesPage-DeletingaWorkspace'>Deleting a Workspace</a></li>
+<li><a href='#ExamplesPage-ShuttingDowntheRepository'>Shutting Down the Repository</a></li>
+<li><a href='#ExamplesPage-JackrabbitCacheConfiguration'>Jackrabbit Cache Configuration</a></li>
+<li><a href='#ExamplesPage-IstheRepositoryRunning?'>Is the Repository Running?</a></li>
+<li><a href='#ExamplesPage-SpringConfiguration'>Spring Configuration</a></li>
+<li><a href='#ExamplesPage-Seealso'>See also</a></li>
+</ul>
+</div>
+
+<h2 id="ExamplesPage-ImportingaFile">Importing a File</h2>
+<p>Also see: <a href="http://svn.apache.org/repos/asf/jackrabbit/sandbox/examples/src/java/org/apache/jackrabbit/examples/FSImport.java" class="external-link" rel="nofollow">FSImport.java</a> for more complete filesystem examples.</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>    public Node importFile (Node folderNode, File file, String mimeType,
+            String encoding) throws RepositoryException, IOException
+    {
+        //create the file node - see section 6.7.22.6 of the spec
+        Node fileNode = folderNode.addNode (file.getName (), &quot;nt:file&quot;);
+
+        //create the mandatory child node - jcr:content
+        Node resNode = fileNode.addNode (&quot;jcr:content&quot;, &quot;nt:resource&quot;);
+        resNode.setProperty (&quot;jcr:mimeType&quot;, mimeType);
+        resNode.setProperty (&quot;jcr:encoding&quot;, encoding);
+        resNode.setProperty (&quot;jcr:data&quot;, new FileInputStream (file));
+        Calendar lastModified = Calendar.getInstance ();
+        lastModified.setTimeInMillis (file.lastModified ());
+        resNode.setProperty (&quot;jcr:lastModified&quot;, lastModified);
+
+        return fileNode;
+    }
+</pre>
+</div></div>
+<h2 id="ExamplesPage-RenamingaNode">Renaming a Node</h2>
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>    void rename(Node node, String newName) throws RepositoryException
+    {
+        node.getSession().move(node.getPath(), node.getParent().getPath() + &quot;/&quot; + newName);
+        // Don&#39;t forget - not necessarily here at this place:
+        // node.getSession().save();
+    }
+</pre>
+</div></div>
+<h2 id="ExamplesPage-RegisteraNodeType">Register a Node Type</h2>
+<p>There are a few solutions in the works. For example, see <a href="http://svn.osafoundation.org/server/commons/trunk/jackrabbit/" class="external-link" rel="nofollow">OSAF offline tool</a>,  <a href="http://issues.apache.org/jira/browse/GRFT-23" class="external-link" rel="nofollow">Graffito Jira Issue</a>.</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>    public void registerNodeType(NodeTypeDef nodeTypeDef, Session session) throws RepositoryException
+    {
+        //NodeTypeRegistry object
+        Workspace wsp = session.getWorkspace();
+        NodeTypeManager ntMgr = wsp.getNodeTypeManager();
+
+        //non-JSR 170 - jackrabbit specific
+        NodeTypeRegistry ntReg =
+                ((NodeTypeManagerImpl) ntMgr).getNodeTypeRegistry();
+        ntReg.registerNodeType(nodeTypeDef);
+    }
+</pre>
+</div></div>
+<p>You can use JCR API to create and register custom node type (Groovy syntax).</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>/* Retrieve node type manager from the session */
+NodeTypeManager nodeTypeManager = session.workspace.nodeTypeManager
+
+/* Create node type */
+NodeTypeTemplate nodeType = nodeTypeManager.createNodeTypeTemplate()
+nodeType.name = &quot;my_custom_node_type&quot;
+
+/* Create a new property */
+PropertyDefinitionTemplate customProperty = nodeTypeManager.createPropertyDefinitionTemplate()
+customProperty.name = &quot;my_custom_property&quot;
+customProperty.requiredType = PropertyType.LONG
+/* Add property to node type */
+nodeType.propertyDefinitionTemplates &lt;&lt; customProperty
+
+/* Register node type */
+nodeTypeManager.registerNodeType(nodeType, false)
+</pre>
+</div></div>
+<h2 id="ExamplesPage-RegisteraNodeType\[CND\]"><p>Register a Node Type [CND]</p></h2>
+<p>Register one or more node types using CND.  CND is described in <a href="http://jackrabbit.apache.org/node-type-notation.html" class="external-link" rel="nofollow">http://jackrabbit.apache.org/node-type-notation.html</a>.</p>
+
+<p>Using JCR Commons <a class="createlink" href="/confluence/pages/createpage.action?spaceKey=JCR&amp;title=CndImporter&amp;linkCreation=true&amp;fromPageId=115513397">CndImporter</a> :</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>public static void RegisterCustomNodeTypes(Session session, String cndFileName)
+    throws Exception {
+    // Register the custom node types defined in the CND file, using JCR Commons CndImporter
+	NodeType[] nodeTypes = CndImporter.registerNodeTypes(new FileReader(cndFileName), session);
+	for (NodeType nt : nodeTypes) {
+		System.out.println(&quot;Registered: &quot; + nt.getName());
+	}
+    
+    // You can also use JCR NodeTypeManager from the Workspace.
+	NodeTypeManager manager = session.getWorkspace().getNodeTypeManager();
+	// ... use manager here ...
+}
+</pre>
+</div></div>
+
+<p>Using deprecated <a class="createlink" href="/confluence/pages/createpage.action?spaceKey=JCR&amp;title=JackrabbitNodeTypeManager&amp;linkCreation=true&amp;fromPageId=115513397">JackrabbitNodeTypeManager</a> API:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>    public void createCustomNodeTypes(Session session)
+        throws RepositoryException, IOException {
+
+        // Get the JackrabbitNodeTypeManager from the Workspace.
+        // Note that it must be cast from the generic JCR NodeTypeManager to
+        // the  Jackrabbit-specific implementation.
+        // (see: http://jackrabbit.apache.org/node-types.html)
+        JackrabbitNodeTypeManager manager =
+           (JackrabbitNodeTypeManager) session.getWorkspace().getNodeTypeManager();
+
+        // Register the custom node types defined in the CND file
+        InputStream is = Thread.currentThread().getContextClassLoader()
+                             .getResourceAsStream(&quot;com/example/jcr/custom.cnd&quot;);
+        manager.registerNodeTypes(is, JackrabbitNodeTypeManager.TEXT_X_JCR_CND);
+    }
+</pre>
+</div></div>
+<p>You can automatically install your node types/namespace during initialization. (This is why the method above pulls the file as classloader resource).</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>    public Session setup(Credentials cred)
+        throws RepositoryException, IOException {
+        Session session;
+
+        session = repository.login(cred);
+
+        // create &#39;custom&#39; namespace if necessary
+        Workspace workspace = session.getWorkspace();
+        NamespaceRegistry reg = workspace.getNamespaceRegistry();
+
+        if (!Arrays.asList(reg.getPrefixes()).contains(&quot;custom&quot;)) {
+            createCustomNodeTypes(session);
+        }
+
+        return session;
+    }
+</pre>
+</div></div>
+<h2 id="ExamplesPage-VersioningBasics">Versioning Basics</h2>
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>    /***
+    * most of the code below is deprecated as of jcr-2.0
+    * please see the javax.jcr.version.VersionManager javadocs - 
+    *
+    * http://www.day.com/maven/jsr170/javadocs/jcr-2.0/index.html
+    */
+
+    public void versioningBasics (Node parentNode, Session session) throws RepositoryException
+    {
+          //create versionable node
+          Node n = parentNode.addNode(&quot;childNode&quot;, &quot;nt:unstructured&quot;);
+          n.addMixin(&quot;mix:versionable&quot;);
+          n.setProperty(&quot;anyProperty&quot;, &quot;Blah&quot;);
+          session.save();
+          Version firstVersion = n.checkin();
+
+          //add new version
+          Node child = parentNode.getNode(&quot;childNode&quot;);
+          child.checkout(); 
+          child.setProperty(&quot;anyProperty&quot;, &quot;Blah2&quot;);
+          session.save();
+          child.checkin(); 
+
+          //print version history
+          VersionHistory history = child.getVersionHistory();
+          for (VersionIterator it = history.getAllVersions(); it.hasNext();) {
+            Version version = (Version) it.next();
+            System.out.println(version.getCreated().getTime());
+          }
+
+          //restoring old version
+          child.checkout();
+          child.restore(firstVersion, true);
+    }
+</pre>
+</div></div>
+<h2 id="ExamplesPage-CreatingaWorkspace">Creating a Workspace</h2>
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>((org.apache.jackrabbit.core.WorkspaceImpl)workspace).createWorkspace(name);
+</pre>
+</div></div>
+<h2 id="ExamplesPage-DeletingaWorkspace">Deleting a Workspace</h2>
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>You have to manually remove the workspace.xml - there&#39;s no programmatic way yet.
+</pre>
+</div></div>
+<h2 id="ExamplesPage-ShuttingDowntheRepository">Shutting Down the Repository</h2>
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>javax.jcr.Session session = ...;
+((org.apache.jackrabbit.core.RepositoryImpl) session.getRepository()).shutdown();
+</pre>
+</div></div>
+<h2 id="ExamplesPage-JackrabbitCacheConfiguration">Jackrabbit Cache Configuration</h2>
+<p>This info has moved to the <a href="CacheManager_115513375.html">CacheManager</a> page.</p>
+
+<h2 id="ExamplesPage-IstheRepositoryRunning?">Is the Repository Running?</h2>
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>/**
+ * Check if a repository is currently running. This only works when
+ * using the CooperativeFileLock, see
+ * http://wiki.apache.org/jackrabbit/RepositoryLock
+ */
+static boolean isRepositoryRunning(String repositoryHome) {
+    File lock = new File(repositoryHome + &quot;/lock.properties&quot;);
+    if (lock.exists()) {
+        lock.delete();
+    }
+    try {
+        Thread.sleep(2000);
+    } catch (Exception e) {
+        throw new RuntimeException(e);
+    }
+    return lock.exists();
+}
+</pre>
+</div></div>
+<h2 id="ExamplesPage-SpringConfiguration">Spring Configuration</h2>
+<p>You can create a Repository reference in Spring in multiple ways, but here's one that uses the <a class="createlink" href="/confluence/pages/createpage.action?spaceKey=JCR&amp;title=RepositoryImpl&amp;linkCreation=true&amp;fromPageId=115513397">RepositoryImpl</a> class:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>    &lt;bean id=&quot;repository&quot; class=&quot;org.apache.jackrabbit.core.RepositoryImpl&quot;&gt;
+        &lt;constructor-arg index=&quot;0&quot; ref=&quot;config&quot; /&gt;
+    &lt;/bean&gt;
+    &lt;bean id=&quot;config&quot; class=&quot;org.apache.jackrabbit.core.config.RepositoryConfig&quot; factory-method=&quot;create&quot;&gt;
+        &lt;constructor-arg index=&quot;0&quot; value=&quot;./repository.xml&quot;/&gt;
+        &lt;constructor-arg index=&quot;1&quot; value=&quot;.&quot; /&gt;
+    &lt;/bean&gt;
+</pre>
+</div></div>
+<p>This will create a repository in the current directory, using ./repository.xml as the configuration file. This isn't as complete as se-jcr will be (hopefully) but this does work with Spring 3.0 and <a class="createlink" href="/confluence/pages/createpage.action?spaceKey=JCR&amp;title=JackRabbit&amp;linkCreation=true&amp;fromPageId=115513397">JackRabbit</a> 2.0.</p>
+
+<h2 id="ExamplesPage-Seealso">See also</h2>
+<ul>
+	<li><a href="EncodingAndEscaping_115513396.html">EncodingAndEscaping</a> !</li>
+</ul>
+                    </div>
+
+                    
+                                                      
+                </div>             </div> 
+            <div id="footer" role="contentinfo">
+                <section class="footer-body">
+                    <p>Document generated by Confluence on May 20, 2019 11:11</p>
+                    <div id="footer-logo"><a href="http://www.atlassian.com/">Atlassian</a></div>
+                </section>
+            </div>
+        </div>     </body>
+</html>

Propchange: jackrabbit/site/live/archive/wiki/JCR/ExamplesPage_115513397.html
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/site/live/archive/wiki/JCR/ExamplesPage_115513397.html
------------------------------------------------------------------------------
    svn:executable = *

Added: jackrabbit/site/live/archive/wiki/JCR/ExcerptProvider_115513398.html
URL: http://svn.apache.org/viewvc/jackrabbit/site/live/archive/wiki/JCR/ExcerptProvider_115513398.html?rev=1859550&view=auto
==============================================================================
--- jackrabbit/site/live/archive/wiki/JCR/ExcerptProvider_115513398.html (added)
+++ jackrabbit/site/live/archive/wiki/JCR/ExcerptProvider_115513398.html Mon May 20 11:23:18 2019
@@ -0,0 +1,144 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Apache Jackrabbit : ExcerptProvider</title>
+        <link rel="stylesheet" href="styles/site.css" type="text/css" />
+        <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    </head>
+
+    <body class="theme-default aui-theme-default">
+        <div id="page">
+            <div id="main" class="aui-page-panel">
+                <div id="main-header">
+                    <div id="breadcrumb-section">
+                        <ol id="breadcrumbs">
+                            <li class="first">
+                                <span><a href="index.html">Apache Jackrabbit</a></span>
+                            </li>
+                                                    <li>
+                                <span><a href="Home_70731.html">Home</a></span>
+                            </li>
+                                                </ol>
+                    </div>
+                    <h1 id="title-heading" class="pagetitle">
+                                                <span id="title-text">
+                            Apache Jackrabbit : ExcerptProvider
+                        </span>
+                    </h1>
+                </div>
+
+                <div id="content" class="view">
+                    <div class="page-metadata">
+                        
+        
+    
+        
+    
+        
+        
+            Created by <span class='author'> ASF Infrabot</span> on May 20, 2019
+                        </div>
+                    <div id="main-content" class="wiki-content group">
+                    <p>An <a href="ExcerptProvider_115513398.html">ExcerptProvider</a> retrieves text excerpts for a node in the query result and marks up the words in the text that match the query terms.</p>
+
+<p>This feature is Jackrabbit specific (introduced in version 1.3) and will not work with other JCR implementations.</p>
+
+<p>Per default highlighting words that matched the query is disabled because this feature requires that additional information is written to the search index. To enable this feature you need to add the following parameter inside the <a href="SearchIndex_115513505.html">SearchIndex</a> element of your workspace.xml or repository.xml file:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>   &lt;param name=&quot;supportHighlighting&quot; value=&quot;true&quot;/&gt;
+</pre>
+</div></div>
+
+<p>Additionally there is a parameter that controls the format of the excerpt created. This must be a class that implements the <a href="http://jackrabbit.apache.org/api/1.6/org/apache/jackrabbit/core/query/lucene/ExcerptProvider.html" class="external-link" rel="nofollow">org.apache.jackrabbit.core.query.lucene.ExcerptProvider</a> interface.</p>
+
+<p>In Jackrabbit 1.3 the default is set to <code>org.apache.jackrabbit.core.query.lucene.DefaultXMLExcerpt</code> and will be changed to <code>org.apache.jackrabbit.core.query.lucene.DefaultHTMLExcerpt</code> in Jackrabbit 1.4. The configuration parameter for this setting is:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>   &lt;param name=&quot;excerptProviderClass&quot; value=&quot;org.apache.jackrabbit.core.query.lucene.DefaultXMLExcerpt&quot;/&gt;
+</pre>
+</div></div>
+
+<h3 id="ExcerptProvider-DefaultXMLExcerpt">DefaultXMLExcerpt</h3>
+
+<p>This excerpt provider creates an XML fragment of the following form:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>&lt;excerpt&gt;
+    &lt;fragment&gt;
+        &lt;highlight&gt;Jackrabbit&lt;/highlight&gt; implements both the mandatory
+        XPath and optional SQL &lt;highlight&gt;query&lt;/highlight&gt; syntax.
+    &lt;/fragment&gt;
+    &lt;fragment&gt;
+        Before parsing the XPath &lt;highlight&gt;query&lt;/highlight&gt; in
+        &lt;highlight&gt;Jackrabbit&lt;/highlight&gt;, the statement is surrounded
+    &lt;/fragment&gt;
+&lt;/excerpt&gt;
+</pre>
+</div></div>
+
+<h3 id="ExcerptProvider-DefaultHTMLExcerpt">DefaultHTMLExcerpt</h3>
+
+<p>This excerpt provider creates an HTML fragment of the following form:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>&lt;div&gt;
+    &lt;span&gt;
+        &lt;strong&gt;Jackrabbit&lt;/strong&gt; implements both the mandatory XPath
+        and optional SQL &lt;strong&gt;query&lt;/strong&gt; syntax.
+    &lt;/span&gt;
+    &lt;span&gt;
+        Before parsing the XPath &lt;strong&gt;query&lt;/strong&gt; in
+        &lt;strong&gt;Jackrabbit&lt;/strong&gt;, the statement is surrounded
+    &lt;/span&gt;
+&lt;/div&gt;
+</pre>
+</div></div>
+
+<h3 id="ExcerptProvider-Howtouseit">How to use it</h3>
+
+<p>If you are using XPath you must use the <code>rep:excerpt()</code> function in the last location step, just like you would select properties:</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>QueryManager qm = session.getWorkspace().getQueryManager();
+Query q = qm.createQuery(&quot;//*[jcr:contains(., &#39;jackrabbit&#39;)]/(@Title|rep:excerpt(.))&quot;, Query.XPATH);
+QueryResult result = q.execute();
+for (RowIterator it = result.getRows(); it.hasNext(); ) {
+    Row r = it.nextRow();
+    Value title = r.getValue(&quot;Title&quot;);
+    Value excerpt = r.getValue(&quot;rep:excerpt(.)&quot;);
+}
+</pre>
+</div></div>
+
+<p>The above code searches for nodes that contain the word jackrabbit and then gets the value of the Title property and an excerpt for each result node.</p>
+
+<p>Starting with Jackrabbit 1.4 it is also possible to use a relative path in the call <code>Row.getValue()</code> while the query statement still remains the same. See <a href="http://issues.apache.org/jira/browse/JCR-860" class="external-link" rel="nofollow">JCR-860</a> for more information. Also starting with Jackrabbit 1.4 you may use a relative path to a string property. The returned value will then be an excerpt based on string value of the property.</p>
+
+<p>Both available excerpt provider will create fragments of about 150 characters and up to 3 fragments.</p>
+
+<p>In SQL the function is called <code>excerpt()</code> without the rep prefix, but the column in the <a class="createlink" href="/confluence/pages/createpage.action?spaceKey=JCR&amp;title=RowIterator&amp;linkCreation=true&amp;fromPageId=115513398">RowIterator</a> will nonetheless be labled rep:excerpt(.)!</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+<pre>QueryManager qm = session.getWorkspace().getQueryManager();
+Query q = qm.createQuery(&quot;select excerpt(.) from nt:resource where contains(., &#39;jackrabbit&#39;)&quot;, Query.SQL);
+QueryResult result = q.execute();
+for (RowIterator it = result.getRows(); it.hasNext(); ) {
+    Row r = it.nextRow();
+    Value excerpt = r.getValue(&quot;rep:excerpt(.)&quot;);
+}
+</pre>
+</div></div>
+                    </div>
+
+                    
+                                                      
+                </div>             </div> 
+            <div id="footer" role="contentinfo">
+                <section class="footer-body">
+                    <p>Document generated by Confluence on May 20, 2019 11:11</p>
+                    <div id="footer-logo"><a href="http://www.atlassian.com/">Atlassian</a></div>
+                </section>
+            </div>
+        </div>     </body>
+</html>

Propchange: jackrabbit/site/live/archive/wiki/JCR/ExcerptProvider_115513398.html
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/site/live/archive/wiki/JCR/ExcerptProvider_115513398.html
------------------------------------------------------------------------------
    svn:executable = *