incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Sling: Everything is a Resource (page edited)
Date Thu, 03 Jan 2008 12:47:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence" />
    <style type="text/css">
    <!--
    body, p, td, table, tr, .bodytext, .stepfield {
	font-family: Verdana, arial, sans-serif;
	font-size: 11px;
	line-height: 16px;
	color: #000000;
	font-weight: normal;
}
#PageContent {
	text-align: left;
	background-color: #fff;
	padding: 0px;
	margin: 0px;
    padding-bottom:20px;
}
/*
** when this stylesheet is used for the Tiny MCE Wysiwyg editor's edit area, we can't
** use an id=PageContent or class=wiki-content, so we must
** set the body style to that used for PageContent, and p to that used for wiki-content.
*/

body {
	margin: 0px;
	padding: 0px;
	text-align: center;
    background-color: #f0f0f0;
}

@media print {

body {
    background-color: #fff;
}

}

.monospaceInput {
    font:12px monospace
}

.wiki-content p, .commentblock p {
    margin: 16px 0px 16px 0px;
    padding: 0px;
}

.wiki-content-preview {
    padding: 5px;
    border-left: 1px solid #3c78b5;
    border-right: 1px solid #3c78b5;
}

ul, ol {
    margin-top: 2px;
    margin-bottom: 2px;
    padding-top: 0px;
    padding-bottom: 0px;
}

pre {
    padding: 0px;
    margin-top: 5px;
    margin-left: 15px;
    margin-bottom: 5px;
    margin-right: 5px;
    text-align: left;
}

.helpheading {
    font-weight: bold;
    background-color: #D0D9BD;
        border-bottom: 1px solid #3c78b5;
        padding: 4px 4px 4px 4px;
        margin: 0px;
        margin-top: 10px;
}
.helpcontent {
        padding: 4px 4px 20px 4px;
    background-color: #f5f7f1;
}

.code {
 	border: 1px dashed #3c78b5;
    font-size: 11px;
	font-family: Courier;
    margin: 10px;
	line-height: 13px;
}

.focusedComment {
    background: #ffffce;
}

.commentBox, .focusedComment {
    padding: 10px;
    margin: 5px 0 5px 0;
    border: 1px #bbb solid;
}

.codeHeader {
    background-color: #f0f0f0;
 	border-bottom: 1px dashed #3c78b5;
    padding: 3px;
	text-align: center;
}

.codeContent {
    text-align: left;
    background-color: #f0f0f0;
    padding: 3px;
}

.preformatted {
 	border: 1px dashed #3c78b5;
    font-size: 11px;
	font-family: Courier;
    margin: 10px;
	line-height: 13px;
}

.preformattedHeader {
    background-color: #f0f0f0;
 	border-bottom: 1px dashed #3c78b5;
    padding: 3px;
	text-align: center;
}

.preformattedContent {
    background-color: #f0f0f0;
    padding: 3px;
}

.panel {
 	border: 1px dashed #3c78b5;
    margin: 10px;
    margin-top: 0px;
}

.panelHeader {
    background-color: #f0f0f0;
 	border-bottom: 1px dashed #3c78b5;
    padding: 3px;
	text-align: center;
}

.panelContent {
    background-color: #f0f0f0;
    padding: 5px;
}

.anonymousAlert {
    background-color: #f0f0f0;
 	border: 1px dashed red;
    font-size: 11px;
    padding: 10px 5px 10px 5px;
    margin: 4px;
	line-height: 13px;
}

.lockAlert {
    background-color: #f0f0f0;
    width: 50%;
 	border: 1px dashed red;
    font-size: 11px;
    padding: 10px 5px 10px 5px;
    margin: 4px;
	line-height: 13px;
}


.code-keyword {
  color: #000091;
  background-color: inherit;
}

.code-object {
  color: #910091;
  background-color: inherit;
}

.code-quote {
  color: #009100;
  background-color: inherit;
}

.code-comment {
  color: #808080;
  background-color: inherit;
}


.code-xml .code-keyword {
  color: inherit;
  font-weight: bold;
}

.code-tag {
  color: #000091;
  background-color: inherit;
}

.breadcrumbs {
    background-color: #f0f0f0;
 	border-color: #3c78b5;
	border-width: 1px 0px 1px 0px;
	border-style: solid;
    font-size: 11px;
    padding: 3px 0px 3px 0px;
}

.navmenu {
    border: 1px solid #ccc;
}

.menuheading {
    font-weight: bold;
    background-color: #f0f0f0;
 	border-bottom: 1px solid #3c78b5;
	padding: 4px 4px 2px 4px;
}

.menuitems {
	padding: 4px 4px 20px 4px;
}

.rightpanel {
    border-left: 1px solid #ccc;
    border-bottom: 1px solid #ccc;
}

#helpheading {
    text-align: left;
    font-weight: bold;
    background-color: #D0D9BD;
 	border-bottom: 1px solid #3c78b5;
	padding: 4px 4px 4px 4px;
	margin: 0px;
}
#helpcontent {
	padding: 4px 4px 4px 4px;
    background-color: #f5f7f1;
}
.helptab-unselected {
    font-weight: bold;
	padding: 5px;
    background-color: #f5f7f1;
}
.helptab-selected {
    font-weight: bold;
    background-color: #D0D9BD;
	padding: 5px;
}
.helptabs {
    margin: 0px;
    background-color: #f5f7f1;
	padding: 5px;
}
.infopanel-heading {
    font-weight: bold;
	padding: 4px 0px 2px 0px;
}

.pagebody {
}

.pageheader {
	padding: 5px 5px 5px 0px;
 	border-bottom: 1px solid #3c78b5;
}

.pagetitle {
	font-size: 22px;
	font-weight: bold;
	font-family: Arial, sans-serif;
	color: #003366;
}

.newpagetitle {
    color: #ccc !important;
}

.steptitle {
	font-size: 18px;
	font-weight: bold;
	font-family: Arial, sans-serif;
	color: #003366;
	margin-bottom: 7px;
}

.substeptitle {
    font-size: 12px;
    font-weight: bold;
    font-family: Arial, sans-serif;
    color: #003366;
    margin: 2px 4px 4px 4px;
    padding: 2px 4px 1px 4px;
}

.stepdesc {
    font-family: Verdana, arial, sans-serif;
	font-size: 11px;
	line-height: 16px;
	font-weight: normal;
    color: #666666;
    margin-top: 7px;
    margin-bottom: 7px;
}

.steplabel {
    font-weight: bold;
    margin-right: 4px;
    color: black;
    float: left;
    width: 15%;
    text-align: right;
}

.stepfield {
    background: #f0f0f0;
    padding: 5px;
}

.submitButtons{
    margin-top:5px;
    text-align:right;
}

.formtitle {
	font-size: 12px;
	font-weight: bold;
	font-family: Arial, sans-serif;
	color: #003366;
}

.sectionbottom {
    border-bottom: 1px solid #3c78b5;
}

.topRow {
    border-top: 2px solid #3c78b5;
}

.tabletitle {
	font-size: 14px;
	font-weight: bold;
	font-family: Arial, sans-serif;
    padding: 3px 0px 2px 0px;
    margin: 8px 4px 2px 0px;
	color: #003366;
	border-bottom: 2px solid #3c78b5;
}
.pagesubheading {
    color: #666666;
    font-size: 10px;
    padding: 0px 0px 5px 0px;
}

HR {
	color: 3c78b5;
	height: 1;
}

A:link, A:visited, A:active, A:hover {
	color: #003366;
}

h1 A:link, h1 A:visited, h1 A:active {
	text-decoration: none;
}

h1 A:hover {
    border-bottom: 1px dotted #003366;
}

.wiki-content > :first-child, .commentblock > :first-child {
    margin-top: 3px;
}

.logocell {
    padding: 10px;
}

input {
	font-family: verdana, geneva, arial, sans-serif;
	font-size: 11px;
	color: #000000;
}

textarea, textarea.editor {
	font-family: verdana, geneva, arial, sans-serif;
	font-size: 11px;
	color: #333333;
}

/* use logoSpaceLink instead.
.spacenametitle {
	font: 21px/31px Impact, Arial, Helvetica;
    font-weight: 100;
    color: #999999;
	margin: 0px;
}
.spacenametitle img {
  margin: 0 0 -4px 0;
}
.spacenametitle a {
    text-decoration: none;
    color: #999999;
}
.spacenametitle a:visited {
    text-decoration: none;
    color: #999999;
}*/

.spacenametitle-printable {
	font: 20px/25px Impact, Arial, Helvetica;
    font-weight: 100;
    color: #999999;
	margin: 0px;
}
.spacenametitle-printable a {
    text-decoration: none;
    color: #999999;
}
.spacenametitle-printable a:visited {
    text-decoration: none;
    color: #999999;
}

.blogDate {
	font-weight: bold;
	text-decoration: none;
	color: black;
}

.blogSurtitle {
    background: #f0f0f0;
 	border: 1px solid #ddd;
	padding: 3px;
	margin: 1px 1px 10px 1px;
}

.blogHeading {
    font-size: 20px;
    line-height: normal;
    font-weight: bold;
    padding: 0px;
    margin: 0px;
}

.blogHeading a {
   text-decoration: none;
   color: black;
}

.endsection {
	align: right;
	color: #666666;
	margin-top: 10px;
}
.endsectionleftnav {
	align: right;
	color: #666666;
	margin-top: 10px;
}

h1 {
	font-size: 24px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
	color: #003366;
 	border-bottom: 1px solid #3c78b5;
	padding: 2px;
	margin: 36px 0px 4px 0px;
}

h2 {
	font-size: 18px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
 	border-bottom: 1px solid #3c78b5;
	padding: 2px;
	margin: 27px 0px 4px 0px;
}

h3 {
	font-size: 14px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
	padding: 2px;
	margin: 21px 0px 4px 0px;
}

h4 {
	font-size: 12px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
	padding: 2px;
	margin: 18px 0px 4px 0px;
}

h4.search {
	font-size: 12px;
	line-height: normal;
	font-weight: normal;
	background-color: #f0f0f0;
	padding: 4px;
	margin: 18px 0px 4px 0px;
}

h5 {
	font-size: 10px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
	padding: 2px;
	margin: 14px 0px 4px 0px;
}

h6 {
	font-size: 8px;
	line-height: normal;
	font-weight: bold;
	background-color: #f0f0f0;
	padding: 2px;
	margin: 14px 0px 4px 0px;
}

.smallfont {
    font-size: 10px;
}
.descfont {
    font-size: 10px;
    color: #666666;
}
.smallerfont {
    font-size: 9px;
}
.smalltext {
    color: #666666;
    font-size: 10px;
}
.smalltext a {
    color: #666666;
}
.smalltext-blue {
    color: #3c78b5;
    font-size: 10px;
}
.surtitle {
    margin-left: 1px;
    margin-bottom: 5px;
    font-size: 14px;
    color: #666666;
}

/* css hack found here:  http://www.fo3nix.pwp.blueyonder.co.uk/tutorials/css/hacks/ */
.navItemOver { font-size: 10px; font-weight: bold; color: #ffffff; background-color: #003366; cursor: hand; voice-family: '\'}\''; voice-family:inherit; cursor: pointer;}
.navItemOver a { color: #ffffff; background-color:#003366; text-decoration: none; }
.navItemOver a:visited { color: #ffffff; background-color:#003366; text-decoration: none; }
.navItemOver a:hover { color: #ffffff; background-color:#003366; text-decoration: none; }
.navItem { font-size: 10px; font-weight: bold; color: #ffffff; background-color: #3c78b5; }
.navItem a { color: #ffffff; text-decoration: none; }
.navItem a:hover { color: #ffffff; text-decoration: none; }
.navItem a:visited { color: #ffffff; text-decoration: none; }

div.padded { padding: 4px; }
div.thickPadded { padding: 10px; }
h3.macrolibrariestitle {
    margin: 0px 0px 0px 0px;
}

div.centered { text-align: center; margin: 10px; }
div.centered table {margin: 0px auto; text-align: left; }

.tableview table {
    margin: 0;
}

.tableview th {
    text-align: left;
    color: #003366;
    font-size: 12px;
    padding: 5px 0px 0px 5px;
    border-bottom: 2px solid #3c78b5;
}
.tableview td {
    text-align: left;
    border-color: #ccc;
    border-width: 0px 0px 1px 0px;
    border-style: solid;
    margin: 0;
    padding: 4px 10px 4px 5px;
}

.grid {
    margin: 2px 0px 5px 0px;
    border-collapse: collapse;
}
.grid th  {
    border: 1px solid #ccc;
    padding: 2px 4px 2px 4px;
    background: #f0f0f0;
    text-align: center;
}
.grid td  {
    border: 1px solid #ccc;
    padding: 3px 4px 3px 4px;
}
.gridHover {
	background-color: #f9f9f9;
}

td.infocell {
    background-color: #f0f0f0;
}
.label {
	font-weight: bold;
	color: #003366;
}

label {
	font-weight: bold;
	color: #003366;
}

.error {
	background-color: #fcc;
}

.errorBox {
	background-color: #fcc;
    border: 1px solid #c00;
    padding: 5px;
    margin: 5px;
}

.errorMessage {
	color: #c00;
}

.success {
	background-color: #dfd;
}

.successBox {
	background-color: #dfd;
    border: 1px solid #090;
    padding: 5px;
    margin-top:5px;
    margin-bottom:5px;
}

blockquote {
	padding-left: 10px;
	padding-right: 10px;
	margin-left: 5px;
	margin-right: 0px;
	border-left: 1px solid #3c78b5;
}

table.confluenceTable
{
    margin: 5px;
    border-collapse: collapse;
}

/* Added as a temporary fix for CONF-4223. The table elements appear to be inheriting the border: none attribute from the sectionMacro class */
table.confluenceTable td.confluenceTd
{
    border-width: 1px;
    border-style: solid;
    border-color: #ccc;
    padding: 3px 4px 3px 4px;
}

/* Added as a temporary fix for CONF-4223. The table elements appear to be inheriting the border: none attribute from the sectionMacro class */
table.confluenceTable th.confluenceTh
{
    border-width: 1px;
    border-style: solid;
    border-color: #ccc;
    padding: 3px 4px 3px 4px;
    background-color: #f0f0f0;
    text-align: center;
}

td.confluenceTd
{
    border-width: 1px;
    border-style: solid;
    border-color: #ccc;
    padding: 3px 4px 3px 4px;
}

th.confluenceTh
{
    border-width: 1px;
    border-style: solid;
    border-color: #ccc;
    padding: 3px 4px 3px 4px;
    background-color: #f0f0f0;
    text-align: center;
}

DIV.small {
	font-size: 9px;
}

H1.pagename {
	margin-top: 0px;
}

IMG.inline  {}

.loginform {
    margin: 5px;
    border: 1px solid #ccc;
}

/* The text how the "This is a preview" comment should be shown. */
.previewnote { text-align: center;
                font-size: 11px;
                    color: red; }

/* How the preview content should be shown */
.previewcontent { background: #E0E0E0; }

/* How the system messages should be shown (DisplayMessage.jsp) */
.messagecontent { background: #E0E0E0; }

/* How the "This page has been modified..." -comment should be shown. */
.conflictnote { }

.createlink {
    color: maroon;
}
a.createlink {
    color: maroon;
}
.templateparameter {
    font-size: 9px;
    color: darkblue;
}

.diffadded {
    background: #ddffdd;
    padding: 1px 1px 1px 4px;
	border-left: 4px solid darkgreen;
}
.diffdeleted {
    color: #999;
    background: #ffdddd;
    padding: 1px 1px 1px 4px;
	border-left: 4px solid darkred;
}
.diffnochange {
    padding: 1px 1px 1px 4px;
	border-left: 4px solid lightgrey;
}
.differror {
    background: brown;
}
.diff {
    font-family: lucida console, courier new, fixed-width;
	font-size: 12px;
	line-height: 14px;
}
.diffaddedchars {
    background-color:#99ff99;
    font-weight:bolder;
}
.diffremovedchars {
    background-color:#ff9999;
    text-decoration: line-through;
    font-weight:bolder;
}

.greybackground {
    background: #f0f0f0
}

.greybox {
 	border: 1px solid #ddd;
	padding: 3px;
	margin: 1px 1px 10px 1px;
}

.borderedGreyBox {
    border: 1px solid #cccccc;
    background-color: #f0f0f0;
    padding: 10px;
}

.greyboxfilled {
 	border: 1px solid #ddd;
    background: #f0f0f0;
    padding: 3px;
	margin: 1px 1px 10px 1px;
}

.navBackgroundBox {
    padding: 5px 5px 5px 5px;
    font-size: 22px;
	font-weight: bold;
	font-family: Arial, sans-serif;
	color: white;
    background: #3c78b5;
    text-decoration: none;
}

.previewBoxTop {
	background-color: #f0f0f0;
    border-width: 1px 1px 0px 1px;
    border-style: solid;
    border-color: #3c78b5;
    padding: 5px;
    margin: 5px 0px 0px 0px;
    text-align: center;
}
.previewContent {
    background-color: #fff;
 	border-color: #3c78b5;
	border-width: 0px 1px 0px 1px;
	border-style: solid;
	padding: 10px;
	margin: 0px;
}
.previewBoxBottom {
	background-color: #f0f0f0;
    border-width: 0px 1px 1px 1px;
    border-style: solid;
    border-color: #3c78b5;
    padding: 5px;
    margin: 0px 0px 5px 0px;
    text-align: center;
}

.functionbox {
    background-color: #f0f0f0;
 	border: 1px solid #3c78b5;
	padding: 3px;
	margin: 1px 1px 10px 1px;
}

.functionbox-greyborder {
    background-color: #f0f0f0;
 	border: 1px solid #ddd;
	padding: 3px;
	margin: 1px 1px 10px 1px;
}

.search-highlight {
    background-color: #ffffcc;
}

/* normal (white) background */
.rowNormal {
    background-color: #ffffff;
 }

/* alternate (pale yellow) background */
.rowAlternate {
    background-color: #f7f7f7;
}

/* used in the list attachments table */
.rowAlternateNoBottomColor {
    background-color: #f7f7f7;
}

.rowAlternateNoBottomNoColor {
}

.rowAlternateNoBottomColor td {
    border-bottom: 0px;
}

.rowAlternateNoBottomNoColor td {
    border-bottom: 0px;
}

/* row highlight (grey) background */
.rowHighlight {
    background-color: #f0f0f0;

}

TD.greenbar {FONT-SIZE: 2px; BACKGROUND: #00df00; BORDER: 1px solid #9c9c9c; PADDING: 0px; }
TD.redbar {FONT-SIZE: 2px; BACKGROUND: #df0000; BORDER: 1px solid #9c9c9c; PADDING: 0px; }
TD.darkredbar {FONT-SIZE: 2px; BACKGROUND: #af0000; BORDER: 1px solid #9c9c9c; PADDING: 0px; }

TR.testpassed {FONT-SIZE: 2px; BACKGROUND: #ddffdd; PADDING: 0px; }
TR.testfailed {FONT-SIZE: 2px; BACKGROUND: #ffdddd; PADDING: 0px; }

.toolbar  {
    margin: 0px;
    border-collapse: collapse;
}

.toolbar td  {
    border: 1px solid #ccc;
    padding: 2px 2px 2px 2px;
    color: #ccc;
}

td.noformatting {
    border-width: 0px;
    border-style: none;
    text-align: center;
	padding: 0px;
}

.commentblock {
    margin: 12px 0 12px 0;
}

/*
 * Divs displaying the license information, if necessary.
 */
.license-eval, .license-none, .license-nonprofit {
    border-top: 1px solid #bbbbbb;
    text-align: center;
    font-size: 10px;
    font-family: Verdana, Arial, Helvetica, sans-serif;
}

.license-eval, .license-none {
    background-color: #ffcccc;
}

.license-eval b, .license-none b {
    color: #990000
}

.license-nonprofit {
    background-color: #ffffff;
}

/*
 * The shadow at the bottom of the page between the main content and the
 * "powered by" section.
 */
.bottomshadow {
    height: 12px;
    background-image: url("$req.contextPath/images/border/border_bottom.gif");
    background-repeat: repeat-x;
}

/*
 * Styling of the operations box
 */
.navmenu .operations li, .navmenu .operations ul {
    list-style: none;
    margin-left: 0;
    padding-left: 0;
}

.navmenu .operations ul {
    margin-bottom: 9px;
}

.navmenu .label {
    font-weight: inherit;
}

/*
 * Styling of ops as a toolbar
 */
.toolbar div {
    display: none;
}

.toolbar .label {
    display: none;
}

.toolbar .operations {
    display: block;
}

.toolbar .operations ul {
    display: inline;
    list-style: none;
    margin-left: 10px;
    padding-left: 0;
}

.toolbar .operations li {
    list-style: none;
    display: inline;
}

/* list page navigational tabs */
#foldertab {
padding: 3px 0px 3px 8px;
margin-left: 0;
border-bottom: 1px solid #3c78b5;
font: bold 11px Verdana, sans-serif;
}

#foldertab li {
list-style: none;
margin: 0;
display: inline;
}

#foldertab li a {
padding: 3px 0.5em;
margin-left: 3px;
border: 1px solid #3c78b5;
border-bottom: none;
background: #3c78b5;
text-decoration: none;
}

#foldertab li a:link { color: #ffffff; }
#foldertab li a:visited { color: #ffffff; }

#foldertab li a:hover {
color: #ffffff;
background: #003366;
border-color: #003366;
}

#foldertab li a.current {
background: white;
border-bottom: 1px solid white;
color: black;
}

#foldertab li a.current:link { color: black; }
#foldertab li a.current:visited { color: black; }
#foldertab li a.current:hover {
background: white;
border-bottom: 1px solid white;
color: black;
}

/* alphabet list */
ul#squaretab {
margin-left: 0;
padding-left: 0;
white-space: nowrap;
font: bold 8px Verdana, sans-serif;
}

#squaretab li {
display: inline;
list-style-type: none;
}

#squaretab a {
padding: 2px 6px;
border: 1px solid #3c78b5;
}

#squaretab a:link, #squaretab a:visited {
color: #fff;
background-color: #3c78b5;
text-decoration: none;
}

#squaretab a:hover {
color: #ffffff;
background-color: #003366;
border-color: #003366;
text-decoration: none;
}

#squaretab li a#current {
background: white;
color: black;
}

.blogcalendar * {
    font-family:verdana, arial, sans-serif;
    font-size:x-small;
    font-weight:normal;
    line-height:140%;
    padding:2px;
}


table.blogcalendar {
    border: 1px solid #3c78b5;
}

.blogcalendar th.calendarhead, a.calendarhead {
    font-size:x-small;
    font-weight:bold;
    padding:2px;
    text-transform:uppercase;
    background-color: #3c78b5;
    color: #ffffff;
    letter-spacing: .3em;
    text-transform: uppercase;
}

.calendarhead:visited {color: white;}
.calendarhead:active {color: white;}
.calendarhead:hover {color: white;}

.blogcalendar th {
    font-size:x-small;
    font-weight:bold;
    padding:2px;
    background-color:#f0f0f0;
}

.blogcalendar td {
    font-size:x-small;
    font-weight:normal;
}

.searchGroup { padding: 0 0 10px 0; background: #f0f0f0; }
.searchGroupHeading { font-size: 10px; font-weight: bold; color: #ffffff; background-color: #3c78b5; padding: 2px 4px 1px 4px; }
.searchItem { padding: 1px 4px 1px 4px; }
.searchItemSelected { padding: 1px 4px 1px 4px; font-weight: bold; background: #ddd; }

/* permissions page styles */
.permissionHeading {
    border-bottom: #bbb; border-width: 0 0 1px 0; border-style: solid; font-size: 16px; text-align: left;
}
.permissionTab {
    border-width: 0 0 0 1px; border-style: solid; background: #3c78b5; color: #ffffff; font-size: 10px;
}
.permissionSuperTab {
    border-width: 0 0 0 1px; border-style: solid; background: #003366; color: #ffffff;
}
.permissionCell {
    border-left: #bbb; border-width: 0 0 0 1px; border-style: solid;
}

/* warning panel */
.warningPanel { background: #FFFFCE; border:#F0C000 1px solid; padding: 8px; margin: 10px; }
/* alert panel */
.alertPanel { background: #FFCCCC; border:#C00 1px solid; padding: 8px; margin: 10px; }
/* info panel */
.infoPanel { background: #D8E4F1; border:#3c78b5 1px solid; padding: 8px; margin: 10px; }

/* side menu highlighting (e.g. space content screen) */
.optionPadded { padding: 2px; }
.optionSelected { background-color: #ffffcc; padding: 2px; border: 1px solid #ddd; margin: -1px; }
.optionSelected a { font-weight: bold; text-decoration: none; color: black; }

/* information macros */
.noteMacro { border-style: solid; border-width: 1px; border-color: #F0C000; background-color: #FFFFCE; text-align:left; margin-top: 5px; margin-bottom: 5px}
.warningMacro { border-style: solid; border-width: 1px; border-color: #c00; background-color: #fcc; text-align:left; margin-top: 5px; margin-bottom: 5px}
.infoMacro { border-style: solid; border-width: 1px; border-color: #3c78b5; background-color: #D8E4F1; text-align:left; margin-top: 5px; margin-bottom: 5px}
.tipMacro { border-style: solid; border-width: 1px; border-color: #090; background-color: #dfd; text-align:left; margin-top: 5px; margin-bottom: 5px}
.informationMacroPadding { padding: 5px 0 0 5px; }

table.infoMacro td, table.warningMacro td, table.tipMacro td, table.noteMacro td, table.sectionMacro td {
    border: none;
}

table.sectionMacroWithBorder td.columnMacro { border-style: dashed; border-width: 1px; border-color: #cccccc;}

.pagecontent
{
    padding: 10px;
    text-align: left;
}

/* styles for links in the top bar */
.topBarDiv a:link {color: #ffffff;}
.topBarDiv a:visited {color: #ffffff;}
.topBarDiv a:active {color: #ffffff;}
.topBarDiv a:hover {color: #ffffff;}
.topBarDiv {color: #ffffff;}

.topBar {
    background-color: #003366;
}


/* styles for extended operations */
.greyLinks a:link {color: #666666; text-decoration:underline;}
.greyLinks a:visited {color: #666666; text-decoration:underline;}
.greyLinks a:active {color: #666666; text-decoration:underline;}
.greyLinks a:hover {color: #666666; text-decoration:underline;}
.greyLinks {color: #666666; display:block; padding: 10px}

.logoSpaceLink {color: #999999; text-decoration: none}
.logoSpaceLink a:link {color: #999999; text-decoration: none}
.logoSpaceLink a:visited {color: #999999; text-decoration: none}
.logoSpaceLink a:active {color: #999999; text-decoration: none}
.logoSpaceLink a:hover {color: #003366; text-decoration: none}

/* basic panel (basicpanel.vmd) style */
.basicPanelContainer {border: 1px solid #3c78b5; margin-top: 2px; margin-bottom: 8px; width: 100%}
.basicPanelTitle {padding: 5px; margin: 0px; background-color: #f0f0f0; color: black; font-weight: bold;}
.basicPanelBody {padding: 5px; margin: 0px}

.separatorLinks a:link {color: white}
.separatorLinks a:visited {color: white}
.separatorLinks a:active {color: white}

.greynavbar {background-color: #f0f0f0; border-top: 1px solid #3c78b5; margin-top: 2px}

div.headerField {
    float: left;
    width: auto;
    height: 100%;
}

.headerFloat {
    margin-left: auto;
    width: 50%;
}

.headerFloatLeft {
    float: left;
    margin-right: 20px;
    margin-bottom: 10px;
}

#headerRow {
    padding: 10px;
}

div.license-personal {
   background-color: #003366;
   color: #ffffff;
}

div.license-personal a {
   color: #ffffff;
}

.greyFormBox {
    border: 1px solid #cccccc;
    padding: 5px;
}

/* IE automatically adds a margin before and after form tags. Use this style to remove that */
.marginlessForm {
    margin: 0px;
}

.openPageHighlight {
    background-color: #ffffcc;
    padding: 2px;
    border: 1px solid #ddd;
}

.editPageInsertLinks, .editPageInsertLinks a
{
    color: #666666;
    font-weight: bold;
    font-size: 10px;
}

/* Style for label heatmap. */
.top10 a {
    font-weight: bold;
    font-size: 2em;
    color: #003366;
}
.top25 a {
    font-weight: bold;
    font-size: 1.6em;
    color: #003366;
}
.top50 a {
    font-size: 1.4em;
    color: #003366;
}
.top100 a {
    font-size: 1.2em;
    color: #003366;
}

.heatmap {
    list-style:none;
    width: 95%;
    margin: 0px auto;
}

.heatmap a {
    text-decoration:none;
}

.heatmap a:hover {
    text-decoration:underline;
}

.heatmap li {
    display: inline;
}

.minitab {
padding: 3px 0px 3px 8px;
margin-left: 0;
margin-top: 1px;
margin-bottom: 0px;
border-bottom: 1px solid #3c78b5;
font: bold 9px Verdana, sans-serif;
text-decoration: none;
float:none;
}
.selectedminitab {
padding: 3px 0.5em;
margin-left: 3px;
margin-top: 1px;
border: 1px solid #3c78b5;
background: white;
border-bottom: 1px solid white;
color: #000000;
text-decoration: none;
}
.unselectedminitab {
padding: 3px 0.5em;
margin-left: 3px;
margin-top: 1px;
border: 1px solid #3c78b5;
border-bottom: none;
background: #3c78b5;
color: #ffffff;
text-decoration: none;
}

a.unselectedminitab:hover {
color: #ffffff;
background: #003366;
border-color: #003366;
}

a.unselectedminitab:link { color: white; }
a.unselectedminitab:visited { color: white; }

a.selectedminitab:link { color: black; }
a.selectedminitab:visited { color: black; }

.linkerror { background-color: #fcc;}

a.labelOperationLink:link {text-decoration: underline}
a.labelOperationLink:active {text-decoration: underline}
a.labelOperationLink:visited {text-decoration: underline}
a.labelOperationLink:hover {text-decoration: underline}

a.newLabel:link {background-color: #ddffdd}
a.newLabel:active {background-color: #ddffdd}
a.newLabel:visited {background-color: #ddffdd}
a.newLabel:hover {background-color: #ddffdd}

ul.square {list-style-type: square}

.inline-control-link {
    background: #ffc;
    font-size: 9px;
    color: #666;
    padding: 2px;
    text-transform: uppercase;
    text-decoration: none;
}


.inline-control-link a:link {text-decoration: none}
.inline-control-link a:active {text-decoration: none}
.inline-control-link a:visited {text-decoration: none}
.inline-control-link a:hover {text-decoration: none}

.inline-control-link {
    background: #ffc;
    font-size: 9px;
    color: #666;
    padding: 2px;
    text-transform: uppercase;
    text-decoration: none;
    cursor: pointer;
}

div.auto_complete {
    width: 350px;
    background: #fff;
}
div.auto_complete ul {
    border: 1px solid #888;
    margin: 0;
    padding: 0;
    width: 100%;
    list-style-type: none;
}
div.auto_complete ul li {
    margin: 0;
    padding: 3px;
}
div.auto_complete ul li.selected {
    background-color: #ffb;
}
div.auto_complete ul strong.highlight {
    color: #800;
    margin: 0;
    padding: 0;
}

/******* Edit Page Styles *******/
.toogleFormDiv{
    border:1px solid #A7A6AA;
    background-color:white;
    padding:5px;
    margin-top: 5px;
}

.toogleInfoDiv{
    border:1px solid #A7A6AA;
    background-color:white;
    display:none;
    padding:5px;
    margin-top: 10px;
}

.inputSection{
    margin-bottom:20px;
}

#editBox{
   border:1px solid lightgray;
   background-color:#F0F0F0;
}

/******* Left Navigation Theme Styles ********/
.leftnav li a {
    text-decoration:none;
    color:white;
    margin:0px;
    display:block;
    padding:2px;
    padding-left:5px;
    background-color: #3c78b5;
    border-top:1px solid #3c78b5;
}

.leftnav li a:active {color:white;}
.leftnav li a:visited {color:white;}
.leftnav li a:hover {background-color: #003366; color:white;}

/* Added by Shaun during i18n */
.replaced
{
    background-color: #33CC66;
}

.topPadding
{
    margin-top: 20px;
}

/* new form style */
.form-block {
    padding: 6px;
}
.form-error-block {
    padding: 6px;
    background: #fcc;
    border-top: #f0f0f0 1px solid;
    border-bottom: #f0f0f0 1px solid;
    margin-bottom: 6px;
    padding: 0 12px 0 12px;
}
.form-element-large {
    font-size: 16px;
    font-weight: bold;
    font-family: Arial, sans-serif;
    color: #003366;
}

.form-element-small {
    font-size: 12px;
    font-weight: bold;
    font-family: Arial, sans-serif;
    color: #003366;
}

.form-header {
    background: lightyellow;
    border-top: #f0f0f0 1px solid;
    border-bottom: #f0f0f0 1px solid;
    margin-bottom: 6px;
    padding: 0 12px 0 12px;
}
.form-header p, .form-block p, .form-error-block p {
    line-height: normal;
    margin: 12px 0 12px 0;
}
.form-example {
    color: #888;
    font-size: 11px;
}
.form-divider {
    border-bottom: #ccc 1px solid;
    margin-bottom: 6px;
}
.form-buttons {
    margin-top: 6px;
    border-top: #ccc 1px solid;
    border-bottom: #ccc 1px solid;
    background: #f0f0f0;
    padding: 10px;
    text-align: center;
}
.form-buttons input {
    width: 100px;
}
.form-block .error {
    padding: 6px;
    margin-bottom: 6px;
}
    -->
    </style>
</head>
<body>

<div id="PageContent">
<table class="pagecontent" border="0" cellpadding="0" cellspacing="0" width="100%"><tr>
<td valign="top" class="pagebody">

    <div class="pageheader">
        <span class="pagetitle">
            Page Edited :
            <a href="http://cwiki.apache.org/confluence/display/SLING">SLING</a> :
            <a href="http://cwiki.apache.org/confluence/display/SLING/Everything+is+a+Resource">Everything is a Resource</a>
        </span>
    </div>

     <p>
        <a href="http://cwiki.apache.org/confluence/display/SLING/Everything+is+a+Resource">Everything is a Resource</a>
        has been edited by             <a href="http://cwiki.apache.org/confluence/display/~fmeschbe">Felix Meschberger</a>
            <span class="smallfont">(Jan 03, 2008)</span>.
     </p>
    <p>
      Change summary:
      <div class="greybox wiki-content"><p>Add section on resource tree exploration and add idea of extending Sling console by resource tree explorer (thanks Alexander Klimetschek)</p></div>
    </p>
     <p>
                 <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=73171&originalVersion=7&revisedVersion=8">(View changes)</a>
     </p>

    <span class="label">Content:</span><br/>
    <div class="greybox wiki-content"><h1><a name="EverythingisaResource-IntroducingtheSlingParadigm%3AEverythingisaResource"></a>Introducing the Sling Paradigm: Everything is a Resource</h1>



<p>Status: DRAFT<br/>
Created: 22. December 2007<br/>
Author: fmeschbe</p>

<div>
<ul>
  <li><a href='#EverythingisaResource-1CurrentState'>1 Current State</a></li>
  <li><a href='#EverythingisaResource-2EntertheSlingParadigm'>2 Enter the Sling Paradigm</a></li>
  <li><a href='#EverythingisaResource-3ImplementingtheSlingParadigm'>3 Implementing the Sling Paradigm</a>
<ul>
  <li><a href='#EverythingisaResource-3.1ResourceProvisioning'>3.1 Resource Provisioning</a></li>
  <li><a href='#EverythingisaResource-3.2Adapters'>3.2 Adapters</a>
<ul>
  <li><a href='#EverythingisaResource-3.2.1Adaptable'>3.2.1 Adaptable</a></li>
  <li><a href='#EverythingisaResource-3.2.1SlingAdaptable'>3.2.1 SlingAdaptable</a></li>
  <li><a href='#EverythingisaResource-3.2.1AdapterFactory'>3.2.1 AdapterFactory</a></li>
  <li><a href='#EverythingisaResource-3.2.1AdapterManager'>3.2.1 AdapterManager</a></li>
</ul></li>
  <li><a href='#EverythingisaResource-3.3ChangeEvents'>3.3 Change Events</a></li>
  <li><a href='#EverythingisaResource-3.4ResourceEnumeration'>3.4 Resource Enumeration</a></li>
</ul></li>
  <li><a href='#EverythingisaResource-4EmployingtheSlingParadigm'>4 Employing the Sling Paradigm</a>
<ul>
  <li><a href='#EverythingisaResource-4.1ResourcesinBundles'>4.1 Resources in Bundles</a></li>
  <li><a href='#EverythingisaResource-4.2Servlets'>4.2 Servlets</a></li>
  <li><a href='#EverythingisaResource-4.3Filters'>4.3 Filters</a>
<ul>
  <li><a href='#EverythingisaResource-4.3.1FilterServices'>4.3.1 Filter Services</a></li>
  <li><a href='#EverythingisaResource-4.3.2FilterScripts'>4.3.2 Filter Scripts</a></li>
</ul></li>
  <li><a href='#EverythingisaResource-4.4ScriptsfromResource'>4.4 Scripts from Resource</a></li>
</ul></li>
  <li><a href='#EverythingisaResource-5ChangestotheCode'>5 Changes to the Code</a>
<ul>
  <li><a href='#EverythingisaResource-5.1SlingAPI'>5.1 Sling API</a></li>
  <li><a href='#EverythingisaResource-5.2OSGiCommons'>5.2 OSGi Commons</a></li>
  <li><a href='#EverythingisaResource-5.3Merge%7B%7Bscripting%2Fresolver%7D%7Dinto%7B%7Bsling%2Fservletresolver%7D%7D'>5.3 Merge <tt>scripting/resolver</tt> into <tt>sling/servlet-resolver</tt></a></li>
  <li><a href='#EverythingisaResource-5.4SeparateObjectContentMappingfromResourceResolution'>5.4 Separate Object Content Mapping from Resource Resolution</a></li>
  <li><a href='#EverythingisaResource-5.5EnhanceSlingConsole'>5.5 Enhance Sling Console</a></li>
</ul></li>
</ul></div>


<h2><a name="EverythingisaResource-1CurrentState"></a>1 Current State</h2>

<p>Currently Sling uses resources, servlets and scripts as follows:</p>

<ul>
	<li>The <tt>Resource</tt> interface is mainly used to abstract JCR <tt>Node</tt> instances</li>
	<li>The <tt>ServletResolver</tt> uses an internal registration of servlets registered as OSGi services with the interface <tt>javax.servlet.Servlet</tt> and selects the servlet based on the resource type of the <tt>Resource</tt> of the request only.</li>
	<li>The <tt>ScriptResolver</tt> uses the <tt>ResourceResolver</tt> to find request handling scripts based on the resource type of the <tt>Resource</tt> of the request, the request selector string and the request method or request extension.</li>
	<li>Request processing filters are based on OSGi services registered with the interface name <tt>javax.servlet.Filter</tt></li>
	<li>Error handling is implemented in the <tt>ServletResolver</tt> implementation using the same mechanism to find a servlet (or script) based on the response status code or the caught <tt>Throwable</tt> as the pseudo request method name and using a different default error handling servlet.</li>
</ul>


<p>This mechanism works rather good, but there are currently enhancement requests, which may not easily be implemented with the current concepts:</p>

<ul>
	<li>Allow scripting of request processing filters. Implementing this requires special filter wrappers, which may select filter scripts.</li>
	<li>Enhance servlet selection to include the same parameters as script resolution, namely the request selector string and the request method or request extension. Implementing this would require replicating much of the code of the current <tt>ScriptResolver</tt> implementation.</li>
</ul>



<h2><a name="EverythingisaResource-2EntertheSlingParadigm"></a>2 Enter the Sling Paradigm</h2>

<p>To overcome the limitations we introduce the Sling paradigm</p>

<div class="panel"><div class="panelContent">
<p>Everything is a Resource</p>
</div></div>

<p>The Sling paradigm brings the paradigm of Java Content Repository API (JCR) <em>Everything is Content</em> to Sling.</p>

<p>This means, that every script, servlet, filter, error handler, etc. is available from the <tt>ResourceResolver</tt> just like normal content providing data to be rendered upon requests. To enable this resource resolution and resources have to provide certain functionality:</p>

<ul>
	<li>Allow registration of resources with the resource resolver. This is required to access servlets and filters registered as OSGi services through the resource resolver.</li>
	<li>Provide eventing mechanism to support caching and cache management</li>
	<li>Extend resource adapter mechanism, that is to provide extension to the <tt>Resource.adaptTo(Class&lt;?&gt;)</tt> method</li>
	<li>Extend resource enumeration to include resources from various sources</li>
</ul>




<h2><a name="EverythingisaResource-3ImplementingtheSlingParadigm"></a>3 Implementing the Sling Paradigm</h2>

<h3><a name="EverythingisaResource-3.1ResourceProvisioning"></a>3.1 Resource Provisioning</h3>

<p>To be able to access resources from different locations through a single resource resolver, a new <tt>ResourceProvider</tt> interface is added. A resource provider is able to provide resources below a certain location in the (virtual) resource tree. The resource resolver selects a resource provider to ask for a resource looking for a longest match amongst the root paths of the providers. If the longest match resource provider cannot find the requested resource, the provider with the second longest match is asked, and so forth.</p>

<p>Accessing the JCR repository is also implemented in the form of a resource provider. This JCR resource provider is registered at the root &#8211; <tt>/</tt> &#8211; of the (virtual) resource tree. Thus the JCR repository is always asked if, no more specific resource provider has the requested resource.</p>

<p>The <tt>ResourceProvider</tt> interface is defined as follows:</p>

<div class="code"><div class="codeContent">
<pre class="code-java"><span class="code-keyword">package</span> org.apache.sling.api.resource;

<span class="code-keyword">public</span> class ResourceProvider {

    /**
     * The name of the service registration property containing the root paths
     * of the resources provided by <span class="code-keyword">this</span> provider (value is <span class="code-quote">"provider.roots"</span>).
     */
    <span class="code-keyword">static</span> <span class="code-keyword">final</span> <span class="code-object">String</span> ROOTS = <span class="code-quote">"provider.roots"</span>;

    /**
     * Returns a resource from <span class="code-keyword">this</span> resource provider or &lt;code&gt;<span class="code-keyword">null</span>&lt;/code&gt; <span class="code-keyword">if</span>
     * the resource provider cannot find it. The path should have one of the
     * {@link #getRoots()} strings as its prefix.
     *
     * @<span class="code-keyword">throws</span> Exception may be thrown in <span class="code-keyword">case</span> of any problem creating the
     *             &lt;code&gt;Resource&lt;/code&gt; instance.
     */
    Resource getResource(ResourceResolver ResourceResolver, <span class="code-object">String</span> path)
            <span class="code-keyword">throws</span> Exception;

}</pre>
</div></div>

<p>Resource providers are registered as OSGi services under the name <tt>org.apache.sling.api.resource.ResourceProvider</tt> providing the list of resource path roots as a service registration property with the name <tt>provider.roots</tt>.</p>


<h3><a name="EverythingisaResource-3.2Adapters"></a>3.2 Adapters</h3>

<p>The <tt>Resource</tt> and <tt>ResourceResolver</tt> interfaces are defined with a method <tt>adaptTo</tt>, which adapts the object to other classes. Using this mechanism the JCR session of the resource resolver calling the <tt>adaptTo</tt> method with the <tt>javax.jcr.Session</tt> class object. Likewise the node on which a resource is based can be retrieved by calling the <tt>Resource.adaptTo</tt> method with the <tt>javax.jcr.Node</tt> class object.</p>

<p>To use resources as scripts, the <tt>Resource.adaptTo</tt> method must support being called with the <tt>org.apache.sling.api.script.SlingScript</tt> class object. But of course, we do not want to integrate the script manager with the resource resolver. To enable adapting objects to classes which are not foreseen by the original implementation, a factory mechanism is used. This way, the script manager can provide an adapter factory to adapt <tt>Resource</tt> to <tt>SlingScript</tt> objects.</p>


<h4><a name="EverythingisaResource-3.2.1Adaptable"></a>3.2.1 Adaptable</h4>

<p>The <tt>Adaptable</tt> interface defines the API to be implemented by a class providing adaptability to another class. The single method defined by this interface is</p>

<div class="code"><div class="codeContent">
<pre class="code-java">/**
 * Adapts the adaptable to another type.
 *
 * @param &lt;AdapterType&gt; The <span class="code-keyword">generic</span> type to which <span class="code-keyword">this</span> resource is adapted
 *            to
 * @param type The <span class="code-object">Class</span> object of the target type, such as
 *            &lt;code&gt;Node.class&lt;/code&gt;
 * @<span class="code-keyword">return</span> The adapter target or &lt;code&gt;<span class="code-keyword">null</span>&lt;/code&gt; <span class="code-keyword">if</span> the resource cannot
 *         adapt to the requested type
 */
&lt;AdapterType&gt; AdapterType adaptTo(<span class="code-object">Class</span>&lt;AdapterType&gt; type);</pre>
</div></div>

<p>This method is called to get a view of the same object in terms of another class. Examples of implementations of this method is the Sling <tt>ResourceResolver</tt> implementation providing adapting to a JCR session and the Sling JCR based <tt>Resource</tt> implementation providing adapting to a JCR node.</p>


<h4><a name="EverythingisaResource-3.2.1SlingAdaptable"></a>3.2.1 SlingAdaptable</h4>

<p>The <tt>SlingAdaptable</tt> class is an implementation of the <tt>Adaptable</tt> interface, calls the <tt>AdapterManager</tt> (see below) to provider an adapter to the <tt>SlingAdaptable</tt> object to the requested class. This class may be extended to have extensible adapters not foreseen at the time of the class development.</p>

<p>An example of extending the <tt>SlingAdaptable</tt> class will be the Sling JCR based <tt>Resource</tt> implementation. This way, such a resource may be adapted to a <tt>SlingScript</tt> by means of an appropriatley programmed <tt>AdapterFactory</tt> (see below).</p>


<h4><a name="EverythingisaResource-3.2.1AdapterFactory"></a>3.2.1 AdapterFactory</h4>

<p>The <tt>AdapterFactory</tt> interface defines the service interface and API for factories supporting extensible adapters for <tt>SlingAdaptable</tt> objects. The interface has a single method:</p>

<div class="code"><div class="codeContent">
<pre class="code-java">/**
 * Adapt the given adaptble object to the adaptable type. The adaptable
 * object is guaranteed to be an instance of one of the classes listed in
 * the {@link #ADAPTABLE_CLASSES} services registration property. The type
 * parameter is on of the classes listed in the {@link #ADAPTER_CLASSES}
 * service registration properties.
 *
 * @param &lt;AdapterType&gt;
 * @param adaptable
 * @param type
 * @<span class="code-keyword">return</span>
 */
&lt;AdapterType&gt; AdapterType getAdapter(<span class="code-object">Object</span> adaptable,
        <span class="code-object">Class</span>&lt;AdapterType&gt; type);</pre>
</div></div>

<p>This method is called by the <tt>AdapterManager</tt> on behalf of the <tt>SlingAdaptable</tt> object providing the <tt>SlingAdaptable</tt> as the <tt>adaptable</tt> parameter the requested class as the <tt>type</tt> parameter. Implementations of this interface are registered as OSGi services providing two lists: The list of classes wich may be adapted and the list of classes to which the adapted class may be adapted.</p>


<h4><a name="EverythingisaResource-3.2.1AdapterManager"></a>3.2.1 AdapterManager</h4>

<p>The <tt>AdapterManager</tt> is an internal class used by the <tt>SlingAdaptable</tt> objects to find an <tt>AdapterFactory</tt> to delegate the <tt>adaptTo</tt> method call to.</p>



<h3><a name="EverythingisaResource-3.3ChangeEvents"></a>3.3 Change Events</h3>

<p>The Sling <tt>ResourceResolver</tt> implementation defines events to be fired on changes in the (virtual) resource tree:</p>

<ul>
	<li>All repository events are forwarded</li>
	<li>Resource provider addition and removal events are generated</li>
</ul>


<p>Events are transmitted using the OSGi EventTracker specification. That is interested parties must register as OSGi event listener services.</p>


<h3><a name="EverythingisaResource-3.4ResourceEnumeration"></a>3.4 Resource Enumeration</h3>

<p>To be help in development and debugging and also to merely visualize the (virtual) resource tree, the resource tree must be explorable. That is, for every resource, the method <tt>ResourceResolver.listChildren(Resource resource)</tt> method must return all resources which may be considered children of the given resource.</p>

<p>Consider for example the following (partial) repository:</p>

<div class="preformatted"><div class="preformattedContent">
<pre>/
+-- filters
        +-- request
                +-- FilterA.esp
                +-- FilterB.jsp
</pre>
</div></div>

<p>Further consider the filter <em>FilterC</em> registered as an OSGi service. Thus the <tt>listChildren</tt> call for the resource at <tt>/filters/request</tt> must return three resources <tt>/filters/request/FilterA.esp</tt>, <tt>/filters/request/FilterB.jsp</tt> and <tt>/filters/request/FilterC</tt>. The first two will be JCR based resources, while the latter will be  a servlet resource.</p>


<h2><a name="EverythingisaResource-4EmployingtheSlingParadigm"></a>4 Employing the Sling Paradigm</h2>

<h3><a name="EverythingisaResource-4.1ResourcesinBundles"></a>4.1 Resources in Bundles</h3>

<p>Resources may be located in OSGi bundles and mapped into the (virtual) resource tree by means of a <tt>BundleResourceProvider</tt>. Bundles containing resources indicate this fact by means of a special bundle manifest header: <tt>Sling-Bundle-Resources</tt>. Two notes regarding bundle resources:</p>

<ol>
	<li>Bundle entries are either files or directories. To have these files and directories be handled as if they would be file and folder nodes in a repository, bundle based files will have a resource type <tt>nt:file</tt> and bundle based directories will have a resource type <tt>nt:folder</tt>.</li>
	<li>Bundle resource may be anything which may be represented by a file (or directory). That is the resources may be static content to be delivered to clients on request or resources may be scripts to be called to handle requests (or filter scripts even).</li>
</ol>



<h3><a name="EverythingisaResource-4.2Servlets"></a>4.2 Servlets</h3>

<p>Servlets to be used for request processing are registered as OSGi services with a series of required service registration properties:</p>

<ol>
	<li><tt>servlet.name</tt> - The name of the servlet as returned from <tt>ServletConfig.getServletName()</tt>. If this property is not set, the <tt>component.name</tt>, <tt>service.pid</tt> and <tt>service.id</tt> properties are checked in order.</li>
	<li><tt>servlet.path</tt> - A list of absolute paths under which the servlet is provided in the (virtual) resource tree.</li>
</ol>


<p>A <tt>ServletResourceProviderManager</tt> will listen for <tt>Servlet</tt> services and - given the correct service registration properties - provide the servlets as resources in the (virtual) resource tree. Such servlets are provided as <tt>ServletResource</tt> instances which adapt to the <tt>javax.servlet.Servlet</tt> class.</p>


<h3><a name="EverythingisaResource-4.3Filters"></a>4.3 Filters</h3>

<p>Filters may be provided in two different ways: As <tt>javax.servlet.Filter</tt> instances registered as OSGi services and as scripts located in a predefined place. When requests are processed the filters are looked up in the (virtual) resource tree below the <tt>/filters</tt> node. The list of filters is comprised of all the filters directly below the respective scope &#8211; <em>request</em> or <em>resource</em> &#8211; and the those below the respective scope and the type of the resource of the request.</p>

<p>The filters are sorted by their names. Hence a convention for the names of the filters in the (virtual) resource tree is defined such that the names is composed of an ordering number and the actual filter name, e.g. <em>0&#95;sample</em>.</p>

<h4><a name="EverythingisaResource-4.3.1FilterServices"></a>4.3.1 Filter Services</h4>

<p>Filters registered as OSGi services have three required service registration properties:</p>

<ol>
	<li><tt>filter.scope</tt> - (String) Scope of the filter, which must be either <em>request</em> or <em>resource</em></li>
	<li><tt>filter.order</tt> - (Integer) Call order of the filter used to define the filter call sequence</li>
	<li><tt>filter.name</tt> - (String) The name of the filter as returned <tt>FilterConfig.getFilterName()</tt>. If this property is not set, the <tt>component.name</tt>, <tt>service.pid</tt> and <tt>service.id</tt> properties are checked in order.</li>
	<li><tt>filter.resource.type</tt> - (String[]) The list of resource types to which this filter applies. This property is optional. If missing, the filter applies to all resource types. If this property is an empty list, the filter is not used as it applies to an empty list of resource types.</li>
</ol>


<p>Such Filter services are added to the (virtual) resource tree at a path defined as follows for each resource type <tt>resource_type</tt> listed in the <tt>filter.resource.type</tt>.</p>

<div class="code"><div class="codeContent">
<pre class="code-java">/filters/${filter.scope}/${resource_type}/${filter.order}_${filter.name}</pre>
</div></div>

<p>If the <tt>filter.resource.type</tt> property is missing, the filter is added at</p>

<div class="code"><div class="codeContent">
<pre class="code-java">/filters/${filter.scope}/${filter.order}_${filter.name}</pre>
</div></div>


<h4><a name="EverythingisaResource-4.3.2FilterScripts"></a>4.3.2 Filter Scripts</h4>

<p>Filter scripts may just be added as resources in the JCR repository at the appropriate location. For example for a request level filter applicable to <tt>nt:file</tt> nodes only, the filter would be placed in the <tt>/filters/request/nt/file</tt> folder.</p>


<h3><a name="EverythingisaResource-4.4ScriptsfromResource"></a>4.4 Scripts from Resource</h3>

<p>A <tt>Resource</tt> returned from the resource resolver may be a script. The script manager registers an <tt>AdapterFactory</tt> to adapt <tt>Resource</tt> to <tt>SlingScript</tt>. This factory will resolve a script engine for the resource file extension and return a <tt>SlingScript</tt> instance based on the <tt>Resource</tt>. If no script engine exists, the <tt>Resource</tt> may not be adapted.</p>

<p>The <tt>AdapterFactory</tt> adapting to a <tt>SlingScript</tt> is also able to adapt to <tt>Servlet</tt> by wrapping the adapted <tt>SlingScript</tt> in a <tt>ScriptServlet</tt>.</p>


<p>h3 4.5 Object Content Mapping</p>

<p>To cope with the new extensible functionality based on the <tt>SlingAdaptable</tt> class and adapter factories, object content mapping cannot be hard coded to just respond to any class. Instead, the Object Content Mapping functionality is in fact provided in terms of adapter factories, which are registered to be able to adapt instances the <tt>Resource</tt> interface to predefined types.</p>

<p>This way, Object Content Mapping takes part in adapter resolution just like any extensible adaption.</p>

<p>As a consequence, Object Content Mapping may probable be taken out of the current <tt>jcr/resource</tt> project into its own project.</p>


<h2><a name="EverythingisaResource-5ChangestotheCode"></a>5 Changes to the Code</h2>


<h3><a name="EverythingisaResource-5.1SlingAPI"></a>5.1 Sling API</h3>

<ol>
	<li>Add <tt>org.apache.sling.api.adapter.Adaptable</tt> interface</li>
	<li><tt>Resource</tt> and <tt>RespourceResolver</tt> interfaces extend the <tt>Adaptable</tt> interface</li>
	<li>Add <tt>org.apache.sling.api.resource.ResourceProvider</tt> interface</li>
	<li>Merge <tt>SlingScriptResolver</tt> and <tt>ServletResolver</tt></li>
</ol>



<h3><a name="EverythingisaResource-5.2OSGiCommons"></a>5.2 OSGi Commons</h3>

<p>The <tt>org.apache.sling.osgi.commons</tt> bundle is a new project providing the following functionality:</p>

<ul>
	<li><tt>ServiceLocator</tt> implementation (moved from <tt>sling/core</tt> project</li>
	<li><tt>SlingAdaptable</tt> class implementing <tt>Adaptable</tt> and leveraging adapter factories</li>
	<li><tt>AdapterFactory</tt> interface</li>
	<li><tt>AdapterManager</tt> selecting <tt>AdapterFactory</tt> instances on behalf of <tt>SlingAdaptable</tt> objects</li>
</ul>



<h3><a name="EverythingisaResource-5.3Merge%7B%7Bscripting%2Fresolver%7D%7Dinto%7B%7Bsling%2Fservletresolver%7D%7D"></a>5.3 Merge <tt>scripting/resolver</tt> into <tt>sling/servlet-resolver</tt></h3>

<p>The <tt>SlingScriptResolver</tt> and  <tt>ServletResolver</tt> interfaces are merged into a single <tt>ServletResolver</tt> interface, which has a <tt>resolve(SlingHttpServletRequest)</tt> and a <tt>find(ResourceResolver, String relPath)</tt> method. The implementation of this method will apply the alogirthm of the current <tt>scripting/resolver</tt> implementation of the <tt>SlingScriptResolver</tt>.</p>

<p>Any script (or servlet or actually code) may call any script or servlet by just resolving the script or servlet to a <tt>Resource</tt> and adapting the resource found to a <tt>SlingScript</tt> or <tt>Servlet</tt>.</p>


<h3><a name="EverythingisaResource-5.4SeparateObjectContentMappingfromResourceResolution"></a>5.4 Separate Object Content Mapping from Resource Resolution</h3>

<p>By applying the mechanisms of adapter factories, Object Content Mapping can be broken out of the <tt>jcr/resource</tt> project into its own project <tt>jcr/ocm</tt>.</p>


<h3><a name="EverythingisaResource-5.5EnhanceSlingConsole"></a>5.5 Enhance Sling Console</h3>

<p>Provide a Sling Console enhancement to explore the (virtual) resource tree</p></div>


</td></tr></table></div>
<p>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
    <tr>
        <td height="12" background="http://cwiki.apache.org/confluence/images/border/border_bottom.gif"><img src="http://cwiki.apache.org/confluence/images/border/spacer.gif" width="1" height="1" border="0"/></td>
    </tr>
</table>

<div class="smalltext">
    Powered by
    <a href="http://www.atlassian.com/software/confluence/default.jsp?clicked=footer" class="smalltext">Atlassian Confluence</a>
    (Version: 2.2.9 Build:#527 Sep 07, 2006)
    -
    <a href="http://jira.atlassian.com/secure/BrowseProject.jspa?id=10470" class="smalltext">Bug/feature request</a><br/>
    <br>
    <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action">Unsubscribe or edit your notifications preferences</a>

</div>

</body>
</html>


Mime
View raw message