Author: bdelacretaz
Date: Fri Nov 28 04:29:48 2008
New Revision: 721453

URL: http://svn.apache.org/viewvc?rev=721453&view=rev
Log:
SLING-673, ESP-based blog sample, based on a contribution by Michael Marth, 
thanks!

Added:
    incubator/sling/trunk/samples/espblog/   (with props)
    incubator/sling/trunk/samples/espblog/README.txt   (with props)
    incubator/sling/trunk/samples/espblog/pom.xml   (with props)
    incubator/sling/trunk/samples/espblog/src/
    incubator/sling/trunk/samples/espblog/src/main/
    incubator/sling/trunk/samples/espblog/src/main/java/
    incubator/sling/trunk/samples/espblog/src/main/java/org/
    incubator/sling/trunk/samples/espblog/src/main/java/org/apache/
    incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/
    
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/
    
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/
    
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/ThumbnailGeneratorService.java
   (with props)
    
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/
    
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/ThumbnailGeneratorServiceImpl.java
   (with props)
    incubator/sling/trunk/samples/espblog/src/main/resources/
    incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/
    
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/
    
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/
    
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/admin.esp
    
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/constants.esp
    
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/edit.esp
    
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css
   (with props)
    
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/header.esp
    
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/html.esp
    
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/list.esp
    
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/menu.esp
    
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/sling-logo.png
   (with props)
    
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/xml.esp
Modified:
    incubator/sling/trunk/pom.xml

Modified: incubator/sling/trunk/pom.xml
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/pom.xml?rev=721453&r1=721452&r2=721453&view=diff
==============================================================================
--- incubator/sling/trunk/pom.xml (original)
+++ incubator/sling/trunk/pom.xml Fri Nov 28 04:29:48 2008
@@ -121,6 +121,7 @@
         <module>samples/path-based-rtp</module>
         <module>samples/webloader/service</module>
         <module>samples/webloader/ui</module>
+        <module>samples/espblog</module>
 
         <!-- Launchpad -->
         <module>launchpad/base</module>

Propchange: incubator/sling/trunk/samples/espblog/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Nov 28 04:29:48 2008
@@ -0,0 +1,11 @@
+target
+bin
+*.iml
+*.ipr
+*.iws
+.settings
+.project
+.classpath
+.externalToolBuilders
+maven-eclipse.xml
+

Added: incubator/sling/trunk/samples/espblog/README.txt
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/README.txt?rev=721453&view=auto
==============================================================================
--- incubator/sling/trunk/samples/espblog/README.txt (added)
+++ incubator/sling/trunk/samples/espblog/README.txt Fri Nov 28 04:29:48 2008
@@ -0,0 +1,46 @@
+Sling ESP blog sample
+---------------------
+
+WHY THIS SAMPLE?
+----------------
+This demonstrates the use of ESP server-side javascript to implement a simple
+blog, with file attachments.
+
+A java service uses JCR observation to detect incoming files (either uploaded
+via the blog forms, or copied via WebDAV), and creates thumbnails of files 
image
+files, to demonstrate observation and OSGi SCR services.
+
+HOW TO INSTALL
+--------------
+Build this bundle and install it in Sling.
+
+For example, if Sling is running on port 8888 (which happens if you start 
+the launchpad/testing module with "mvn jetty:run"), this will build and 
+install it:
+
+    mvn -P autoInstallBundle clean install 
-Dsling.url=http://localhost:8888/system/console
+    
+To verify that the bundle is correctly installed:
+
+1) http://localhost:8888/apps/espblog/html.esp must return the html.esp 
+   script.
+
+2) The console at http://localhost:8888/system/console/bundles must 
+    list the bundle named "Sling - ESP blog sample" as active.    
+
+You also need to set "allow anonymous access" to false in the 
+SlingAuthenticator config, via http://localhost:8888/system/console/configMgr
+
+HOW TO TEST
+-----------
+http://localhost:8888/content/espblog/*.html must display the "Sling ESP
+blog sample" page, with the Home/Admin/New Post/... menu.
+
+Create a new post using the "New Post" menu.
+
+The post can include an attachment, if that's an image the included
+ThumbnailGeneratorService generates thumbnails in different sizes, displayed
+on the post's page. This happens asynchronously, so depending on your 
+machine's speed the thumbnails might only appear after a few seconds.
+
+The ESP scripts are found under /apps/espblog in the repository.
\ No newline at end of file

Propchange: incubator/sling/trunk/samples/espblog/README.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/samples/espblog/pom.xml
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/pom.xml?rev=721453&view=auto
==============================================================================
--- incubator/sling/trunk/samples/espblog/pom.xml (added)
+++ incubator/sling/trunk/samples/espblog/pom.xml Fri Nov 28 04:29:48 2008
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+  <!--
+    Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements. See the NOTICE file distributed with this work 
for
+    additional information regarding copyright ownership. The ASF licenses 
this file to you under the Apache License, Version 2.0 (the "License"); you may 
not
+    use this file except in compliance with the License. You may obtain a copy 
of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+    applicable law or agreed to in writing, software distributed under the 
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 
ANY
+    KIND, either express or implied. See the License for the specific language 
governing permissions and limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+  
+  <parent>
+    <groupId>org.apache.sling</groupId>
+    <artifactId>sling</artifactId>
+    <version>3-incubator</version>
+    <relativePath>../../../parent/pom.xml</relativePath>
+  </parent>
+   
+  <groupId>org.apache.sling.samples</groupId>
+  <artifactId>org.apache.sling.samples.espblog</artifactId>
+  <packaging>bundle</packaging>
+  <version>2.0.3-incubator-SNAPSHOT</version>
+  <name>Sling - ESP blog sample</name>
+  <description>
+    Sample Sling application - blog written using ESP scripts.
+  </description>
+  
+  <scm>
+    
<connection>scm:svn:http://svn.apache.org/repos/asf/incubator/sling/trunk/samples/espblog</connection>
+    
<developerConnection>scm:svn:https://svn.apache.org/repos/asf/incubator/sling/trunk/samples/espblog</developerConnection>
+    
<url>http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog</url>
+  </scm>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-scr-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Sling-Initial-Content>initial-content</Sling-Initial-Content>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <configuration>
+          
<excludePackageNames>org.apache.sling.samples.espblog.internal</excludePackageNames>
+        </configuration>
+      </plugin>
+    </plugins>
+  </reporting>
+  
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.sling</groupId>
+      <artifactId>org.apache.sling.api</artifactId>
+      <version>2.0.2-incubator</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sling</groupId>
+      <artifactId>org.apache.sling.jcr.api</artifactId>
+      <version>2.0.2-incubator</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+  
+</project>
\ No newline at end of file

Propchange: incubator/sling/trunk/samples/espblog/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/ThumbnailGeneratorService.java
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/ThumbnailGeneratorService.java?rev=721453&view=auto
==============================================================================
--- 
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/ThumbnailGeneratorService.java
 (added)
+++ 
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/ThumbnailGeneratorService.java
 Fri Nov 28 04:29:48 2008
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.samples.espblog;
+
+/** Empty interface, the SCR plugin requires one
+ *  to process our service implementation.
+ */
+public interface ThumbnailGeneratorService {
+}
\ No newline at end of file

Propchange: 
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/ThumbnailGeneratorService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/ThumbnailGeneratorService.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: 
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/ThumbnailGeneratorServiceImpl.java
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/ThumbnailGeneratorServiceImpl.java?rev=721453&view=auto
==============================================================================
--- 
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/ThumbnailGeneratorServiceImpl.java
 (added)
+++ 
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/ThumbnailGeneratorServiceImpl.java
 Fri Nov 28 04:29:48 2008
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.samples.espblog.internal;
+
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.imageio.ImageIO;
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+import javax.jcr.observation.ObservationManager;
+
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.samples.espblog.ThumbnailGeneratorService;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Observe the espblog content for changes, and generate
+ * thumbnails when images are added.
+ * 
+ * @scr.service
+ * @scr.component immediate="true" metatype="false"
+ * @scr.property name="service.description" value="Sling ESP blog sample 
thumbnails generator"
+ * @scr.property name="service.vendor" value="Apache Software Foundation"
+ * 
+ */
+public class ThumbnailGeneratorServiceImpl implements 
ThumbnailGeneratorService, EventListener {
+
+    private Session session;
+    private ObservationManager observationManager;
+    
+       /** @scr.reference */
+       private SlingRepository repository;
+       
+    /** @scr.property value="/content/espblog" */
+    private static final String CONTENT_PATH_PROPERTY = "content.path";
+
+       private static final Logger log = LoggerFactory
+                       .getLogger(ThumbnailGeneratorServiceImpl.class);
+       
+       private Map<String, String> supportedMimeTypes = new HashMap<String, 
String>();
+
+       protected void activate(ComponentContext context)  throws Exception {
+           supportedMimeTypes.put("image/jpeg", ".jpg");
+        supportedMimeTypes.put("image/png", ".png");
+        
+        String contentPath = 
(String)context.getProperties().get(CONTENT_PATH_PROPERTY);
+
+               session = repository.loginAdministrative(null);
+               if 
(repository.getDescriptor(Repository.OPTION_OBSERVATION_SUPPORTED).equals("true"))
 {
+                       observationManager = 
session.getWorkspace().getObservationManager();
+                       String[] types = { "nt:file" };
+                       observationManager.addEventListener(this, 
Event.NODE_ADDED, contentPath, true, null, types, false);
+               }
+       }
+       
+    protected void deactivate(ComponentContext componentContext) throws 
RepositoryException {
+        if(observationManager != null) {
+            observationManager.removeEventListener(this);
+        }
+        if (session != null) {
+            session.logout();
+            session = null;
+        }
+    }
+
+       public void onEvent(EventIterator it) {
+        while (it.hasNext()) {
+            Event event = it.nextEvent();
+            try {
+                if (event.getType() == Event.NODE_ADDED && 
!(event.getPath().contains("thumbnails"))) {
+                    log.info("new upload: {}", event.getPath());
+                    Node addedNode = 
session.getRootNode().getNode(event.getPath().substring(1));
+                    processNewNode(addedNode);
+                    log.info("finished processing of {}", event.getPath());
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+    }
+
+    private String getMimeType(Node n) throws RepositoryException {
+           String result = null;
+               final String mimeType = 
n.getProperty("jcr:mimeType").getString();
+               
+               for(String key : supportedMimeTypes.keySet()) {
+                   if(mimeType!=null && mimeType.startsWith(key)) {
+                       result = key;
+                       break;
+                   }
+               }
+               
+               if(result == null) {
+                       log.info("Node {} rejected, unsupported mime-type {}", 
n.getPath(), mimeType);
+               }
+               
+               if(n.getName().startsWith(".")) {
+                       log.info("Node {} rejected, name starts with '.'", 
n.getPath(), mimeType);
+                       result = null;
+               }
+               
+               return result;
+       }
+       
+       private void processNewNode(Node addedNode) throws Exception {
+           final String mimeType = getMimeType(addedNode);
+               if (mimeType == null) {
+                       return;
+               }
+               final String suffix = supportedMimeTypes.get(mimeType); 
+               
+               // Scale to a temp file for simplicity
+               log.info("Creating thumbnails for node {}", 
addedNode.getPath());
+               final int [] widths = { 50, 100, 250 };
+               for(int width : widths) {
+                   createThumbnail(addedNode, width, mimeType, suffix);
+               }
+       }
+       
+       private void createThumbnail(Node image, int scalePercent, String 
mimeType, String suffix) throws Exception {
+        final File tmp = File.createTempFile(getClass().getSimpleName(), 
suffix);
+        try {
+            scale(image.getProperty("jcr:data").getStream(), scalePercent, new 
FileOutputStream(tmp), suffix);
+            
+            // Create thumbnail node and set the mandatory properties
+            Node thumbnailFolder = getThumbnailFolder(image);
+            Node thumbnail = 
thumbnailFolder.addNode(image.getParent().getName() + "_" + scalePercent + 
suffix, "nt:file");
+            Node contentNode = thumbnail.addNode("jcr:content", "nt:resource");
+            contentNode.setProperty("jcr:data", new FileInputStream(tmp));
+            contentNode.setProperty("jcr:lastModified", 
Calendar.getInstance());    
+            contentNode.setProperty("jcr:mimeType", mimeType);
+
+            session.save();
+            
+            log.info("Created thumbnail " + contentNode.getPath());
+        } finally {
+            if(tmp != null) {
+                tmp.delete();
+            }
+        }
+           
+       }
+
+       private Node getThumbnailFolder(Node addedNode) throws Exception {
+               Node post = addedNode.getParent().getParent().getParent();
+               if (post.hasNode("thumbnails")) {
+                       log.info("thumbnails node exists already at " + 
post.getPath());
+                       return post.getNode("thumbnails");
+               } else {
+                       Node t = post.addNode("thumbnails", "nt:folder");
+                       session.save();
+                       return t;
+               }
+       }
+
+       public void scale(InputStream inputStream, int width, OutputStream 
outputStream, String suffix) throws IOException {
+               if(inputStream == null) {
+                       throw new IOException("InputStream is null");
+               }
+               
+        final BufferedImage src = ImageIO.read(inputStream);
+               if(src == null) {
+                   final StringBuffer sb = new StringBuffer();
+                   for(String fmt : ImageIO.getReaderFormatNames()) {
+                       sb.append(fmt);
+                       sb.append(' ');
+                   }
+                       throw new IOException("Unable to read image, registered 
formats: " + sb);
+               }
+               
+        final double scale = (double)width / src.getWidth();
+        
+               int destWidth = width;
+               int destHeight = new Double(src.getHeight() * scale).intValue();
+               log.debug("Generating thumbnail, w={}, h={}", destWidth, 
destHeight);
+               BufferedImage dest = new BufferedImage(destWidth, destHeight, 
BufferedImage.TYPE_INT_RGB);
+               Graphics2D g = dest.createGraphics();
+               AffineTransform at = AffineTransform.getScaleInstance((double) 
destWidth / src.getWidth(), (double) destHeight  / src.getHeight());
+               g.drawRenderedImage(src, at);
+               ImageIO.write(dest, suffix.substring(1), outputStream);
+       }
+}
\ No newline at end of file

Propchange: 
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/ThumbnailGeneratorServiceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/ThumbnailGeneratorServiceImpl.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/admin.esp
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/admin.esp?rev=721453&view=auto
==============================================================================
--- 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/admin.esp
 (added)
+++ 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/admin.esp
 Fri Nov 28 04:29:48 2008
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
"http://www.w3.org/TR/html4/strict.dtd";>
+
+<% 
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+ 
+<html>
+<%
+pageTitle = "Blog admin"
+load("header.esp")
+%>
+       <body>
+               <div class="title">
+                 <div class="logo">
+                   <a href="http://incubator.apache.org/sling";>
+                     <img border="0" src="/apps/espblog/sling-logo.png"/>
+                   </a>
+                 </div>
+               </div>
+               
+               <div class="menu">
+                       <%
+                       load("menu.esp");
+                       %>
+       </div>
+       
+       <div class="main">
+                       <h1><%= pageTitle %></h1>
+                                       
+                         <table>
+                           <tr>
+                             <th>Title</th>
+                       
+                             <th>Date</th>
+                             <th colspan="2">Controls</th>
+                           </tr>
+                           
+                           <%
+                           df = new java.text.SimpleDateFormat( "yyyy-MM-dd 
HH:mm" );
+                       
+                           posts = currentNode.getNodes()
+                           for (a in posts) {
+                               post = posts[a]
+                               if(!post.created) {
+                                 // does not look like one of our posts
+                                 continue;
+                               }
+                           %>
+                           
+                           <tr>
+                             <td><%=post.title%></td>
+                             <td><%=df.format(post.created.getTime())%></td>
+                             <td><a 
href="/content/espblog/posts/<%=a%>.html">View</a>&nbsp;<a 
href="/content/espblog/posts/<%=a%>.edit.html">Edit</a></td>
+                             <td>
+                               <form method="POST" 
action="/content/espblog/posts/<%=a%>">
+                                         <input name=":redirect" type="hidden" 
value="/content/espblog/posts.admin.html"/> 
+                                         <input name=":operation" 
type="hidden" value="delete"/> 
+                                         <input type="submit" value="Delete">
+                               </form>                           
+                             </td>
+                           </tr>
+                           
+                         <%}%>
+                         </table>
+               </div>                    
+       </body>
+</html>
\ No newline at end of file

Added: 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/constants.esp
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/constants.esp?rev=721453&view=auto
==============================================================================
--- 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/constants.esp
 (added)
+++ 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/constants.esp
 Fri Nov 28 04:29:48 2008
@@ -0,0 +1,22 @@
+<% 
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+
+<%
+BLOG_TITLE="Sling ESP blog sample";
+%>
\ No newline at end of file

Added: 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/edit.esp
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/edit.esp?rev=721453&view=auto
==============================================================================
--- 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/edit.esp
 (added)
+++ 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/edit.esp
 Fri Nov 28 04:29:48 2008
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
"http://www.w3.org/TR/html4/strict.dtd";>
+
+<% 
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+
+<html>
+<%
+pageTitle = currentNode.title ? currentNode.title : "New post";
+load("header.esp");
+%>
+       <body>
+               
+               <div class="title">
+                 <div class="logo">
+                   <a href="http://incubator.apache.org/sling";>
+                     <img border="0" src="/apps/espblog/sling-logo.png"/>
+                   </a>
+                 </div>
+               </div>
+               
+               <div class="menu">
+                       <%
+                       load("menu.esp");
+                       %>
+       </div>
+       
+       <div class="main">
+                       <h1><%= pageTitle %></h1>
+                                       
+                       <form class="hform" method="POST" action="<%= 
currentNode.getPath().lastIndexOf("*") != currentNode.getPath().length-1 ? 
currentNode : "/content/espblog/posts/*" %>" enctype="multipart/form-data">     
                                       
+                                       
+                                       <p><label>Title</label>
+                                       <input name="title" type="text" 
size="80" value="<%= currentNode.getPath().lastIndexOf("*") != 
currentNode.getPath().length-1 ? currentNode.title : "" %>"></p>
+                                       
+                                       <p><label>Body</label>
+                                       <textarea name="posttext" cols="40" 
rows="5"><%= currentNode.getPath().lastIndexOf("*") != 
currentNode.getPath().length-1 ? currentNode.posttext : "" %></textarea></p>
+                                       
+                                       <p><label>File</label><input 
type="file" name="attachments/*"/></p>
+
+                                       
+                                       <input type="hidden" name="created"/> 
+                                       <input name=":redirect" type="hidden" 
value="/content/espblog/posts.admin.html"/> 
+                                                                               
                
+                               <input type="submit" value="Post" 
class="button">
+                       </form>
+               </div>                                  
+       </body>
+</html>

Added: 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css?rev=721453&view=auto
==============================================================================
--- 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css
 (added)
+++ 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css
 Fri Nov 28 04:29:48 2008
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* @override http://incubator.apache.org/sling/site/media.data/site.css */
+
+body { background-color: #ffffff; color: #3b3b3b; font-family: Tahoma, Arial, 
sans-serif; font-size: 10pt; line-height: 140% }
+h1, h2, h3, h4, h5, h6 { font-weight: normal; color: #000000; line-height: 
100%; }
+h1 { font-size: 200% }
+h2 { font-size: 175% }
+h3 { font-size: 150% }
+h4 { font-size: 140% }
+h5 { font-size: 130% }
+h6 { font-size: 120% }
+a { color: #1980af }
+a:visited { color: #1980af }
+a:hover { color: #1faae9 }
+.title { position: absolute; left: 1px; right: 1px; top:25px; height: 81px; 
background: url(http://incubator.apache.org/sling/site/media.data/gradient.png) 
repeat-x; background-position: bottom; }
+.logo { position: absolute; width: 15em; height: 81px; text-align: center; }
+.header { text-align: right; margin-right: 20pt; }
+.menu { border-top: 10px solid #f9bb00; position: absolute; top: 107px; left: 
1px; width: 15em; bottom: 0px; padding: 0px; background-color: #fcfcfc }
+.menu ul { background-color: #fdf5d9; list-style: none; padding-left: 4em; 
margin-top: 0px; padding-top: 2em; padding-bottom: 2em; margin-left: 0px; 
color: #4a4a43}
+.menu a { text-decoration: none; color: #4a4a43 }
+.main { position: absolute; border-top: 10px solid #cde0ea; top: 107px; left: 
15em; right: 1px; margin-left: 2px; padding-right: 4em; padding-left: 1em; 
padding-top: 1em;}
+.code { color: black; background-color: #eeeeee; border: solid 1px black; 
margin-top: 0.5em; margin-bottom: 0.5em; }
+.codeHeader { text-align: center; font-family: monospace; border-bottom:1px 
solid black; padding-top: 0.5em; padding-bottom: 0.5em; margin-bottom: 0.5em; }
+.codeContent { padding: 0.5em }
+.codeContent pre { margin: 0em }
+.code-keyword { color: #880000 }
+.code-quote { color: #008800 }
+.code-object { color: #0000dd }
+.code-java { margin: 0em }
+.preformatted { color: black; background-color: #eeeeee; border: solid 1px 
black; padding: 0.5em }
+.preformattedContent pre { margin: 0em }
+table.confluenceTable { border-collapse:collapse; margin:5px; }
+table.confluenceTable th.confluenceTh { background-color:#FDF5D9; border:1px 
solid #CCCCCC; padding:3px 4px; text-align:center; }
+table.confluenceTable td.confluenceTd { border:1px solid #CCCCCC; padding:3px 
4px; }
+.infoMacro { background-color: #D8E4F1; border: 1px solid #3C78B5; }
+.noteMacro { background-color: #FFFFCE; border: 1px solid #F0C000; }
+.tipMacro { background-color: #DDFFDD; border: 1px solid #009900; }
+.warningMacro { background-color: #FFCCCC; border: 1px solid #CC0000; }
+.note { font-size: 80%; }
\ No newline at end of file

Propchange: 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css
------------------------------------------------------------------------------
    svn:executable = *

Propchange: 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/header.esp
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/header.esp?rev=721453&view=auto
==============================================================================
--- 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/header.esp
 (added)
+++ 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/header.esp
 Fri Nov 28 04:29:48 2008
@@ -0,0 +1,31 @@
+<% 
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+
+<%
+load("constants.esp");
+if(typeof(pageTitle) == "undefined") {
+  pageTitle = BLOG_TITLE;
+}
+%>
+
+<head>
+       <link rel="stylesheet" href="/apps/espblog/espblog.css" type="text/css" 
media="screen" charset="utf-8">
+       <link rel="alternate" type="application/rss+xml" title="RSS Entries" 
href="http://<%=request.getServerName()%>:<%=request.getServerPort()%>/content/espblog/posts.xml"/>
                
+       <title><%= pageTitle %></title>
+</head>
\ No newline at end of file

Added: 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/html.esp
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/html.esp?rev=721453&view=auto
==============================================================================
--- 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/html.esp
 (added)
+++ 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/html.esp
 Fri Nov 28 04:29:48 2008
@@ -0,0 +1,103 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
"http://www.w3.org/TR/html4/strict.dtd";>
+
+<% 
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+
+<html>
+<%
+load("header.esp");
+load("constants.esp");
+
+function render(attachmentNode) {
+  
if(attachmentNode.getNode("jcr:content").getProperty("jcr:mimeType").getString().substring(0,5)
 == "image") {
+    %><p><img src="<%=attachmentNode%>"></p><%
+  } else {     
+    %><p><a href="<%=attachmentNode%>">Download 
<%=attachmentNode.getName()%></a></p><%
+  }    
+}
+
+function renderMedia(postNode, mediaFolderName) {
+       if(postNode.hasNode(mediaFolderName)) {
+               %><h3><%= mediaFolderName %></h3><%
+               var nodes = currentNode.getNode(mediaFolderName).getNodes();
+               for(i in nodes) {
+             render(nodes[i]);
+               }
+       }
+}
+%>
+       <body>
+               <div class="title">
+                 <div class="logo">
+                   <a href="http://incubator.apache.org/sling";>
+                     <img border="0" src="/apps/espblog/sling-logo.png"/>
+                   </a>
+                 </div>
+               </div>
+               
+               <div class="menu">
+                       <%
+                       load("menu.esp");
+                       %>
+       </div>
+       
+       <div class="main">
+                       <h1><%= BLOG_TITLE %></h1>
+                       <div id="postbody">     
+                               <h2><%=currentNode.title ? currentNode.title : 
""%></h2>        
+                               <p><%=currentNode.posttext ? 
currentNode.posttext : ""%></p>
+                               
+                               <%
+                               if(currentNode.hasNode("comments")) {
+                                   %><h3>Comments</h3><%
+                                       comments = 
currentNode.getNode("comments").getNodes()
+                                       for (a in comments) {
+                                               comment = comments[a]
+                                               if(comment.commenttext){
+                                       %>
+                                       
+                                       <div>
+                                       <%=comment.commenter ? 
comment.commenter : "an anonymous coward"%> said:
+                                       <p><%=comment.commenttext%></p> 
+                                       </div>
+                               
+                               <%
+                                               }
+                                       }
+                               }
+                               %>
+                                               
+                               <% if(currentNode.title) { %>                   
                                
+                           <h3>Comment on this post</h3>
+                               <form class="hform" method="POST" 
action="<%=currentNode%>/comments/*">
+                                       <p><label>Your name</label><input 
type="text" size="80" name="commenter"/></p>
+                                       <p><label>Your comment</label>
+                                       <textarea name="commenttext" 
cols="40"></textarea></p>
+                                       <input name=":redirect" type="hidden" 
value="<%=currentNode%>.view.html"/> 
+                                       <input type="submit" value="Submit" 
class="button"/>
+                               </form>
+                               <% } %>
+                       </div>
+                       <div id="resources">
+                               <% renderMedia(currentNode, "attachments"); %>
+                               <% renderMedia(currentNode, "thumbnails"); %>
+                       </div>
+               </div>                  
+       </body>
+</html>

Added: 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/list.esp
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/list.esp?rev=721453&view=auto
==============================================================================
--- 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/list.esp
 (added)
+++ 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/list.esp
 Fri Nov 28 04:29:48 2008
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
"http://www.w3.org/TR/html4/strict.dtd";>
+
+<% 
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+
+<%    
+   var queryManager = 
currentNode.getSession().getWorkspace().getQueryManager();  
+   if(request.getParameter('qt')) {
+       var query = 
queryManager.createQuery("/jcr:root/content/espblog/posts/element(*, 
nt:unstructured)[jcr:contains(., '"+request.getParameter("qt")+"')] order by 
@created descending", "xpath");
+   } else { 
+       var query = 
queryManager.createQuery("/jcr:root/content/espblog/posts/element(*, 
nt:unstructured) order by @created descending", "xpath");
+   }
+   var result = query.execute().getNodes();
+%>
+
+<html>
+
+       <%
+       load("header.esp");
+       %>
+
+       <body>
+               <div class="title">
+                 <div class="logo">
+                   <a href="http://incubator.apache.org/sling";>
+                     <img border="0" src="/apps/espblog/sling-logo.png"/>
+                   </a>
+                 </div>
+               </div>
+               
+               <div class="menu">
+                       <%
+                       load("menu.esp");
+                       %>
+       </div>
+       
+       <div class="main">
+                       <h1><%= pageTitle %></h1>
+                       <h2><%= request.getParameter('qt') ? "Search results" : 
"Recent posts" %></h2>
+               
+                       <div id="postbody">
+                               <%
+                               df = new Packages.java.text.SimpleDateFormat( 
"yyyy-MM-dd HH:mm" );
+       
+                               while(result.hasNext()) {
+                                       post = result.nextNode()
+                               %> 
+       
+                                       <h3><a href="<%= post.getPath() 
%>.html"><%=post.title%></a></h3>
+                                       <strong>Posted at 
<%=df.format(post.created.getTime())%></strong><br>                             
      
+                                       <p><%=post.posttext%><br/><strong 
class="highlight"><a href="<%=post%>.html"><%=post.hasNode("comments") ? "See 
comments" : "Be the first to comment"%> </a></strong> </p>
+                               <%}%>   
+                       </div>
+               </div>                  
+       </body>
+</html>
\ No newline at end of file

Added: 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/menu.esp
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/menu.esp?rev=721453&view=auto
==============================================================================
--- 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/menu.esp
 (added)
+++ 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/menu.esp
 Fri Nov 28 04:29:48 2008
@@ -0,0 +1,32 @@
+<% 
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+
+<%
+load("constants.esp");
+%>
+
+<div id="header">                              
+       <ul class="tabs">
+               <li><a href="/content/espblog/posts.list.html">Home</a></li>
+               <li><a href="/content/espblog/posts.admin.html">Admin</a></li>
+               <li><a href="/content/espblog/posts/*.edit.html">New 
Post</a></li>
+               <li><a href="/content/espblog/posts.xml">RSS feed</a></li>
+               <li><form method="GET" 
action="/content/espblog/posts.list.html"><input type="text" name="qt" 
size="10" value="Search"/></form></li>    
+       </ul>
+</div>
\ No newline at end of file

Added: 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/sling-logo.png
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/sling-logo.png?rev=721453&view=auto
==============================================================================
Binary file - no diff available.

Propchange: 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/sling-logo.png
------------------------------------------------------------------------------
    svn:executable = *

Propchange: 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/sling-logo.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/xml.esp
URL: 
http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/xml.esp?rev=721453&view=auto
==============================================================================
--- 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/xml.esp
 (added)
+++ 
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/xml.esp
 Fri Nov 28 04:29:48 2008
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+
+<% 
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+
+<%    
+   var queryManager = 
currentNode.getSession().getWorkspace().getQueryManager();  
+   var query = 
queryManager.createQuery("/jcr:root/content/espblog/posts/element(*, 
nt:unstructured) order by @created descending", "xpath");
+   var result = query.execute().getNodes();
+   
+%>
+
+<rss version="2.0">
+   <channel>
+      <title>My Sling Blog</title>
+      <link><%=request.getRequestURL()%></link>
+      <description>RSS 2.0 feed of my Sling blog</description>
+      
+      <%
+       df = new java.text.SimpleDateFormat( "EEE', 'dd' 'MMM' 'yyyy' 
'HH:mm:ss' 'Z", Packages.java.util.Locale.US);
+       var counter = 0;
+       while(result.hasNext() && counter < 10) {
+               counter++;
+               post = result.nextNode()
+      %>
+      
+      <item>
+         <title><%=post.title%></title>
+         
<link>http://<%=request.getServerName()%>:<%=request.getServerPort()%><%=post%>.html</link>
+         <description><%=post.posttext%></description>
+         <pubDate><%=df.format(post.created.getTime())%></pubDate>
+      </item>
+      
+      <%
+      }
+      %>
+     
+   </channel>
+</rss>
\ No newline at end of file


Reply via email to