blob: ef6cd4b14ce5491596448cc1f6ddb38f19da7135 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta content="Apache Forrest" name="Generator">
<meta name="Forrest-version" content="0.8-dev">
<meta name="Forrest-skin-name" content="pelt">
<title>Libre QuickStart (v0.8-dev)</title>
<link type="text/css" href="../skin/basic.css" rel="stylesheet">
<link media="screen" type="text/css" href="../skin/screen.css" rel="stylesheet">
<link media="print" type="text/css" href="../skin/print.css" rel="stylesheet">
<link type="text/css" href="../skin/profile.css" rel="stylesheet">
<script src="../skin/getBlank.js" language="javascript" type="text/javascript"></script><script src="../skin/getMenu.js" language="javascript" type="text/javascript"></script><script src="../skin/fontsize.js" language="javascript" type="text/javascript"></script>
<link rel="shortcut icon" href="../favicon.ico">
</head>
<body onload="init()">
<script type="text/javascript">ndeSetTextSize();</script>
<div id="top">
<!--+
|breadtrail
+-->
<div class="breadtrail">
<a href="http://www.apache.org/">apache</a> &gt; <a href="http://forrest.apache.org/">forrest</a><script src="../skin/breadcrumbs.js" language="JavaScript" type="text/javascript"></script>
</div>
<!--+
|header
+-->
<div class="header">
<!--+
|start group logo
+-->
<div class="grouplogo">
<a href="http://www.apache.org/"><img class="logoImage" alt="Apache" src="../images/apache-forrest.png" title="The Apache Software Foundation"></a>
</div>
<!--+
|end group logo
+-->
<!--+
|start Project Logo
+-->
<div class="projectlogo">
<a href="http://forrest.apache.org/"><img class="logoImage" alt="Forrest" src="../images/project-logo.gif" title="Apache Forrest"></a>
</div>
<!--+
|end Project Logo
+-->
<!--+
|start Search
+-->
<div class="searchbox">
<form action="http://www.google.com/search" method="get" class="roundtopsmall">
<input value="forrest.apache.org" name="sitesearch" type="hidden"><input onFocus="getBlank (this, 'Search the site with google');" size="25" name="q" id="query" type="text" value="Search the site with google">&nbsp;
<input name="Search" value="Search" type="submit">
</form>
</div>
<!--+
|end search
+-->
<!--+
|start Tabs
+-->
<ul id="tabs">
<li>
<a class="unselected" href="../index.html">Welcome</a>
</li>
<li>
<a class="unselected" href="../contrib.html">Developers</a>
</li>
<li class="current">
<a class="selected" href="../versions/index.html">Versioned Docs</a>
</li>
<li>
<a class="unselected" href="../pluginDocs/index.html">Plugins</a>
</li>
<li>
<a class="unselected" href="../tools/index.html">Tools</a>
</li>
</ul>
<!--+
|end Tabs
+-->
</div>
</div>
<div id="main">
<div id="publishedStrip">
<!--+
|start Subtabs
+-->
<div id="level2tabs">
<a class="unselected" href="../docs_0_70/index.html">0.70 (current)</a><a class="selected" href="../docs_0_80/index.html">0.80-dev (under development)</a><a class="unselected" href="../docs_0_60/index.html">0.60 (past)</a>
</div>
<!--+
|end Endtabs
+-->
<script type="text/javascript"><!--
document.write("Last Published: " + document.lastModified);
// --></script>
</div>
<!--+
|breadtrail
+-->
<div class="breadtrail">
&nbsp;
</div>
<!--+
|start Menu, mainarea
+-->
<!--+
|start Menu
+-->
<div id="menu">
<div onclick="SwitchMenu('menu_selected_1.1', '../skin/')" id="menu_selected_1.1Title" class="menutitle" style="background-image: url('../skin/images/chapter_open.gif');">0.80-dev</div>
<div id="menu_selected_1.1" class="selectedmenuitemgroup" style="display: block;">
<div class="menuitem">
<a href="../docs_0_80/index.html">Overview</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/your-project.html">Using Forrest</a>
</div>
<div onclick="SwitchMenu('menu_1.1.3', '../skin/')" id="menu_1.1.3Title" class="menutitle">How-To</div>
<div id="menu_1.1.3" class="menuitemgroup">
<div class="menuitem">
<a href="../docs_0_80/howto/index.html">Overview</a>
</div>
<div onclick="SwitchMenu('menu_1.1.3.2', '../skin/')" id="menu_1.1.3.2Title" class="menutitle">Install Forrest</div>
<div id="menu_1.1.3.2" class="menuitemgroup">
<div class="menuitem">
<a href="../docs_0_80/build.html" title="Build and install the current unreleased version">Building Forrest from Source</a>
</div>
</div>
<div class="menuitem">
<a href="../docs_0_80/upgrading_08.html">Upgrading to 0.8</a>
</div>
<div class="menuitem">
<a href="">Use Forrest</a>
</div>
<div onclick="SwitchMenu('menu_1.1.3.5', '../skin/')" id="menu_1.1.3.5Title" class="menutitle">Customize Forrest</div>
<div id="menu_1.1.3.5" class="menuitemgroup">
<div class="menuitem">
<a href="../docs_0_80/sitemap-explain.html">Sitemaps explained</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/howto/howto-custom-html-source.html">Custom html source</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/project-sitemap.html">Project sitemap</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/howto/howto-editcss.html">Edit CSS (WYSIWYG)</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/howto/howto-pdf-tab.html" title="Generate one pdf-document for all pages of a tab">Create tab PDF</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/howto/howto-corner-images.html">CSS corner SVG</a>
</div>
</div>
<div onclick="SwitchMenu('menu_1.1.3.6', '../skin/')" id="menu_1.1.3.6Title" class="menutitle">Integrate Forrest with tools</div>
<div id="menu_1.1.3.6" class="menuitemgroup">
<div class="menuitem">
<a href="../docs_0_80/howto/howto-forrest-from-maven.html">Maven Integration</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/catalog.html">Using DTD Catalogs</a>
</div>
</div>
<div onclick="SwitchMenu('menu_1.1.3.7', '../skin/')" id="menu_1.1.3.7Title" class="menutitle">Extend Forrest</div>
<div id="menu_1.1.3.7" class="menuitemgroup">
<div class="menuitem">
<a href="../docs_0_80/howto/howto-buildPlugin.html">Build a Plugin</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/skin-package.html">Package new Skins</a>
</div>
</div>
<div class="menuitem">
<a href="../docs_0_80/howto/howto-asf-mirror.html">Download mirror</a>
</div>
<div onclick="SwitchMenu('menu_1.1.3.9', '../skin/')" id="menu_1.1.3.9Title" class="menutitle">Adding Documentation</div>
<div id="menu_1.1.3.9" class="menuitemgroup">
<div class="menuitem">
<a href="../howto-howto.html" title="Instructions for writing a new howto-document">Write a How-to</a>
</div>
<div onclick="SwitchMenu('menu_1.1.3.9.2', '../skin/')" id="menu_1.1.3.9.2Title" class="menutitle">Multipage HowTo</div>
<div id="menu_1.1.3.9.2" class="menuitemgroup">
<div class="menuitem">
<a href="../docs_0_80/howto/multi/howto-multi.html">Introduction</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/howto/multi/step1.html">Step 1</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/howto/multi/step2.html">Step 2</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/howto/multi/step3.html">Step 3</a>
</div>
</div>
</div>
</div>
<div class="menuitem">
<a href="../docs_0_80/faq.html">FAQs</a>
</div>
<div onclick="SwitchMenu('menu_1.1.5', '../skin/')" id="menu_1.1.5Title" class="menutitle">Background</div>
<div id="menu_1.1.5" class="menuitemgroup">
<div class="menuitem">
<a href="../docs_0_80/linking.html">Menus and Linking</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/searching.html">Search Options in Forrest</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/locationmap.html">Locationmap</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/sitemap-ref.html">Sitemap Reference</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/skins.html" title="About default skins, their naming and features">Skins</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/status-themes.html">Dispatcher versus Skins</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/cap.html">Sourcetype Action</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/validation.html">XML validation and entity resolution</a>
</div>
</div>
<div class="menuitem">
<a href="../docs_0_80/changes.html">Changes</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/glossary.html">Glossary</a>
</div>
<div onclick="SwitchMenu('menu_1.1.8', '../skin/')" id="menu_1.1.8Title" class="menutitle">Reference docs</div>
<div id="menu_1.1.8" class="menuitemgroup">
<div onclick="SwitchMenu('menu_1.1.8.1', '../skin/')" id="menu_1.1.8.1Title" class="menutitle">DTD documentation</div>
<div id="menu_1.1.8.1" class="menuitemgroup">
<div class="menuitem">
<a href="../dtdx/dtd-docs.html">Overview</a>
</div>
<div class="menuitem">
<a href="../dtdx/document-v20.dtdx.html">document-v20</a>
</div>
<div class="menuitem">
<a href="../dtdx/howto-v20.dtdx.html">howto-v20</a>
</div>
<div class="menuitem">
<a href="../dtdx/faq-v20.dtdx.html">faq-v20</a>
</div>
<div class="menuitem">
<a href="../dtdx/document-v13.dtdx.html">document-v13</a>
</div>
<div class="menuitem">
<a href="../dtdx/howto-v13.dtdx.html">howto-v13</a>
</div>
<div class="menuitem">
<a href="../dtdx/faq-v13.dtdx.html">faq-v13</a>
</div>
</div>
<div onclick="SwitchMenu('menu_1.1.8.2', '../skin/')" id="menu_1.1.8.2Title" class="menutitle">Doc samples</div>
<div id="menu_1.1.8.2" class="menuitemgroup">
<div class="menuitem">
<a href="../dtdx/document-v13.html">document-v13</a>
</div>
<div class="menuitem">
<a href="../dtdx/document-v20.html">document-v20</a>
</div>
</div>
</div>
<div onclick="SwitchMenu('menu_selected_1.1.9', '../skin/')" id="menu_selected_1.1.9Title" class="menutitle" style="background-image: url('../skin/images/chapter_open.gif');">Older Docs</div>
<div id="menu_selected_1.1.9" class="selectedmenuitemgroup" style="display: block;">
<div class="menuitem">
<a href="../docs_0_80/primer.html">Forrest Primer</a>
</div>
<div class="menupage">
<div class="menupagetitle">Libre</div>
</div>
<div class="menuitem">
<a href="../docs_0_80/dreams.html">Dream list</a>
</div>
<div class="menuitem">
<a href="../docs_0_80/howto/cvs-ssh/howto-cvs-ssh.html">CVS over SSH</a>
</div>
</div>
</div>
<div id="credit">
<hr>
This is documentation for development version v0.8
(<a href="http://forrest.apache.org/versions/">More</a>)</div>
<div id="roundbottom">
<img style="display: none" class="corner" height="15" width="15" alt="" src="../skin/images/rc-b-l-15-1body-2menu-3menu.png"></div>
<!--+
|alternative credits
+-->
<div id="credit2">
<a href="http://apachecon.com/2007/EU/"><img border="0" title="ApacheCon Europe 2007" alt="ApacheCon Europe 2007 - logo" src="http://apache.org/ads/ApacheCon/2007-europe-125x125.png" style="width: 125px;height: 125px;"></a><a href="http://people.apache.org/calendar.html#200711"><img border="0" title="ApacheCon US 2007" alt="ApacheCon US 2007 - logo" src="http://apache.org/ads/ApacheCon/2007-usa-125x125.png" style="width: 125px;height: 125px;"></a>
</div>
</div>
<!--+
|end Menu
+-->
<!--+
|start content
+-->
<div id="content">
<div title="Portable Document Format" class="pdflink">
<a class="dida" href="libre-intro.pdf"><img alt="PDF -icon" src="../skin/images/pdfdoc.gif" class="skin"><br>
PDF</a>
</div>
<div class="trail">Font size:
&nbsp;<input value="Reset" class="resetfont" title="Reset text" onclick="ndeSetTextSize('reset'); return false;" type="button">
&nbsp;<input value="-a" class="smallerfont" title="Shrink text" onclick="ndeSetTextSize('decr'); return false;" type="button">
&nbsp;<input value="+a" class="biggerfont" title="Enlarge text" onclick="ndeSetTextSize('incr'); return false;" type="button">
</div>
<h1>Libre QuickStart</h1>
<div class="abstract">
This document is the current full documentation on the "libre" generator
that was implanted into xml-forrest.
</div>
<div id="motd-area">
This is documentation for development version v0.8
(<a href="http://forrest.apache.org/versions/">More</a>)</div>
<div id="minitoc-area">
<ul class="minitoc">
<li>
<a href="#Intro">Intro</a>
</li>
<li>
<a href="#Using+Libre+now+%280.0+alfa%29">Using Libre now (0.0 alfa)</a>
<ul class="minitoc">
<li>
<a href="#Generated+Output">Generated Output</a>
</li>
<li>
<a href="#Contents">libre.xml Contents</a>
<ul class="minitoc">
<li>
<a href="#Building+Blocks">Building Blocks</a>
</li>
</ul>
</li>
<li>
<a href="#Important+Side+Effects">Important Side Effects</a>
<ul class="minitoc">
<li>
<a href="#No+libre.xml">No libre.xml</a>
</li>
<li>
<a href="#No+Duplicates">No Duplicates</a>
</li>
</ul>
</li>
<li>
<a href="#Example+Constructs">Example Constructs</a>
<ul class="minitoc">
<li>
<a href="#Sorting+your+files+or+your+menu+entries%3F">Sorting your files or your menu entries?</a>
</li>
<li>
<a href="#Naming+your+files+or+asking+them+their+name%3F">Naming your files or asking them their name?</a>
</li>
</ul>
</li>
</ul>
</li>
<li>
<a href="#Next+Libre+%280.1%29">Next Libre (0.1)</a>
<ul class="minitoc">
<li>
<a href="#Itches">Itches</a>
</li>
<li>
<a href="#Upcoming+Features">Upcoming Features</a>
<ul class="minitoc">
<li>
<a href="#Combinations+of+filter+logic">Combinations of filter logic</a>
</li>
<li>
<a href="#Separating+property-retrieval+from+formatting+and%0A++++++++++++testing">Separating property-retrieval from formatting and
testing</a>
</li>
<li>
<a href="#Replace+the+introspection+with+semantically+richer+named%0A++++++++++++properties+to+read.">Replace the introspection with semantically richer named
properties to read.</a>
</li>
</ul>
</li>
<li>
<a href="#Avalonising">Avalonising</a>
</li>
<li>
<a href="#Unresolved+Discussions">Unresolved Discussions</a>
</li>
</ul>
</li>
<li>
<a href="#Libre+Design">Libre Design</a>
<ul class="minitoc">
<li>
<a href="#Dependencies">Dependencies</a>
</li>
</ul>
</li>
</ul>
</div>
<a name="N10010"></a><a name="Intro"></a>
<h2 class="underlined_10">Intro</h2>
<div class="section">
<div class="warning">
<div class="label">Warning</div>
<div class="content">
This document is still relevant for ideas and potential solutions.
However, the experimental code for Libre was removed from the scratchpad
on 2003-04-18 during spring cleaning. If you want to resurrect it, then
use the cvs tag "before_libre_departure".
</div>
</div>
<p>
The libre idea was born out of the cocoon book.xml itch. The actual need
to start scratching was introduced by the higher volume of
book.xml-editing-work that came along with the cocoon documentation and
xml-forrest efforts.
</p>
<p>
The single idea behind it in fact is trying to automatically generate
part of the navigation tree which is held now in the different book.xml
's. This automation effort however is held back by the lack of meta-data
you can extract from the filesystem itself. This is why the libre
approach still requires you to add this extra metadata using some
libre.xml file. This libre.xml however has the following main advantages
over the book.xml:
</p>
<ul>
<li>The settings are 'inherited' down the directory tree, so you do not
need a libre.xml on each directory level. You only need it to change
the subdir traversing strategy from its parent dir.</li>
<li>It combines some 'filesystem-introspection'-like declarations
that are used in run-time filtering, sorting and attributing decisions.
Introspection strategies are currently based on either (1) reading properties
of the java.io.File object at hand, or (2) executing xpath expressions on the
pointed at XML file. </li>
</ul>
</div>
<a name="N10029"></a><a name="Using+Libre+now+%280.0+alfa%29"></a>
<h2 class="underlined_10">Using Libre now (0.0 alfa)</h2>
<div class="section">
<div class="warning">
<div class="label">Warning</div>
<div class="content">
Disclaimer: most of what you read below is 'how it was intended' . To
what extent that matches the actual execution process is largely
dependent on my programming skills and thoroughness of testing.
<br>
In other words: don't expect a thing unless you've seen it work. (at
this time)
</div>
</div>
<a name="N10034"></a><a name="Generated+Output"></a>
<h3 class="underlined_5">Generated Output</h3>
<p>
The XML output that comes out of the generator largely follows this
example:
</p>
<pre class="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;collection xmlns="http://outerx.org/yer/hierarchy/0.1"&gt;
&lt;collection label="content"&gt;
&lt;collection label="xdocs"&gt;
&lt;item label="dreams.xml"
href="src/documentation/content/xdocs/dreams.xml"
title="Forrest dream list"/&gt;
&lt;item label="faq.xml"
href="src/documentation/content/xdocs/faq.xml"/&gt;
&lt;item label="book.xml"
href="src/documentation/content/xdocs/book.xml"/&gt;
&lt;item label="contrib.xml"
href="src/documentation/content/xdocs/contrib.xml"
title="Contribution to Forrest"/&gt;
&lt;item label="mail-archives.xml"
href="src/documentation/content/xdocs/mail-archives.xml"
title="Mail Archives"/&gt;
&lt;item label="mail-lists.xml"
href="src/documentation/content/xdocs/mail-lists.xml"
title="Mailing Lists"/&gt;
&lt;item label="license.xml"
href="src/documentation/content/xdocs/license.xml"
title="The Apache Software License"/&gt;
&lt;item label="index.xml"
href="src/documentation/content/xdocs/index.xml"
title="Welcome to Forrest"/&gt;
&lt;item label="who.xml"
href="src/documentation/content/xdocs/who.xml"
title="Who we are"/&gt;
&lt;/collection&gt;
&lt;/collection&gt;
&lt;/collection&gt;</pre>
<p>
And it's not getting any harder in fact: only 2 elements,
<span class="codefrag">&lt;collection&gt;</span> and <span class="codefrag">&lt;item&gt;</span> and that
should do. The first maps to a menu-group in the navigation, guess
what the second maps to?
</p>
<p>
The number and value (and its meaning) of the attributes on these
elements are specified in the libre.xml file.
</p>
<a name="N1004E"></a><a name="Contents"></a>
<h3 class="underlined_5">libre.xml Contents</h3>
<p>
That libre.xml file follows the
src/resources/schema/dtd/libre-v10.dtd. In fact the current release
allows for some extra elements (I'll explain where) and some
unrestricted attribute CDATA types that cause some extensible xml
output resp. some java-introspection to be triggered. So basically the
DTD will be limiting you more than the runtime interpretation. (future
versions will try to narrow this down seriously, main reason is that a
more elaborate DTD allows for more XML-editor assistance in editing
the files.)
</p>
<p>
The dtd:
</p>
<pre class="code">&lt;!ELEMENT libre (entry | auto)*&gt;
&lt;!ELEMENT entry (label?, href?)&gt;
&lt;!ATTLIST entry
location CDATA #REQUIRED
&gt;
&lt;!ELEMENT auto (filter?, sorter?, label?, href?)&gt;
&lt;!ELEMENT label (xpath | property)&gt;
&lt;!ELEMENT href (xpath | property)&gt;
&lt;!ELEMENT filter (xpath | property)&gt;
&lt;!ATTLIST filter
logic (inverse | normal) "normal"
clear (yes | no) "no"
&gt;
&lt;!ELEMENT sorter (xpath | property)&gt;
&lt;!ATTLIST sorter
order (ascending | descending) "ascending"
clear (yes | no) "no"
&gt;
&lt;!ELEMENT xpath EMPTY&gt;
&lt;!ATTLIST xpath
expression CDATA #REQUIRED
&gt;
&lt;!ELEMENT property EMPTY&gt;
&lt;!ATTLIST property
name CDATA #REQUIRED
mask CDATA #IMPLIED
regex CDATA #IMPLIED
substitute CDATA #IMPLIED
&gt;</pre>
<a name="N10060"></a><a name="Building+Blocks"></a>
<h4>Building Blocks</h4>
<p>
The following elements get the following meaning when interpreted by
the LibreConfigBuilder
</p>
<pre class="code">&lt;libre xmlns="http://outerx.org/libre/config/0.1"&gt;</pre>
<ul>
<li>This is one of those libre.xml files, that will configure how
items are filteres, sorted and attributed</li>
</ul>
<pre class="code">&lt;entry location="[relative location path]" /&gt;</pre>
<ul>
<li>Allows to manually sort out specific files or directories.</li>
<li>Comparable to standard book.xml behaviour, except for the fact
that </li>
<ul>
<li>libre doesn't yet support external hrefs (should be easy
though)</li>
<li>there is no difference between <span class="codefrag">&lt;menu&gt;</span> and
<span class="codefrag">&lt;menu-item&gt;</span>, there just is <span class="codefrag">&lt;entry&gt;</span>. It
will become a <span class="codefrag">&lt;collection&gt;</span> or <span class="codefrag">&lt;item&gt;</span> in
the output based on the fact if the location points to a directory resp. a
file.</li>
<li>For locations that point to a filter it doesn't make sense, but
when it points to a directory it is nested <span class="codefrag">&lt;filter&gt;</span> and
<span class="codefrag">&lt;sort&gt;</span> elements get inherited down to the next level. </li>
</ul>
</ul>
<div class="fixme">
<div class="label">Fixme (mpo)</div>
<div class="content">
This last remarks actually means (1) I need to update the DTD to
reflect this and (2) check the code for actually doing this.
</div>
</div>
<pre class="code">&lt;auto&gt;</pre>
<ul>
<li>Automatically generates more <span class="codefrag">&lt;collection&gt;</span>
and <span class="codefrag">&lt;item&gt;</span> elements in the output, based on the
specifications of the nested elements: <span class="codefrag">&lt;filter&gt;</span> (which
resources?) and <span class="codefrag">&lt;sort&gt;</span> (in which order?).</li>
</ul>
<pre class="code">&lt;filter logic="inverse" clear="no"&gt;</pre>
<ul>
<li>This element wraps a so-called AttributeReader (there are
currently two of them: <span class="codefrag">&lt;xpath&gt;</span> and
<span class="codefrag">&lt;property&gt;</span>)</li>
<li>The AttributeReader is going to specify which
information-element is going to be retrieved from the file or directory it is
pointing at. Depending on which one is used this wrapping filter will test for
presence or regex match of the resource being read. Based on the outcome of
this test (true or false) the passed file will be accepted or not in the
list.</li>
<li>This wrapping filter element allows to inverse the
acceptance-logic (accept what normally should be rejected and vice versa).</li>
<li>Using the <span class="codefrag">clear="yes"</span> attribute stops the
inheritance of the used filter strategy from the parent directory. Instead the
default filter strategy (which is to accept all files) is slided in at this
level.</li>
</ul>
<pre class="code">&lt;sort order="descending" clear="no"&gt;</pre>
<ul>
<li>This element wraps a so called AttributeReader (there are
currently two of them: <span class="codefrag">&lt;xpath&gt;</span> and
<span class="codefrag">&lt;property&gt;</span>).</li>
<li>The AttributeReader is going to specify which
information-element is going to be retrieved from the file or directory it is
pointing at. This information element will be considered to be a simple
Key-String and <span class="codefrag">&lt;collection&gt;</span> and <span class="codefrag">&lt;item&gt;</span>
elements in the output will appear in the order defined by the alphabetic
sorting of these keys.</li>
<li>This wrapping sort element allows to reverse the order.
(z-&gt;a instead of a-&gt;z)</li>
<li>Using the <span class="codefrag">clear="yes"</span> attribute stops the
inheritance of the used sort strategy from the parent directory. Instead the
default sort strategy (which is to use default filesystem sorting, alphabetic
on filename) is slided in at this level.</li>
</ul>
<pre class="code">&lt;label&gt;, &lt;href&gt;, &lt;YOURTAG&gt;.... {AttributeDefinitions}</pre>
<ul>
<li>The remainder of the elements inside the
<span class="codefrag">&lt;auto&gt;</span> tag specify the attributes that need to be applied to
the generated <span class="codefrag">&lt;collection&gt;</span> and <span class="codefrag">&lt;item&gt;</span>
elements in the output: <span class="codefrag">&lt;item label=".." href=".." YOURTAG=".."
/&gt;</span>
</li>
<li>There is currently only support for adding attributes, not
nested elements.</li>
<li>These elements all wrap a so called AttributeReader (there are
currently two of them: &lt;xpath&gt; and &lt;property&gt;)</li>
<li>In these cases the wrapped AttributeReader is going to specify
which information-element is going to be retrieved from the file or directory
it is pointing at. This information element will be considered to be a simple
String-value that gets slided in as the corresponding output attribute
value.</li>
</ul>
<pre class="code">&lt;xpath expression="/document/header/title/text()"&gt;</pre>
<ul>
<li>This element specifies an xpath AttributeReader to use inside
<span class="codefrag">&lt;filter&gt;</span>, <span class="codefrag">&lt;sort&gt;</span> or
{AttributeDefinitions}.</li>
<li>It allows to specify an xpath expression that should result in
one single text node to be returned when applied to the root node of the xml
file at the location of any given entry. The contents of this text-node is the
string value to sort (<span class="codefrag">&lt;sort&gt;</span> usage) or to fill in the
specified attribute (<span class="codefrag">&lt;label&gt;</span>, <span class="codefrag">&lt;href&gt;</span>...
use). When inside a <span class="codefrag">&lt;filter&gt;</span>: the presence of the node
results in passing the test.</li>
</ul>
<div class="warning">
<div class="label">Warning</div>
<div class="content">
This currently breaks for non xml (<span class="codefrag">*.gif</span>) files, so get
your filter right please, and in the mean time: sorry for not being
able to use it in the filter yet <span class="codefrag">:-(</span>.
</div>
</div>
<pre class="code">&lt;property name="path" regex="(\.[\\/])*(.*)" substitute="$2"/&gt;
&lt;property name="name" mask="CVS"/&gt;</pre>
<ul>
<li>This element specifies an xpath AttributeReader to use inside
<span class="codefrag">&lt;filter&gt;</span>, <span class="codefrag">&lt;sort&gt;</span> or
{AttributeDefinitions}.</li>
<li>It allows to specify a JavaBean-like property to read (this
introspection behavior will probably not survive the future release) on the
file at the 'location' of any given entry. The (object-)value of this property
is automatically converted to a String (toString()) that becomes the value to
sort (<span class="codefrag">&lt;sort&gt;</span> usage) or to fill in the specified attribute
(<span class="codefrag">&lt;label&gt;</span>, <span class="codefrag">&lt;href&gt;</span>... use). When inside a
<span class="codefrag">&lt;filter&gt;</span>, the test passes if the read property is not null
or "".</li>
<li>Furthermore this element allows to express more elaborate
true-false tests (filter use) or regex substitution (other use)
attributes:</li>
<ul>
<li>combination of @regex with @substitute accounts for a
s/{regex}/{substitute}/ kind of operation on the string property.</li>
<li>while @mask or @regex by their own (filter use) allow for a
glob-mask or regex test to be applied on the read property.</li>
</ul>
</ul>
<a name="N1016C"></a><a name="Important+Side+Effects"></a>
<h3 class="underlined_5">Important Side Effects</h3>
<p>
There are some things that libre is doing that you should be aware of.
</p>
<a name="N10175"></a><a name="No+libre.xml"></a>
<h4>No libre.xml</h4>
<p>
When using an <span class="codefrag">&lt;auto&gt; </span>section, the filter will
NEVER accept the <span class="codefrag">libre.xml</span> file to be in the generated
output. You can however include a manual <span class="codefrag">&lt;entry&gt;</span>
to point to the <span class="codefrag">libre.xml</span> file if needed.
</p>
<a name="N1018B"></a><a name="No+Duplicates"></a>
<h4>No Duplicates</h4>
<p>
You can combine multiple <span class="codefrag">&lt;entry&gt;</span> and
<span class="codefrag">&lt;auto&gt;</span> elements after each other. The system will
make sure that the resulting list of <span class="codefrag">&lt;collection&gt;</span>
and <span class="codefrag">&lt;item&gt;</span> will not contain duplicates. So the
filters in <span class="codefrag">&lt;auto&gt;</span> sections lower down the
<span class="codefrag">libre.xml</span> file can include already accepted files or
directories, they will only show up once in the output.
</p>
<a name="N101A8"></a><a name="Example+Constructs"></a>
<h3 class="underlined_5">Example Constructs</h3>
<p>
Adding sorting and filtering to the filesystem with libre becomes a
subtle play with editable filesystem properties, smart XML content and
<span class="codefrag">libre.xml</span> configs. This should be considered as the
'extended' contract between the following roles in the documentation
system: the one choosing (or creating) the DTDs, the one applying
those to create content and give the resulting files a name, the one
that sets up the directories to store those files and writes the
<span class="codefrag">libre.xml</span> files.
</p>
<a name="N101B7"></a><a name="Sorting+your+files+or+your+menu+entries%3F"></a>
<h4>Sorting your files or your menu entries?</h4>
<p>
In every case the very pragmatic approach can become something like
this:
</p>
<pre class="code">+ content
+ xdocs
+ 010Topic
+ 010Foo
+ 111Bar
+ 050Aspect
+ NotInList</pre>
<p>
In combination with something that lives by the introduced
alphabetic order, but yet hides the ugly number-prefixes:
</p>
<pre class="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE libre PUBLIC "-//Outerthought//DTD Libre Configuration V0.1//EN" "libre-v01.dtd" &gt;
&lt;libre xmlns="http://outerx.org/libre/config/0.1"&gt;
&lt;auto&gt;
&lt;filter logic="normal"&gt;
&lt;property name="name" regex="\d{3}(.*)"/&gt;
&lt;/filter&gt;
&lt;label&gt;
&lt;property name="name" regex="\d{3}(.*)" substitute="$1"/&gt;
&lt;/label&gt;
&lt;/auto&gt;
&lt;/libre&gt;</pre>
<p>
Will produce an automatic list of entries (collections and items in
the output) that
</p>
<ul>
<li>
<span class="codefrag">&lt;filter&gt;</span>: only resources which name starts
with a 3-digit pattern</li>
<li>No <span class="codefrag">&lt;sort&gt;</span>: in their natural filesystem order
assured by the digit-prefix</li>
<li>
<span class="codefrag">&lt;label&gt;</span>: hold a label attribute that strips
of the ugly number prefix</li>
</ul>
<p>
Of course the advantage over book.xml only comes when more menu
items should be easily slided in later on, and/or deeply nested
directory structures can all benefit from this same
filenaming/sorting strategy.
</p>
<a name="N101E5"></a><a name="Naming+your+files+or+asking+them+their+name%3F"></a>
<h4>Naming your files or asking them their name?</h4>
<p>
Given the poor expressiveness of the filesystem, the labels that
need to show up in the menu can hardly remain the filenames they are
now (specially if we're adding these ugly number prefixes). Instead
we can sign a contract with the content writer to also provide the
navigation system with a sensible name for his entry using XML
metadata that the system will pick up using an xpath expression.
</p>
<pre class="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE libre PUBLIC "-//Outerthought//DTD Libre Configuration V0.1//EN" "libre-v01.dtd" &gt;
&lt;libre xmlns="http://outerx.org/libre/config/0.1"&gt;
&lt;entry location="dreams.xml" &gt;
&lt;label&gt;
&lt;xpath expression="/document/header/title/text()"/&gt;
&lt;/label&gt;
&lt;/entry&gt;
&lt;auto&gt;
&lt;filter&gt;
&lt;property name="name" regex="\.xml$" /&gt;
&lt;/filter&gt;
&lt;sorter&gt;
&lt;xpath expression="/document/header/title/text()"/&gt;
&lt;/sorter&gt;
&lt;label&gt;
&lt;xpath expression="/document/header/title/text()"/&gt;
&lt;/label&gt;
&lt;/auto&gt;
&lt;/libre&gt;</pre>
</div>
<a name="N101F5"></a><a name="Next+Libre+%280.1%29"></a>
<h2 class="underlined_10">Next Libre (0.1)</h2>
<div class="section">
<div class="note">
<div class="label">Note</div>
<div class="content">
Next libre is in fact largely in your hands... just drop the forrest-dev
<a href="../mail-lists.html">mail list</a> a line, and see what
happens...
</div>
</div>
<a name="N10202"></a><a name="Itches"></a>
<h3 class="underlined_5">Itches</h3>
<p>
There is quite a number of fast code patches that can/need to happen
</p>
<ul>
<li>package renaming and restructuring (ideas welcome, but not top of
mind)</li>
<li>on same level: possible xmlns and/or elms/atts renaming on the
generated output and the libre.xml file</li>
<li>when compiling you currently get 4 stupid deprecation warnings
that should be removed, in fact:</li>
<li>LibreConfigHelper has a silly test in it to switch to own parser
and resolver if there is no avalon component manager in the neighborhoud
(historical reason is the testing outside cocoon with the command line util,
which should become some kind of avalon based junit task: if you have a clue
how to start this, throw it at us please.)</li>
<li>xpath property reader needs to survive working on a non-xml
document (by returning nothing rather then breaking on the exception)</li>
<li>general robustness and resilience towards
mis-configurations</li>
<li>filestreams need to get closed and avalon resources need to be
released properly</li>
<li>caching at the level of the generator needs to be set up</li>
<li>in fact general performance has not been subject to loads of
early optimizations :-P</li>
</ul>
<a name="N1022A"></a><a name="Upcoming+Features"></a>
<h3 class="underlined_5">Upcoming Features</h3>
<p>
More importantly however there is a major set of new features that is
waiting to get in there. It all boils down in fact to having a more
expressive libre.xml file... some of the thoughts:
</p>
<a name="N10233"></a><a name="Combinations+of+filter+logic"></a>
<h4>Combinations of filter logic</h4>
<p>
Some itching stuff:
</p>
<ul>
<li>logic="inverse" on the &lt;filter&gt; element seems a bit
awkward</li>
<li>
<em>n</em>th degree of slickness in the regexes will only bring
us so far, combinatory filter logic seems to be the way to go...:</li>
</ul>
<pre class="code">&lt;!ELEMENT filter (xpath | property | and | or | not)&gt;
&lt;!ELEMENT not (xpath | property | and | or | not)&gt;
&lt;!ELEMENT and (xpath | property | and | or | not)+&gt;
&lt;!ELEMENT or (xpath | property | and | or | not)+&gt;</pre>
<p>
So we can make up some richer:
</p>
<pre class="code">
&lt;filter&gt;
&lt;not&gt;
&lt;and&gt;
&lt;xpath .../&gt;
&lt;not&gt;&lt;property ..../&gt;&lt;/not&gt;
&lt;or&gt;
...
&lt;/or&gt;
&lt;/and&gt;
&lt;/not&gt;
&lt;/filter&gt;
</pre>
<a name="N10253"></a><a name="Separating+property-retrieval+from+formatting+and%0A++++++++++++testing"></a>
<h4>Separating property-retrieval from formatting and
testing</h4>
<p>
Playing around with the attributes in <span class="codefrag">&lt;property&gt;</span>:
</p>
<ul>
<li>poses hard to explain combinatory effects (@regex with
@substitute vs without, @regex can't be combined with @mask, different
behaviour inside &lt;filter&gt;== test or &lt;sort&gt;==formatting)</li>
<li>which in fact are hard (if not impossible) to rule out by
modifying the DTD</li>
<li>makes you wonder why it's not available on the &lt;xpath&gt;
?</li>
</ul>
<p>
So maybe an example more down the lines of the following would be
easier to use:
</p>
<pre class="code">&lt;label&gt;&lt;!-- same applies for the sort context --&gt;
&lt;regexformatter exp="..." substitute="...."&gt;
&lt;property name="absoluteLocation" /&gt;
&lt;/regexformatter&gt;
&lt;/label&gt;</pre>
<p>
Allowing the formatter to be used around the xpath reader as well.
And opening up the possibility to maybe format other stuff than
Strings: <span class="codefrag">&lt;dateformat format="dd/mmm/yy"&gt; </span>
</p>
<p>
It would also clearly distinguish the semantical difference of
applying a test in the <span class="codefrag">&lt;filter&gt;</span> context:
</p>
<pre class="code">&lt;filter&gt;
&lt;regextest match="..."&gt;
&lt;property ... /&gt;
&lt;/regextest&gt;
&lt;/filter&gt;</pre>
<p>
And more logically introduce other tests like <span class="codefrag">&lt;globtest
match="..."&gt;</span> or <span class="codefrag">&lt;availabletest&gt;</span> or...
</p>
<a name="N1028C"></a><a name="Replace+the+introspection+with+semantically+richer+named%0A++++++++++++properties+to+read."></a>
<h4>Replace the introspection with semantically richer named
properties to read.</h4>
<p>
Currently the <span class="codefrag">&lt;property name="someJavaBeanProp"&gt;</span>
is applied in a java introspection for the
<span class="codefrag">getSomeJavaBeanProp()</span> on the <span class="codefrag">java.io.File</span>
object that is actually representing the node in the hierarchy at
any given time. The DTD declares the attribute as of type CDATA.
These decisions however:
</p>
<ul>
<li>lead to a lesser user guidance for the libre.xml writer using
an XML (and DTD) savvy editor </li>
<li>leads to assuming the <span class="codefrag">libre.xml</span> editor has access
to and knows how to interpret jdk javadoc</li>
<li>leads to poor semantical support and thus more possible RUNTIME
errors for those just filling in some valid CDATA value that is not mapping any
getter.</li>
<li>leads to confusion for all, since who actually knows the subtle
difference between all the get*Path methods on java.io.File?</li>
</ul>
<p>
So the big idea here would be to go for an upfront declared list of
sensible and clearly defined properties that we would like to
read... Today's ideas about that list:
</p>
<ul>
<li>name</li>
<li>isDirectory (isCollection?)</li>
<li>abs and relPath (or abs/rel Location? why would we need
abs?)</li>
<li>canRead</li>
<li>canWrite</li>
<li>lastModified</li>
<li>length</li>
</ul>
<p>
The DTD would then list the possible attributeValues.
</p>
<a name="N102D0"></a><a name="Avalonising"></a>
<h3 class="underlined_5">Avalonising</h3>
<p>
There are a number of perceived opportunities in taking up a stronger
dependecy towards Avalon. Some of the possibilities become clear when
looking into the current design...
</p>
<ul>
<li>Currently the EntryFactory is a abstract factory, the factory
part could be done by an Avalon Component manager. Which would also allow the
EntryFactory to become a cleaner component interface then it is now.</li>
<li>Some investigation/feedback on the current hacker-way of using
the Composables could be nice</li>
<li>The current cli part in the package is only there for testing
(avoiding the cocoon webapp cycle when developing/testing) it should be
replaced by a more formal test class that actually would take up the role
(probably delegate to ECM or the like) of the componentmanager to give the
HierarchyReader the (avalon) environment he needs.</li>
</ul>
<a name="N102E6"></a><a name="Unresolved+Discussions"></a>
<h3 class="underlined_5">Unresolved Discussions</h3>
<ul>
<li>do we need support for nested elements inside
<span class="codefrag">&lt;item&gt;</span> output (retrieved by e.g. xpath expressions)?</li>
<li>do we need an extra <span class="codefrag">&lt;constant&gt;</span> like
attributereader that would allow like book.xml to add fixed values for
expressed attributes</li>
<li>clear set out inheritance rules, just doing 'something' now
:-(</li>
<li>votes on needed file properties to replace the current (limiting
and semantically poor) Java-introspection</li>
</ul>
</div>
<a name="N10303"></a><a name="Libre+Design"></a>
<h2 class="underlined_10">Libre Design</h2>
<div class="section">
<p>
So why is that silly 'yer' package name in there? Yer originally was
some all-hierarchy-structures to SAX event thing, and since some of that
is in here as well, we kind of picked that idea up out of the dustbin.
</p>
<p>
So reflecting the current packagenames we kind of have these sets of
responsibilities
</p>
<ul>
<li>
<em>*.yer.hierarchy</em>: describe in a formal way how hierarchies
should be built up in order to have them dumped to XML using the
HierarchyReader.</li>
<li>
<em>*.yer.use.cocoon</em>:house of the generator. It basically just
gets a reader and subscribes the next ContentHandler in the cocoon pipeline to
the HierarchyReader that it is using.</li>
<li>
<em>*.yer.impl</em>: hold the different implementations of the
*.yer.hierarchy API </li>
<li>
<em>*.yer.impl.fs</em>: (only current impl) Build the described
filesystem oriented implementation of the hierarchy. It is using the libre
configuration strategy.</li>
<li>
<em>*.yer.libre</em>: provide a generic strategy for adding
filtering, sorting and attributing information to a hierarchy through the use
of XML config files (in an XML configuration/declarative manner)</li>
</ul>
<p>
... hope this somewhat clarifies how things have been setup for now.
</p>
<a name="N1032E"></a><a name="Dependencies"></a>
<h3 class="underlined_5">Dependencies</h3>
<ul>
<li>The regex stuff inside libre adds the dependency upon the oro
package. Basically I failed to find substitution support inside the regex
package (which is already in cocoon) in a timeframe comparable to just get on
with this using oro.</li>
<li>The HierarchyGenerator is the first one in the chain (and the
last in fact) that actually needs the cocoon package (at least it was intended
this way, could be that there are some glitches on this statement)</li>
<li>There is a sort of false dependency on Avalon right now (some
Composables in there, no real container stuff though). As expressed higher
there are some plans to stronger benefit from this dependency. </li>
</ul>
</div>
</div>
<!--+
|end content
+-->
<div class="clearboth">&nbsp;</div>
</div>
<div id="footer">
<!--+
|start bottomstrip
+-->
<div class="lastmodified">
<script type="text/javascript"><!--
document.write("Last Published: " + document.lastModified);
// --></script>
</div>
<div class="copyright">
Copyright &copy;
2002-2007 <a href="http://www.apache.org/licenses/">The Apache Software Foundation.</a>
</div>
<!--+
|end bottomstrip
+-->
</div>
</body>
</html>