SLING-11306: Update to sling 47 (#2)
diff --git a/bnd.bnd b/bnd.bnd
new file mode 100644
index 0000000..3aa4fae
--- /dev/null
+++ b/bnd.bnd
@@ -0,0 +1,20 @@
+Bundle-Category: sling,jcr
+Export-Package: org.apache.jackrabbit.server.io;version=${jackrabbit.version};provide:=true
+
+Private-Package:\
+ org.apache.jackrabbit.server,\
+ org.apache.jackrabbit.webdav.simple,\
+ org.apache.sling.jcr.webdav.impl.*
+
+-includeresource:\
+ @jackrabbit-jcr-server-*.jar!/\
+ (org/apache/jackrabbit/webdav/jcr/DavLocatorFactoryImpl*.class|\
+ org/apache/jackrabbit/webdav/jcr/ItemResourceConstants*.class|\
+ org/apache/jackrabbit/webdav/jcr/JcrDavException*.class|\
+ org/apache/jackrabbit/webdav/jcr/JcrDavSession*.class|\
+ org/apache/jackrabbit/webdav/jcr/JcrValueType*.class|\
+ org/apache/jackrabbit/webdav/jcr/lock/*|\
+ META-INF/maven/**)
+
+-removeheaders:\
+ Include-Resource
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index a725a3b..9c51400 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,13 +22,12 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.sling</groupId>
- <artifactId>sling</artifactId>
- <version>26</version>
+ <artifactId>sling-bundle-parent</artifactId>
+ <version>47</version>
<relativePath />
</parent>
<artifactId>org.apache.sling.jcr.webdav</artifactId>
- <packaging>bundle</packaging>
<version>2.3.9-SNAPSHOT</version>
<name>Apache Sling JCR WebDAV</name>
@@ -40,46 +39,28 @@
<connection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-webdav.git</connection>
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-webdav.git</developerConnection>
<url>https://gitbox.apache.org/repos/asf?p=sling-org-apache-sling-jcr-webdav.git</url>
+ <tag>HEAD</tag>
</scm>
<properties>
- <jackrabbit.version>2.14.2</jackrabbit.version>
+ <sling.java.version>8</sling.java.version>
+ <project.build.outputTimestamp>1</project.build.outputTimestamp>
+ <jackrabbit.version>2.14.3</jackrabbit.version>
</properties>
<build>
<plugins>
<plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-scr-plugin</artifactId>
- <version>1.26.4</version>
+ <groupId>biz.aQute.bnd</groupId>
+ <artifactId>bnd-maven-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-Category>sling,jcr</Bundle-Category>
- <Export-Package>
- org.apache.jackrabbit.server.io;version=${jackrabbit.version};provide:=true
- </Export-Package>
- <Private-Package>
- org.apache.jackrabbit.server,
- org.apache.jackrabbit.webdav.simple,
- org.apache.sling.jcr.webdav.impl.*
- </Private-Package>
- <Embed-Dependency>
- jackrabbit-jcr-server;inline=
- org/apache/jackrabbit/webdav/jcr/DavLocatorFactoryImpl*.class|
- org/apache/jackrabbit/webdav/jcr/ItemResourceConstants*.class|
- org/apache/jackrabbit/webdav/jcr/JcrDavException*.class|
- org/apache/jackrabbit/webdav/jcr/JcrDavSession*.class|
- org/apache/jackrabbit/webdav/jcr/JcrValueType*.class|
- org/apache/jackrabbit/webdav/jcr/lock/*|
- META-INF/maven/**
- </Embed-Dependency>
- </instructions>
- </configuration>
+ <groupId>biz.aQute.bnd</groupId>
+ <artifactId>bnd-baseline-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
</plugin>
</plugins>
</build>
@@ -106,12 +87,6 @@
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.commons.osgi</artifactId>
- <version>2.0.6</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.commons.mime</artifactId>
<version>2.1.2</version>
<scope>provided</scope>
@@ -127,12 +102,11 @@
<dependency>
<groupId>javax.jcr</groupId>
<artifactId>jcr</artifactId>
- <version>2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
+ <artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
@@ -144,20 +118,23 @@
<!-- OSGi Libraries -->
<dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.scr.annotations</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
- <version>6.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.service.component</artifactId>
- <version>1.3.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.service.component.annotations</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.service.metatype.annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
@@ -178,9 +155,29 @@
<version>2.0.8</version>
<scope>provided</scope>
</dependency>
+
+ <!-- Test Dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>4.5.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.testing.sling-mock.junit4</artifactId>
+ <version>3.2.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.testing.osgi-mock.junit4</artifactId>
+ <version>3.2.2</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/src/main/java/org/apache/sling/jcr/webdav/impl/handler/DefaultHandlerService.java b/src/main/java/org/apache/sling/jcr/webdav/impl/handler/DefaultHandlerService.java
index 3021e6b..3ddc8cc 100644
--- a/src/main/java/org/apache/sling/jcr/webdav/impl/handler/DefaultHandlerService.java
+++ b/src/main/java/org/apache/sling/jcr/webdav/impl/handler/DefaultHandlerService.java
@@ -18,13 +18,6 @@
*/
package org.apache.sling.jcr.webdav.impl.handler;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Modified;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.server.io.DefaultHandler;
import org.apache.jackrabbit.server.io.DeleteContext;
import org.apache.jackrabbit.server.io.DeleteHandler;
@@ -40,9 +33,15 @@
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavResource;
import org.apache.jackrabbit.webdav.property.PropEntry;
-import org.apache.sling.commons.osgi.OsgiUtil;
import org.apache.sling.jcr.webdav.impl.servlets.SlingWebDavServlet;
-import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Modified;
+import org.osgi.service.component.propertytypes.ServiceRanking;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import java.io.IOException;
import java.util.Map;
@@ -53,34 +52,43 @@
* Wraps {@link org.apache.jackrabbit.server.io.DefaultHandler} in order to run
* it as a service.
*/
-@Component(metatype = true, label = "%defaulthandler.name", description = "%defaulthandler.description")
-@Properties({
- @Property(name = Constants.SERVICE_RANKING, intValue = 1000, propertyPrivate = false),
- @Property(name = SlingWebDavServlet.TYPE_COLLECTIONS, value = SlingWebDavServlet.TYPE_COLLECTIONS_DEFAULT, propertyPrivate = false),
- @Property(name = SlingWebDavServlet.TYPE_NONCOLLECTIONS, value = SlingWebDavServlet.TYPE_NONCOLLECTIONS_DEFAULT, propertyPrivate = false),
- @Property(name = SlingWebDavServlet.TYPE_CONTENT, value = SlingWebDavServlet.TYPE_CONTENT_DEFAULT, propertyPrivate = false) })
-@Service
-public class DefaultHandlerService implements IOHandler, PropertyHandler, CopyMoveHandler,
- DeleteHandler {
+@Component(
+ immediate = true,
+ service = {
+ IOHandler.class,
+ PropertyHandler.class,
+ CopyMoveHandler.class,
+ DeleteHandler.class
+ })
+@ServiceRanking(1000)
+@Designate(ocd = DefaultHandlerService.Config.class)
+public class DefaultHandlerService implements IOHandler, PropertyHandler, CopyMoveHandler, DeleteHandler {
private DefaultHandler delegatee;
+ @SuppressWarnings("java:S100")
+ @ObjectClassDefinition(name = "%defaulthandler.name", description = "%defaulthandler.description")
+ public @interface Config {
+
+ @AttributeDefinition(name = "%type.collections.name", description = "%type.collections.description")
+ String type_collections() default SlingWebDavServlet.TYPE_COLLECTIONS_DEFAULT;
+
+ @AttributeDefinition(name = "%type.noncollections.name", description = "%type.noncollections.description")
+ String type_noncollections() default SlingWebDavServlet.TYPE_NONCOLLECTIONS_DEFAULT;
+
+ @AttributeDefinition(name = "%type.content.name", description = "%type.content.description")
+ String type_content() default SlingWebDavServlet.TYPE_CONTENT_DEFAULT;
+ }
+
@Activate
@Modified
@SuppressWarnings("unused")
- private void activate(final Map<String, Object> properties) {
- final String collectionType = OsgiUtil.toString(
- properties.get(SlingWebDavServlet.TYPE_COLLECTIONS),
- SlingWebDavServlet.TYPE_COLLECTIONS_DEFAULT);
- final String nonCollectionType = OsgiUtil.toString(
- properties.get(SlingWebDavServlet.TYPE_NONCOLLECTIONS),
- SlingWebDavServlet.TYPE_NONCOLLECTIONS_DEFAULT);
- final String contentType = OsgiUtil.toString(
- properties.get(SlingWebDavServlet.TYPE_CONTENT),
- SlingWebDavServlet.TYPE_CONTENT_DEFAULT);
+ private void activate(final Config config) {
+ final String collectionType = config.type_collections();
+ final String nonCollectionType = config.type_noncollections();
+ final String contentType = config.type_content();
- this.delegatee = new DefaultHandler(null, collectionType,
- nonCollectionType, contentType);
+ this.delegatee = new DefaultHandler(null, collectionType, nonCollectionType, contentType);
}
@Deactivate
diff --git a/src/main/java/org/apache/sling/jcr/webdav/impl/handler/DirListingExportHandlerService.java b/src/main/java/org/apache/sling/jcr/webdav/impl/handler/DirListingExportHandlerService.java
index 6aaa989..a5e8857 100644
--- a/src/main/java/org/apache/sling/jcr/webdav/impl/handler/DirListingExportHandlerService.java
+++ b/src/main/java/org/apache/sling/jcr/webdav/impl/handler/DirListingExportHandlerService.java
@@ -18,20 +18,17 @@
*/
package org.apache.sling.jcr.webdav.impl.handler;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.server.io.DirListingExportHandler;
import org.apache.jackrabbit.server.io.IOHandler;
import org.apache.jackrabbit.server.io.PropertyHandler;
-import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.propertytypes.ServiceRanking;
/**
* Wraps {@link org.apache.jackrabbit.server.io.DirListingExportHandler} in order to run it as a service.
*/
-@Component(metatype = true, label = "%dirlistingexporthandler.name", description = "%dirlistingexporthandler.description")
-@Property(name = Constants.SERVICE_RANKING, intValue = 100, propertyPrivate = false)
-@Service(value = {IOHandler.class, PropertyHandler.class})
+@Component(immediate = true, service = { IOHandler.class, PropertyHandler.class })
+@ServiceRanking(100)
public class DirListingExportHandlerService extends DirListingExportHandler {
}
diff --git a/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingCopyMoveManager.java b/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingCopyMoveManager.java
index 312e031..cdfee7c 100644
--- a/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingCopyMoveManager.java
+++ b/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingCopyMoveManager.java
@@ -34,7 +34,7 @@
private final SlingHandlerManager<CopyMoveHandler> handlerManager;
public SlingCopyMoveManager(final String referenceName) {
- handlerManager = new SlingHandlerManager<CopyMoveHandler>(referenceName);
+ handlerManager = new SlingHandlerManager<>(referenceName);
}
@Override
diff --git a/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingDeleteManager.java b/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingDeleteManager.java
index 156a720..1bb1942 100644
--- a/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingDeleteManager.java
+++ b/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingDeleteManager.java
@@ -34,7 +34,7 @@
private final SlingHandlerManager<DeleteHandler> handlerManager;
public SlingDeleteManager(final String referenceName) {
- handlerManager = new SlingHandlerManager<DeleteHandler>(referenceName);
+ handlerManager = new SlingHandlerManager<>(referenceName);
}
@Override
diff --git a/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingHandlerManager.java b/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingHandlerManager.java
index 6660095..8afa92e 100644
--- a/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingHandlerManager.java
+++ b/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingHandlerManager.java
@@ -33,7 +33,7 @@
*/
public class SlingHandlerManager<ManagedType> {
- private final TreeMap<ServiceReference, ManagedType> handlerServices = new TreeMap<ServiceReference, ManagedType>();
+ private final TreeMap<ServiceReference, ManagedType> handlerServices = new TreeMap<>();
private ComponentContext componentContext;
@@ -58,9 +58,9 @@
entries = this.handlerServices.entrySet();
}
- final ArrayList<ManagedType> ioHandlers = new ArrayList<ManagedType>(
+ final ArrayList<ManagedType> ioHandlers = new ArrayList<>(
entries.size());
- final Map<ServiceReference, ManagedType> updates = new HashMap<ServiceReference, ManagedType>();
+ final Map<ServiceReference, ManagedType> updates = new HashMap<>();
for (Entry<ServiceReference, ManagedType> entry : entries) {
final ManagedType ioHandler;
if (entry.getValue() == null) {
diff --git a/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingIOManager.java b/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingIOManager.java
index ed1c9be..f6289c1 100644
--- a/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingIOManager.java
+++ b/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingIOManager.java
@@ -33,7 +33,7 @@
private final SlingHandlerManager<IOHandler> handlerManager;
public SlingIOManager(final String referenceName) {
- handlerManager = new SlingHandlerManager<IOHandler>(referenceName);
+ handlerManager = new SlingHandlerManager<>(referenceName);
}
@Override
diff --git a/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingPropertyManager.java b/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingPropertyManager.java
index 30f3d90..2ab3734 100644
--- a/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingPropertyManager.java
+++ b/src/main/java/org/apache/sling/jcr/webdav/impl/handler/SlingPropertyManager.java
@@ -34,7 +34,7 @@
private final SlingHandlerManager<PropertyHandler> handlerManager;
public SlingPropertyManager(final String referenceName) {
- handlerManager = new SlingHandlerManager<PropertyHandler>(referenceName);
+ handlerManager = new SlingHandlerManager<>(referenceName);
}
@Override
diff --git a/src/main/java/org/apache/sling/jcr/webdav/impl/helper/SlingResourceConfig.java b/src/main/java/org/apache/sling/jcr/webdav/impl/helper/SlingResourceConfig.java
index 8f94274..aa810e6 100644
--- a/src/main/java/org/apache/sling/jcr/webdav/impl/helper/SlingResourceConfig.java
+++ b/src/main/java/org/apache/sling/jcr/webdav/impl/helper/SlingResourceConfig.java
@@ -27,7 +27,6 @@
import org.apache.jackrabbit.webdav.simple.ResourceConfig;
import org.apache.jackrabbit.webdav.simple.SimpleWebdavServlet;
import org.apache.sling.commons.mime.MimeTypeService;
-import org.apache.sling.commons.osgi.OsgiUtil;
import org.apache.sling.jcr.webdav.impl.servlets.SlingWebDavServlet;
import javax.jcr.Item;
@@ -56,7 +55,7 @@
private final Dictionary<String, String> servletInitParams;
public SlingResourceConfig(MimeTypeService mimeTypeService,
- Dictionary<?, ?> config,
+ SlingWebDavServlet.Config config,
IOManager ioManager,
PropertyManager propertyManager,
CopyMoveManager copyMoveManager,
@@ -66,46 +65,25 @@
this.propertyManager = propertyManager;
this.copyMoveManager = copyMoveManager;
this.deleteManager = deleteManager;
- collectionTypes = OsgiUtil.toStringArray(
- config.get(SlingWebDavServlet.COLLECTION_TYPES),
- SlingWebDavServlet.COLLECTION_TYPES_DEFAULT);
- String[] filterPrefixes = OsgiUtil.toStringArray(
- config.get(SlingWebDavServlet.FILTER_PREFIXES),
- SlingWebDavServlet.FILTER_PREFIXES_DEFAULT);
- String[] filterNodeTypes = OsgiUtil.toStringArray(
- config.get(SlingWebDavServlet.FILTER_TYPES),
- SlingWebDavServlet.EMPTY_DEFAULT);
- String[] filterURIs = OsgiUtil.toStringArray(
- config.get(SlingWebDavServlet.FILTER_URIS),
- SlingWebDavServlet.EMPTY_DEFAULT);
+ collectionTypes = config.collection_types();
+ String[] filterPrefixes = config.filter_prefixes();
+ String[] filterNodeTypes = config.filter_types();
+ String[] filterURIs = config.filter_uris();
itemFilter = new DefaultItemFilter();
itemFilter.setFilteredPrefixes(filterPrefixes);
itemFilter.setFilteredURIs(filterURIs);
itemFilter.setFilteredNodetypes(filterNodeTypes);
- servletContextPath = OsgiUtil.toString(
- config.get(SlingWebDavServlet.PROP_CONTEXT),
- SlingWebDavServlet.DEFAULT_CONTEXT);
+ servletContextPath = config.dav_root();
+ servletInitParams = new Hashtable<>();
+ servletInitParams.put(SimpleWebdavServlet.INIT_PARAM_RESOURCE_PATH_PREFIX, servletContextPath);
+ String value = config.dav_realm();
+ servletInitParams.put(SimpleWebdavServlet.INIT_PARAM_AUTHENTICATE_HEADER, "Basic realm=\"" + value + "\"");
- servletInitParams = new Hashtable<String, String>();
- servletInitParams.put(
- SimpleWebdavServlet.INIT_PARAM_RESOURCE_PATH_PREFIX,
- servletContextPath);
- String value = OsgiUtil.toString(
- config.get(SlingWebDavServlet.PROP_REALM),
- SlingWebDavServlet.DEFAULT_REALM);
- servletInitParams.put(
- SimpleWebdavServlet.INIT_PARAM_AUTHENTICATE_HEADER,
- "Basic realm=\"" + value + "\"");
-
- boolean createAbsoluteUri = OsgiUtil.toBoolean(
- config.get(SlingWebDavServlet.PROP_CREATE_ABSOLUTE_URI),
- SlingWebDavServlet.DEFAULT_CREATE_ABSOLUTE_URI);
- servletInitParams.put(
- SimpleWebdavServlet.INIT_PARAM_CREATE_ABSOLUTE_URI,
- Boolean.toString(createAbsoluteUri));
+ boolean createAbsoluteUri = config.dav_create$_$absolute$_$uri();
+ servletInitParams.put(SimpleWebdavServlet.INIT_PARAM_CREATE_ABSOLUTE_URI, Boolean.toString(createAbsoluteUri));
}
// ---------- ResourceConfig overwrites
diff --git a/src/main/java/org/apache/sling/jcr/webdav/impl/servlets/SlingWebDavServlet.java b/src/main/java/org/apache/sling/jcr/webdav/impl/servlets/SlingWebDavServlet.java
index 2785e69..5fbb6c9 100644
--- a/src/main/java/org/apache/sling/jcr/webdav/impl/servlets/SlingWebDavServlet.java
+++ b/src/main/java/org/apache/sling/jcr/webdav/impl/servlets/SlingWebDavServlet.java
@@ -26,15 +26,6 @@
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.ConfigurationPolicy;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.ReferencePolicy;
-import org.apache.felix.scr.annotations.References;
-import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.server.SessionProvider;
import org.apache.jackrabbit.server.io.CopyMoveHandler;
import org.apache.jackrabbit.server.io.DeleteHandler;
@@ -54,93 +45,106 @@
import org.apache.sling.jcr.webdav.impl.helper.SlingLocatorFactory;
import org.apache.sling.jcr.webdav.impl.helper.SlingResourceConfig;
import org.apache.sling.jcr.webdav.impl.helper.SlingSessionProvider;
-import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.propertytypes.ServiceDescription;
+import org.osgi.service.component.propertytypes.ServiceVendor;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
/**
* The <code>SlingWebDavServlet</code> implements the WebDAV protocol as a
* default servlet for Sling handling all WebDAV methods.
*
*/
-@Component(name = "org.apache.sling.jcr.webdav.impl.servlets.SimpleWebDavServlet",
- label = "%dav.name", description = "%dav.description",
- metatype = true,
- policy = ConfigurationPolicy.REQUIRE)
-@Service(Servlet.class)
-@Properties({
- @Property(name = Constants.SERVICE_DESCRIPTION, value = "Sling WebDAV Servlet"),
- @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation"),
- @Property(name = "sling.servlet.resourceTypes", value = "sling/servlet/default", propertyPrivate = true),
- @Property(name = "sling.servlet.methods", value = "*", propertyPrivate = true) })
- @References({
- @Reference(name = SlingWebDavServlet.IOHANDLER_REF_NAME, referenceInterface = IOHandler.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
- @Reference(name = SlingWebDavServlet.PROPERTYHANDLER_REF_NAME, referenceInterface = PropertyHandler.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
- @Reference(name = SlingWebDavServlet.COPYMOVEHANDLER_REF_NAME, referenceInterface = CopyMoveHandler.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC),
- @Reference(name = SlingWebDavServlet.DELETEHANDLER_REF_NAME, referenceInterface = DeleteHandler.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC)
-})
+@Component(
+ name = "org.apache.sling.jcr.webdav.impl.servlets.SimpleWebDavServlet",
+ configurationPolicy = ConfigurationPolicy.REQUIRE,
+ service = { Servlet.class },
+ property = {
+ "sling.servlet.resourceTypes=sling/servlet/default",
+ "sling.servlet.methods=*"
+ },
+ reference = {
+ @Reference( name = SlingWebDavServlet.IOHANDLER_REF_NAME, service = IOHandler.class,
+ cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC,
+ bind = "bindIOHandler", unbind = "unbindIOHandler"),
+ @Reference( name = SlingWebDavServlet.PROPERTYHANDLER_REF_NAME, service = PropertyHandler.class,
+ cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC,
+ bind = "bindPropertyHandler", unbind = "unbindPropertyHandler"),
+ @Reference( name = SlingWebDavServlet.COPYMOVEHANDLER_REF_NAME, service = CopyMoveHandler.class,
+ cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC,
+ bind = "bindCopyMoveHandler", unbind = "unbindCopyMoveHandler"),
+ @Reference( name = SlingWebDavServlet.DELETEHANDLER_REF_NAME, service = DeleteHandler.class,
+ cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC,
+ bind = "bindDeleteHandler", unbind = "unbindDeleteHandler")
+
+ })
+@ServiceDescription("Sling WebDAV Servlet")
+@ServiceVendor("The Apache Software Foundation")
+@Designate(ocd = SlingWebDavServlet.Config.class)
public class SlingWebDavServlet extends SimpleWebdavServlet {
public static final String DEFAULT_CONTEXT = "/dav";
-
- @Property(DEFAULT_CONTEXT)
- public static final String PROP_CONTEXT = "dav.root";
-
public static final boolean DEFAULT_CREATE_ABSOLUTE_URI = true;
-
- @Property(boolValue=DEFAULT_CREATE_ABSOLUTE_URI)
- public static final String PROP_CREATE_ABSOLUTE_URI = "dav.create-absolute-uri";
-
public static final String DEFAULT_REALM = "Sling WebDAV";
-
- @Property(DEFAULT_REALM)
- public static final String PROP_REALM = "dav.realm";
-
- public static final String COLLECTION_TYPES = "collection.types";
-
public static final String TYPE_NONCOLLECTIONS_DEFAULT = "nt:file";
-
public static final String TYPE_CONTENT_DEFAULT = "nt:resource";
-
- @Property(name = COLLECTION_TYPES)
- public static final String[] COLLECTION_TYPES_DEFAULT = new String[] {
- TYPE_NONCOLLECTIONS_DEFAULT, TYPE_CONTENT_DEFAULT };
-
- public static final String FILTER_PREFIXES = "filter.prefixes";
-
- @Property(name = FILTER_PREFIXES)
- public static final String[] FILTER_PREFIXES_DEFAULT = new String[] {
- "rep", "jcr" };
-
- public static final String[] EMPTY_DEFAULT = new String[0];
-
- @Property({})
- public static final String FILTER_TYPES = "filter.types";
-
- @Property({})
- public static final String FILTER_URIS = "filter.uris";
-
public static final String TYPE_COLLECTIONS_DEFAULT = "sling:Folder";
-
- @Property(TYPE_COLLECTIONS_DEFAULT)
public static final String TYPE_COLLECTIONS = "type.collections";
-
- @Property(TYPE_NONCOLLECTIONS_DEFAULT)
public static final String TYPE_NONCOLLECTIONS = "type.noncollections";
-
- @Property(TYPE_CONTENT_DEFAULT)
public static final String TYPE_CONTENT = "type.content";
static final String IOHANDLER_REF_NAME = "IOHandler";
-
static final String PROPERTYHANDLER_REF_NAME = "PropertyHandler";
-
static final String COPYMOVEHANDLER_REF_NAME = "CopyMoveHandler";
-
static final String DELETEHANDLER_REF_NAME = "DeleteHandler";
+ @SuppressWarnings("java:S100")
+ @ObjectClassDefinition(name = "%dav.name", description = "%dav.description")
+ public @interface Config {
+
+ @AttributeDefinition(name = "%dav.root.name", description = "%dav.root.description")
+ String dav_root() default DEFAULT_CONTEXT;
+
+ @AttributeDefinition(name = "%dav.create-absolute-uri.name", description = "%dav.create-absolute-uri.description")
+ boolean dav_create$_$absolute$_$uri() default DEFAULT_CREATE_ABSOLUTE_URI;
+
+ @AttributeDefinition(name = "%dav.realm.name", description = "%dav.realm.description")
+ String dav_realm() default DEFAULT_REALM;
+
+ @AttributeDefinition(name = "%collection.types.name", description = "%collection.types.description")
+ String[] collection_types() default {TYPE_NONCOLLECTIONS_DEFAULT, TYPE_CONTENT_DEFAULT};
+
+ @AttributeDefinition(name = "%filter.prefixes.name", description = "%filter.prefixes.description")
+ String[] filter_prefixes() default {"rep", "jcr"};
+
+ @AttributeDefinition(name = "%filter.types.name", description = "%filter.types.description")
+ String[] filter_types() default {};
+
+ @AttributeDefinition(name = "%filter.uris.name", description = "%filter.uris.description")
+ String[] filter_uris() default {};
+
+ @AttributeDefinition(name = "%type.collections.name", description = "%type.collections.description")
+ String type_collections() default TYPE_COLLECTIONS_DEFAULT;
+
+ @AttributeDefinition(name = "%type.noncollections.name", description = "%type.noncollections.description")
+ String type_noncollections() default TYPE_NONCOLLECTIONS_DEFAULT;
+
+ @AttributeDefinition(name = "%type.content.name", description = "%type.content.description")
+ String type_content() default TYPE_CONTENT_DEFAULT;
+ }
+
@Reference
private SlingRepository repository;
@@ -150,17 +154,13 @@
@Reference
private MimeTypeService mimeTypeService;
- private final SlingIOManager ioManager = new SlingIOManager(
- IOHANDLER_REF_NAME);
+ private final SlingIOManager ioManager = new SlingIOManager(IOHANDLER_REF_NAME);
- private final SlingPropertyManager propertyManager = new SlingPropertyManager(
- PROPERTYHANDLER_REF_NAME);
+ private final SlingPropertyManager propertyManager = new SlingPropertyManager(PROPERTYHANDLER_REF_NAME);
- private final SlingCopyMoveManager copyMoveManager = new SlingCopyMoveManager(
- COPYMOVEHANDLER_REF_NAME);
+ private final SlingCopyMoveManager copyMoveManager = new SlingCopyMoveManager(COPYMOVEHANDLER_REF_NAME);
- private final SlingDeleteManager deleteManager = new SlingDeleteManager(
- DELETEHANDLER_REF_NAME);
+ private final SlingDeleteManager deleteManager = new SlingDeleteManager(DELETEHANDLER_REF_NAME);
private SlingResourceConfig resourceConfig;
@@ -221,9 +221,8 @@
return sessionProvider;
}
- // ---------- SCR integration
-
- protected void activate(ComponentContext context)
+ @Activate
+ protected void activate(ComponentContext context, Config config)
throws NamespaceException, ServletException {
this.ioManager.setComponentContext(context);
@@ -232,21 +231,20 @@
this.deleteManager.setComponentContext(context);
resourceConfig = new SlingResourceConfig(mimeTypeService,
- context.getProperties(),
- ioManager,
- propertyManager,
- copyMoveManager,
- deleteManager);
+ config,
+ ioManager,
+ propertyManager,
+ copyMoveManager,
+ deleteManager);
- // Register servlet, and set the contextPath field to signal successful
- // registration
- Servlet simpleServlet = new SlingSimpleWebDavServlet(resourceConfig,
- getRepository());
+ // Register servlet, and set the contextPath field to signal successful registration
+ Servlet simpleServlet = new SlingSimpleWebDavServlet(resourceConfig, getRepository());
httpService.registerServlet(resourceConfig.getServletContextPath(),
simpleServlet, resourceConfig.getServletInitParams(), null);
simpleWebDavServletRegistered = true;
}
+ @Deactivate
protected void deactivate(ComponentContext context) {
if (simpleWebDavServletRegistered) {
diff --git a/src/main/resources/OSGI-INF/l10n/org.apache.sling.jcr.webdav.impl.handler.DefaultHandlerService$Config.properties b/src/main/resources/OSGI-INF/l10n/org.apache.sling.jcr.webdav.impl.handler.DefaultHandlerService$Config.properties
new file mode 100644
index 0000000..957a06c
--- /dev/null
+++ b/src/main/resources/OSGI-INF/l10n/org.apache.sling.jcr.webdav.impl.handler.DefaultHandlerService$Config.properties
@@ -0,0 +1,47 @@
+#
+# 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.
+#
+
+defaulthandler.name = Apache Sling Default Handler Service
+defaulthandler.description = The Apache Sling Default Handler Service \
+ wraps a org.apache.jackrabbit.server.io.DefaultHandler instance in order to \
+ run it as a service.
+
+type.collections.name = Collection Primary Type
+type.collections.description = The JCR Primary Node Type to assign to nodes \
+ created to reflect WebDAV collections. The default value is sling:Folder. \
+ You may name any primary node type here, provided it allows the creation of \
+ nodes of this type and the defined Non-Collection Primary Type below it.
+
+type.noncollections.name = Non-Collection Primary Type
+type.noncollections.description = The JCR Primary Node Type to assign to \
+ nodes created to reflect WebDAV non-collection resources. The default value \
+ is nt:file. You may name any primary node type here, provided the node type \
+ is allowed to be created below nodes of the type defined for the Collection \
+ Primary Type and that a child node with the name "jcr:content" may be created \
+ below the non-collection resource whose type is defined by the Content Primary \
+ Type.
+
+type.content.name = Content Primary Type
+type.content.description = The JCR Primary Node Type to assign to the \
+ jcr:content child node of a WebDAV non-collection resource. The default value \
+ is nt:resource. You may name any primary node type here, provided the node \
+ type is allowed to be created as the jcr:content child node of the node type \
+ defined by the Non-Collection Primary Type. In addition the node type must \
+ allow at least the following properties: jcr:data (binary), jcr:lastModified \
+ (date), and jcr:mimeType (string).
diff --git a/src/main/resources/OSGI-INF/l10n/metatype.properties b/src/main/resources/OSGI-INF/l10n/org.apache.sling.jcr.webdav.impl.servlets.SlingWebDavServlet$Config.properties
similarity index 96%
rename from src/main/resources/OSGI-INF/l10n/metatype.properties
rename to src/main/resources/OSGI-INF/l10n/org.apache.sling.jcr.webdav.impl.servlets.SlingWebDavServlet$Config.properties
index 3a4fe61..b0993d0 100644
--- a/src/main/resources/OSGI-INF/l10n/metatype.properties
+++ b/src/main/resources/OSGI-INF/l10n/org.apache.sling.jcr.webdav.impl.servlets.SlingWebDavServlet$Config.properties
@@ -42,10 +42,6 @@
wraps a org.apache.jackrabbit.server.io.DirListingExportHandler instance in order to \
run it as a service.
-defaulthandler.name = Apache Sling Default Handler Service
-defaulthandler.description = The Apache Sling Default Handler Service \
- wraps a org.apache.jackrabbit.server.io.DefaultHandler instance in order to \
- run it as a service.
dav.name = Apache Sling Simple WebDAV Servlet
dav.description = The Simple WebDAV Servlet allows direct access to the \
diff --git a/src/test/java/org/apache/sling/jcr/webdav/impl/handler/DefaultHandlerServiceTest.java b/src/test/java/org/apache/sling/jcr/webdav/impl/handler/DefaultHandlerServiceTest.java
new file mode 100644
index 0000000..e8ae0fb
--- /dev/null
+++ b/src/test/java/org/apache/sling/jcr/webdav/impl/handler/DefaultHandlerServiceTest.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.jcr.webdav.impl.handler;
+
+import org.apache.jackrabbit.server.io.CopyMoveHandler;
+import org.apache.jackrabbit.server.io.DeleteHandler;
+import org.apache.jackrabbit.server.io.IOHandler;
+import org.apache.jackrabbit.server.io.PropertyHandler;
+import org.apache.sling.jcr.webdav.impl.servlets.SlingWebDavServlet;
+import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import static org.junit.Assert.assertNotNull;
+
+public class DefaultHandlerServiceTest {
+
+ @Rule
+ public final OsgiContext context = new OsgiContext();
+
+ private DefaultHandlerService defaultHandlerService;
+
+ @Before
+ public void setUp() {
+ defaultHandlerService = new DefaultHandlerService();
+ Dictionary<String, Object> properties = new Hashtable<>();
+ properties.put(SlingWebDavServlet.TYPE_COLLECTIONS, SlingWebDavServlet.TYPE_COLLECTIONS_DEFAULT);
+ properties.put(SlingWebDavServlet.TYPE_NONCOLLECTIONS, SlingWebDavServlet.TYPE_NONCOLLECTIONS_DEFAULT);
+ properties.put(SlingWebDavServlet.TYPE_CONTENT, SlingWebDavServlet.TYPE_CONTENT_DEFAULT);
+
+ context.registerInjectActivateService(DefaultHandlerService.class, defaultHandlerService, properties);
+ }
+
+ @Test
+ public void testIfServiceActive() {
+ assertNotNull(context.getService(CopyMoveHandler.class));
+ assertNotNull(context.getService(PropertyHandler.class));
+ assertNotNull(context.getService(IOHandler.class));
+ assertNotNull(context.getService(DeleteHandler.class));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/jcr/webdav/impl/handler/DirListingExportHandlerServiceTest.java b/src/test/java/org/apache/sling/jcr/webdav/impl/handler/DirListingExportHandlerServiceTest.java
new file mode 100644
index 0000000..e887898
--- /dev/null
+++ b/src/test/java/org/apache/sling/jcr/webdav/impl/handler/DirListingExportHandlerServiceTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.webdav.impl.handler;
+
+import org.apache.sling.testing.mock.osgi.MockOsgi;
+import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+
+import static org.junit.Assert.assertNotNull;
+
+public class DirListingExportHandlerServiceTest {
+
+ @Rule
+ public final OsgiContext context = new OsgiContext();
+
+ private DirListingExportHandlerService dirListingExportHandlerService;
+
+ private BundleContext bundleContext;
+
+ @Before
+ public void setUp() {
+ bundleContext = MockOsgi.newBundleContext();
+ dirListingExportHandlerService = new DirListingExportHandlerService();
+ context.registerService(DirListingExportHandlerService.class, dirListingExportHandlerService);
+ }
+
+ @Test
+ public void testIfServiceActive() {
+ MockOsgi.activate(dirListingExportHandlerService, bundleContext);
+ DirListingExportHandlerService registeredService = context.getService(DirListingExportHandlerService.class);
+ assertNotNull(registeredService);
+
+ MockOsgi.deactivate(dirListingExportHandlerService, bundleContext);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/jcr/webdav/impl/servlets/SlingWebDavServletTest.java b/src/test/java/org/apache/sling/jcr/webdav/impl/servlets/SlingWebDavServletTest.java
new file mode 100644
index 0000000..b96fb0f
--- /dev/null
+++ b/src/test/java/org/apache/sling/jcr/webdav/impl/servlets/SlingWebDavServletTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.webdav.impl.servlets;
+
+import org.apache.sling.commons.mime.MimeTypeService;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.testing.mock.osgi.MockOsgi;
+import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
+import org.apache.sling.testing.mock.sling.MockJcrSlingRepository;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.http.HttpService;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(MockitoJUnitRunner.class)
+public class SlingWebDavServletTest {
+
+ @Rule
+ public final OsgiContext context = new OsgiContext();
+
+ private SlingWebDavServlet slingWebDavServlet;
+ private BundleContext bundleContext;
+ private SlingRepository repository;
+
+ @Before
+ public void setUp() {
+ bundleContext = MockOsgi.newBundleContext();
+ Dictionary<String, Object> properties = new Hashtable<>();
+
+ properties.put("dav.root", SlingWebDavServlet.DEFAULT_CONTEXT);
+ properties.put("dav.realm", SlingWebDavServlet.DEFAULT_REALM);
+ properties.put("dav.create-absolute-uri", SlingWebDavServlet.DEFAULT_CREATE_ABSOLUTE_URI);
+ properties.put(SlingWebDavServlet.TYPE_COLLECTIONS, SlingWebDavServlet.TYPE_COLLECTIONS_DEFAULT);
+ properties.put(SlingWebDavServlet.TYPE_NONCOLLECTIONS, SlingWebDavServlet.TYPE_NONCOLLECTIONS_DEFAULT);
+ properties.put(SlingWebDavServlet.TYPE_CONTENT, SlingWebDavServlet.TYPE_CONTENT_DEFAULT);
+
+ //Mock HttpService
+ HttpService httpService = Mockito.mock(HttpService.class);
+ context.registerService(HttpService.class, httpService);
+
+ //Mock MimeTypeService
+ MimeTypeService mimeTypeService = Mockito.mock(MimeTypeService.class);
+ context.registerService(MimeTypeService.class, mimeTypeService);
+
+ repository = context.registerInjectActivateService(new MockJcrSlingRepository());
+ slingWebDavServlet = context.registerInjectActivateService(new SlingWebDavServlet(), properties);
+ }
+
+ @Test
+ public void testIfServiceActive() {
+ assertNotNull(slingWebDavServlet);
+ }
+}
\ No newline at end of file