This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.fsresource-0.9.2-incubator in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-fsresource.git
commit ae86586288512ca31da9904ed5f540f5d7a942d5 Author: Felix Meschberger <[email protected]> AuthorDate: Thu Jun 18 09:21:02 2009 +0000 Move Sling to new TLP location git-svn-id: https://svn.eu.apache.org/repos/asf/sling/tags/org.apache.sling.fsresource-0.9.2-incubator@785979 13f79535-47bb-0310-9956-ffa450edef68 --- LICENSE | 202 ++++++++++++++ NOTICE | 8 + pom.xml | 101 +++++++ .../sling/fsprovider/internal/FsFolderServlet.java | 161 +++++++++++ .../fsprovider/internal/FsProviderConstants.java | 46 ++++ .../sling/fsprovider/internal/FsResource.java | 164 ++++++++++++ .../fsprovider/internal/FsResourceProvider.java | 294 +++++++++++++++++++++ src/main/resources/META-INF/DISCLAIMER | 7 + src/main/resources/META-INF/LICENSE | 202 ++++++++++++++ src/main/resources/META-INF/NOTICE | 8 + .../OSGI-INF/metatype/metatype.properties | 40 +++ 11 files changed, 1233 insertions(+) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..7a727bf --- /dev/null +++ b/NOTICE @@ -0,0 +1,8 @@ +Apache Sling File System Resource Provider +Copyright 2008-2009 The Apache Software Foundation + +Apache Sling is based on source code originally developed +by Day Software (http://www.day.com/). + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..87d1d03 --- /dev/null +++ b/pom.xml @@ -0,0 +1,101 @@ +<?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>5-incubator</version> + <relativePath>../../parent/pom.xml</relativePath> + </parent> + + <artifactId>org.apache.sling.fsresource</artifactId> + <packaging>bundle</packaging> + <version>0.9.2-incubator</version> + + <name>Apache Sling Filesystem Resource Provider</name> + <description> + Provides a ResourceProvider implementation supporting filesystem + based resources. + </description> + + <scm> + <connection>scm:svn:http://svn.apache.org/repos/asf/incubator/sling/tags/org.apache.sling.fsresource-0.9.2-incubator</connection> + <developerConnection>scm:svn:https://svn.apache.org/repos/asf/incubator/sling/tags/org.apache.sling.fsresource-0.9.2-incubator</developerConnection> + <url>http://svn.apache.org/viewvc/incubator/sling/tags/org.apache.sling.fsresource-0.9.2-incubator</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> + <Private-Package> + org.apache.sling.fsprovider.internal + </Private-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + </dependency> + <dependency> + <groupId>javax.jcr</groupId> + <artifactId>jcr</artifactId> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.api</artifactId> + <version>2.0.2-incubator</version> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.adapter</artifactId> + <version>2.0.2-incubator</version> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.osgi.core</artifactId> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.osgi.compendium</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + </dependencies> +</project> diff --git a/src/main/java/org/apache/sling/fsprovider/internal/FsFolderServlet.java b/src/main/java/org/apache/sling/fsprovider/internal/FsFolderServlet.java new file mode 100644 index 0000000..784e9cf --- /dev/null +++ b/src/main/java/org/apache/sling/fsprovider/internal/FsFolderServlet.java @@ -0,0 +1,161 @@ +/* + * 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.fsprovider.internal; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Date; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceNotFoundException; +import org.apache.sling.api.resource.ResourceUtil; +import org.apache.sling.api.servlets.SlingSafeMethodsServlet; + +/** + * The <code>FsFolderServlet</code> lists the files and folders of a folder + * mapped into the Sling resource tree. The listing produced is similar to the + * default index listing produced by Apache httpd. + * + * @scr.component immediate="true" metatype="no" + * @scr.service interface="javax.servlet.Servlet" + * @scr.property name="service.description" value="FileSystem Folder Servlet" + * @scr.property name="service.vendor" value="The Apache Software Foundation" + * @scr.property name="sling.servlet.methods" value="GET" + * @scr.property name="sling.servlet.resourceTypes" + * valueRef="FsProviderConstants.RESOURCE_TYPE_FOLDER" + */ +public class FsFolderServlet extends SlingSafeMethodsServlet { + + // a number of blanks used to format the listing of folder entries + private static final String NAME_BLANKS = " "; + + @Override + protected void doGet(SlingHttpServletRequest request, + SlingHttpServletResponse response) throws IOException { + + // if the request URL is not terminated with a slash, redirect to the + // same URL with a trailing slash (this makes preparing the response + // easier + if (!request.getRequestURI().endsWith("/")) { + response.sendRedirect(request.getRequestURL() + "/"); + return; + } + + // ensure the resource adapts to a filesystem folder; generally + // this should be the case, but we never know whether someone really + // creates a JCR resource with the fs provider folder resource type + Resource res = request.getResource(); + File file = res.adaptTo(File.class); + if (file == null || !file.isDirectory()) { + throw new ResourceNotFoundException( + request.getResource().getPath(), + "Resource is not a file system folder"); + } + + response.setContentType("text/html"); + response.setCharacterEncoding("UTF-8"); + PrintWriter pw = response.getWriter(); + + pw.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\"> <html>"); + + pw.printf("<head><title>Index of %s</title></head><body>%n", + res.getPath()); + pw.printf("<h1>Index of %s</h1>%n", res.getPath()); + + pw.println("<pre>"); + pw.println("Name Last modified Size Description"); + pw.println("<hr>"); + + // only draw parent link if the parent is also a fs resource + Resource parent = ResourceUtil.getParent(res); + if (parent != null && parent.adaptTo(File.class) != null) { + pw.println("<a href='..'>Parent Directory</a>"); + } + + // render the children + renderChildren(pw, file); + + pw.println("</pre>"); + pw.println("</body></html>"); + } + + // ---------- internal + + /** + * Renders the children of the <code>parent</code> folder to the output. + */ + private void renderChildren(PrintWriter pw, File parent) { + File[] children = parent.listFiles(); + if (children != null && children.length > 0) { + Arrays.sort(children, FileNameComparator.INSTANCE); + + for (File child : children) { + + String name = child.getName(); + if (child.isDirectory()) { + name = name.concat("/"); + } + + String displayName = name; + if (displayName.length() >= 32) { + displayName = displayName.substring(0, 29).concat("..."); + pw.printf("<a href='%s'>%s</a>", name, displayName); + } else { + String blanks = NAME_BLANKS.substring(0, + 32 - displayName.length()); + pw.printf("<a href='%s'>%s</a>%s", name, displayName, + blanks); + } + + pw.print(" " + new Date(child.lastModified())); + + pw.print(" "); + if (child.isFile()) { + pw.print(child.length()); + } else { + pw.print("-"); + } + + pw.println(); + } + } + } + + // order files by type (folder before files) and name (case insensitive) + private static class FileNameComparator implements Comparator<File> { + + public static final FileNameComparator INSTANCE = new FileNameComparator(); + + public int compare(File f1, File f2) { + if (f1.isDirectory() && !f2.isDirectory()) { + return -1; + } else if (!f1.isDirectory() && f2.isDirectory()) { + return 1; + } + + return f1.getName().compareToIgnoreCase(f2.getName()); + } + } + +} diff --git a/src/main/java/org/apache/sling/fsprovider/internal/FsProviderConstants.java b/src/main/java/org/apache/sling/fsprovider/internal/FsProviderConstants.java new file mode 100644 index 0000000..96e3db6 --- /dev/null +++ b/src/main/java/org/apache/sling/fsprovider/internal/FsProviderConstants.java @@ -0,0 +1,46 @@ +/* + * 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.fsprovider.internal; + +/** + * The <code>FsProviderConstants</code> interface defines public constants for + * the {@link FsResourceProvider}. + */ +public interface FsProviderConstants { + + /** + * The common resource super type for files and folders mapped into the + * resource tree by the {@link FsResourceProvider} (value is + * "sling/fs/resource"). + */ + static final String RESOURCE_TYPE_ROOT = "sling/fs/resource"; + + /** + * The resource type for file system files mapped into the resource tree by + * the {@link FsResourceProvider} (value is "sling/fs/file"). + */ + static final String RESOURCE_TYPE_FILE = "sling/fs/file"; + + /** + * The resource type for file system folders mapped into the resource tree + * by the {@link FsResourceProvider} (value is "sling/fs/folder"). + */ + static final String RESOURCE_TYPE_FOLDER = "sling/fs/folder"; + +} diff --git a/src/main/java/org/apache/sling/fsprovider/internal/FsResource.java b/src/main/java/org/apache/sling/fsprovider/internal/FsResource.java new file mode 100644 index 0000000..ee3d567 --- /dev/null +++ b/src/main/java/org/apache/sling/fsprovider/internal/FsResource.java @@ -0,0 +1,164 @@ +/* + * 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.fsprovider.internal; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; + +import org.apache.sling.adapter.SlingAdaptable; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceMetadata; +import org.apache.sling.api.resource.ResourceResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The <code>FsResource</code> represents a file system file or folder as + * a Sling Resource. + */ +public class FsResource extends SlingAdaptable implements Resource { + + // default log, assigned on demand + private Logger log; + + // the owning resource resolver + private final ResourceResolver resolver; + + // the path of this resource in the resource tree + private final String resourcePath; + + // the file wrapped by this instance + private final File file; + + // the resource type, assigned on demand + private String resourceType; + + // the resource metadata, assigned on demand + private ResourceMetadata metaData; + + /** + * Creates an instance of this Filesystem resource. + * + * @param resolver The owning resource resolver + * @param resourcePath The resource path in the resource tree + * @param file The wrapped file + */ + FsResource(ResourceResolver resolver, String resourcePath, File file) { + this.resolver = resolver; + this.resourcePath = resourcePath; + this.file = file; + } + + /** + * Returns the path of this resource + */ + public String getPath() { + return resourcePath; + } + + /** + * Returns the resource meta data for this resource containing the file + * length, last modification time and the resource path (same as + * {@link #getPath()}). + */ + public ResourceMetadata getResourceMetadata() { + if (metaData == null) { + metaData = new ResourceMetadata(); + metaData.setContentLength(file.length()); + metaData.setModificationTime(file.lastModified()); + metaData.setResolutionPath(resourcePath); + } + return metaData; + } + + /** + * Returns the resource resolver which cause this resource object to be + * created. + */ + public ResourceResolver getResourceResolver() { + return resolver; + } + + /** + * Returns {@link FsProviderConstants#RESOURCE_TYPE_ROOT} + */ + public String getResourceSuperType() { + return FsProviderConstants.RESOURCE_TYPE_ROOT; + } + + /** + * Returns {@link FsProviderConstants#RESOURCE_TYPE_FILE} if this resource + * wraps a file. Otherwise {@link FsProviderConstants#RESOURCE_TYPE_FOLDER} + * is returned. + */ + public String getResourceType() { + if (resourceType == null) { + resourceType = file.isFile() + ? FsProviderConstants.RESOURCE_TYPE_FILE + : FsProviderConstants.RESOURCE_TYPE_FOLDER; + } + + return resourceType; + } + + /** + * Returns an adapter for this resource. This implementation supports + * <code>File</code>, <code>InputStream</code> and <code>URL</code> + * plus those supported by the adapter manager. + */ + @SuppressWarnings("unchecked") + public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) { + if (type == File.class) { + + return (AdapterType) file; + + } else if (type == InputStream.class && file.canRead()) { + + try { + return (AdapterType) new FileInputStream(file); + } catch (IOException ioe) { + getLog().info("Cannot open a stream on the file " + file, ioe); + } + + } else if (type == URL.class) { + + try { + return (AdapterType) file.toURI().toURL(); + } catch (MalformedURLException mue) { + getLog().info( + "Cannot convert the file path " + file + " to an URL", mue); + } + } + + return super.adaptTo(type); + } + + // ---------- internal + + private Logger getLog() { + if (log == null) { + log = LoggerFactory.getLogger(getClass()); + } + return log; + } +} diff --git a/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java b/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java new file mode 100644 index 0000000..0bc19e5 --- /dev/null +++ b/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java @@ -0,0 +1,294 @@ +/* + * 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.fsprovider.internal; + +import java.io.File; +import java.util.Collections; +import java.util.Dictionary; +import java.util.Iterator; +import java.util.NoSuchElementException; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.servlet.http.HttpServletRequest; + +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceProvider; +import org.apache.sling.api.resource.ResourceResolver; +import org.osgi.framework.BundleContext; +import org.osgi.service.component.ComponentContext; + +/** + * The <code>FsResourceProvider</code> is a resource provider which maps + * filesystem files and folders into the virtual resource tree. The provider is + * implemented in terms of a component factory, that is multiple instances of + * this provider may be created by creating respective configuration. + * <p> + * Each provider instance is configured with to properties: The location in the + * resource tree where resources are provided ({@link ResourceProvider#ROOTS}) + * and the file system path from where files and folders are mapped into the + * resource ({@link #PROP_PROVIDER_FILE}). + * + * @scr.component name="org.apache.sling.fsprovider.internal.FsResourceProvider" + * label="%resource.resolver.name" + * description="%resource.resolver.description" + * factory="org.apache.sling.fsprovider.internal.FsResourceProviderFactory" + * @scr.service + * @scr.property name="service.description" value="Sling Filesystem Resource + * Provider" + * @scr.property name="service.vendor" value="The Apache Software Foundation" + * @scr.property nameRef="ResourceProvider.ROOTS" + * @scr.property nameRef="PROP_PROVIDER_FILE" + */ +public class FsResourceProvider implements ResourceProvider { + + /** + * The name of the configuration property providing file system path of + * files and folders mapped into the resource tree (value is + * "provider.file"). + */ + public static final String PROP_PROVIDER_FILE = "provider.file"; + + // The location in the resource tree where the resources are mapped + private String providerRoot; + + // providerRoot + "/" to be used for prefix matching of paths + private String providerRootPrefix; + + // The "root" file or folder in the file system + private File providerFile; + + /** + * Same as {@link #getResource(ResourceResolver, String)}, i.e. the + * <code>request</code> parameter is ignored. + * + * @see #getResource(ResourceResolver, String) + */ + public Resource getResource(ResourceResolver resourceResolver, + HttpServletRequest request, String path) { + return getResource(resourceResolver, path); + } + + /** + * Returns a resource wrapping a filesystem file or folder for the given + * path. If the <code>path</code> is equal to the configured resource tree + * location of this provider, the configured file system file or folder is + * used for the resource. Otherwise the configured resource tree location + * prefix is removed from the path and the remaining relative path is used + * to access the file or folder. If no such file or folder exists, this + * method returns <code>null</code>. + */ + public Resource getResource(ResourceResolver resourceResolver, String path) { + return getResource(resourceResolver, path, getFile(path)); + } + + /** + * Returns an iterator of resources. + */ + public Iterator<Resource> listChildren(Resource parent) { + File parentFile = parent.adaptTo(File.class); + + // not a FsResource, try to create one from the resource + if (parentFile == null) { + // if the parent path is at or below the provider root, get + // the respective file + parentFile = getFile(parent.getPath()); + + // if the parent path is actually the parent of the provider + // root, return a single element iterator just containing the + // provider file, unless the provider file is a directory and + // a repository item with the same path actually exists + if (parentFile == null) { + + String parentPath = parent.getPath().concat("/"); + if (providerRoot.startsWith(parentPath)) { + String relPath = providerRoot.substring(parentPath.length()); + if (relPath.indexOf('/') < 0) { + Resource res = getResource( + parent.getResourceResolver(), providerRoot, + providerFile); + if (res != null) { + return Collections.singletonList(res).iterator(); + } + } + } + + // no children here + return null; + } + } + + final File[] children = parentFile.listFiles(); + + if (children != null && children.length > 0) { + final ResourceResolver resolver = parent.getResourceResolver(); + final String parentPath = parent.getPath(); + return new Iterator<Resource>() { + int index = 0; + + Resource next = seek(); + + public boolean hasNext() { + return next != null; + } + + public Resource next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + + Resource result = next; + next = seek(); + return result; + } + + public void remove() { + throw new UnsupportedOperationException("remove"); + } + + private Resource seek() { + while (index < children.length) { + File file = children[index++]; + String path = parentPath + "/" + file.getName(); + Resource result = getResource(resolver, path, file); + if (result != null) { + return result; + } + } + + // nothing found any more + return null; + } + }; + } + + // no children + return null; + } + + // ---------- SCR Integration + + protected void activate(ComponentContext context) { + Dictionary<?, ?> props = context.getProperties(); + + String providerRoot = (String) props.get(ROOTS); + if (providerRoot == null || providerRoot.length() == 0) { + throw new IllegalArgumentException(ROOTS + " property must be set"); + } + + String providerFileName = (String) props.get(PROP_PROVIDER_FILE); + if (providerFileName == null || providerFileName.length() == 0) { + throw new IllegalArgumentException(PROP_PROVIDER_FILE + + " property must be set"); + } + + this.providerRoot = providerRoot; + this.providerRootPrefix = providerRoot.concat("/"); + this.providerFile = getProviderFile(providerFileName, + context.getBundleContext()); + } + + protected void deactivate(ComponentContext context) { + this.providerRoot = null; + this.providerRootPrefix = null; + this.providerFile = null; + } + + // ---------- internal + + private File getProviderFile(String providerFileName, + BundleContext bundleContext) { + + // the file object from the plain name + File providerFile = new File(providerFileName); + + // resolve relative file name against sling.home or current + // working directory + if (!providerFile.isAbsolute()) { + String home = bundleContext.getProperty("sling.home"); + if (home != null && home.length() > 0) { + providerFile = new File(home, providerFileName); + } + } + + // resolve the path + providerFile = providerFile.getAbsoluteFile(); + + // if the provider file does not exist, create an empty new folder + if (!providerFile.exists() && !providerFile.mkdirs()) { + throw new IllegalArgumentException( + "Cannot create provider file root " + providerFile); + } + + return providerFile; + } + + /** + * Returns a file corresponding to the given absolute resource tree path. If + * the path equals the configured provider root, the provider root file is + * returned. If the path starts with the configured provider root, a file is + * returned relative to the provider root file whose relative path is the + * remains of the resource tree path without the provider root path. + * Otherwise <code>null</code> is returned. + */ + private File getFile(String path) { + if (path.equals(providerRoot)) { + return providerFile; + } + + if (path.startsWith(providerRootPrefix)) { + String relPath = path.substring(providerRootPrefix.length()); + return new File(providerFile, relPath); + } + + return null; + } + + private Resource getResource(ResourceResolver resourceResolver, + String resourcePath, File file) { + + if (file != null) { + + // if the file is a directory, and a repository item exists for + // the path, do not return the directory here + if (file.isDirectory()) { + Session session = resourceResolver.adaptTo(Session.class); + if (session != null) { + try { + if (session.itemExists(resourcePath)) { + return null; + } + } catch (RepositoryException re) { + // don't care + } + } + } + + // if the file exists, but is not a directory or no repository entry + // exists, return it as a resource + if (file.exists()) { + return new FsResource(resourceResolver, resourcePath, file); + } + + } + + // not applicable or not an existing file path + return null; + } +} diff --git a/src/main/resources/META-INF/DISCLAIMER b/src/main/resources/META-INF/DISCLAIMER new file mode 100644 index 0000000..90850c2 --- /dev/null +++ b/src/main/resources/META-INF/DISCLAIMER @@ -0,0 +1,7 @@ +Apache Sling is an effort undergoing incubation at The Apache Software Foundation (ASF), +sponsored by the Apache Jackrabbit PMC. Incubation is required of all newly accepted +projects until a further review indicates that the infrastructure, communications, +and decision making process have stabilized in a manner consistent with other +successful ASF projects. While incubation status is not necessarily a reflection of +the completeness or stability of the code, it does indicate that the project has yet +to be fully endorsed by the ASF. \ No newline at end of file diff --git a/src/main/resources/META-INF/LICENSE b/src/main/resources/META-INF/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/src/main/resources/META-INF/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. diff --git a/src/main/resources/META-INF/NOTICE b/src/main/resources/META-INF/NOTICE new file mode 100644 index 0000000..7a727bf --- /dev/null +++ b/src/main/resources/META-INF/NOTICE @@ -0,0 +1,8 @@ +Apache Sling File System Resource Provider +Copyright 2008-2009 The Apache Software Foundation + +Apache Sling is based on source code originally developed +by Day Software (http://www.day.com/). + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). diff --git a/src/main/resources/OSGI-INF/metatype/metatype.properties b/src/main/resources/OSGI-INF/metatype/metatype.properties new file mode 100644 index 0000000..06ec635 --- /dev/null +++ b/src/main/resources/OSGI-INF/metatype/metatype.properties @@ -0,0 +1,40 @@ +# +# 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. +# + + +# +# This file contains localization strings for configuration labels and +# descriptions as used in the metatype.xml descriptor generated by the +# the SCR plugin + +# +# Localizations for FsResourceProvider configuration +resource.resolver.name = Apache Sling Filesystem Resource Provider +resource.resolver.description = Configure an instance of the filesystem \ + resource provider in terms of provider root and filesystem location + +provider.roots.name = Provider Root +provider.roots.description = Location in the virtual resource tree where the \ + filesystem resources are mapped in. This property must not be an empty string. +provider.file.name = Filesystem Root +provider.file.description = Filesystem directory mapped to the virtual \ + resource tree. This property must not be an empty string. If the path is \ + relative it is resolved against sling.home or the current working directory. \ + The path may be a file or folder. If the path does not address an existing \ + file or folder, an empty folder is created. -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
