Move Sling to new TLP location
git-svn-id: https://svn.eu.apache.org/repos/asf/sling/tags/org.apache.sling.jcr.jackrabbit.server-2.0.2-incubator@785979 13f79535-47bb-0310-9956-ffa450edef68
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..5e34972
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,8 @@
+Apache Sling JCR Jackrabbit Server
+Copyright 2008 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/README.txt b/README.txt
new file mode 100644
index 0000000..188b1e7
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,38 @@
+Apache Sling JCR Jackrabbit Server
+
+Bundle providing support to embed Jackrabbit Repository
+instances and publish via RMI and/or JNDI
+
+Disclaimer
+==========
+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.
+
+Getting Started
+===============
+
+This component uses a Maven 2 (http://maven.apache.org/) build
+environment. It requires a Java 5 JDK (or higher) and Maven (http://maven.apache.org/)
+2.0.7 or later. We recommend to use the latest Maven version.
+
+If you have Maven 2 installed, you can compile and
+package the jar using the following command:
+
+ mvn package
+
+See the Maven 2 documentation for other build features.
+
+The latest source code for this component is available in the
+Subversion (http://subversion.tigris.org/) source repository of
+the Apache Software Foundation. If you have Subversion installed,
+you can checkout the latest source using the following command:
+
+ svn checkout http://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/jackrabbit-server
+
+See the Subversion documentation for other source control features.
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..0fa6edf
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,217 @@
+<?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>3-incubator</version>
+ <relativePath>../../parent/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>org.apache.sling.jcr.jackrabbit.server</artifactId>
+ <packaging>bundle</packaging>
+ <version>2.0.2-incubator</version>
+
+ <name>Sling - Jackrabbit Embedded Repository</name>
+ <description>
+ Bundle providing support to embed Jackrabbit Repository
+ instances and publish via RMI and/or JNDI
+ </description>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/incubator/sling/tags/org.apache.sling.jcr.jackrabbit.server-2.0.2-incubator</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/incubator/sling/tags/org.apache.sling.jcr.jackrabbit.server-2.0.2-incubator</developerConnection>
+ <url>http://svn.apache.org/viewvc/incubator/sling/tags/org.apache.sling.jcr.jackrabbit.server-2.0.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>
+ <Bundle-Category>
+ sling,jcr,jackrabbit
+ </Bundle-Category>
+ <Bundle-Activator>
+ org.apache.sling.jcr.jackrabbit.server.Activator
+ </Bundle-Activator>
+ <Private-Package>
+ org.apache.sling.jcr.jackrabbit.server
+ </Private-Package>
+ <Import-Package>
+ org.apache.sling.*, javax.jcr.*,
+ javax.naming.*, javax.xml.*,
+ javax.security.*,
+ org.apache.commons.collections.*,
+ org.apache.jackrabbit.api,
+ org.osgi.*,
+ org.slf4j, org.xml.sax, org.xml.sax.helpers
+ </Import-Package>
+ <DynamicImport-Package>*</DynamicImport-Package>
+
+ <!-- Embedd some libraries -->
+ <Embed-Transitive>true</Embed-Transitive>
+ <Embed-Dependency>
+ <!-- core repository implementation -->
+ jackrabbit-jcr-rmi; jackrabbit-core;
+ jackrabbit-jcr-commons;
+ jackrabbit-spi-commons; jackrabbit-spi;
+ lucene-core; derby; concurrent,
+
+ <!-- jackrabbit text extraction -->
+ jackrabbit-text-extractors,
+ tm-extractors,
+ pdfbox;version=0.7.1,
+ poi;version=3.0.1-FINAL,
+ poi-scratchpad;version=3.0.1-FINAL,
+ nekohtml,
+ xercesImpl
+ </Embed-Dependency>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <excludePackageNames>
+ org.apache.sling.jcr.jackrabbit
+ </excludePackageNames>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.jcr.api</artifactId>
+ <version>2.0.2-incubator</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.jcr.base</artifactId>
+ <version>2.0.2-incubator</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <!-- The core repository implementation -->
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-core</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-jcr-commons</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
+ <!-- Export embedded repositories through RMI -->
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-jcr-rmi</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
+ <!-- Text Extractor support -->
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-text-extractors</artifactId>
+ <version>1.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.poi</groupId>
+ <artifactId>poi</artifactId>
+ <version>3.0.1-FINAL</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.poi</groupId>
+ <artifactId>poi-scratchpad</artifactId>
+ <version>3.0.1-FINAL</version>
+ </dependency>
+ <dependency>
+ <groupId>pdfbox</groupId>
+ <artifactId>pdfbox</artifactId>
+ <version>0.7.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.textmining</groupId>
+ <artifactId>tm-extractors</artifactId>
+ <!--
+ NOTE: tm-extractors V0.4 is under Apache License,
+ but later versions are not (SLING-494).
+ -->
+ <version>0.4</version>
+ </dependency>
+
+ <!-- Neko HTML Dependencies for bundle inclusion -->
+ <dependency>
+ <groupId>xerces</groupId>
+ <artifactId>xercesImpl</artifactId>
+ <version>2.8.1</version>
+ </dependency>
+ <dependency>
+ <groupId>nekohtml</groupId>
+ <artifactId>nekohtml</artifactId>
+ <version>0.9.4</version>
+ </dependency>
+
+ <!-- OSGi Libraries -->
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+
+ <!-- Testing -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.framework</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+
+ </dependencies>
+
+</project>
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/server/AbstractRegistrationSupport.java b/src/main/java/org/apache/sling/jcr/jackrabbit/server/AbstractRegistrationSupport.java
new file mode 100644
index 0000000..8955673
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/server/AbstractRegistrationSupport.java
@@ -0,0 +1,364 @@
+/*
+ * 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.jcr.jackrabbit.server;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.jcr.Repository;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.ComponentConstants;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.log.LogService;
+
+/**
+ * The <code>AbstractRegistrationSupport</code> class is the base class for
+ * registration purposes of embedded repositories.
+ * <p>
+ * This base class cares for synchronization issues of the
+ * {@link #activate(ComponentContext)}, {@link #deactivate(ComponentContext)},
+ * {@link #bindRepository(ServiceReference)} and
+ * {@link #unbindRepository(ServiceReference)} methods. Implementations of the
+ * abstract API may safely assume to run thread-safe.
+ * <p>
+ * To ensure this thread-safeness, said methods should not be overwritten.
+ */
+abstract public class AbstractRegistrationSupport {
+
+ /**
+ * The LogService for logging. Extensions of this class must declare the log
+ * service as a reference or call the {@link #bindLog(LogService)} to enable
+ * logging correctly.
+ */
+ private LogService log;
+
+ /**
+ * The OSGi ComponentContext.
+ */
+ private ComponentContext componentContext;
+
+ /**
+ * The (possibly empty) map of repositories which have been bound to the
+ * registry before the registry has been activated.
+ */
+ private final Map<String, ServiceReference> repositoryRegistrationBacklog = new HashMap<String, ServiceReference>();
+
+ /**
+ * The map of repositories which have been bound to the registry component
+ * and which are actually registered with the registry.
+ */
+ private final Map<String, Object> registeredRepositories = new HashMap<String, Object>();
+
+ /**
+ * A lock to serialize access to the registry management in this class.
+ */
+ protected final Object registryLock = new Object();
+
+ // ---------- API to be implemented by extensions --------------------------
+
+ /**
+ * Performs additional activation tasks. This method is called by the
+ * {@link #activate(ComponentContext)} method and is intended for internal
+ * setup, such as acquiring the registry.
+ *
+ * @return Whether the activation succeeded or not. If <code>true</code>
+ * is returned, activation succeeded and any repositories which have
+ * been bound before the component was activated are now actually
+ * registered. If <code>false</code> is returned, activation
+ * failed and this component is disabled and receives no further
+ * repository bind and unbound events (apart for unbind events for
+ * repositories which have already been bound).
+ */
+ protected abstract boolean doActivate();
+
+ /**
+ * Performs additional deactivation tasks. This method is called by the
+ * {@link #deactivate(ComponentContext)} method and is intended for internal
+ * cleanup of setup done by the {@link #doActivate()} method.
+ * <p>
+ * This method is always called, regardless of whether {@link #doActivate()}
+ * succeeded or not.
+ */
+ protected abstract void doDeactivate();
+
+ /**
+ * Called to actually register a repository with the registry. This method
+ * is called by {@link #activate(ComponentContext)} for any repositories
+ * bound before the component was activated and by
+ * {@link #bindRepository(ServiceReference)} for any repositories bound
+ * after the component was activated.
+ * <p>
+ * If actual registration fails, this method is expected to return
+ * <code>null</code> to indicate this fact. In this case, the
+ * {@link #unbindRepository(String, Object)} will NOT be called for the
+ * named repository.
+ * <p>
+ * This method may safely assume that it is only called on or after
+ * activation of this component on or before the component deactivation.
+ *
+ * @param name The name under which the repository is to be registered.
+ * @param repository The <code>javax.jcr.Repository</code> to register.
+ * @return Returns an object which is later given as the <code>data</code>
+ * parameter to the {@link #unbindRepository(String, Object)} method
+ * to unregister the repository of the given name. This may be
+ * <code>null</code> if actual registration failed.
+ */
+ protected abstract Object bindRepository(String name, Repository repository);
+
+ /**
+ * Called to actually unregister a repository with the registry. This method
+ * is called by {@link #unbindRepository(ServiceReference)} for any
+ * repositories unbound before the component is deactivated and by
+ * {@link #deactivate(ComponentContext)} for any repositories not unbound
+ * before the component is deactivated.
+ * <p>
+ * If the {@link #bindRepository(String, Repository)} returned
+ * <code>null</code> for when the named repository was registered, this
+ * method is not called.
+ * <p>
+ * This method may safely assume that it is only called on or after
+ * activation of this component on or before the component deactivation.
+ *
+ * @param name The name under which the repository is to be registered.
+ * @param data The data object returned by the
+ * {@link #bindRepositoryInternal(String, ServiceReference)}
+ * method.
+ */
+ protected abstract void unbindRepository(String name, Object data);
+
+ // ---------- Implementation support methods -------------------------------
+
+ /**
+ * Returns the OSGi <code>ComponentContext</code> of this component. This
+ * method returns <code>null</code> before the {@link #doActivate()}
+ * method is called and after the {@link #doDeactivate()} method has been
+ * called. That is, this method does not return <code>null</code> if it is
+ * fully operational.
+ */
+ protected ComponentContext getComponentContext() {
+ return this.componentContext;
+ }
+
+ /**
+ * Logs a message with optional <code>Throwable</code> stack trace to the
+ * log service or <code>stderr</code> if no log service is available.
+ *
+ * @param level The <code>LogService</code> level at which to log the
+ * message.
+ * @param message The message to log, this should of course not be
+ * <code>null</code>.
+ * @param t The <code>Throwable</code> to log along with the message. This
+ * may be <code>null</code>.
+ */
+ protected void log(int level, String message, Throwable t) {
+ LogService log = this.log;
+ if (log != null) {
+ log.log(level, message, t);
+ } else {
+ System.err.print(level + " - " + message);
+ if (t != null) {
+ t.printStackTrace(System.err);
+ }
+ }
+
+ }
+
+ /**
+ * Returns the <code>name</code> property from the service properties or
+ * <code>null</code> if no such property exists or the property is an
+ * empty string.
+ *
+ * @param reference The <code>ServiceReference</code> whose
+ * <code>name</code> property is to be returned.
+ * @return The non-empty name property or <code>null</code>.
+ */
+ protected String getName(ServiceReference reference) {
+ String name = (String) reference.getProperty(SlingServerRepository.REPOSITORY_REGISTRATION_NAME);
+ if (name == null || name.length() == 0) {
+ this.log.log(LogService.LOG_DEBUG,
+ "registerRepository: Repository not to be registered");
+ return null;
+ }
+
+ return name;
+ }
+
+ // ---------- SCR intergration ---------------------------------------------
+
+ /**
+ * Activates this component thread-safely as follows:
+ * <ol>
+ * <li>Set the OSGi ComponentContext field
+ * <li>Call {@link #doActivate()}
+ * <li>Register repositores bound before activation calling
+ * {@link #bindRepository(String, Repository)} for each such repository.
+ * </ol>
+ * <p>
+ * If {@link #doActivate()} returns <code>false</code>, the repositories
+ * already bound are not actually registered, but this component is
+ * disabled.
+ *
+ * @param componentContext The OSGi <code>ComponentContext</code> of this
+ * component.
+ */
+ protected void activate(ComponentContext componentContext) {
+ synchronized (this.registryLock) {
+ this.componentContext = componentContext;
+
+ if (this.doActivate()) {
+ // register all repositories in the tmp map
+ for (Iterator<Map.Entry<String, ServiceReference>> ri = this.repositoryRegistrationBacklog.entrySet().iterator(); ri.hasNext();) {
+ Map.Entry<String, ServiceReference> entry = ri.next();
+
+ this.bindRepositoryInternal(entry.getKey(),
+ entry.getValue());
+
+ ri.remove();
+ }
+ } else {
+ // disable this component
+ String name = (String) componentContext.getProperties().get(
+ ComponentConstants.COMPONENT_NAME);
+ this.getComponentContext().disableComponent(name);
+ }
+ }
+ }
+
+ /**
+ * Deactivates this component thread-safely as follows:
+ * <ol>
+ * <li>Unregister repositores still bound calling
+ * {@link #unbindRepository(String, Object)} for each such repository.
+ * <li>Call {@link #doDeactivate()}
+ * <li>Clear the OSGi ComponentContext field
+ * </ol>
+ *
+ * @param componentContext The OSGi <code>ComponentContext</code> of this
+ * component.
+ */
+ protected void deactivate(ComponentContext context) {
+
+ synchronized (this.registryLock) {
+
+ // unregister all repositories in the tmp map
+ for (Iterator<Map.Entry<String, Object>> ri = this.registeredRepositories.entrySet().iterator(); ri.hasNext();) {
+ Map.Entry<String, Object> entry = ri.next();
+
+ this.unbindRepository(entry.getKey(), entry.getValue());
+
+ ri.remove();
+ }
+
+ this.doDeactivate();
+
+ this.componentContext = null;
+ }
+ }
+
+ /**
+ * Registers the repository identified by the OSGi service reference under
+ * the name set as service property. If the repository service has not
+ * name property, the repository is not registered.
+ *
+ * @param reference The <code>ServiceReference</code> representing the
+ * repository to register.
+ */
+ protected void bindRepository(ServiceReference reference) {
+ String name = this.getName(reference);
+
+ if (name != null) {
+ synchronized (this.registryLock) {
+ if (this.componentContext == null) {
+ // no context to register with, delay ??
+ this.repositoryRegistrationBacklog.put(name, reference);
+ } else {
+ this.bindRepositoryInternal(name, reference);
+ }
+ }
+ } else {
+ this.log(LogService.LOG_INFO, "Service "
+ + reference.getProperty(Constants.SERVICE_ID)
+ + " has no name property, not registering", null);
+ }
+ }
+
+ /**
+ * Unregisters the repository identified by the OSGi service reference under
+ * the name set as service property. If the repository service has no
+ * name property, the repository is assumed not be registered and nothing
+ * needs to be done.
+ *
+ * @param reference The <code>ServiceReference</code> representing the
+ * repository to unregister.
+ */
+ protected void unbindRepository(ServiceReference reference) {
+ String name = this.getName(reference);
+ if (name != null) {
+
+ synchronized (this.registryLock) {
+ // unbind the repository
+ Object data = this.registeredRepositories.remove(name);
+ if (data != null) {
+ this.unbindRepository(name, data);
+ }
+
+ // ensure unregistered from internal and temporary map
+ this.repositoryRegistrationBacklog.remove(name);
+
+ // make sure we have no reference to the service
+ if (this.componentContext != null) {
+ this.componentContext.getBundleContext().ungetService(reference);
+ }
+ }
+ } else {
+ this.log(LogService.LOG_DEBUG, "Service "
+ + reference.getProperty(Constants.SERVICE_ID)
+ + " has no name property, nothing to unregister", null);
+ }
+ }
+
+ /** Binds the LogService */
+ protected void bindLog(LogService log) {
+ this.log = log;
+ }
+
+ /** Unbinds the LogService */
+ protected void unbindLog(LogService log) {
+ this.log = null;
+ }
+
+ //---------- internal -----------------------------------------------------
+
+ /**
+ * Internal bind method called by {@link #activate(ComponentContext)} and
+ * {@link #bindRepository(ServiceReference)} to actually control the
+ * registration process by retrieving the repository and calling the
+ * {@link #bindRepository(String, Repository)} method.
+ */
+ private void bindRepositoryInternal(String name, ServiceReference reference) {
+ Repository repository = (Repository) this.getComponentContext().getBundleContext().getService(
+ reference);
+ Object data = this.bindRepository(name, repository);
+ if (data != null) {
+ this.registeredRepositories.put(name, data);
+ }
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/server/Activator.java b/src/main/java/org/apache/sling/jcr/jackrabbit/server/Activator.java
new file mode 100644
index 0000000..14ba45c
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/server/Activator.java
@@ -0,0 +1,202 @@
+/*
+ * 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.jcr.jackrabbit.server;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Hashtable;
+
+import org.apache.sling.jcr.base.util.RepositoryAccessor;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>Activator</code> TODO
+ */
+public class Activator implements BundleActivator, ServiceListener {
+
+ /** default log */
+ private static final Logger log = LoggerFactory.getLogger(Activator.class);
+
+ public static final String SERVER_REPOSITORY_FACTORY_PID = SlingServerRepository.class.getName();
+
+ /**
+ * The name of the configuration property naming the Sling Context for which
+ * a factory configuration has been created.
+ */
+ public static final String SLING_CONTEXT = "sling.context";
+
+ /**
+ * The name of the framework property containing the default sling context
+ * name.
+ */
+ public static final String SLING_CONTEXT_DEFAULT = "sling.context.default";
+
+ // The name of the Configuration Admin Service
+ private static final String CONFIG_ADMIN_NAME = ConfigurationAdmin.class.getName();
+
+ // this bundle's context, used by verifyConfiguration
+ private BundleContext bundleContext;
+
+ // the name of the default sling context
+ private String slingContext;
+
+ protected String getRepositoryName() {
+ return "jackrabbit";
+ }
+
+ public void start(BundleContext context) {
+
+ this.bundleContext = context;
+
+ // check the name of the default context, nothing to do if none
+ slingContext = context.getProperty(SLING_CONTEXT_DEFAULT);
+ if (slingContext == null) {
+ slingContext = "default";
+ }
+
+ ServiceReference sr = context.getServiceReference(CONFIG_ADMIN_NAME);
+ if (sr != null) {
+
+ // immediately verify the configuration as the service is here
+ verifyConfiguration(sr);
+
+ } else {
+
+ // register as service listener for Configuration Admin to verify
+ // the configuration when the service is registered
+ try {
+ bundleContext.addServiceListener(this, "("
+ + Constants.OBJECTCLASS + "=" + CONFIG_ADMIN_NAME + ")");
+ } catch (InvalidSyntaxException ise) {
+ log.error(
+ "start: Failed to register for Configuration Admin Service, will not verify configuration",
+ ise);
+ }
+ }
+ }
+
+ public void stop(BundleContext arg0) {
+ // nothing to do
+ }
+
+ // ---------- ServiceListener ----------------------------------------------
+
+ public void serviceChanged(ServiceEvent event) {
+ if (event.getType() == ServiceEvent.REGISTERED) {
+
+ // verify the configuration with the newly registered service
+ verifyConfiguration(event.getServiceReference());
+
+ // don't care for any more service state changes
+ bundleContext.removeServiceListener(this);
+ }
+ }
+
+ // ---------- internal -----------------------------------------------------
+
+ private void verifyConfiguration(ServiceReference ref) {
+ ConfigurationAdmin ca = (ConfigurationAdmin) bundleContext.getService(ref);
+ if (ca == null) {
+ log.error("verifyConfiguration: Failed to get Configuration Admin Service from Service Reference");
+ return;
+ }
+
+ try {
+ // find a configuration for theses properties...
+ Configuration[] cfgs = ca.listConfigurations("("
+ + ConfigurationAdmin.SERVICE_FACTORYPID + "="
+ + SERVER_REPOSITORY_FACTORY_PID + ")");
+ if (cfgs != null && cfgs.length > 0) {
+ log.info(
+ "verifyConfiguration: {} Configurations available for {}, nothing to do",
+ new Object[] { new Integer(cfgs.length),
+ SERVER_REPOSITORY_FACTORY_PID });
+ return;
+ }
+
+ // No config, create a default one.
+ Hashtable<String, String> defaultConfig = new Hashtable<String, String>();
+ final String overrideUrl = bundleContext.getProperty(RepositoryAccessor.REPOSITORY_URL_OVERRIDE_PROPERTY);
+ if(overrideUrl != null && overrideUrl.length() > 0) {
+ // Ignore other parameters if override URL (SLING-254) is set
+ defaultConfig.put(RepositoryAccessor.REPOSITORY_URL_OVERRIDE_PROPERTY, overrideUrl);
+ log.info(RepositoryAccessor.REPOSITORY_URL_OVERRIDE_PROPERTY + "=" + overrideUrl +
+ ", using it to create the default configuration");
+
+ } else {
+ initDefaultConfig(defaultConfig, bundleContext);
+ }
+
+ // create the factory and set the properties
+ Configuration config = ca.createFactoryConfiguration(SERVER_REPOSITORY_FACTORY_PID);
+ config.update(defaultConfig);
+
+ log.info("verifyConfiguration: Created configuration {} for {}",
+ config.getPid(), config.getFactoryPid());
+
+ } catch (Throwable t) {
+ log.error(
+ "verifyConfiguration: Cannot check or define configuration", t);
+ } finally {
+ bundleContext.ungetService(ref);
+ }
+ }
+
+ private void initDefaultConfig(Hashtable<String, String> props, BundleContext bundleContext) throws IOException {
+ File homeDir;
+ String slingHomePath = bundleContext.getProperty("sling.home");
+ if (slingHomePath != null) {
+ homeDir = new File(slingHomePath, getRepositoryName());
+ } else {
+ homeDir = new File(getRepositoryName());
+ }
+
+ // make sure jackrabbit home exists
+ log.info("Creating default config for Jackrabbit in " + homeDir);
+ if (!homeDir.isDirectory()) {
+ if (!homeDir.mkdirs()) {
+ log.info("verifyConfiguration: Cannot create Jackrabbit home "
+ + homeDir + ", failed creating default configuration");
+ return;
+ }
+ }
+
+ // ensure the configuration file (inside the home Dir !)
+ File configFile = new File(homeDir, "repository.xml");
+ SlingServerRepository.copyFile(bundleContext.getBundle(),
+ "repository.xml", configFile);
+
+ // default config values
+ props.put(SLING_CONTEXT, slingContext);
+ props.put(SlingServerRepository.REPOSITORY_CONFIG_URL,
+ configFile.getPath());
+ props.put(SlingServerRepository.REPOSITORY_HOME_DIR,
+ homeDir.getPath());
+ props.put(SlingServerRepository.REPOSITORY_REGISTRATION_NAME,
+ this.getRepositoryName());
+ }
+}
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/server/JndiRegistrationSupport.java b/src/main/java/org/apache/sling/jcr/jackrabbit/server/JndiRegistrationSupport.java
new file mode 100644
index 0000000..10c3036
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/server/JndiRegistrationSupport.java
@@ -0,0 +1,158 @@
+/*
+ * 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.jcr.jackrabbit.server;
+
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import javax.jcr.Repository;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.osgi.service.log.LogService;
+
+
+/**
+ * The <code>JndiRegistrationSupport</code> extends the
+ * {@link AbstractRegistrationSupport} class to register repositories with a
+ * JNDI context whose provider URL and initial factory class name may be
+ * configured.
+ * <p>
+ * Note: Currently, only these two properties are declared to be configurable,
+ * in the future a mechanism should be devised to support declaration of more
+ * properties.
+ *
+ * @scr.component immediate="true" label="%jndi.name"
+ * description="%jndi.description"
+ * @scr.reference name="Repository" interface="javax.jcr.Repository"
+ * policy="dynamic" cardinality="0..n"
+ * @scr.reference name="Log" interface="org.osgi.service.log.LogService"
+ * policy="dynamic" cardinality="0..1"
+ * @scr.property name="java.naming.factory.initial"
+ * value="org.apache.jackrabbit.core.jndi.provider.DummyInitialContextFactory"
+ * label="%jndi.factory.name"
+ * description="%jndi.factory.description"
+ * @scr.property name="java.naming.provider.url" value="http://incubator.apache.org/sling"
+ * label="%jndi.providerurl.name"
+ * description="%jndi.providerurl.description"
+ * @scr.property name="service.vendor" value="The Apache Software Foundation"
+ * @scr.property name="service.description" value="JNDI Repository Registration"
+ */
+public class JndiRegistrationSupport extends AbstractRegistrationSupport {
+
+ private Context jndiContext;
+
+ // ---------- SCR intergration ---------------------------------------------
+
+ protected boolean doActivate() {
+ @SuppressWarnings("unchecked")
+ Dictionary<String, Object> props = this.getComponentContext().getProperties();
+ Properties env = new Properties();
+ for (Enumeration<String> pe = props.keys(); pe.hasMoreElements();) {
+ String key = pe.nextElement();
+ if (key.startsWith("java.naming.")) {
+ env.setProperty(key, (String) props.get(key));
+ }
+ }
+
+ try {
+ // create the JNDI context for registration
+ this.jndiContext = this.createInitialContext(env);
+
+ this.log(LogService.LOG_INFO, "Using JNDI context "
+ + this.jndiContext.getEnvironment() + " to register repositories",
+ null);
+
+ return true;
+ } catch (NamingException ne) {
+ this.log(
+ LogService.LOG_ERROR,
+ "Problem setting up JNDI initial context, repositories will not be registered. Reason: "
+ + ne.getMessage(), null);
+ }
+
+ // fallback to false
+ return false;
+ }
+
+ protected void doDeactivate() {
+ if (this.jndiContext != null) {
+ try {
+ this.jndiContext.close();
+ } catch (NamingException ne) {
+ this.log(LogService.LOG_INFO, "Problem closing JNDI context", ne);
+ }
+
+ this.jndiContext = null;
+ }
+ }
+
+ private Context createInitialContext(final Properties env) throws NamingException {
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<Context>() {
+ public Context run() throws NamingException {
+ Thread currentThread = Thread.currentThread();
+ ClassLoader old = currentThread.getContextClassLoader();
+ currentThread.setContextClassLoader(JndiRegistrationSupport.this.getClass().getClassLoader());
+ try {
+ return new InitialContext(env);
+ } finally {
+ currentThread.setContextClassLoader(old);
+ }
+ }
+ });
+ } catch (PrivilegedActionException pae) {
+ // we now that this method only throws a NamingException
+ throw (NamingException) pae.getCause();
+ }
+ }
+
+ protected Object bindRepository(String name, Repository repository) {
+
+ if (this.jndiContext != null) {
+ try {
+ this.jndiContext.bind(name, repository);
+ this.log(LogService.LOG_INFO, "Repository bound to JNDI as " + name,
+ null);
+ return repository;
+ } catch (NamingException ne) {
+ this.log(LogService.LOG_ERROR, "Failed to register repository " + name, ne);
+ }
+ }
+
+ // fall back to unregistered in case of failures or no context
+ return null;
+ }
+
+ protected void unbindRepository(String name, Object data) {
+ if (this.jndiContext != null) {
+ try {
+ this.jndiContext.unbind(name);
+ this.log(LogService.LOG_INFO, "Repository " + name
+ + " unbound from JNDI", null);
+ } catch (NamingException ne) {
+ this.log(LogService.LOG_ERROR, "Problem unregistering repository "
+ + name, ne);
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/server/RmiRegistrationSupport.java b/src/main/java/org/apache/sling/jcr/jackrabbit/server/RmiRegistrationSupport.java
new file mode 100644
index 0000000..7bff561
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/server/RmiRegistrationSupport.java
@@ -0,0 +1,291 @@
+/*
+ * 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.jcr.jackrabbit.server;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.rmi.NoSuchObjectException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.rmi.server.UnicastRemoteObject;
+
+import javax.jcr.Repository;
+
+import org.apache.jackrabbit.rmi.jackrabbit.JackrabbitServerAdapterFactory;
+import org.apache.jackrabbit.rmi.server.RemoteAdapterFactory;
+import org.osgi.service.log.LogService;
+
+/**
+ * The <code>RmiRegistrationSupport</code> extends the
+ * {@link AbstractRegistrationSupport} class to register repositories with an
+ * RMI registry whose provider localhost port may be configured.
+ * <p>
+ * Note: Currently only registries in this Java VM are supported. In the future
+ * support for external registries may be added.
+ *
+ * @scr.component immediate="true" label="%rmi.name"
+ * description="%rmi.description"
+ * @scr.reference name="Repository" interface="javax.jcr.Repository"
+ * policy="dynamic" cardinality="0..n"
+ * @scr.reference name="Log" interface="org.osgi.service.log.LogService"
+ * policy="dynamic" cardinality="0..1"
+ * @scr.property name="service.vendor" value="The Apache Software Foundation"
+ * @scr.property name="service.description" value="RMI based Repository Registration"
+ */
+public class RmiRegistrationSupport extends AbstractRegistrationSupport {
+
+ /**
+ * @scr.property value="1099" type="Integer" label="%rmi.port.name"
+ * description="%rmi.port.description"
+ */
+ public static final String PROP_REGISTRY_PORT = "port";
+
+ private int registryPort;
+
+ /** The private RMI registry, only defined if possible */
+ private Registry registry;
+
+ private boolean registryIsPrivate;
+
+ // ---------- SCR intergration ---------------------------------------------
+
+ /**
+ * Read the registry port from the configuration properties. If the value is
+ * invalid (higher than 65525), the RMI registry is disabled. Likewise the
+ * registry is disabled, if the port property is negative. If the port is
+ * zero or not a number, the default port (1099) is assumed.
+ */
+ protected boolean doActivate() {
+
+ Object portProp = this.getComponentContext().getProperties().get(
+ PROP_REGISTRY_PORT);
+ this.registryPort = (portProp instanceof Number)
+ ? ((Number) portProp).intValue()
+ : 0;
+
+ // ensure correct value
+ if (this.registryPort < 0) {
+ this.log(LogService.LOG_WARNING,
+ "RMI registry disabled (no or negative RMI port configured)",
+ null);
+ return false;
+ } else if (this.registryPort == 0) {
+ this.registryPort = Registry.REGISTRY_PORT;
+ } else if (this.registryPort == 0 || this.registryPort > 0xffff) {
+ this.log(LogService.LOG_WARNING,
+ "Illegal RMI registry port number " + this.registryPort
+ + ", disabling RMI registry", null);
+ return false;
+ }
+
+ this.log(LogService.LOG_INFO, "Using RMI Registry port "
+ + this.registryPort, null);
+ return true;
+ }
+
+ /**
+ * If a private registry has been acquired this method unexports the
+ * registry object to free the RMI registry OID for later use.
+ */
+ protected void doDeactivate() {
+ // if we have a private RMI registry, unexport it here to free
+ // the RMI registry OID
+ if (this.registry != null && this.registryIsPrivate) {
+ try {
+ UnicastRemoteObject.unexportObject(this.registry, true);
+ this.log(LogService.LOG_INFO,
+ "Unexported private RMI Registry at " + this.registryPort,
+ null);
+ } catch (NoSuchObjectException nsoe) {
+ // not expected, but don't really care either
+ this.log(LogService.LOG_INFO,
+ "Cannot unexport private RMI Registry reference", nsoe);
+ }
+ }
+ this.registry = null;
+ }
+
+ protected Object bindRepository(String name, Repository repository) {
+ return new RmiRegistration(name, repository);
+ }
+
+ protected void unbindRepository(String name, Object data) {
+ RmiRegistration rr = (RmiRegistration) data;
+ rr.unregister();
+ }
+
+ // ---------- support for private rmi registries ---------------------------
+
+ /**
+ * Tries to create a private registry at the configured port. If this fails
+ * (for example because a registry already exists in the VM, a registry stub
+ * for the port is returned. This latter stub may or may not connect to a
+ * real registry, which may only be found out, when trying to register
+ * repositories.
+ */
+ private Registry getPrivateRegistry() {
+ if (this.registry == null) {
+ try {
+ // no, so try to create first
+ this.registry = LocateRegistry.createRegistry(this.registryPort);
+ this.registryIsPrivate = true;
+ this.log(LogService.LOG_INFO, "Using private RMI Registry at "
+ + this.registryPort, null);
+
+ } catch (RemoteException re) {
+ // creating failed, check whether there is already one
+ this.log(LogService.LOG_INFO,
+ "Cannot create private registry, trying existing registry at "
+ + this.registryPort + ", reason: " + re.toString(),
+ null);
+
+ try {
+ this.registry = LocateRegistry.getRegistry(this.registryPort);
+ this.registryIsPrivate = false;
+ this.log(LogService.LOG_INFO,
+ "Trying existing registry at " + this.registryPort,
+ null);
+
+ } catch (RemoteException pre) {
+ this.log(
+ LogService.LOG_ERROR,
+ "Cannot get existing registry, will not register repositories on RMI",
+ pre);
+ }
+ }
+ }
+
+ return this.registry;
+ }
+
+ /**
+ * Returns a Jackrabbit JCR RMI <code>RemoteAdapterFactory</code> to be
+ * used to publish local (server-side) JCR objects to a remote client.
+ * <p>
+ * This method returns an instance of the
+ * <code>JackrabbitServerAdapterFactory</code> class to enable the use of
+ * the Jackrabbit API over RMI. Extensions of this class may overwrite this
+ * method to return a different implementation to provide different JCR
+ * extension API depending on the server implementation.
+ */
+ protected RemoteAdapterFactory getRemoteAdapterFactory() {
+ return new JackrabbitServerAdapterFactory();
+ }
+
+ // ---------- Inner Class --------------------------------------------------
+
+ private class RmiRegistration {
+
+ private String rmiName;
+
+ private Remote rmiRepository;
+
+ RmiRegistration(String rmiName, Repository repository) {
+ this.register(rmiName, repository);
+ }
+
+ public String getRmiName() {
+ return this.rmiName;
+ }
+
+ public Remote getRmiRepository() {
+ return this.rmiRepository;
+ }
+
+ public String getRmiURL() {
+ String host;
+ try {
+ host = InetAddress.getLocalHost().getCanonicalHostName();
+ } catch (IOException ignore) {
+ host = "localhost";
+ }
+ return "//" + host + ":" + RmiRegistrationSupport.this.registryPort
+ + "/" + this.getRmiName();
+ }
+
+ private void register(String rmiName, Repository repository) {
+ System.setProperty("java.rmi.server.useCodebaseOnly", "true");
+
+ // try to create remote repository and keep it to ensure it is
+ // unexported in the unregister() method
+ try {
+ RemoteAdapterFactory raf = getRemoteAdapterFactory();
+ this.rmiRepository = raf.getRemoteRepository(repository);
+ } catch (RemoteException e) {
+ RmiRegistrationSupport.this.log(LogService.LOG_ERROR,
+ "Unable to create remote repository.", e);
+ return;
+ } catch (Exception e) {
+ RmiRegistrationSupport.this.log(
+ LogService.LOG_ERROR,
+ "Unable to create RMI repository. jcr-rmi.jar might be missing.",
+ e);
+ return;
+ }
+
+ try {
+ // check whether we have a private registry already
+ Registry registry = RmiRegistrationSupport.this.getPrivateRegistry();
+ if (registry != null) {
+ registry.bind(rmiName, this.rmiRepository);
+ this.rmiName = rmiName;
+ RmiRegistrationSupport.this.log(LogService.LOG_INFO,
+ "Repository bound to " + this.getRmiURL(), null);
+ }
+
+ } catch (NoSuchObjectException nsoe) {
+ // the registry does not really exist
+ RmiRegistrationSupport.this.log(LogService.LOG_WARNING,
+ "Cannot contact RMI registry at "
+ + RmiRegistrationSupport.this.registryPort
+ + ", repository not registered", null);
+ } catch (Exception e) {
+ RmiRegistrationSupport.this.log(LogService.LOG_ERROR,
+ "Unable to bind repository via RMI.", e);
+ }
+ }
+
+ public void unregister() {
+ // unregister repository
+ if (this.rmiName != null) {
+ try {
+ RmiRegistrationSupport.this.getPrivateRegistry().unbind(
+ this.rmiName);
+ RmiRegistrationSupport.this.log(LogService.LOG_INFO,
+ "Repository unbound from " + this.getRmiURL(), null);
+ } catch (Exception e) {
+ RmiRegistrationSupport.this.log(LogService.LOG_ERROR,
+ "Error while unbinding repository from JNDI: " + e,
+ null);
+ }
+ }
+
+ // drop strong reference to remote repository
+ if (this.rmiRepository != null) {
+ try {
+ UnicastRemoteObject.unexportObject(this.rmiRepository, true);
+ } catch (NoSuchObjectException nsoe) {
+ // not expected, but don't really care either
+ RmiRegistrationSupport.this.log(LogService.LOG_INFO,
+ "Cannot unexport remote Repository reference", nsoe);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/apache/sling/jcr/jackrabbit/server/SlingServerRepository.java b/src/main/java/org/apache/sling/jcr/jackrabbit/server/SlingServerRepository.java
new file mode 100644
index 0000000..648034e
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/jackrabbit/server/SlingServerRepository.java
@@ -0,0 +1,209 @@
+/*
+ * 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.jcr.jackrabbit.server;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.Dictionary;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.base.AbstractSlingRepository;
+import org.osgi.framework.Bundle;
+import org.osgi.service.log.LogService;
+
+/**
+ * The <code>SlingServerRepository</code> TODO
+ *
+ * @scr.component label="%repository.name" description="%repository.description"
+ * factory="org.apache.sling.jcr.jackrabbit.server.SlingServerRepositoryFactory"
+ *
+ * @scr.property name="service.vendor" value="The Apache Software Foundation"
+ * @scr.property name="service.description"
+ * value="Factory for embedded Jackrabbit Repository Instances"
+ */
+public class SlingServerRepository extends AbstractSlingRepository
+ implements Repository, SlingRepository {
+
+ /**
+ * The name of the configuration property defining the URL to the
+ * repository configuration file (value is
+ * "config").
+ * <p>
+ * If the configuration file is located in the local file system, the
+ * "file:" scheme must still be specified.
+ * <p>
+ * This parameter is mandatory for this activator to start the repository.
+ *
+ * @scr.property value=""
+ */
+ public static final String REPOSITORY_CONFIG_URL = "config";
+
+ /**
+ * The name of the configuration property defining the file system
+ * directory where the repository files are located (value is
+ * "home").
+ * <p>
+ * This parameter is mandatory for this activator to start the repository.
+ *
+ * @scr.property value=""
+ */
+ public static final String REPOSITORY_HOME_DIR = "home";
+
+ /**
+ * @scr.property value=""
+ */
+ public static final String REPOSITORY_REGISTRATION_NAME = "name";
+
+ //---------- Repository Management ----------------------------------------
+
+ @Override
+ protected Repository acquireRepository() {
+ Repository repository = super.acquireRepository();
+ if (repository != null) {
+ return repository;
+ }
+
+ @SuppressWarnings("unchecked")
+ Dictionary<String, Object> environment = this.getComponentContext().getProperties();
+ String configURLObj = (String) environment.get(REPOSITORY_CONFIG_URL);
+ String home = (String) environment.get(REPOSITORY_HOME_DIR);
+
+ // somewhat dirty hack to have the derby.log file in a sensible
+ // location, but don't overwrite anything already set
+ if (System.getProperty("derby.stream.error.file") == null) {
+ String derbyLog = home + "/derby.log";
+ System.setProperty("derby.stream.error.file", derbyLog);
+ }
+
+ InputStream ins = null;
+ try {
+
+ // check whether the URL is a file path
+ File configFile = new File(configURLObj);
+ if (configFile.canRead()) {
+ ins = new FileInputStream(configFile);
+ } else {
+ URL configURL = new URL(configURLObj);
+ ins = configURL.openStream();
+ }
+
+ RepositoryConfig crc = RepositoryConfig.create(ins, home);
+ return RepositoryImpl.create(crc);
+
+ } catch (IOException ioe) {
+
+ log(LogService.LOG_ERROR,
+ "acquireRepository: IO problem starting repository from "
+ + configURLObj + " in " + home, ioe);
+
+ } catch (RepositoryException re) {
+
+ log(LogService.LOG_ERROR,
+ "acquireRepository: Repository problem starting repository from "
+ + configURLObj + " in " + home, re);
+ } finally {
+ if (ins != null) {
+ try {
+ ins.close();
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+ }
+
+ // got no repository ....
+ return null;
+ }
+
+ @Override
+ protected void disposeRepository(Repository repository) {
+ super.disposeRepository(repository);
+
+ if (repository instanceof RepositoryImpl) {
+
+ try {
+ ((RepositoryImpl) repository).shutdown();
+ } catch (Throwable t) {
+ log(LogService.LOG_ERROR,
+ "deactivate: Unexpected problem shutting down repository",
+ t);
+ }
+
+ } else {
+ log(LogService.LOG_INFO,
+ "Repository is not a RepositoryImpl, nothing to do");
+ }
+ }
+
+ //---------- Helper -------------------------------------------------------
+
+ public static void copyFile(Bundle bundle, String entryPath, File destFile) throws FileNotFoundException, IOException {
+ if (destFile.canRead()) {
+ // nothing to do, file exists
+ return;
+ }
+
+ // copy from property
+ URL entryURL = bundle.getEntry(entryPath);
+ if (entryURL == null) {
+ throw new FileNotFoundException(entryPath);
+ }
+
+ // check for a file property
+ InputStream source = entryURL.openStream();
+
+ OutputStream dest = null;
+ try {
+
+ // ensure path to parent folder of licFile
+ destFile.getParentFile().mkdirs();
+
+ dest = new FileOutputStream(destFile);
+ byte[] buf = new byte[2048];
+ int rd;
+ while ( (rd = source.read(buf)) >= 0) {
+ dest.write(buf, 0, rd);
+ }
+
+
+ } finally {
+ if (dest != null) {
+ try {
+ dest.close();
+ } catch (IOException ignore) {
+ }
+ }
+
+ // licSource is not null
+ try {
+ source.close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
+}
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..aef89ed
--- /dev/null
+++ b/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,404 @@
+
+ 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.
+
+
+APACHE SLING SUBCOMPONENTS:
+
+Apache Sling includes subcomponents with separate copyright notices and
+license terms. Your use of these subcomponents is subject to the terms
+and conditions of the following licenses.
+
+W3C XPath parser
+
+ XPath 2.0/XQuery 1.0 Parser:
+ http://www.w3.org/2002/11/xquery-xpath-applets/xgrammar.zip
+
+ Copyright (C) 2002 World Wide Web Consortium, (Massachusetts Institute of
+ Technology, European Research Consortium for Informatics and Mathematics,
+ Keio University). All Rights Reserved.
+
+ This work is distributed under the W3C(R) Software License in the hope
+ that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ W3C(R) SOFTWARE NOTICE AND LICENSE
+ http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+
+ This work (and included software, documentation such as READMEs, or
+ other related items) is being provided by the copyright holders under
+ the following license. By obtaining, using and/or copying this work,
+ you (the licensee) agree that you have read, understood, and will comply
+ with the following terms and conditions.
+
+ Permission to copy, modify, and distribute this software and its
+ documentation, with or without modification, for any purpose and
+ without fee or royalty is hereby granted, provided that you include
+ the following on ALL copies of the software and documentation or
+ portions thereof, including modifications:
+
+ 1. The full text of this NOTICE in a location viewable to users
+ of the redistributed or derivative work.
+
+ 2. Any pre-existing intellectual property disclaimers, notices,
+ or terms and conditions. If none exist, the W3C Software Short
+ Notice should be included (hypertext is preferred, text is
+ permitted) within the body of any redistributed or derivative code.
+
+ 3. Notice of any changes or modifications to the files, including
+ the date changes were made. (We recommend you provide URIs to the
+ location from which the code is derived.)
+
+ THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT
+ HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED,
+ INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS
+ FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR
+ DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS,
+ TRADEMARKS OR OTHER RIGHTS.
+
+ COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR
+ DOCUMENTATION.
+
+ The name and trademarks of copyright holders may NOT be used in
+ advertising or publicity pertaining to the software without specific,
+ written prior permission. Title to copyright in this software and
+ any associated documentation will at all times remain with
+ copyright holders.
+
+Concurrent
+
+ http://g.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html
+
+ All classes are released to the public domain and may be used for any
+ purpose whatsoever without permission or acknowledgment. Portions of
+ the CopyOnWriteArrayList and ConcurrentReaderHashMap classes are adapted
+ from Sun JDK source code. These are copyright of Sun Microsystems, Inc,
+ and are used with their kind permission, as described in this license:
+
+ TECHNOLOGY LICENSE FROM SUN MICROSYSTEMS, INC. TO DOUG LEA
+
+ Whereas Doug Lea desires to utlized certain Java Software technologies
+ in the util.concurrent technology; and Whereas Sun Microsystems, Inc.
+ ("Sun") desires that Doug Lea utilize certain Java Software technologies
+ in the util.concurrent technology;
+
+ Therefore the parties agree as follows, effective May 31, 2002:
+
+ "Java Software technologies" means
+
+ classes/java/util/ArrayList.java, and
+ classes/java/util/HashMap.java.
+
+ The Java Software technologies are Copyright (c) 1994-2000 Sun
+ Microsystems, Inc. All rights reserved.
+
+ Sun hereby grants Doug Lea a non-exclusive, worldwide, non-transferrable
+ license to use, reproduce, create derivate works of, and distribute the
+ Java Software and derivative works thereof in source and binary forms
+ as part of a larger work, and to sublicense the right to use, reproduce
+ and distribute the Java Software and Doug Lea's derivative works as the
+ part of larger works through multiple tiers of sublicensees provided that
+ the following conditions are met:
+
+ -Neither the name of or trademarks of Sun may be used to endorse or
+ promote products including or derived from the Java Software technology
+ without specific prior written permission; and
+ -Redistributions of source or binary code must contain the above
+ copyright notice, this notice and and the following disclaimers:
+
+ This software is provided "AS IS," without a warranty of any kind.
+ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ MICROSYSTEMS, INC. AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
+ SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
+ THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN MICROSYSTEMS, INC.
+ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES,
+ HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
+ THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN MICROSYSTEMS, INC.
+ HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+ You acknowledge that Software is not designed,licensed or intended for
+ use in the design, construction, operation or maintenance of any nuclear
+ facility.
+
+PDFBox
+
+ Copyright (c) 2003-2005, www.pdfbox.org
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of pdfbox; nor the names of its contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ OF SUCH DAMAGE.
+
+CyberNeko HTML Parser
+
+ The CyberNeko Software License, Version 1.0
+
+ (C) Copyright 2002-2005, Andy Clark. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ 3. The end-user documentation included with the redistribution,
+ if any, must include the following acknowledgment:
+ "This product includes software developed by Andy Clark."
+ Alternately, this acknowledgment may appear in the software itself,
+ if and wherever such third-party acknowledgments normally appear.
+
+ 4. The names "CyberNeko" and "NekoHTML" must not be used to endorse
+ or promote products derived from this software without prior
+ written permission. For written permission, please contact
+ andyc@cyberneko.net.
+
+ 5. Products derived from this software may not be called "CyberNeko",
+ nor may "CyberNeko" appear in their name, without prior written
+ permission of the author.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ ====================================================================
+
+ This license is based on the Apache Software License, version 1.1.
diff --git a/src/main/resources/META-INF/NOTICE b/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..85768b3
--- /dev/null
+++ b/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,36 @@
+Apache Sling JCR Jackrabbit Server
+Copyright 2008 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/).
+
+This product contains an XPath parser from the World Wide Web Consortium.
+Copyright (c) 2002 World Wide Web Consortium, (Massachusetts Institute of
+Technology, European Research Consortium for Informatics and Mathematics,
+Keio University).
+
+This product includes software developed at pdfbox.org.
+Copyright (c) 2003-2005, www.pdfbox.org
+
+This product includes the CyberNeko HTML Parser
+(C) Copyright 2002-2005, Andy Clark.
+
+This software contains code written by Ryan Ackley.
+Please go to http://www.textmining.org for the latest version.
+
+This product includes Apache Xerces, portions of which were
+originally based on the following:
+- software copyright (c) 1999, IBM Corporation., http://www.ibm.com.
+- software copyright (c) 1999, Sun Microsystems., http://www.sun.com.
+- voluntary contributions made by Paul Eng on behalf of the
+ Apache Software Foundation that were originally developed at iClick, Inc.,
+ software copyright (c) 1999.
+
+This product includes Apache Derby, which is based on source code originally
+developed at the International Business Machines Corporation.
+(C) Copyright 1997,2004 International Business Machines Corporation.
+All rights reserved.
+(C) Copyright IBM Corp. 2003.
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..630bf02
--- /dev/null
+++ b/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -0,0 +1,146 @@
+#
+# 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 Sling SCR plugin
+
+repository.name = Embedded JCR Repository
+repository.description = Configuration to launch an embedded JCR Repository \
+ and provide it as a SlingRepository, standard JCR Repository and CRXRepository. \
+ In addition, if the registration URL is not empty, the repository is registered \
+ as defined.
+
+admin.name.name = Administator
+admin.name.description = The user name of the administrative user. This user \
+ name is used to implement the SlingRepository.loginAdministrative(String) \
+ method. It is intended for this user to provide full read/write access to \
+ repository.
+
+admin.password.name = Administrator Password
+admin.password.description = Password for the administrative user.
+
+anonymous.name.name = Anonymous
+anonymous.name.description = The user name of the anonymous user. This user \
+ name is used to implement the Repository.login methods without a Credentials \
+ instance.
+
+anonymous.password.name = Anonymous Password
+anonymous.password.description = Password for the anonymous user.
+
+autostart.name = Autostart
+autostart.description = Check to have the embedded JCR repository started as \
+ soon as the configuration is activated. If not checked, the respository is \
+ only started when used the first time.
+
+config.name = Configuration File
+config.description = Filename or URL of the configuration file for the embedded \
+ JCR repository. The name is first checked, whether it points to a readable file. \
+ If no, the name is assumed to be an URL which must be accessible from the Sling \
+ Server. \
+
+defaultWorkspace.name = Default Workspace
+defaultWorkspace.description = Name of the workspace to use by default if not \
+ is given in any of the login methods. This name is used to implement the \
+ SlingRepository.getDefaultWorkspace() method. If this name is empty, a null \
+ value is used in JCR calls so that the default workspace provided by the \
+ JCR repository is used.
+
+home.name = Repository Home
+home.description = Name of a filesystem directory in which to launch the \
+ embedded JCR Repository.
+
+poll.active.name = Poll Intervall Active
+poll.active.description = The interval in seconds between two consecutive \
+ checks whether the repository is still accessbible, once it has been acquired.\
+ The default value is 10 seconds, the minimum allowed value is 2 seconds, \
+ smaller values are corected to the minimum.
+
+poll.inactive.name = Poll Intervall Inactive
+poll.inactive.description = The interval in seconds between two consecutive \
+ checks whether the repository has become accessbible if the repository is \
+ not immediately accessible or connection to the repository has been lost. \
+ The default value is 10 seconds, the minimum allowed value is 2 seconds, \
+ smaller values are corected to the minimum.
+
+pool.maxActive.name = Maximum Sessions
+pool.maxActive.description = The maximum number of sessions which may be logged \
+ in through the Sling Repository. This number limits the number of sessions \
+ provided by the session pool at any one time. If more sessions are requested \
+ the respective threads have to wait for sessions to be logged out by other \
+ threads. Default if negative or not set is virtually unlimited. \
+ See Session Wait Time.
+
+pool.maxActiveWait.name = Session Wait Time
+pool.maxActiveWait.description = The number of seconds to wait for a session \
+ to become available if the maximum number of sessions has been provided. If \
+ no session becomes available within time frame, access to the repository fails. \
+ Default if negative or not set is 10 seconds.
+
+pool.maxIdle.name = Maximum Idle Sessions
+pool.maxIdle.description = The maximum number of sessions to keep in the pool. \
+ The bigger this number, the more sessions are kept in the pool, the more login \
+ round trips may be saved. On the other hand, each session requires a certain \
+ amount of memory. Default if negative or not set is 10 idle sessions.
+
+name.name = Embedded JCR Repository Name
+name.description = The name under which the embedded repository will be \
+ registered JNDI and RMI registries. The respective registry services listen \
+ for embedded CRX repositories to be launched and register each under the name \
+ configured. If no name is configured, the repository will not be registered.
+
+repository.url.override.property.name = Repository URL override property
+repository.url.override.property.description = Name of the system or \
+ configuration Property that provides a repository connection URL to replace \
+ the embedded JCR Repository. \
+ If the corresponding System Property value is not empty, it is used to acquire \
+ a Repository via JNDI or RMI, instead of using the embedded one. \
+ Leave this value empty to force the use of the embedded Repository.
+
+#
+# JNDI Registration Support
+jndi.name = Embedded JCR Repository JNDI Registrar
+jndi.description = The JNDI Registrar listens for CRX embedded repositories \
+ to be registered as services and registers them in the JNDI context under the \
+ name specified in the "name" service property.
+
+jndi.factory.name = Initial Context Factory
+jndi.factory.description = The fully qualified class name of the factory class \
+ that will create an initial context.
+
+jndi.providerurl.name = Provider URL
+jndi.providerurl.description = An URL string for the service provider (e.g. \
+ "ldap://somehost:389").
+
+#
+# RMI Registration Support
+rmi.name = Embedded JCR Repository RMI Registrar
+rmi.description = The RMI Registrar listens for CRX embedded repositories \
+ to be registered as services and registers them in an RMI registry under the \
+ name specified in the "name" service property.
+
+rmi.port.name = Port Number
+rmi.port.description = Port number of the RMI registry to use. The RMI Registrar \
+ first tries to create a private RMI registry at this port. If this fails, an \
+ existing registry is tried to connect at this port on local host. If this \
+ number is negative, the RMI Registrar is disabled. If this number is higher \
+ than 65535, an error message is logged and the RMI Registrar is also \
+ disabled. If this number is zero, the system default RMI Registry port 1099 \
+ is used.
diff --git a/src/main/resources/repository.xml b/src/main/resources/repository.xml
new file mode 100644
index 0000000..f650ae9
--- /dev/null
+++ b/src/main/resources/repository.xml
@@ -0,0 +1,73 @@
+<?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.
+-->
+<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.2//EN"
+ "http://jackrabbit.apache.org/dtd/repository-1.4.dtd">
+<Repository>
+ <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+ <param name="path" value="${rep.home}/repository"/>
+ </FileSystem>
+
+ <Security appName="Jackrabbit">
+ <AccessManager class="org.apache.jackrabbit.core.security.SimpleAccessManager">
+ </AccessManager>
+
+ <LoginModule class="org.apache.jackrabbit.core.security.SimpleLoginModule">
+ <param name="anonymousId" value="anonymous"/>
+ </LoginModule>
+ </Security>
+
+ <Workspaces rootPath="${rep.home}/workspaces" defaultWorkspace="default"/>
+
+ <Workspace name="${wsp.name}">
+ <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+ <param name="path" value="${wsp.home}"/>
+ </FileSystem>
+ <PersistenceManager class="org.apache.jackrabbit.core.persistence.db.DerbyPersistenceManager">
+ <param name="url" value="jdbc:derby:${wsp.home}/db;create=true"/>
+ <param name="schemaObjectPrefix" value="${wsp.name}_"/>
+ </PersistenceManager>
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${wsp.home}/index"/>
+ <param name="textFilterClasses" value="org.apache.jackrabbit.extractor.MsWordTextExtractor,org.apache.jackrabbit.extractor.MsExcelTextExtractor,org.apache.jackrabbit.extractor.MsPowerPointTextExtractor,org.apache.jackrabbit.extractor.PdfTextExtractor,org.apache.jackrabbit.extractor.OpenOfficeTextExtractor,org.apache.jackrabbit.extractor.RTFTextExtractor,org.apache.jackrabbit.extractor.HTMLTextExtractor,org.apache.jackrabbit.extractor.XMLTextExtractor"/>
+ <param name="extractorPoolSize" value="2"/>
+ <param name="supportHighlighting" value="true"/>
+ </SearchIndex>
+ </Workspace>
+
+ <Versioning rootPath="${rep.home}/version">
+ <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+ <param name="path" value="${rep.home}/version" />
+ </FileSystem>
+
+ <PersistenceManager class="org.apache.jackrabbit.core.persistence.db.DerbyPersistenceManager">
+ <param name="url" value="jdbc:derby:${rep.home}/version/db;create=true"/>
+ <param name="schemaObjectPrefix" value="version_"/>
+ </PersistenceManager>
+ </Versioning>
+
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${rep.home}/repository/index"/>
+ <param name="textFilterClasses" value="org.apache.jackrabbit.extractor.MsWordTextExtractor,org.apache.jackrabbit.extractor.MsExcelTextExtractor,org.apache.jackrabbit.extractor.MsPowerPointTextExtractor,org.apache.jackrabbit.extractor.PdfTextExtractor,org.apache.jackrabbit.extractor.OpenOfficeTextExtractor,org.apache.jackrabbit.extractor.RTFTextExtractor,org.apache.jackrabbit.extractor.HTMLTextExtractor,org.apache.jackrabbit.extractor.XMLTextExtractor"/>
+ <param name="extractorPoolSize " value="2"/>
+ <param name="supportHighlighting" value="true"/>
+ </SearchIndex>
+
+ <DataStore class="org.apache.jackrabbit.core.data.FileDataStore"/>
+</Repository>
\ No newline at end of file