You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2008/04/04 15:32:19 UTC

svn commit: r644707 - in /incubator/sling/trunk: ./ samples/ samples/webloader/ samples/webloader/service/ samples/webloader/service/src/ samples/webloader/service/src/main/ samples/webloader/service/src/main/java/ samples/webloader/service/src/main/ja...

Author: bdelacretaz
Date: Fri Apr  4 06:32:12 2008
New Revision: 644707

URL: http://svn.apache.org/viewvc?rev=644707&view=rev
Log:
SLING-358 - Webloader sample mini-application

Added:
    incubator/sling/trunk/samples/
    incubator/sling/trunk/samples/pom.xml   (with props)
    incubator/sling/trunk/samples/webloader/   (with props)
    incubator/sling/trunk/samples/webloader/pom.xml   (with props)
    incubator/sling/trunk/samples/webloader/service/   (with props)
    incubator/sling/trunk/samples/webloader/service/README.txt   (with props)
    incubator/sling/trunk/samples/webloader/service/pom.xml   (with props)
    incubator/sling/trunk/samples/webloader/service/src/
    incubator/sling/trunk/samples/webloader/service/src/main/
    incubator/sling/trunk/samples/webloader/service/src/main/java/
    incubator/sling/trunk/samples/webloader/service/src/main/java/org/
    incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/
    incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/
    incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/
    incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/
    incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/Webloader.java   (with props)
    incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/WebloaderException.java   (with props)
    incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/WebloaderJobStatus.java   (with props)
    incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/
    incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/ProgressInputStream.java   (with props)
    incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/WebLoaderImpl.java   (with props)
    incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/WebloaderJob.java   (with props)
    incubator/sling/trunk/samples/webloader/ui/   (with props)
    incubator/sling/trunk/samples/webloader/ui/README.txt   (with props)
    incubator/sling/trunk/samples/webloader/ui/pom.xml   (with props)
    incubator/sling/trunk/samples/webloader/ui/src/
    incubator/sling/trunk/samples/webloader/ui/src/main/
    incubator/sling/trunk/samples/webloader/ui/src/main/resources/
    incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/
    incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/ROOT.xjson
    incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/apps/
    incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/apps/sling/
    incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/apps/sling/webloader/
    incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/apps/sling/webloader/POST.esp
    incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/apps/sling/webloader/html.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=644707&r1=644706&r2=644707&view=diff
==============================================================================
--- incubator/sling/trunk/pom.xml (original)
+++ incubator/sling/trunk/pom.xml Fri Apr  4 06:32:12 2008
@@ -126,6 +126,9 @@
         <module>extensions/apt/parser</module>
         <module>extensions/apt/servlet</module>
 
+        <!-- Samples -->
+        <module>samples</module>
+
     </modules>
     <distributionManagement>
         <!-- place our releases in the incubator's repository -->

Added: incubator/sling/trunk/samples/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/pom.xml?rev=644707&view=auto
==============================================================================
--- incubator/sling/trunk/samples/pom.xml (added)
+++ incubator/sling/trunk/samples/pom.xml Fri Apr  4 06:32:12 2008
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  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>1-incubator-SNAPSHOT</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.samples</artifactId>
+    <packaging>pom</packaging>
+    <version>2.0.0-incubator-SNAPSHOT</version>
+
+    <name>Sling Samples</name>
+    <description>
+        Parent POM for the Sling sample modules.
+    </description>
+
+    <scm>
+        <connection>
+            scm:svn:http://svn.apache.org/repos/asf/incubator/sling/trunk/samples
+        </connection>
+        <developerConnection>
+            scm:svn:https://svn.apache.org/repos/asf/incubator/sling/trunk/samples
+        </developerConnection>
+        <url>
+            http://svn.apache.org/viewvc/incubator/sling/trunk/samples
+        </url>
+    </scm>
+
+    <modules>
+        <module>webloader</module>
+    </modules>
+</project>

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

Propchange: incubator/sling/trunk/samples/webloader/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Apr  4 06:32:12 2008
@@ -0,0 +1,9 @@
+target
+bin
+*.iml
+*.ipr
+*.iws
+.settings
+.project
+.classpath
+.externalToolBuilders

Added: incubator/sling/trunk/samples/webloader/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/pom.xml?rev=644707&view=auto
==============================================================================
--- incubator/sling/trunk/samples/webloader/pom.xml (added)
+++ incubator/sling/trunk/samples/webloader/pom.xml Fri Apr  4 06:32:12 2008
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  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>org.apache.sling.samples</artifactId>
+        <version>2.0.0-incubator-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.samples.webloader</artifactId>
+    <packaging>pom</packaging>
+    <version>2.0.0-incubator-SNAPSHOT</version>
+
+    <name>Sling Webloader</name>
+    <description>
+	The Sling Webloader sample retrieves documents from the Web using
+        a Google search, and loads them into the repository.
+        The Webloader consists of two modules, a reusable service module and
+        a simple demo user interface (ui module).
+    </description>
+
+    <scm>
+        <connection>
+            scm:svn:http://svn.apache.org/repos/asf/incubator/sling/trunk/samples/webloader
+        </connection>
+        <developerConnection>
+            scm:svn:https://svn.apache.org/repos/asf/incubator/sling/trunk/samples/webloader
+        </developerConnection>
+        <url>
+            http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader
+        </url>
+    </scm>
+
+    <modules>
+        <module>service</module>
+        <module>ui</module>
+    </modules>
+</project>

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

Propchange: incubator/sling/trunk/samples/webloader/service/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Apr  4 06:32:12 2008
@@ -0,0 +1,9 @@
+target
+bin
+*.iml
+*.ipr
+*.iws
+.settings
+.project
+.classpath
+.externalToolBuilders

Added: incubator/sling/trunk/samples/webloader/service/README.txt
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/service/README.txt?rev=644707&view=auto
==============================================================================
--- incubator/sling/trunk/samples/webloader/service/README.txt (added)
+++ incubator/sling/trunk/samples/webloader/service/README.txt Fri Apr  4 06:32:12 2008
@@ -0,0 +1,8 @@
+---------------------------------------
+Sling Webloader sample - OSGi service
+---------------------------------------
+This is the service component of the Webloader sample, this bundle provides
+a service according to the org.apache.sling.samples.webloader.Webloader
+interface.
+
+The sibling "webloader.ui" bundle provides an example user interface.

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

Added: incubator/sling/trunk/samples/webloader/service/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/service/pom.xml?rev=644707&view=auto
==============================================================================
--- incubator/sling/trunk/samples/webloader/service/pom.xml (added)
+++ incubator/sling/trunk/samples/webloader/service/pom.xml Fri Apr  4 06:32:12 2008
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  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>org.apache.sling.samples.webloader</artifactId>
+        <version>2.0.0-incubator-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.samples.webloader.service</artifactId>
+    <packaging>bundle</packaging>
+    <version>2.0.0-incubator-SNAPSHOT</version>
+
+    <name>Sling Webloader Service</name>
+    <description>
+        Sample OSGi service that retrieves documents from the Web using a Google
+        search, and stores them into the repository.
+    </description>
+
+    <scm>
+        <connection>
+            scm:svn:http://svn.apache.org/repos/asf/incubator/sling/trunk/samples/webloader/service
+        </connection>
+        <developerConnection>
+            scm:svn:https://svn.apache.org/repos/asf/incubator/sling/trunk/samples/webloader/service
+        </developerConnection>
+        <url>
+            http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/service
+        </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>
+                        <Export-Package>
+                            !org.apache.sling.samples.webloader.internal,
+                            org.apache.sling.samples.webloader.*
+                        </Export-Package>
+                        <Private-Package>
+                            org.apache.sling.samples.webloader.*
+                        </Private-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>${pom.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.jcr.api</artifactId>
+            <version>${pom.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.mime</artifactId>
+            <version>${pom.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+        </dependency>
+    </dependencies>
+</project>

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

Added: incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/Webloader.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/Webloader.java?rev=644707&view=auto
==============================================================================
--- incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/Webloader.java (added)
+++ incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/Webloader.java Fri Apr  4 06:32:12 2008
@@ -0,0 +1,41 @@
+/*
+ * 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.webloader;
+
+/** Gets documents from the Web via a Google query, and stores them into the
+ *  repository. The service interface is designed to be easy to use from Sling
+ *  scripts.
+ */  
+public interface Webloader {
+    /** Create a new job that loads documents in the repository, and start
+     *  it immediately 
+     *  @return the job ID
+     *  @param webQuery used to Google for documents to retrieve
+     *  @param storagePath documents are stored under this path in the repository
+     *  @param fileExtensions comma-separated list of extensions , each one 
+     *      is passed in turn to Google as a "filetype:" search option
+     *  @param maxDocsToRetrieve up to this many documents are stored
+     *  @param maxDocSizeInKb documents over this size are ignored, to speed up the process
+     */
+    String createJob(String webQuery, String storagePath, 
+            String fileExtensions, int maxDocsToRetrieve, int maxDocSizeInKb);
+    
+    /** Get the status of a job given its ID
+     *  @return null if the job doesn't exist
+     */
+    WebloaderJobStatus getJobStatus(String jobId);
+}

Propchange: incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/Webloader.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

Added: incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/WebloaderException.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/WebloaderException.java?rev=644707&view=auto
==============================================================================
--- incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/WebloaderException.java (added)
+++ incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/WebloaderException.java Fri Apr  4 06:32:12 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.
+ */
+package org.apache.sling.samples.webloader;
+
+import org.apache.sling.api.SlingException;
+
+/** Webloader-specific exception */
+@SuppressWarnings("serial")
+public class WebloaderException extends SlingException {
+    public WebloaderException(String reason) {
+        super(reason);
+    }
+    
+    public WebloaderException(String reason, Throwable cause) {
+        super(reason, cause);
+    }
+}

Propchange: incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/WebloaderException.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

Added: incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/WebloaderJobStatus.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/WebloaderJobStatus.java?rev=644707&view=auto
==============================================================================
--- incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/WebloaderJobStatus.java (added)
+++ incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/WebloaderJobStatus.java Fri Apr  4 06:32:12 2008
@@ -0,0 +1,36 @@
+/*
+ * 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.webloader;
+
+/** Provides status information about a Webloader job */
+public interface WebloaderJobStatus {
+    
+    /** Is this job still running? */
+    boolean isRunning();
+    
+    /** @return the error cause if the job aborted */ 
+    Throwable getError();
+    
+    /** Get the "main" status info, like "loading document foo.pdf"... */
+    String getStatusInfo();
+    
+    /** Get status details, like "19234 bytes loaded" */
+    String getStatusDetails();
+    
+    /** How many documents loaded by this job already? */
+    int getNumberOfDocumentsLoaded();
+}

Propchange: incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/WebloaderJobStatus.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

Added: incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/ProgressInputStream.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/ProgressInputStream.java?rev=644707&view=auto
==============================================================================
--- incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/ProgressInputStream.java (added)
+++ incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/ProgressInputStream.java Fri Apr  4 06:32:12 2008
@@ -0,0 +1,53 @@
+/*
+ * 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.webloader.internal;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/** InputStream that calls reportProgress during each read() call */
+public class ProgressInputStream extends FilterInputStream {
+
+    private final int length;
+
+    public ProgressInputStream(InputStream in, int length) {
+        super(in);
+        this.length = length;
+    }
+
+    public int read() throws IOException {
+        int r = super.read();
+        reportProgress(r, length);
+        return r;
+    }
+
+    public int read(byte b[]) throws IOException {
+        int r = super.read(b);
+        reportProgress(r, length);
+        return r;
+    }
+
+    public int read(byte b[], int off, int len) throws IOException {
+        int r = super.read(b, off, len);
+        reportProgress(r, length);
+        return r;
+    }
+
+    protected void reportProgress(int bytesRead, int totalBytesToRead) {
+    }
+}

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

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

Added: incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/WebLoaderImpl.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/WebLoaderImpl.java?rev=644707&view=auto
==============================================================================
--- incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/WebLoaderImpl.java (added)
+++ incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/WebLoaderImpl.java Fri Apr  4 06:32:12 2008
@@ -0,0 +1,94 @@
+/*
+ * 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.webloader.internal;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.sling.commons.mime.MimeTypeService;
+import org.apache.sling.samples.webloader.Webloader;
+import org.apache.sling.samples.webloader.WebloaderJobStatus;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** Webloader implementation, manages WebloaderJobs
+ *  
+ * @scr.service
+ *
+ * @scr.component
+ *  immediate="true"
+ *  metatype="false"
+ *
+ * @scr.property
+ *  name="service.description"
+ *  value="Sling Webloader service"
+ *
+ * @scr.property
+ *  name="service.vendor"
+ *  value="The Apache Software Foundation"
+ *
+ */
+public class WebLoaderImpl implements Webloader {
+    
+    private static final Logger log = LoggerFactory.getLogger(WebLoaderImpl.class);
+    
+    private final Map<String, WebloaderJob> jobs = new HashMap<String, WebloaderJob>();
+    
+    /** @scr.reference */
+    private SlingRepository repository;
+    
+    /** @scr.reference */
+    private MimeTypeService mimeTypeService;
+
+    /** @inheritDoc */
+    public String createJob(String webQuery, String storagePath, String 
+            fileExtensions, int maxDocsToRetrieve, int maxDocSizeInKb) {
+        deleteFinishedJobs();
+        final WebloaderJob j = new WebloaderJob(repository, mimeTypeService, 
+                webQuery, storagePath, fileExtensions, maxDocsToRetrieve, maxDocSizeInKb);
+        synchronized (jobs) {
+            jobs.put(j.getJobId(), j);
+        }
+        log.info("Created job {}", j);
+        return j.getJobId();
+    }
+
+    /** @inheritDoc */
+    public WebloaderJobStatus getJobStatus(String jobId) {
+        return jobs.get(jobId);
+    }
+
+    /** Remove finished jobs from our list of jobs */
+    protected void deleteFinishedJobs() {
+        final List<WebloaderJob> toDelete = new LinkedList<WebloaderJob>();
+        for(WebloaderJob j : jobs.values()) {
+            if(!j.isRunning()) {
+                toDelete.add(j);
+            }
+        }
+        
+        synchronized (jobs) {
+            for(WebloaderJob j : toDelete) {
+                jobs.remove(j.getJobId());
+            }
+        }
+    }
+
+}

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

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

Added: incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/WebloaderJob.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/WebloaderJob.java?rev=644707&view=auto
==============================================================================
--- incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/WebloaderJob.java (added)
+++ incubator/sling/trunk/samples/webloader/service/src/main/java/org/apache/sling/samples/webloader/internal/WebloaderJob.java Fri Apr  4 06:32:12 2008
@@ -0,0 +1,357 @@
+/*
+ * 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.webloader.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.html.HTML;
+import javax.swing.text.html.HTMLDocument;
+import javax.swing.text.html.HTMLEditorKit;
+
+import org.apache.sling.commons.mime.MimeTypeService;
+import org.apache.sling.samples.webloader.WebloaderException;
+import org.apache.sling.samples.webloader.WebloaderJobStatus;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** A Webloader job, manages retrieval of documents from the web and storage
+ *  in the Sling repository. This code is based on the "populate.jsp" example
+ *  of the jackrabbit-webapp module.
+ */ 
+class WebloaderJob extends Thread implements WebloaderJobStatus {
+    private Throwable error;
+    private int numDocsLoaded;
+    private final int maxDocsToRetrieve;
+    private final int maxDocSize;
+    private String statusInfo = "initialized";
+    private String statusDetails = "";
+    private boolean running = true;
+    private final String jobId;
+    private final String webQuery;
+    private String storagePath;
+    private final SlingRepository repository;
+    private final MimeTypeService mimeTypeService;
+    private Session session;
+    private Node storageRoot;
+    private static int idCounter;
+    private final String [] filetypes;
+    
+    public static final String [] DEFAULT_FILETYPES = { "pdf", "rtf", "ppt", "doc", "xls" };
+    public static final int URL_RETRIEVE_TIMEOUT_SECONDS = 10;
+    
+    private static final Logger log = LoggerFactory.getLogger(WebloaderJob.class);
+    
+    @SuppressWarnings("serial")
+    static class DocTooBigException extends IOException {
+        DocTooBigException(URL url, int size) {
+            super("Document at URL " + url + " too big (" + size + " bytes), will be ignored");
+        }
+    }
+    
+    WebloaderJob(SlingRepository repository, MimeTypeService mimeTypeService, 
+            String webQuery, String storagePath, String fileExtensions, int maxDocsToRetrieve, int maxDocSize) {
+        synchronized (WebloaderJob.class) {
+            jobId = String.valueOf(idCounter++);
+        }
+        
+        this.repository = repository;
+        this.mimeTypeService = mimeTypeService;
+        this.webQuery = webQuery;
+        this.storagePath = storagePath;
+        this.maxDocsToRetrieve = maxDocsToRetrieve;
+        this.maxDocSize = maxDocSize;
+        
+        final String [] ft = fileExtensions == null ? null : fileExtensions.split(",");
+        if(ft!=null && ft.length > 0) {
+            filetypes = new String[ft.length];
+            for(int i=0; i < ft.length; i++) {
+                filetypes[i] = ft[i].trim().toLowerCase();
+            }
+        } else {
+            filetypes = DEFAULT_FILETYPES;
+        }
+        
+        if(mimeTypeService == null) {
+            throw new WebloaderException("Missing MimeTypeService");
+        }
+        if(repository == null) {
+            throw new WebloaderException("Missing Repository");
+        }
+        
+        setDaemon(true);
+        start();
+    }
+    
+    @Override
+    public String toString() {
+        final StringBuffer sb = new StringBuffer();
+        for(String str : filetypes) {
+            if(sb.length() > 0) {
+                sb.append(",");
+            }
+            sb.append(str);
+        }
+        
+        return getClass().getSimpleName() + ", webQuery=" + webQuery 
+            + ", storagePath=" + storagePath
+            + ", fileTypes=" + sb.toString()
+            + ", maxDocsToRetrieve=" + maxDocsToRetrieve
+            + ", maxDocSize=" + maxDocSize
+        ;
+    }
+    
+    @Override
+    public void run() {
+        log.debug("Job thread starting: {}", this);
+        
+        // TODO should use a session provided by client, but can we use it
+        // safely for our async job?
+        session = null;
+        
+        if(storagePath.charAt(0) == '/') {
+            storagePath = storagePath.substring(1);
+        }
+        final String absStoragePath = "/" + storagePath;
+        
+        try {
+            session = repository.loginAdministrative(null);
+            if(session.itemExists(absStoragePath)) {
+                final Item i = session.getItem(absStoragePath);
+                if(i.isNode()) {
+                    storageRoot = (Node)i;
+                } else {
+                    throw new WebloaderException("Item at " + storagePath + " is not a Node");
+                }
+            } else {
+                // TODO deep-create hierarchy if needed
+                storageRoot = session.getRootNode().addNode(storagePath);
+                session.save();
+            }
+            
+            int offset = 0;
+            for(String type : filetypes) {
+                final URL[] urls = getDocumentUrlsFromGoogle(type, offset);
+                for(URL url : urls) {
+                    try {
+                        getAndStoreDocument(url);
+                        session.save();
+                        numDocsLoaded++;
+                        if(numDocsLoaded >= maxDocsToRetrieve) {
+                            break;
+                        }
+                    } catch(DocTooBigException dtb) {
+                        log.info(dtb.getMessage());
+                    } catch(Exception e) {
+                        log.warn("Exception while retrieving url " + url, e);
+                    } finally {
+                        session.refresh(false);
+                    }
+                }
+                offset += 10;
+                
+                if(numDocsLoaded >= maxDocsToRetrieve) {
+                    break;
+                }
+            }
+            
+            statusInfo = "All done.";
+            
+        } catch(Exception e) {
+            error = e;
+            log.warn("Exception in WebloaderJob.run()", e);
+            statusInfo = "Exception while running job: " + e;
+            
+        } finally {
+            if(session != null) {
+                session.logout();
+            }
+            statusDetails = "";
+            running = false;
+        }
+        
+        if(numDocsLoaded >= maxDocsToRetrieve) {
+            log.info("Stopped after retrieving maximum number of documents ({})", maxDocsToRetrieve);
+        }
+        
+        log.info("Job thread ends: {}, {} documents loaded", this, numDocsLoaded);
+    }
+    
+    private URL [] getDocumentUrlsFromGoogle(String currentFiletype, int start) throws IOException, BadLocationException {
+        final List urls = new ArrayList();
+        String query = webQuery + " filetype:" + currentFiletype;
+        final URL google = new URL("http://www.google.com/search?q=" +
+                URLEncoder.encode(query, "UTF-8") + "&start=" + start);
+        log.debug("Querying {}", google.toString());
+        statusInfo = "Querying " + google.toString();
+        statusDetails = "";
+        URLConnection con = google.openConnection();
+        con.setRequestProperty("User-Agent", "");
+        InputStream in = con.getInputStream();
+        try {
+            HTMLEditorKit kit = new HTMLEditorKit();
+            HTMLDocument doc = new HTMLDocument();
+            doc.putProperty("IgnoreCharsetDirective", Boolean.TRUE);
+            kit.read(new InputStreamReader(in, "UTF-8"), doc, 0);
+            HTMLDocument.Iterator it = doc.getIterator(HTML.Tag.A);
+            while (it.isValid()) {
+                if(it.getAttributes() != null) {
+                    String href = (String) it.getAttributes().getAttribute(HTML.Attribute.HREF);
+                    if (href != null && href.endsWith("." + currentFiletype)) {
+                        URL url = new URL(new URL("http", "www.google.com", "dummy"), href);
+                        if (url.getHost().indexOf("google") == -1) {
+                            log.debug("Got document URL from google: {}", url);
+                            statusDetails = "Got URL " + url;
+                            urls.add(url);
+                        }
+                    }
+                }
+                it.next();
+            }
+        } finally {
+            in.close();
+        }
+        return (URL[]) urls.toArray(new URL[urls.size()]);
+
+    }
+    
+    private void getAndStoreDocument(URL currentURL) throws RepositoryException, IOException {
+
+        statusInfo = "Retrieving document " + currentURL;
+        statusDetails = "";
+        
+        // build JCR path for storing document, based on its URL
+        String path = currentURL.getPath();
+        if (path.startsWith("/")) {
+            path = path.substring(1);
+        }
+        final String host = currentURL.getHost();
+        final List folderNames = new ArrayList();
+        folderNames.addAll(Arrays.asList(host.split("\\.")));
+        Collections.reverse(folderNames);
+        folderNames.addAll(Arrays.asList(path.split("/", 0)));
+        final String filename = URLDecoder.decode((String) folderNames.remove(folderNames.size() - 1), "UTF-8").replaceAll(":", "_");
+        Node node = storageRoot;
+        for (Iterator fn = folderNames.iterator(); fn.hasNext(); ) {
+            String name = URLDecoder.decode((String) fn.next(), "UTF-8");
+            name = name.replaceAll(":", "_");
+            if (name.length() == 0) {
+                continue;
+            }
+            if (!node.hasNode(name)) {
+                node.addNode(name, "nt:folder");
+            }
+            node = node.getNode(name);
+        }
+        
+        log.debug("Retrieving document {}, will be stored at {}", currentURL, node.getPath() + "/" + filename);
+        
+        if (!node.hasNode(filename)) {
+            Node file = node.addNode(filename, "nt:file");
+            final Node resource = file.addNode("jcr:content", "nt:resource");
+            getAndStoreContent(currentURL, resource, filename);
+        }
+
+    }
+    
+    private void getAndStoreContent(URL currentURL, Node resource, String filename) 
+    throws RepositoryException, IOException {
+        statusInfo = "Retrieving content from " + currentURL;
+        statusDetails = "";
+        
+        final URLConnection con = currentURL.openConnection();
+        con.setReadTimeout(URL_RETRIEVE_TIMEOUT_SECONDS * 1000);
+        InputStream in = con.getInputStream();
+        try {
+            // Read with a ProgressInputStream, so that our status is updated while
+            // downloading
+            int length = con.getContentLength();
+            if (length != -1) {
+                if(length > maxDocSize * 1024) {
+                    throw new DocTooBigException(currentURL, length);
+                }
+                in = new ProgressInputStream(in, length) {
+                    int nextReport = 0;
+                    protected void reportProgress(int bytesRead, int totalBytesToRead) {
+                        if(bytesRead > nextReport) {
+                            nextReport += 1024;
+                            statusDetails = "Downloaded " + bytesRead + " bytes out of " + totalBytesToRead;
+                        }
+                    }
+                };
+            }
+            
+            resource.setProperty("jcr:data", in);
+            final String mimeType = mimeTypeService.getMimeType(filename);
+            resource.setProperty("jcr:mimeType", mimeType);
+            final Calendar lastModified = Calendar.getInstance();
+            lastModified.setTimeInMillis(con.getLastModified());
+            resource.setProperty("jcr:lastModified", lastModified);
+        } finally {
+            if(in != null) {
+                in.close();
+            }
+        }
+    }
+    
+    String getJobId() {
+        return jobId;
+    }
+    
+    /** {@inheritDoc} */
+    public Throwable getError() {
+        return error;
+    }
+
+    /** {@inheritDoc} */
+    public int getNumberOfDocumentsLoaded() {
+        return numDocsLoaded;
+    }
+
+    /** {@inheritDoc} */
+    public String getStatusInfo() {
+        return statusInfo;
+    }
+
+    /** {@inheritDoc} */
+    public String getStatusDetails() {
+        return statusDetails;
+    }
+
+    /** {@inheritDoc} */
+    public boolean isRunning() {
+        return running;
+    }
+
+}

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

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

Propchange: incubator/sling/trunk/samples/webloader/ui/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Apr  4 06:32:12 2008
@@ -0,0 +1,9 @@
+target
+bin
+*.iml
+*.ipr
+*.iws
+.settings
+.project
+.classpath
+.externalToolBuilders

Added: incubator/sling/trunk/samples/webloader/ui/README.txt
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/ui/README.txt?rev=644707&view=auto
==============================================================================
--- incubator/sling/trunk/samples/webloader/ui/README.txt (added)
+++ incubator/sling/trunk/samples/webloader/ui/README.txt Fri Apr  4 06:32:12 2008
@@ -0,0 +1,6 @@
+---------------------------------------
+Sling Webloader sample - user interface
+---------------------------------------
+After loading the sibling "webloader.service" bundle and this bundle,
+http://localhost:8888/bin/sling/webloader.html should display the "Sling
+Webloader" page, that gives access to the Webloader service. 

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

Added: incubator/sling/trunk/samples/webloader/ui/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/ui/pom.xml?rev=644707&view=auto
==============================================================================
--- incubator/sling/trunk/samples/webloader/ui/pom.xml (added)
+++ incubator/sling/trunk/samples/webloader/ui/pom.xml Fri Apr  4 06:32:12 2008
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  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>org.apache.sling.samples.webloader</artifactId>
+        <version>2.0.0-incubator-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.samples.webloader.ui</artifactId>
+    <packaging>bundle</packaging>
+    <version>2.0.0-incubator-SNAPSHOT</version>
+
+    <name>Sling Webloader User Interface</name>
+    <description>
+        Simple user interface for the Sling Webloader service.
+    </description>
+
+    <scm>
+        <connection>
+            scm:svn:http://svn.apache.org/repos/asf/incubator/sling/trunk/samples/webloader/ui
+        </connection>
+        <developerConnection>
+            scm:svn:https://svn.apache.org/repos/asf/incubator/sling/trunk/samples/webloader/ui
+        </developerConnection>
+        <url>
+            http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/ui
+        </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>
+</project>

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

Added: incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/ROOT.xjson
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/ROOT.xjson?rev=644707&view=auto
==============================================================================
--- incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/ROOT.xjson (added)
+++ incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/ROOT.xjson Fri Apr  4 06:32:12 2008
@@ -0,0 +1,12 @@
+{
+	"bin" : {
+	    "jcr:primaryType" : "nt:unstructured",
+	    "sling" : {
+		    "jcr:primaryType" : "nt:unstructured",
+		    "webloader" : {
+			    "jcr:primaryType" : "nt:unstructured",
+			    "sling:resourceType" : "sling/webloader"
+		    }
+	    }
+	}
+}

Added: incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/apps/sling/webloader/POST.esp
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/apps/sling/webloader/POST.esp?rev=644707&view=auto
==============================================================================
--- incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/apps/sling/webloader/POST.esp (added)
+++ incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/apps/sling/webloader/POST.esp Fri Apr  4 06:32:12 2008
@@ -0,0 +1,61 @@
+<%
+/*
+ * 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.
+ */
+%>
+
+<% /*
+	Webloader POST processing: create a new job and redirect to its status page
+*/ %>
+
+<%
+  var loader = sling.getService(Packages.org.apache.sling.samples.webloader.Webloader);
+  
+  var webQuery = request.getParameter("webQuery");
+  var storagePath = request.getParameter("storagePath");
+  var maxDocsToRetrieve = request.getParameter("maxDocsToRetrieve");
+  var maxDocSize = request.getParameter("maxDocSize");
+  var fileTypes = request.getParameter("fileTypes"); 
+  
+  if(!webQuery) {
+    response.sendError(400, "required parameter missing: webQuery");
+  }
+  if(!storagePath) {
+  	storagePath = "/webloader";
+  }
+  if(!maxDocsToRetrieve) {
+  	maxDocsToRetrieve = 25;
+  }
+  if(!maxDocSize) {
+    maxDocSize = 512;
+  }
+  
+  var jobId = loader.createJob(webQuery, storagePath, fileTypes, maxDocsToRetrieve, maxDocSize);
+  
+  var statusPath = 
+  	request.getContextPath() 
+  	+ request.getRequestPathInfo().getResourcePath()
+  	+ "." + jobId + ".html" 
+  ;
+  
+  var status = loader.getJobStatus(jobId);
+  
+  if(status==null) {
+    response.sendError(500, "Webloader status not available (or not anymore) for job " + jobId);
+  }
+  
+  response.sendRedirect(statusPath);
+%>

Added: incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/apps/sling/webloader/html.esp
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/apps/sling/webloader/html.esp?rev=644707&view=auto
==============================================================================
--- incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/apps/sling/webloader/html.esp (added)
+++ incubator/sling/trunk/samples/webloader/ui/src/main/resources/initial-content/apps/sling/webloader/html.esp Fri Apr  4 06:32:12 2008
@@ -0,0 +1,156 @@
+<%
+/*
+ * 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.
+ */
+%>
+
+<% /*
+	Webloader GET request processing
+	Display a form to create new jobs, or, if a selector is given, display 
+	the status of that job
+*/ %>
+
+<%  
+  // get job ID from selectors, for example webloader.5.html displays status of job 5
+  var jobId = null;
+  var selectors = request.getRequestPathInfo().getSelectors();
+  if(selectors.length > 0) {
+    jobId = selectors[0];
+  }
+  
+  var loader = sling.getService(Packages.org.apache.sling.samples.webloader.Webloader);
+  var status = loader.getJobStatus(jobId);
+  var running = status!=null && status.isRunning();
+%>
+
+<%
+function showForm() {
+  %>
+  <hr/>
+  <h2>Create a new webloader job</h2>
+  <form method="POST">
+    <table>
+      <tr>
+        <td>
+        	Web query to use to select documents:
+        </td>
+        <td>
+        	<input type="text" name="webQuery" size="60" value="drums"/>
+        </td>
+      </tr>
+      <tr>
+        <td>
+        	Storage path for retrieved documents:
+        </td>
+        <td>
+        	<input type="text" name="storagePath" size="60" value="/webloader"/>
+        </td>
+      </tr>
+      <tr>
+        <td>
+        	Maximum number of documents to retrieve:
+        </td>
+        <td>
+        	<input type="text" name="maxDocsToRetrieve" value="25"/>
+        </td>
+      </tr>
+      <tr>
+        <td>
+        	Maximum size of a single document in kilobytes:
+        </td>
+        <td>
+        	<input type="text" name="maxDocSize" value="512"/>
+        </td>
+      </tr>
+      <tr>
+        <td>
+        	Comma-separated list of file types to consider (empty=default):
+        </td>
+        <td>
+        	<input type="text" name="fileTypes" size="60" value="pdf, rtf, ppt, doc, xls"/>
+        </td>
+      </tr>
+    </table>
+    <input type="submit"/>
+  </form>
+  <%
+}
+%>
+
+<%
+function showStatus() {
+  if(status==null) {
+    response.sendError(404, "Webloader status not available (or not anymore) for job " + jobId);
+  }
+  var statusString = status.isRunning() ? "running" : "done";
+  %>
+  <hr/>
+  <h2>Webloader job <%= jobId + " " + statusString %></h2>
+  
+  <p>
+    Job info: <b><%= status %></b>.
+  </p>
+  <p>
+  	  <b><%= status.statusInfo %></b>
+  	  ,
+  	  <em><%= status.statusDetails %></em>
+  </p>
+  <p>
+    <b><%= status.numberOfDocumentsLoaded %></b> documents have been loaded.
+  </p>
+  <%
+}
+%>
+
+<%
+  var autoRefresh = status!=null && status.isRunning(); 
+%>
+
+<html>
+  <head>
+    <link type="text/css" rel="stylesheet" href="/sling/res/ui/admin.css">
+    <% if(autoRefresh) { %>
+      <meta http-equiv="refresh" content="1"/>
+    <% } %>
+  </head>
+  <body>
+    <div id="main">
+      <h1>Sling Webloader</h1>
+      
+      <% if(autoRefresh) { %>
+      <p>
+      	This page <b>reloads itself</b> automatically every second, while the webloader job is running.
+      </p>
+      <% } %>
+      
+      <p>
+      	This example application retrieves documents from the Web using
+      	a Google query, and loads them in the repository. It is based on the
+      	the Jackrabbit <em>populate.jsp</em> example, ported to Sling.
+      </p>
+      
+	    <%
+		  if(status!=null) {
+		    showStatus();
+		  }
+		  
+		  if(!running) {
+		    showForm();
+		  }
+		%>
+    </div>
+  </body>
+</html>